diff options
author | Eike Ziller <eike.ziller@qt.io> | 2019-10-23 07:41:01 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2019-10-23 07:41:01 +0200 |
commit | 9760d02b77c31c9ed34bd10703d0fc55b9cdb300 (patch) | |
tree | 6faf6a17abe30669acd30a7041b8a58b7bddcd86 | |
parent | b8657ac73930bc729d601366b047528847413f9e (diff) | |
parent | 1b655f76ad61cc17483d00b8ece06e08afaeaf01 (diff) |
Merge remote-tracking branch 'origin/4.11'
Conflicts:
src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
src/plugins/qtsupport/qtversionmanager.cpp
Change-Id: I2f29dd2e86b028be46184b12ac2c17ace2513d5a
107 files changed, 1988 insertions, 977 deletions
diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index f122ef1daf..300b7cd50a 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -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}") diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 30a062ecb8..172f2e6dcf 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -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. diff --git a/doc/images/qtcreator-mcu-device.png b/doc/images/qtcreator-mcu-device.png Binary files differnew file mode 100644 index 0000000000..4159ec10c6 --- /dev/null +++ b/doc/images/qtcreator-mcu-device.png diff --git a/doc/images/qtcreator-mcu-kit.png b/doc/images/qtcreator-mcu-kit.png Binary files differnew file mode 100644 index 0000000000..e91f784a39 --- /dev/null +++ b/doc/images/qtcreator-mcu-kit.png diff --git a/doc/images/qtcreator-mcu-options.png b/doc/images/qtcreator-mcu-options.png Binary files differnew file mode 100644 index 0000000000..e5bcf1f4e6 --- /dev/null +++ b/doc/images/qtcreator-mcu-options.png diff --git a/doc/src/ios/creator-ios-dev.qdoc b/doc/src/ios/creator-ios-dev.qdoc index ba67111ea2..633d027521 100644 --- a/doc/src/ios/creator-ios-dev.qdoc +++ b/doc/src/ios/creator-ios-dev.qdoc @@ -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 diff --git a/doc/src/mcu/creator-mcu-dev.qdoc b/doc/src/mcu/creator-mcu-dev.qdoc new file mode 100644 index 0000000000..c4da995de3 --- /dev/null +++ b/doc/src/mcu/creator-mcu-dev.qdoc @@ -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 +*/ diff --git a/doc/src/overview/creator-only/creator-mobile-targets.qdoc b/doc/src/overview/creator-only/creator-mobile-targets.qdoc index 37822c534f..470d5c2360 100644 --- a/doc/src/overview/creator-only/creator-mobile-targets.qdoc +++ b/doc/src/overview/creator-only/creator-mobile-targets.qdoc @@ -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 diff --git a/doc/src/overview/creator-only/creator-target-platforms.qdocinc b/doc/src/overview/creator-only/creator-target-platforms.qdocinc index c269e61404..95015bd805 100644 --- a/doc/src/overview/creator-only/creator-target-platforms.qdocinc +++ b/doc/src/overview/creator-only/creator-target-platforms.qdocinc @@ -42,6 +42,8 @@ \li iOS + \li Microcontroller Units (MCU) + \li QNX \li Universal Windows Platform (UWP) @@ -96,6 +98,11 @@ \li \image ok \li \row + \li MCUs + \li \image ok + \li \image ok + \li \image ok + \row \li QNX \li \image ok \li \image ok diff --git a/doc/src/projects/creator-only/creator-projects-creating.qdoc b/doc/src/projects/creator-only/creator-projects-creating.qdoc index 557b2acfcb..1bca73e551 100644 --- a/doc/src/projects/creator-only/creator-projects-creating.qdoc +++ b/doc/src/projects/creator-only/creator-projects-creating.qdoc @@ -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 diff --git a/doc/src/qnx/creator-developing-qnx.qdoc b/doc/src/qnx/creator-developing-qnx.qdoc index 7787437303..8dce60438d 100644 --- a/doc/src/qnx/creator-developing-qnx.qdoc +++ b/doc/src/qnx/creator-developing-qnx.qdoc @@ -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 diff --git a/doc/src/qtcreator-toc.qdoc b/doc/src/qtcreator-toc.qdoc index 7527b8a965..7774af4951 100644 --- a/doc/src/qtcreator-toc.qdoc +++ b/doc/src/qtcreator-toc.qdoc @@ -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 diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 3269b43f78..696ccf90c1 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -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 diff --git a/qtcreator_ide_branding.pri b/qtcreator_ide_branding.pri index f068254edc..ddd9fd42c7 100644 --- a/qtcreator_ide_branding.pri +++ b/qtcreator_ide_branding.pri @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.cpp new file mode 100644 index 0000000000..a634e76b8f --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.cpp @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.h b/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.h new file mode 100644 index 0000000000..a5962c5dcb --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/commands/changeselectioncommand.h @@ -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) diff --git a/share/qtcreator/qml/qmlpuppet/commands/commands.pri b/share/qtcreator/qml/qmlpuppet/commands/commands.pri index 3bf0305103..78dfcd8eb1 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/commands.pri +++ b/share/qtcreator/qml/qmlpuppet/commands/commands.pri @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp index 73c8138a43..c5468bc999 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp @@ -50,7 +50,7 @@ ValuesChangedCommand::ValuesChangedCommand(const QVector<PropertyValueContainer> { } -QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const +const QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const { return m_valueChangeVector; } diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h index 96050aee7f..bf7fe1e43d 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h +++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.h @@ -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) diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp index 5ac0e1057b..3e57baffd0 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp @@ -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,13 +138,16 @@ 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() == pixmapChangedCommandType) + 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) return command.value<ChildrenChangedCommand>() == controlCommand.value<ChildrenChangedCommand>(); @@ -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); } diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h index 2c53a77c90..edf290f38a 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h @@ -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: diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h index 43c50b510c..0b5a5ca334 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceclientinterface.h @@ -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() {} diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp index 8d1ad20c31..d2b7cb2620 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.cpp @@ -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"); diff --git a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h index 0fddbde5c0..b452c802be 100644 --- a/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h +++ b/share/qtcreator/qml/qmlpuppet/interfaces/nodeinstanceserverinterface.h @@ -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 &) {} diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index f6ad8b58f2..d3b693788a 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -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 - } + focus: true - Column { - y: 32 - Slider { - id: slider + View3D { + id: editView + anchors.fill: parent + enableWireframeMode: true + camera: editCamera - value: -600 - from: -1200 - to: 600 - } - Slider { - id: slider2 + AxisHelper { + id: axisGrid + enableXZGrid: true + enableAxisLines: false + } - value: 0 - from: -360 - to: 360 - } - CheckBox { - id: checkBox - text: "Light" - Rectangle { - anchors.fill: parent - z: -1 + Light { + id: pointLight + visible: showEditLight + position: editCamera.position + lightType: Light.Point } - } - } - Binding { - target: view.scene - property: "rotation.y" - value: slider2.value - } + Camera { + id: editCamera + y: 200 + z: -300 + clipFar: 100000 + projectionMode: usePerspective ? Camera.Perspective : Camera.Orthographic + } - property alias scene: view.scene - property alias showLight: checkBox.checked + Component.onCompleted: { + pointLight.setParentItem(editView.scene); + editCamera.setParentItem(editView.scene); + } + } - id: viewWindow + WasdController { + id: cameraControl + controlledObject: editView.camera + acceptedButtons: Qt.RightButton - View3D { - id: view - anchors.fill: parent - enableWireframeMode: true - camera: camera01 + onInputsNeedProcessingChanged: designStudioNativeCameraControlHelper.enabled + = cameraControl.inputsNeedProcessing - Light { - id: directionalLight - visible: checkBox.checked + // Use separate native timer as QML timers don't work inside Qt Design Studio + Connections { + target: designStudioNativeCameraControlHelper + onUpdateInputs: cameraControl.processInputs() + } } + } - Camera { - id: camera01 - z: slider.value + Column { + y: 8 + CheckBox { + id: editLightCheckbox + checked: false + text: qsTr("Use Edit View Light") + onCheckedChanged: cameraControl.forceActiveFocus() } - Component.onCompleted: { - directionalLight.setParentItem(view.scene) - camera01.setParentItem(view.scene) + 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 + } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp new file mode 100644 index 0000000000..c05e8230bf --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.cpp @@ -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; +} + +} +} diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h new file mode 100644 index 0000000000..87ef1025ff --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/cameracontrolhelper.h @@ -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; +}; + +} +} diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri new file mode 100644 index 0000000000..7b86f8bc82 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri @@ -0,0 +1,2 @@ +HEADERS += $$PWD/cameracontrolhelper.h +SOURCES += $$PWD/cameracontrolhelper.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index 300f80d2b3..50c0bd41bb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index 60d34c909d..bd293488f1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -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()); - else - instance.resetProperty("visible"); - } + if (!auxiliaryContainer.value().isNull()) + instance.setHideInEditor(auxiliaryContainer.value().toBool()); + else + 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; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h index fb8b081b45..65c2bdfac1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -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); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index 7fa0e316b6..2f0244ddeb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -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>()); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h index 55114e872a..8aa7ce4ad4 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h @@ -193,6 +193,8 @@ public: virtual PropertyNameList ignoredProperties() const; + void virtual setHideInEditor(bool b); + protected: explicit ObjectNodeInstance(QObject *object); void doResetProperty(const PropertyName &propertyName); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 2b644b5959..d0931da3e0 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index 9254cb4157..962336ccdc 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -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); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp index cb5af3dc80..fed075a486 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.cpp @@ -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(); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.h index af30c423d6..18c2056174 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5testnodeinstanceserver.h @@ -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; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp new file mode 100644 index 0000000000..29c3ab3f29 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp @@ -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 + diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h new file mode 100644 index 0000000000..6bfc2a02a1 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h @@ -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 diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index 87aea97d8d..376ca29524 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -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); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h index 2bfc5147a7..7e72878dca 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -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); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri index 39599385a8..d0bab57ca1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppet.pri @@ -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) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml index 11c358af2a..bf42b96415 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml @@ -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() } } diff --git a/src/app/main.cpp b/src/app/main.cpp index c7b5aff49c..4b74be64dc 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -43,7 +43,6 @@ #include <QFontDatabase> #include <QFileInfo> #include <QLibraryInfo> -#include <QLoggingCategory> #include <QSettings> #include <QStyle> #include <QTextStream> diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h index aa9aea8778..3faddcecb3 100644 --- a/src/libs/qmljs/parser/qmljsast_p.h +++ b/src/libs/qmljs/parser/qmljsast_p.h @@ -1766,7 +1766,7 @@ public: { return expression->firstSourceLocation(); } SourceLocation lastSourceLocation() const override - { return expression->lastSourceLocation(); } + { return semicolonToken.isValid() ? semicolonToken : expression->lastSourceLocation(); } // attributes ExpressionNode *expression; diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp index fad25230a3..6bbd71367c 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp @@ -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); diff --git a/src/libs/qtcreatorcdbext/stringutils.cpp b/src/libs/qtcreatorcdbext/stringutils.cpp index cd4eb683b0..7a8554f91c 100644 --- a/src/libs/qtcreatorcdbext/stringutils.cpp +++ b/src/libs/qtcreatorcdbext/stringutils.cpp @@ -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) diff --git a/src/libs/qtcreatorcdbext/stringutils.h b/src/libs/qtcreatorcdbext/stringutils.h index e8297d44a4..f891cf3ae7 100644 --- a/src/libs/qtcreatorcdbext/stringutils.h +++ b/src/libs/qtcreatorcdbext/stringutils.h @@ -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); diff --git a/src/libs/qtcreatorcdbext/symbolgroup.cpp b/src/libs/qtcreatorcdbext/symbolgroup.cpp index 8404f0d77c..0d55fb6a39 100644 --- a/src/libs/qtcreatorcdbext/symbolgroup.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroup.cpp @@ -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 diff --git a/src/libs/qtcreatorcdbext/symbolgroup.h b/src/libs/qtcreatorcdbext/symbolgroup.h index 20281a500b..92ac15238f 100644 --- a/src/libs/qtcreatorcdbext/symbolgroup.h +++ b/src/libs/qtcreatorcdbext/symbolgroup.h @@ -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); diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp index d595a5925b..9ac8b821bf 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp @@ -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)); diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp index 14c3732678..e06cf91fe0 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.cpp @@ -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. -static inline int assignStdStringI(SymbolGroupNode *n, int type, - const AssignmentStringData &data, +template <typename string> +static inline int assignStdStringI(SymbolGroupNode *n, int type, + 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; } diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.h b/src/libs/qtcreatorcdbext/symbolgroupvalue.h index b2c89cba47..bb69794cc0 100644 --- a/src/libs/qtcreatorcdbext/symbolgroupvalue.h +++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.h @@ -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 *> diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp index 80ddeafa1a..0e19dba5e9 100644 --- a/src/libs/utils/buildablehelperlibrary.cpp +++ b/src/libs/utils/buildablehelperlibrary.cpp @@ -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); diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 8608756627..3e8e2ac3bc 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -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 { diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 2026ad1068..4d1243cfdf 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -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; diff --git a/src/plugins/autotest/boost/boosttesttreeitem.cpp b/src/plugins/autotest/boost/boosttesttreeitem.cpp index e2e58c28af..98a27c0497 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.cpp +++ b/src/plugins/autotest/boost/boosttesttreeitem.cpp @@ -203,12 +203,14 @@ QList<TestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const }); for (auto it = testsPerProjectfile.begin(), end = testsPerProjectfile.end(); it != end; ++it) { - BoostTestConfiguration *config = new BoostTestConfiguration; - config->setProject(project); - config->setProjectFile(it.key()); - config->setTestCaseCount(it.value().testCases); - config->setInternalTargets(it.value().internalTargets); - result.append(config); + 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->setInternalTarget(target); + result.append(config); + } } return result; } @@ -245,12 +247,14 @@ QList<TestConfiguration *> BoostTestTreeItem::getSelectedTestConfigurations() co auto end = testCasesForProjectFile.cend(); for (auto it = testCasesForProjectFile.cbegin(); it != end; ++it) { - BoostTestConfiguration *config = new BoostTestConfiguration; - config->setProject(project); - config->setProjectFile(it.key()); - config->setTestCases(it.value().testCases); - config->setInternalTargets(it.value().internalTargets); - result.append(config); + for (const QString &target : it.value().internalTargets) { + BoostTestConfiguration *config = new BoostTestConfiguration; + config->setProject(project); + config->setProjectFile(it.key()); + config->setTestCases(it.value().testCases); + config->setInternalTarget(target); + result.append(config); + } } return result; } diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 53d8a126be..81316f033b 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -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) { - return si.path.endsWith(ending); - }).path; + FilePath precompiled_header + = FilePath::fromString(findOrDefault(t.sources, [&ending](const SourceInfo &si) { + return si.path.endsWith(ending); + }).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); diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp index 357adf1312..3e8e5b4003 100644 --- a/src/plugins/coreplugin/helpmanager.cpp +++ b/src/plugins/coreplugin/helpmanager.cpp @@ -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>(); diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h index 12a3ac7b1e..7b7e4f052e 100644 --- a/src/plugins/coreplugin/helpmanager.h +++ b/src/plugins/coreplugin/helpmanager.h @@ -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); diff --git a/src/plugins/coreplugin/helpmanager_implementation.h b/src/plugins/coreplugin/helpmanager_implementation.h index 89296691ee..9af4a49938 100644 --- a/src/plugins/coreplugin/helpmanager_implementation.h +++ b/src/plugins/coreplugin/helpmanager_implementation.h @@ -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; diff --git a/src/plugins/cppcheck/cppchecktool.h b/src/plugins/cppcheck/cppchecktool.h index ff668cf40e..203dc2edd2 100644 --- a/src/plugins/cppcheck/cppchecktool.h +++ b/src/plugins/cppcheck/cppchecktool.h @@ -49,7 +49,6 @@ class Project; namespace Cppcheck { namespace Internal { -class Diagnostic; class CppcheckRunner; class CppcheckTextMarkManager; class CppcheckOptions; diff --git a/src/plugins/cppcheck/cppchecktrigger.h b/src/plugins/cppcheck/cppchecktrigger.h index 069bfc7b04..a745f232e3 100644 --- a/src/plugins/cppcheck/cppchecktrigger.h +++ b/src/plugins/cppcheck/cppchecktrigger.h @@ -42,10 +42,6 @@ class IDocument; class IEditor; } -namespace CppTools { -class ProjectInfo; -} - namespace Cppcheck { namespace Internal { diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 7fde0b3a57..aafcd35b37 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -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; diff --git a/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp index bdf88eaf5c..1f1320c403 100644 --- a/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp +++ b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp @@ -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()) { diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index a5554a3aa8..4e04a02fc4 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -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(); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 8fa02ef988..a90c569c6d 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -442,6 +442,7 @@ public: m_lookupRequests.clear(); m_locationTimer.stop(); m_locationMark.reset(); + m_stackHandler.resetLocation(); m_disassemblerAgent.resetLocation(); m_toolTipManager.resetLocation(); } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 0fbb1fb735..cdbe82a7a5 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -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")); diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index aeafc69fbf..65c6f09264 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -314,6 +314,11 @@ void StackHandler::scheduleResetLocation() m_contentsValid = false; } +void StackHandler::resetLocation() +{ + emit layoutChanged(); +} + int StackHandler::stackRowCount() const { // Only one "thread" for now. diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index 22be87b16f..10ce5a4e85 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -112,6 +112,7 @@ public: bool isContentsValid() const { return m_contentsValid; } bool operatesByInstruction() const; void scheduleResetLocation(); + void resetLocation(); QIcon iconForRow(int row) const; diff --git a/src/plugins/help/helpmanager.cpp b/src/plugins/help/helpmanager.cpp index 6d41b79ff3..3c40e18702 100644 --- a/src/plugins/help/helpmanager.cpp +++ b/src/plugins/help/helpmanager.cpp @@ -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, diff --git a/src/plugins/help/helpmanager.h b/src/plugins/help/helpmanager.h index 49ca60f468..bcde6b794c 100644 --- a/src/plugins/help/helpmanager.h +++ b/src/plugins/help/helpmanager.h @@ -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); diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index deed8605ae..ef25f4f45c 100644 --- a/src/plugins/mcusupport/CMakeLists.txt +++ b/src/plugins/mcusupport/CMakeLists.txt @@ -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 diff --git a/src/plugins/mcusupport/mcusupport.pro b/src/plugins/mcusupport/mcusupport.pro index 9bb79364f8..3f6d598f59 100644 --- a/src/plugins/mcusupport/mcusupport.pro +++ b/src/plugins/mcusupport/mcusupport.pro @@ -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 diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index cb8ef1afce..35e3e9a471 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -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", diff --git a/src/plugins/mcusupport/mcusupport_dependencies.pri b/src/plugins/mcusupport/mcusupport_dependencies.pri index b6fd4f9e6b..1f2dd5bc64 100644 --- a/src/plugins/mcusupport/mcusupport_dependencies.pri +++ b/src/plugins/mcusupport/mcusupport_dependencies.pri @@ -7,4 +7,5 @@ QTC_LIB_DEPENDS += \ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ + debugger \ cmakeprojectmanager diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp new file mode 100644 index 0000000000..c61a3b6f6d --- /dev/null +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -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 diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h new file mode 100644 index 0000000000..3df2d065ab --- /dev/null +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -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 diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index da1bf9f0d9..1396d4226f 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -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" diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 0a5a157a93..9735203427 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -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; diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index 3bb35bfe75..e1345cb50e 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -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; } diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 0b426bbca4..37e94751ff 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -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); } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index d8b9744ce8..2865841453 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -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) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 9bf5fab113..c645a96774 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -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 diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index c67b527abb..ac40e87c79 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -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 } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.cpp index 3e4a20a1b3..feafd9b1df 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.cpp @@ -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) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.h index f3f87e4721..02590bf62e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditortransaction.h @@ -38,6 +38,8 @@ public: Q_INVOKABLE void start(); Q_INVOKABLE void end(); + Q_INVOKABLE bool active() const; + protected: void timerEvent(QTimerEvent *event) override; diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index f77ac4645b..1e1032900b 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -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); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index e7d60b25d2..3d57b3a16a 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -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,16 +280,19 @@ 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; qCInfo(instanceViewBenchmark) << "dispatching command" << command.userType() << command.typeName(); - if (command.userType() == informationChangedCommandType) { + if (command.userType() == informationChangedCommandType) { nodeInstanceClient()->informationChanged(command.value<InformationChangedCommand>()); - } else if (command.userType() == valuesChangedCommandType) { + } else if (command.userType() == valuesChangedCommandType) { nodeInstanceClient()->valuesChanged(command.value<ValuesChangedCommand>()); - } else if (command.userType() == pixmapChangedCommandType) { + } 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) { nodeInstanceClient()->childrenChanged(command.value<ChildrenChangedCommand>()); @@ -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)); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h index b1525b4408..a6a7f6ce99 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h @@ -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; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 66d503078b..7200231267 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -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()) diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index 12a55c25fe..adf962c2cc 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -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) diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 8699389182..e3598b09c0 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -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 diff --git a/src/plugins/qmldesigner/documentmanager.cpp b/src/plugins/qmldesigner/documentmanager.cpp index 45fd495759..2cae7208c5 100644 --- a/src/plugins/qmldesigner/documentmanager.cpp +++ b/src/plugins/qmldesigner/documentmanager.cpp @@ -424,7 +424,8 @@ 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. - *resourceFilePath = project->projectDirectory().toString() + "/" + isoIconsQrcFile; + 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. ProjectExplorer::ProjectNode *projectNode = ProjectExplorer::ProjectTree::nodeForFile(qmlFileName)->parentProjectNode(); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index c62c75be98..0d7b54c68e 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -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", diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 4653d8bad0..4182ca2826 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -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, diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 5844b3f2a1..5888f6a938 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -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.", - qPrintable(autoDetectionSource)); + 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) { - const QDir versionHelpDir(docPath); - foreach (const QString &helpFile, - versionHelpDir.entryList(QStringList("*.qch"), QDir::Files)) - files << docPath + helpFile; - } + const QStringList docPaths = QStringList( + {v->docsPath().toString() + QChar('/'), v->docsPath().toString() + "/qch/"}); + for (const QString &docPath : docPaths) { + const QDir versionHelpDir(docPath); + 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,8 +508,7 @@ 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(); + return m_versions.values(); } QList<BaseQtVersion *> QtVersionManager::sortVersions(const QList<BaseQtVersion *> &input) @@ -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; } - qDeleteAll(m_versions); - m_versions.clear(); - foreach (BaseQtVersion *v, sortedNewVersions) - m_versions.insert(v->uniqueId(), v); - - if (!changedVersions.isEmpty() || !addedVersions.isEmpty() || !removedVersions.isEmpty()) - updateDocumentation(); + 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 = 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 diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h index bc451f163e..2c05485c60 100644 --- a/src/plugins/qtsupport/qtversionmanager.h +++ b/src/plugins/qtsupport/qtversionmanager.h @@ -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(); }; diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index ec4726aa6f..73c407c361 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -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) { diff --git a/src/shared/qtcreator_gui_pch.h b/src/shared/qtcreator_gui_pch.h index b25dbf67b7..9ac491898b 100644 --- a/src/shared/qtcreator_gui_pch.h +++ b/src/shared/qtcreator_gui_pch.h @@ -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 diff --git a/src/shared/qtcreator_pch.h b/src/shared/qtcreator_pch.h index 4988f3d939..a80eb42e7a 100644 --- a/src/shared/qtcreator_pch.h +++ b/src/shared/qtcreator_pch.h @@ -29,26 +29,38 @@ */ #if defined __cplusplus -#include <QtGlobal> +#include <QtCore/qsystemdetection.h> -#ifdef Q_WS_WIN -# define _POSIX_ -# include <limits.h> -# undef _POSIX_ +#ifdef Q_OS_WIN +#define WIN32_LEAN_AND_MEAN + +// lib/Utils needs defines for Windows 8 +#ifdef Q_CC_MINGW +#define WINVER _WIN32_WINNT_WIN8 +#define _WIN32_WINNT _WIN32_WINNT_WIN8 +#endif // Q_CC_MINGW +#define NOHELP +#include <qt_windows.h> + +#undef DELETE +#undef IN +#undef OUT +#undef ERROR +#undef ABSOLUTE + +//QT_NO_FLOAT16_OPERATORS is used on Visual Studio 2017 (and earlier): +//when including <QFloat16> and <bitset> in the same translation unit, +//it would cause a compilation error due to a toolchain bug (see [QTBUG-72073]) +#if _MSC_VER <= 1920 +#define QT_NO_FLOAT16_OPERATORS #endif -#include <QCoreApplication> -#include <QList> -#include <QVariant> -#include <QObject> -#include <QRegExp> -#include <QString> -#include <QStringList> -#include <QTextCodec> -#include <QPointer> -#include <QScopedPointer> -#include <QSharedPointer> -#include <QDebug> +#define _POSIX_ +#include <limits.h> +#undef _POSIX_ +#endif // Q_OS_WIN + +#include <QtCore> #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include <QTextStream> @@ -59,7 +71,7 @@ using Qt::dec; using Qt::showbase; using Qt::hex; using Qt::noforcesign; -#endif +#endif //QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include <stdlib.h> -#endif +#endif //defined __cplusplus diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index 3715ae9349..105b0a63f0 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -44,6 +44,7 @@ extend_qtc_executable(qml2puppet statepreviewimagechangedcommand.cpp statepreviewimagechangedcommand.h synchronizecommand.cpp synchronizecommand.h tokencommand.cpp tokencommand.h + changeselectioncommand.cpp changeselectioncommand.h valueschangedcommand.cpp ) @@ -86,6 +87,14 @@ extend_qtc_executable(qml2puppet nodeinstanceclientproxy.cpp nodeinstanceclientproxy.h ) +find_package(Qt5 COMPONENTS Quick3D QUIET) +extend_qtc_executable(qml2puppet + CONDITION TARGET Qt5::Quick3 + FEATURE_INFO "Qt Quick 3D" + DEPENDS Qt5::Quick3D + DEFINES QUICK3D_MODULE +) + extend_qtc_executable(qml2puppet SOURCES_PREFIX "${SRCDIR}/interfaces" SOURCES @@ -96,6 +105,12 @@ extend_qtc_executable(qml2puppet ) extend_qtc_executable(qml2puppet + SOURCES_PREFIX "${SRCDIR}/qml2puppet/editor3d" + SOURCES + cameracontrolhelper.cpp cameracontrolhelper.h +) + +extend_qtc_executable(qml2puppet SOURCES_PREFIX "${SRCDIR}/qml2puppet/instances" SOURCES anchorchangesnodeinstance.cpp anchorchangesnodeinstance.h @@ -119,6 +134,7 @@ extend_qtc_executable(qml2puppet qt5previewnodeinstanceserver.cpp qt5previewnodeinstanceserver.h qt5rendernodeinstanceserver.cpp qt5rendernodeinstanceserver.h qt5testnodeinstanceserver.cpp qt5testnodeinstanceserver.h + quick3dnodeinstance.cpp quick3dnodeinstance.h quickitemnodeinstance.cpp quickitemnodeinstance.h servernodeinstance.cpp servernodeinstance.h ) diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs index 02a6f6e31f..995c29eac0 100644 --- a/src/tools/qml2puppet/qml2puppet.qbs +++ b/src/tools/qml2puppet/qml2puppet.qbs @@ -93,6 +93,8 @@ QtcTool { "commands/tokencommand.h", "commands/valueschangedcommand.cpp", "commands/valueschangedcommand.h", + "commands/changeselectioncommand.cpp", + "commands/changeselectioncommand.h", "container/addimportcontainer.cpp", "container/addimportcontainer.h", "container/idcontainer.cpp", @@ -173,6 +175,8 @@ QtcTool { "instances/qmlpropertychangesnodeinstance.h", "instances/qmlstatenodeinstance.cpp", "instances/qmlstatenodeinstance.h", + "instances/quick3dnodeinstance.cpp", + "instances/quick3dnodeinstance.h", "instances/qmltransitionnodeinstance.cpp", "instances/qmltransitionnodeinstance.h", "instances/qt3dpresentationnodeinstance.cpp", @@ -191,6 +195,8 @@ QtcTool { "instances/qt5testnodeinstanceserver.h", "instances/servernodeinstance.cpp", "instances/servernodeinstance.h", + "editor3d/cameracontrolhelper.cpp", + "editor3d/cameracontrolhelper.h", "qml2puppetmain.cpp", ] } diff --git a/tests/system/objects.map b/tests/system/objects.map index 1d4fab657e..27e82838e7 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -98,7 +98,7 @@ :New_Core::Internal::NewDialog {name='Core__Internal__NewDialog' type='Core::Internal::NewDialog' visible='1' windowTitle?='New*'} :New_ProjectExplorer::JsonWizard {type='ProjectExplorer::JsonWizard' unnamed='1' visible='1'} :Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'} -:No valid kits found._QLabel {text?='*No valid kits found.*' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:No valid kits found._QLabel {text?='*No suitable kits found.*' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :OpenDocuments_Widget {type='Core::Internal::OpenEditorsWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Open Documents'} :Options.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 08398f14fa..193ef324af 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -116,6 +116,11 @@ def __createProjectSetNameAndPath__(path, projectName = None, checks = True): clickButton(waitForObject(":Next_QPushButton")) return str(projectName) + +def __createProjectHandleTranslationSelection__(): + clickButton(":Next_QPushButton") + + def __handleBuildSystem__(buildSystem): combo = "{name='BuildSystem' type='QComboBox' visible='1'}" try: @@ -230,6 +235,7 @@ def createProject_Qt_GUI(path, projectName, checks = True, addToVersionControl = test.compare(findObject(":formFileLineEdit_Utils::FileNameValidatingLineEdit").text, ui_file) clickButton(waitForObject(":Next_QPushButton")) + __createProjectHandleTranslationSelection__() __selectQtVersionDesktop__(checks, available, True) expectedFiles = [] @@ -253,6 +259,7 @@ def createProject_Qt_Console(path, projectName, checks = True, buildSystem = Non available = __createProjectOrFileSelectType__(" Application", "Qt Console Application") __createProjectSetNameAndPath__(path, projectName, checks) __handleBuildSystem__(buildSystem) + __createProjectHandleTranslationSelection__() __selectQtVersionDesktop__(checks, available) expectedFiles = [] @@ -279,6 +286,7 @@ def createNewQtQuickApplication(workingDir, projectName=None, __handleBuildSystem__(buildSystem) requiredQt = __createProjectHandleQtQuickSelection__(minimumQtVersion) __modifyAvailableTargets__(available, requiredQt) + __createProjectHandleTranslationSelection__() checkedTargets = __chooseTargets__(targets, available) snooze(1) if len(checkedTargets): @@ -368,6 +376,7 @@ def createNewCPPLib(projectDir, projectName, className, target, isStatic): LibType.getStringForLib(libType)) __createProjectHandleModuleSelection__("Core") className = __createProjectHandleClassInformation__(className) + __createProjectHandleTranslationSelection__() __chooseTargets__(target, available) clickButton(waitForObject(":Next_QPushButton")) __createProjectHandleLastPage__() @@ -381,6 +390,7 @@ def createNewQtPlugin(projectDir, projectName, className, target, baseClass="QGe "window=':New_ProjectExplorer::JsonWizard'}"), LibType.getStringForLib(LibType.QT_PLUGIN)) className = __createProjectHandleClassInformation__(className, baseClass) + __createProjectHandleTranslationSelection__() __chooseTargets__(target, available) clickButton(waitForObject(":Next_QPushButton")) __createProjectHandleLastPage__() diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py index 534317c3d1..69a69ace30 100644 --- a/tests/system/suite_general/tst_create_proj_wizard/test.py +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -132,6 +132,8 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms, clickButton(waitForObject(":Next_QPushButton")) if specialHandlingFunc: specialHandlingFunc(displayedPlatforms, *args) + if not ('Plain C' in template): + __createProjectHandleTranslationSelection__() verifyKitCheckboxes(kits, displayedPlatforms) safeClickButton("Cancel") if counter < len(availableBuildSystems) - 1: diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp index 234fc0987c..df11072707 100644 --- a/tests/unit/unittest/compileroptionsbuilder-test.cpp +++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp @@ -593,14 +593,14 @@ TEST_F(CompilerOptionsBuilder, BuildAllOptions) ASSERT_THAT(compilerOptionsBuilder.options(), ElementsAre("-nostdinc", "-nostdinc++", + "-arch", + "x86_64", "-fsyntax-only", "-m64", "--target=x86_64-apple-darwin10", "-x", "c++", "-std=c++17", - "-arch", - "x86_64", "-DprojectFoo=projectBar", "-I", IsPartOfHeader("wrappedQtHeaders"), "-I", IsPartOfHeader(toNative("wrappedQtHeaders/QtCore").toStdString()), |