Merge remote-tracking branch 'origin/4.11'

Change-Id: I48e406d43f185e893523cc5e0dcf288afdc3e36c
This commit is contained in:
Eike Ziller
2019-10-17 07:32:01 +02:00
133 changed files with 2326 additions and 1070 deletions

View File

@@ -34,10 +34,6 @@ if (WITH_TESTS)
set(IMPLICIT_DEPENDS Qt5::Test) set(IMPLICIT_DEPENDS Qt5::Test)
endif() endif()
if (BUILD_WITH_PCH)
list(APPEND IMPLICIT_DEPENDS Qt5::Core)
endif()
find_package(Qt5 find_package(Qt5
COMPONENTS Concurrent Core Gui LinguistTools Network PrintSupport Qml Quick COMPONENTS Concurrent Core Gui LinguistTools Network PrintSupport Qml Quick
QuickWidgets Sql Widgets Xml ${QT_TEST_COMPONENT} QuickWidgets Sql Widgets Xml ${QT_TEST_COMPONENT}

View File

@@ -288,6 +288,14 @@ endfunction()
function(enable_pch target) function(enable_pch target)
if (BUILD_WITH_PCH) if (BUILD_WITH_PCH)
# Skip PCH for targets that do not use the expected visibility settings:
get_target_property(visibility_property "${target}" CXX_VISIBILITY_PRESET)
get_target_property(inlines_property "${target}" VISIBILITY_INLINES_HIDDEN)
if (NOT visibility_property STREQUAL "hidden" OR NOT inlines_property)
return()
endif()
get_target_property(target_type ${target} TYPE) get_target_property(target_type ${target} TYPE)
if (NOT ${target_type} STREQUAL "OBJECT_LIBRARY") if (NOT ${target_type} STREQUAL "OBJECT_LIBRARY")
function(_recursively_collect_dependencies input_target) function(_recursively_collect_dependencies input_target)
@@ -309,19 +317,25 @@ function(enable_pch target)
function(_add_pch_target pch_target pch_file pch_dependency) function(_add_pch_target pch_target pch_file pch_dependency)
if (EXISTS ${pch_file}) if (EXISTS ${pch_file})
add_library(${pch_target} STATIC add_library(${pch_target} STATIC
${CMAKE_BINARY_DIR}/empty_pch.cpp) ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c)
target_compile_definitions(${pch_target} PRIVATE ${DEFAULT_DEFINES}) target_compile_definitions(${pch_target} PRIVATE ${DEFAULT_DEFINES})
set_target_properties(${pch_target} PROPERTIES set_target_properties(${pch_target} PROPERTIES
PRECOMPILE_HEADERS ${pch_file}) PRECOMPILE_HEADERS ${pch_file}
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON)
target_link_libraries(${pch_target} PRIVATE ${pch_dependency}) target_link_libraries(${pch_target} PRIVATE ${pch_dependency})
endif() endif()
endfunction() endfunction()
if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole) if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole)
file(WRITE ${CMAKE_BINARY_DIR}/empty_pch.cpp.in "/*empty file*/") file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in "/*empty file*/")
configure_file( configure_file(
${CMAKE_BINARY_DIR}/empty_pch.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in
${CMAKE_BINARY_DIR}/empty_pch.cpp) ${CMAKE_CURRENT_BINARY_DIR}/empty_pch.cpp)
configure_file(
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c_cpp.in
${CMAKE_CURRENT_BINARY_DIR}/empty_pch.c)
_add_pch_target(QtCreatorPchGui _add_pch_target(QtCreatorPchGui
"${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets) "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets)
@@ -329,12 +343,14 @@ function(enable_pch target)
"${PROJECT_SOURCE_DIR}/src/shared/qtcreator_pch.h" Qt5::Core) "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_pch.h" Qt5::Core)
endif() endif()
set(PCH_TARGET QtCreatorPchConsole) unset(PCH_TARGET)
if ("Qt5::Widgets" IN_LIST dependencies) if ("Qt5::Widgets" IN_LIST dependencies)
set(PCH_TARGET QtCreatorPchGui) set(PCH_TARGET QtCreatorPchGui)
elseif ("Qt5::Core" IN_LIST dependencies)
set(PCH_TARGET QtCreatorPchConsole)
endif() endif()
if (TARGET ${PCH_TARGET}) if (TARGET "${PCH_TARGET}")
set_target_properties(${target} PROPERTIES set_target_properties(${target} PROPERTIES
PRECOMPILE_HEADERS_REUSE_FROM ${PCH_TARGET}) PRECOMPILE_HEADERS_REUSE_FROM ${PCH_TARGET})
endif() endif()
@@ -364,7 +380,7 @@ endfunction()
# #
function(add_qtc_library name) function(add_qtc_library name)
cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION" "" cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION;BUILD_BY_DEFAULT" "DESTINATION"
"DEFINES;DEPENDS;EXTRA_TRANSLATIONS;INCLUDES;PUBLIC_DEFINES;PUBLIC_DEPENDS;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;PROPERTIES" ${ARGN} "DEFINES;DEPENDS;EXTRA_TRANSLATIONS;INCLUDES;PUBLIC_DEFINES;PUBLIC_DEPENDS;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;PROPERTIES" ${ARGN}
) )
@@ -384,8 +400,13 @@ function(add_qtc_library name)
set(library_type OBJECT) set(library_type OBJECT)
endif() endif()
set(_exclude_from_all EXCLUDE_FROM_ALL)
if (_arg_BUILD_BY_DEFAULT)
unset(_exclude_from_all)
endif()
# Do not just build libraries... # Do not just build libraries...
add_library(${name} ${library_type} EXCLUDE_FROM_ALL ${_arg_SOURCES}) add_library(${name} ${library_type} ${_exclude_from_all} ${_arg_SOURCES})
add_library(${IDE_CASED_ID}::${name} ALIAS ${name}) add_library(${IDE_CASED_ID}::${name} ALIAS ${name})
set_public_headers(${name} "${_arg_SOURCES}") set_public_headers(${name} "${_arg_SOURCES}")
@@ -432,6 +453,11 @@ function(add_qtc_library name)
set(skip_translation ON) set(skip_translation ON)
endif() endif()
set(_DESTINATION "${IDE_BIN_PATH}")
if (_arg_DESTINATION)
set(_DESTINATION "${_arg_DESTINATION}")
endif()
qtc_output_binary_dir(_output_binary_dir) qtc_output_binary_dir(_output_binary_dir)
set_target_properties(${name} PROPERTIES set_target_properties(${name} PROPERTIES
SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
@@ -440,7 +466,7 @@ function(add_qtc_library name)
VISIBILITY_INLINES_HIDDEN ON VISIBILITY_INLINES_HIDDEN ON
BUILD_RPATH "${_LIB_RPATH}" BUILD_RPATH "${_LIB_RPATH}"
INSTALL_RPATH "${_LIB_RPATH}" INSTALL_RPATH "${_LIB_RPATH}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_BIN_PATH}" RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}"
LIBRARY_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}" LIBRARY_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}"
ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}"
${_arg_PROPERTIES} ${_arg_PROPERTIES}
@@ -454,7 +480,7 @@ function(add_qtc_library name)
install(TARGETS ${name} install(TARGETS ${name}
EXPORT ${IDE_CASED_ID} EXPORT ${IDE_CASED_ID}
RUNTIME DESTINATION "${IDE_BIN_PATH}" RUNTIME DESTINATION "${_DESTINATION}"
LIBRARY LIBRARY
DESTINATION "${IDE_LIBRARY_PATH}" DESTINATION "${IDE_LIBRARY_PATH}"
${NAMELINK_OPTION} ${NAMELINK_OPTION}

View File

@@ -23,6 +23,7 @@ you can check out from the public Git repository. For example:
* Added option to change line ending style via editor tool bar * Added option to change line ending style via editor tool bar
* Fixed that explicit colors or styles in KSyntaxHighlighting specifications were ignored * Fixed that explicit colors or styles in KSyntaxHighlighting specifications were ignored
(QTCREATORBUG-13545, QTCREATORBUG-22229, QTCREATORBUG-22646) (QTCREATORBUG-13545, QTCREATORBUG-22229, QTCREATORBUG-22646)
* Fixed behavior of backtab with multi-line selection (QTCREATORBUG-16970)
### Language Client ### Language Client
@@ -37,10 +38,12 @@ you can check out from the public Git repository. For example:
* Fixed that build environment was not used for asking compilers about built-in headers * Fixed that build environment was not used for asking compilers about built-in headers
(QTCREATORBUG-17985) (QTCREATORBUG-17985)
* Fixed handling of `-mllvm` command line option * Fixed handling of `-mllvm` command line option
* Fixed handling of `noexcept` when refactoring (QTCREATORBUG-11849, QTCREATORBUG-19699)
### QML ### QML
* Fixed pragma reformatting * Updated to parser from Qt 5.15
* Fixed pragma reformatting (QTCREATORBUG-22326)
### Python ### Python
@@ -55,6 +58,7 @@ you can check out from the public Git repository. For example:
## Projects ## Projects
* Added experimental support for Qt for WebAssembly (QTCREATORBUG-21068) * Added experimental support for Qt for WebAssembly (QTCREATORBUG-21068)
* Added experimental support for Qt for MCUs
* Added `Build` > `Build for Run Configuration` (QTCREATORBUG-22403) * Added `Build` > `Build for Run Configuration` (QTCREATORBUG-22403)
* Added more space for custom command line arguments (QTCREATORBUG-17890) * Added more space for custom command line arguments (QTCREATORBUG-17890)
* Added option to continue building after a single project failed with `Build` > `Build All` * Added option to continue building after a single project failed with `Build` > `Build All`
@@ -63,13 +67,14 @@ you can check out from the public Git repository. For example:
* Added option for translation file to wizards (QTCREATORBUG-7453) * Added option for translation file to wizards (QTCREATORBUG-7453)
* Added option to rename files with same base name when renaming files via project tree * Added option to rename files with same base name when renaming files via project tree
(QTCREATORBUG-21738) (QTCREATORBUG-21738)
* Changed build process to run with low priority (QTCREATORBUG-5155) * Added option for running build process with low priority (QTCREATORBUG-5155)
* Made it possible to schedule running the project while building it (QTCREATORBUG-14297) * Made it possible to schedule running the project while building it (QTCREATORBUG-14297)
* Improved unconfigured project page (QTCREATORBUG-20018) * Improved unconfigured project page (QTCREATORBUG-20018)
* Fixed parsing of `lld` output (QTCREATORBUG-22623) * Fixed parsing of `lld` output (QTCREATORBUG-22623)
* Fixed issues with expanding macros in environment variables * Fixed issues with expanding macros in environment variables
* Fixed that generated files were appearing in Locator and project wide searches * Fixed that generated files were appearing in Locator and project wide searches
(QTCREATORBUG-20176) (QTCREATORBUG-20176)
* Fixed disabled project context menu item (QTCREATORBUG-22850)
### QMake ### QMake
@@ -110,7 +115,14 @@ you can check out from the public Git repository. For example:
* Added support for loading results from `clang-tidy` and `clazy` that were * Added support for loading results from `clang-tidy` and `clazy` that were
exported with `-export-fixes` exported with `-export-fixes`
* Added option for overriding configuration per project * Added option for overriding configuration per project
* Added option to analyze only open or edited documents
* Changed to use separate `clang-tidy` executable * Changed to use separate `clang-tidy` executable
* Separated diagnostic configuration settings for code model
(`C++` > `Code Model`) and analyzer (`Analyzer` > `Clang Tools`)
## Qt Widget Designer
* Fixed lookup of resources (QTCREATORBUG-22909, QTCREATORBUG-22962)
## Qt Quick Designer ## Qt Quick Designer
@@ -118,7 +130,10 @@ you can check out from the public Git repository. For example:
* Added support for importing 3D assets into Quick3D components * Added support for importing 3D assets into Quick3D components
(QDS-1051, QDS-1053) (QDS-1051, QDS-1053)
* Added option for keyframe time in `Edit` dialog (QDS-1072) * Added option for keyframe time in `Edit` dialog (QDS-1072)
* Added snapping of timeline playhead to keyframes when shift-dragging
(QDS-1068)
* Fixed issues with dragging timeline items (QDS-1074) * Fixed issues with dragging timeline items (QDS-1074)
* Fixed various timeline editor issues (QDS-1073)
## Version Control Systems ## Version Control Systems
@@ -146,7 +161,7 @@ you can check out from the public Git repository. For example:
### Android ### Android
* Added warning if `sdkmanager` could not be run, including hint to correct Java SDK * Added warning if `sdkmanager` could not be run, including hint to appropriate Java SDK
(QTCREATORBUG-22626) (QTCREATORBUG-22626)
* Added knowledge of Android 10 and API level 29 * Added knowledge of Android 10 and API level 29
* Fixed issue with multiple Java versions in `PATH` (QTCREATORBUG-22504) * Fixed issue with multiple Java versions in `PATH` (QTCREATORBUG-22504)
@@ -155,15 +170,18 @@ you can check out from the public Git repository. For example:
* Moved support for [Qt for Device Creation](https://doc.qt.io/QtForDeviceCreation/qtdc-index.html) * Moved support for [Qt for Device Creation](https://doc.qt.io/QtForDeviceCreation/qtdc-index.html)
(Boot2Qt) to open source (Boot2Qt) to open source
* Fixed issues with SFTP on Windows (QTCREATORBUG-22471)
### QNX ### QNX
* Fixed registration of toolchain as C compiler * Fixed registration of toolchain as C compiler
* Fixed issue with license checking of QCC * Fixed issue with license checking of QCC
* Fixed deployment of public key (QTCREATORBUG-22591)
### Bare Metal ### Bare Metal
* Added support for STM8 and MSP430 architectures * Added support for STM8 and MSP430 architectures
* Fixed that it was not possible to add custom deployment steps (QTCREATORBUG-22977)
## Credits for these changes go to: ## Credits for these changes go to:
Aleksei German Aleksei German
@@ -180,7 +198,9 @@ David Schulz
Denis Shienkov Denis Shienkov
Eike Ziller Eike Ziller
Frederik Schwarzer Frederik Schwarzer
Henning Gruendl
Joel Smith Joel Smith
Laurent Montel
Leander Schulten Leander Schulten
Leena Miettinen Leena Miettinen
Mahmoud Badri Mahmoud Badri
@@ -199,6 +219,7 @@ Thomas Hartmann
Tim Henning Tim Henning
Tim Jenssen Tim Jenssen
Tobias Hunger Tobias Hunger
Tommi Pekkala
Uladzislau Paulovich Uladzislau Paulovich
Ulf Hermann Ulf Hermann
Ville Nummela Ville Nummela

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2018 The Qt Company Ltd. ** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -64,7 +64,7 @@
\row \row
\li Find free Qt-based applications \li Find free Qt-based applications
\li \l{http://qt-apps.org/}{Qt Apps} \li \l{https://github.com/topics/qt}{Qt Apps on GitHub}
\row \row
\li Develop with a commercial Qt license and support - \li Develop with a commercial Qt license and support -

View File

@@ -143,7 +143,7 @@ class PlainDumper:
d.putValue(d.hexencode(val), 'utf8:1:0') d.putValue(d.hexencode(val), 'utf8:1:0')
elif sys.version_info[0] <= 2 and isinstance(val, unicode): elif sys.version_info[0] <= 2 and isinstance(val, unicode):
d.putValue(val) d.putValue(val)
else: # Assuming LazyString elif val is not None: # Assuming LazyString
d.putCharArrayValue(val.address, val.length, d.putCharArrayValue(val.address, val.length,
val.type.target().sizeof) val.type.target().sizeof)

View File

@@ -0,0 +1,101 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick3D 1.0
import QtQuick.Controls 2.0
Window {
width: 1024
height: 768
visible: true
title: "3D"
flags: Qt.WindowStaysOnTopHint | Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
Rectangle {
color: "black"
anchors.fill: parent
}
Column {
y: 32
Slider {
id: slider
value: -600
from: -1200
to: 600
}
Slider {
id: slider2
value: 0
from: -360
to: 360
}
CheckBox {
id: checkBox
text: "Light"
Rectangle {
anchors.fill: parent
z: -1
}
}
}
Binding {
target: view.scene
property: "rotation.y"
value: slider2.value
}
property alias scene: view.scene
property alias showLight: checkBox.checked
id: viewWindow
View3D {
id: view
anchors.fill: parent
enableWireframeMode: true
camera: camera01
Light {
id: directionalLight
visible: checkBox.checked
}
Camera {
id: camera01
z: slider.value
}
Component.onCompleted: {
directionalLight.setParentItem(view.scene)
camera01.setParentItem(view.scene)
}
}
}

View File

@@ -28,7 +28,5 @@ be met: https://www.gnu.org/licenses/gpl-3.0.html.</string>
<string>qml2puppet</string> <string>qml2puppet</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.qt-project.qtcreator.qml2puppet</string> <string>org.qt-project.qtcreator.qml2puppet</string>
<key>LSUIElement</key>
<string>1</string>
</dict> </dict>
</plist> </plist>

View File

@@ -958,7 +958,6 @@ void NodeInstanceServer::setInstancePropertyVariant(const PropertyValueContainer
void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer) void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &auxiliaryContainer)
{ {
//instanceId() == 0: the item is root
if (auxiliaryContainer.instanceId() == 0 && (auxiliaryContainer.name() == "width" || if (auxiliaryContainer.instanceId() == 0 && (auxiliaryContainer.name() == "width" ||
auxiliaryContainer.name() == "height")) { auxiliaryContainer.name() == "height")) {
@@ -978,6 +977,16 @@ void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &
} else { } else {
rootNodeInstance().resetProperty(propertyName); rootNodeInstance().resetProperty(propertyName);
} }
} 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");
}
}
} }
} }

View File

@@ -633,7 +633,7 @@ QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorN
if (mockHash.contains(typeName)) if (mockHash.contains(typeName))
object = QmlPrivateGate::createComponent(mockHash.value(typeName), context); object = QmlPrivateGate::createComponent(mockHash.value(typeName), context);
else else if (majorNumber != -1 && minorNumber != -1)
object = QmlPrivateGate::createPrimitive(polishTypeName, majorNumber, minorNumber, context); object = QmlPrivateGate::createPrimitive(polishTypeName, majorNumber, minorNumber, context);
/* Let's try to create the primitive from source, since with incomplete meta info this might be a pure /* Let's try to create the primitive from source, since with incomplete meta info this might be a pure

View File

@@ -60,8 +60,33 @@
#include <designersupportdelegate.h> #include <designersupportdelegate.h>
#include <QQmlProperty>
#include <QOpenGLContext>
#include <QQuickView>
namespace QmlDesigner { namespace QmlDesigner {
static QVariant objectToVariant(QObject *object)
{
return QVariant::fromValue(object);
}
static QObject *createEditView3D(QQmlEngine *engine)
{
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
QWindow *window = qobject_cast<QWindow *>(component.create());
//For macOS we have to use the 4.1 core profile
QSurfaceFormat surfaceFormat = window->requestedFormat();
surfaceFormat.setVersion(4, 1);
surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
window->setFormat(surfaceFormat);
return window;
}
Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) : Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
Qt5NodeInstanceServer(nodeInstanceClient) Qt5NodeInstanceServer(nodeInstanceClient)
{ {
@@ -122,6 +147,49 @@ bool Qt5InformationNodeInstanceServer::isDirtyRecursiveForParentInstances(QQuick
return false; return false;
} }
QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
const QList<ServerNodeInstance> &instanceList) const
{
for (const ServerNodeInstance &instance : instanceList) {
if (instance.isSubclassOf("QQuick3DViewport")) {
for (const ServerNodeInstance &child : instanceList) { /* Look for scene node */
/* The QQuick3DViewport always creates a root node.
* This root node contains the complete scene. */
if (child.isSubclassOf("QQuick3DNode") && child.parent() == instance)
return child.internalObject()->property("parent").value<QObject *>();
}
}
}
return nullptr;
}
void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeInstance> &instanceList)
{
ServerNodeInstance root = rootNodeInstance();
QObject *node = nullptr;
bool showCustomLight = false;
if (root.isSubclassOf("QQuick3DNode")) {
node = root.internalObject();
showCustomLight = true; // Pure node scene we should add a custom light
} else {
node = findRootNodeOf3DViewport(instanceList);
}
if (node) { // If we found a scene we create the edit view
QObject *view = createEditView3D(engine());
QQmlProperty sceneProperty(view, "scene", context());
node->setParent(view);
sceneProperty.write(objectToVariant(node));
QQmlProperty parentProperty(node, "parent", context());
parentProperty.write(objectToVariant(view));
QQmlProperty completeSceneProperty(view, "showLight", context());
completeSceneProperty.write(showCustomLight);
}
}
void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands() void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands()
{ {
static bool inFunction = false; static bool inFunction = false;
@@ -232,6 +300,8 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
sendChildrenChangedCommand(instanceList); sendChildrenChangedCommand(instanceList);
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList)); nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE"))
setup3DEditView(instanceList);
} }
void Qt5InformationNodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList) void Qt5InformationNodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList)

View File

@@ -51,6 +51,9 @@ protected:
bool isDirtyRecursiveForParentInstances(QQuickItem *item) const; bool isDirtyRecursiveForParentInstances(QQuickItem *item) const;
private: private:
void setup3DEditView(const QList<ServerNodeInstance> &instanceList);
QObject *findRootNodeOf3DViewport(const QList<ServerNodeInstance> &instanceList) const;
QSet<ServerNodeInstance> m_parentChangedSet; QSet<ServerNodeInstance> m_parentChangedSet;
QList<ServerNodeInstance> m_completedComponentList; QList<ServerNodeInstance> m_completedComponentList;
QList<TokenCommand> m_tokenList; QList<TokenCommand> m_tokenList;

View File

@@ -54,7 +54,6 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
NodeInstanceClientProxy(parent) NodeInstanceClientProxy(parent)
{ {
prioritizeDown(); prioritizeDown();
DesignerSupport::activateDesignerWindowManager();
if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) { if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) {
qputenv("DESIGNER_DONT_USE_SHARED_MEMORY", "1"); qputenv("DESIGNER_DONT_USE_SHARED_MEMORY", "1");
setNodeInstanceServer(new Qt5TestNodeInstanceServer(this)); setNodeInstanceServer(new Qt5TestNodeInstanceServer(this));
@@ -62,12 +61,20 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
readDataStream(); readDataStream();
QCoreApplication::exit(); QCoreApplication::exit();
} else if (QCoreApplication::arguments().at(2) == QLatin1String("previewmode")) { } else if (QCoreApplication::arguments().at(2) == QLatin1String("previewmode")) {
DesignerSupport::activateDesignerWindowManager();
setNodeInstanceServer(new Qt5PreviewNodeInstanceServer(this)); setNodeInstanceServer(new Qt5PreviewNodeInstanceServer(this));
initializeSocket(); initializeSocket();
} else if (QCoreApplication::arguments().at(2) == QLatin1String("editormode")) { } else if (QCoreApplication::arguments().at(2) == QLatin1String("editormode")) {
/* The editormode does not use the DesignerWindowManager,
* because we want to be able to show the 3D Edit View
* as a normal QQuickView.
* The DesignerWindowManager prevents any window from actually being shown. */
if (!qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE"))
DesignerSupport::activateDesignerWindowManager();
setNodeInstanceServer(new Qt5InformationNodeInstanceServer(this)); setNodeInstanceServer(new Qt5InformationNodeInstanceServer(this));
initializeSocket(); initializeSocket();
} else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) { } else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) {
DesignerSupport::activateDesignerWindowManager();
setNodeInstanceServer(new Qt5RenderNodeInstanceServer(this)); setNodeInstanceServer(new Qt5RenderNodeInstanceServer(this));
initializeSocket(); initializeSocket();
} }

View File

@@ -37,6 +37,9 @@
#include <createscenecommand.h> #include <createscenecommand.h>
#include <reparentinstancescommand.h> #include <reparentinstancescommand.h>
#include <QDebug>
#include <QOpenGLContext>
namespace QmlDesigner { namespace QmlDesigner {
Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient)
@@ -68,6 +71,17 @@ void Qt5NodeInstanceServer::initializeView()
DesignerSupport::createOpenGLContext(m_quickView.data()); DesignerSupport::createOpenGLContext(m_quickView.data());
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")
&& QCoreApplication::arguments().at(2) == "editormode") {
/* In '3d editormode' we do not use the DesignerWindowManager
* and since we do not show the QQuickView we have to manually create the OpenGL context */
auto context = new QOpenGLContext(m_quickView);
context->setFormat(surfaceFormat);
context->create();
if (!context->makeCurrent(m_quickView))
qWarning("QOpenGLContext: makeCurrent() failed...");
}
if (qEnvironmentVariableIsSet("QML_FILE_SELECTORS")) { if (qEnvironmentVariableIsSet("QML_FILE_SELECTORS")) {
QQmlFileSelector *fileSelector = new QQmlFileSelector(engine(), engine()); QQmlFileSelector *fileSelector = new QQmlFileSelector(engine(), engine());
QStringList customSelectors = QString::fromUtf8(qgetenv("QML_FILE_SELECTORS")).split(","); QStringList customSelectors = QString::fromUtf8(qgetenv("QML_FILE_SELECTORS")).split(",");

View File

@@ -67,6 +67,7 @@ class ServerNodeInstance
friend class NodeInstanceServer; friend class NodeInstanceServer;
friend class Qt4NodeInstanceServer; friend class Qt4NodeInstanceServer;
friend class Qt4PreviewNodeInstanceServer; friend class Qt4PreviewNodeInstanceServer;
friend class Qt5InformationNodeInstanceServer;
friend class Qt5NodeInstanceServer; friend class Qt5NodeInstanceServer;
friend class Qt5PreviewNodeInstanceServer; friend class Qt5PreviewNodeInstanceServer;
friend class Qt5TestNodeInstanceServer; friend class Qt5TestNodeInstanceServer;
@@ -162,6 +163,8 @@ public:
QList<ServerNodeInstance> stateInstances() const; QList<ServerNodeInstance> stateInstances() const;
static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
private: // functions private: // functions
ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance); ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);
@@ -192,8 +195,6 @@ private: // functions
void paintUpdate(); void paintUpdate();
static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
void setNodeSource(const QString &source); void setNodeSource(const QString &source);
bool holdsGraphical() const; bool holdsGraphical() const;

View File

@@ -132,8 +132,20 @@ int main(int argc, char *argv[])
// Since we always render text into an FBO, we need to globally disable // Since we always render text into an FBO, we need to globally disable
// subpixel antialiasing and instead use gray. // subpixel antialiasing and instead use gray.
qputenv("QSG_DISTANCEFIELD_ANTIALIASING", "gray"); qputenv("QSG_DISTANCEFIELD_ANTIALIASING", "gray");
#ifdef Q_OS_OSX //This keeps qml2puppet from stealing focus #ifdef Q_OS_MACOS
if (!qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")) {
qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "true"); qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "true");
} else {
// We have to parse the arguments before Q[Gui]Application creation
// Since the Qt arguments are not filtered out, yet we do not know the position of the argument
for (int i = 0; i < argc; ++i) {
const char *arg = argv[i];
//In previewmode and rendermode we hide the process
if (!qstrcmp(arg, "previewmode") || !qstrcmp(arg, "rendermode"))
qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "true");
// This keeps qml2puppet from stealing focus
}
}
#endif #endif
//If a style different from Desktop is set we have to use QGuiApplication //If a style different from Desktop is set we have to use QGuiApplication

View File

@@ -7,5 +7,6 @@
<file>mockfiles/SwipeView.qml</file> <file>mockfiles/SwipeView.qml</file>
<file>mockfiles/GenericBackend.qml</file> <file>mockfiles/GenericBackend.qml</file>
<file>mockfiles/Dialog.qml</file> <file>mockfiles/Dialog.qml</file>
<file>mockfiles/EditView3D.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -203,7 +203,7 @@ Item {
id: mapMouseArea id: mapMouseArea
anchors.fill: parent anchors.fill: parent
onPositionChanged: { onPositionChanged: {
if (pressed && mouse.button === Qt.LeftButton) { if (pressed && mouse.buttons === Qt.LeftButton) {
var xx = Math.max(0, Math.min(mouse.x, parent.width)) var xx = Math.max(0, Math.min(mouse.x, parent.width))
var yy = Math.max(0, Math.min(mouse.y, parent.height)) var yy = Math.max(0, Math.min(mouse.y, parent.height))

View File

@@ -152,11 +152,15 @@ Item {
var y = extendedFunctionButton.mapToGlobal(0,0).y - 40 var y = extendedFunctionButton.mapToGlobal(0,0).y - 40
bindingEditor.showWidget(x, y) bindingEditor.showWidget(x, y)
bindingEditor.text = backendValue.expression bindingEditor.text = backendValue.expression
bindingEditor.prepareBindings()
} }
BindingEditor { BindingEditor {
id: bindingEditor id: bindingEditor
backendValueProperty: backendValue
modelNodeBackendProperty: modelNodeBackend
onRejected: { onRejected: {
hideWidget() hideWidget()
expressionDialogLoader.visible = false expressionDialogLoader.visible = false

View File

@@ -1,6 +1,6 @@
{ {
"version": 1, "version": 1,
"supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], "supportedProjectTypes": [ "PythonProject" ],
"id": "U.QtForPythonApplicationWindow", "id": "U.QtForPythonApplicationWindow",
"category": "F.Application", "category": "F.Application",
"trDescription": "Creates a Qt for Python application that contains an empty window.", "trDescription": "Creates a Qt for Python application that contains an empty window.",

View File

@@ -16,6 +16,4 @@ add_subdirectory(sqlite)
add_subdirectory(clangsupport) add_subdirectory(clangsupport)
add_subdirectory(tracing) add_subdirectory(tracing)
if (WIN32) add_subdirectory(qtcreatorcdbext)
add_subdirectory(qtcreatorcdbext)
endif()

View File

@@ -863,8 +863,13 @@ UiImport: UiImportHead UiVersionSpecifier Semicolon;
UiImport: UiImportHead UiVersionSpecifier T_AS QmlIdentifier Semicolon; UiImport: UiImportHead UiVersionSpecifier T_AS QmlIdentifier Semicolon;
/. /.
case $rule_number: { case $rule_number: {
sym(1).UiImport->versionToken = loc(2); auto versionToken = loc(2);
sym(1).UiImport->version = sym(2).UiVersionSpecifier; auto version = sym(2).UiVersionSpecifier;
sym(1).UiImport->version = version;
if (version->minorToken.isValid()) {
versionToken.length += version->minorToken.length + (version->minorToken.offset - versionToken.offset - versionToken.length);
}
sym(1).UiImport->versionToken = versionToken;
sym(1).UiImport->asToken = loc(3); sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4); sym(1).UiImport->importIdToken = loc(4);
sym(1).UiImport->importId = stringRef(4); sym(1).UiImport->importId = stringRef(4);

View File

@@ -398,8 +398,13 @@ bool Parser::parse(int startToken)
#line 866 "qmljs.g" #line 866 "qmljs.g"
case 22: { case 22: {
sym(1).UiImport->versionToken = loc(2); auto versionToken = loc(2);
sym(1).UiImport->version = sym(2).UiVersionSpecifier; auto version = sym(2).UiVersionSpecifier;
sym(1).UiImport->version = version;
if (version->minorToken.isValid()) {
versionToken.length += version->minorToken.length + (version->minorToken.offset - versionToken.offset - versionToken.length);
}
sym(1).UiImport->versionToken = versionToken;
sym(1).UiImport->asToken = loc(3); sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4); sym(1).UiImport->importIdToken = loc(4);
sym(1).UiImport->importId = stringRef(4); sym(1).UiImport->importId = stringRef(4);

View File

@@ -265,6 +265,11 @@ public:
addLocation(line, column); addLocation(line, column);
} }
void pragmaLibrary() override
{
isLibrary = true;
}
virtual QList<SourceLocation> locations() { return _locations; } virtual QList<SourceLocation> locations() { return _locations; }
const QString documentPath; const QString documentPath;

View File

@@ -24,8 +24,9 @@
****************************************************************************/ ****************************************************************************/
#include "qmljsreformatter.h" #include "qmljsreformatter.h"
#include "qmljscodeformatter.h" #include "qmljscodeformatter.h"
#include "qmljsbind.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include "parser/qmljsastvisitor_p.h" #include "parser/qmljsastvisitor_p.h"
#include "parser/qmljsengine_p.h" #include "parser/qmljsengine_p.h"
@@ -122,6 +123,10 @@ public:
// emit directives // emit directives
if (_doc->bind()->isJsLibrary()) {
out(QLatin1String(".pragma library"));
newLine();
}
const QList<SourceLocation> &directives = _doc->jsDirectives(); const QList<SourceLocation> &directives = _doc->jsDirectives();
for (const auto &d: directives) { for (const auto &d: directives) {
quint32 line = 1; quint32 line = 1;

View File

@@ -1,29 +1,41 @@
#todo if (NOT WIN32 OR NOT MSVC)
# - handle if there is no debug python lib python35_d
# - needs to be tested
if (MINGW)
message(STATUS "MinGW detected. Removing qtcreatorcdbext from build.")
return() return()
endif() endif()
include(CheckIncludeFile) find_path(WDbgExtsPath wdbgexts.h
check_include_file(wdbgexts.h HAVE_WDBGEXTS_H) HINTS
if (NOT HAVE_WDBGEXTS_H) "$ENV{CDB_PATH}"
"$ENV{ProgramFiles}/Debugging Tools For Windows/sdk"
"$ENV{ProgramFiles}/Debugging Tools For Windows (x86)/sdk"
"$ENV{ProgramFiles}/Debugging Tools For Windows (x64)/sdk"
"$ENV{ProgramFiles}/Debugging Tools For Windows 64-bit/sdk"
"$ENV{ProgramW6432}/Debugging Tools For Windows (x86)/sdk"
"$ENV{ProgramW6432}/Debugging Tools For Windows (x64)/sdk"
"$ENV{ProgramW6432}/Debugging Tools For Windows 64-bit/sdk"
"$ENV{ProgramFiles}/Windows Kits/8.0/Debuggers"
"$ENV{ProgramFiles}/Windows Kits/8.1/Debuggers"
"$ENV{ProgramFiles}/Windows Kits/10/Debuggers"
"$ENV{ProgramFiles\(x86\)}/Windows Kits/8.0/Debuggers/inc"
"$ENV{ProgramFiles\(x86\)}/Windows Kits/8.1/Debuggers/inc"
"$ENV{ProgramFiles\(x86\)}/Windows Kits/10/Debuggers/inc"
)
if (NOT WDbgExtsPath)
message(WARNING "wdbgexts.h not found. Removing qtcreatorcdbext from build.") message(WARNING "wdbgexts.h not found. Removing qtcreatorcdbext from build.")
return() return()
endif() endif()
find_package(PythonLibs 3.5) find_library(DbgEngLib dbgeng HINTS ${WDbgExtsPath})
if (NOT ${PYTHONLIBS_FOUND})
message(WARNING "PythonLibs 3.5 not found. Removing qtcreatorcdbext from build.") set(ArchSuffix 32)
return() if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ArchSuffix 64)
endif() endif()
add_qtc_library(qtcreatorcdbext add_qtc_library(qtcreatorcdbext
DEPENDS ${PYTHON_LIBRARIES} BUILD_BY_DEFAULT
INCLUDES ${PYTHON_INCLUDE_DIR} DEPENDS ${DbgEngLib}
DEFINES WITH_PYTHON=1 DESTINATION lib/qtcreatorcdbext${ArchSuffix}/
SOURCES SOURCES
common.cpp common.h common.cpp common.h
containers.cpp containers.h containers.cpp containers.h
@@ -33,14 +45,53 @@ add_qtc_library(qtcreatorcdbext
iinterfacepointer.h iinterfacepointer.h
knowntype.h knowntype.h
outputcallback.cpp outputcallback.h outputcallback.cpp outputcallback.h
pycdbextmodule.cpp pycdbextmodule.h qtcreatorcdbext.def
pyfield.cpp pyfield.h
pystdoutredirect.cpp pystdoutredirect.h
pytype.cpp pytype.h
pyvalue.cpp pyvalue.h
qtcreatorcdbextension.cpp qtcreatorcdbextension.cpp
stringutils.cpp stringutils.h stringutils.cpp stringutils.h
symbolgroup.cpp symbolgroup.h symbolgroup.cpp symbolgroup.h
symbolgroupnode.cpp symbolgroupnode.h symbolgroupnode.cpp symbolgroupnode.h
symbolgroupvalue.cpp symbolgroupvalue.h symbolgroupvalue.cpp symbolgroupvalue.h
) )
find_package(PythonLibs 3.5)
if (NOT ${PYTHONLIBS_FOUND})
message(WARNING "PythonLibs (at least version 3.5) not found. qtcreatorcdbext will be built without Python support.")
return()
endif()
set(PythonRegex "^(.*)/(.*)/(python[0-9]+)${CMAKE_IMPORT_LIBRARY_SUFFIX}$")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(PythonRegex "^(.*)/(.*)/(python[0-9]+_d)${CMAKE_IMPORT_LIBRARY_SUFFIX}$")
endif()
foreach(lib IN LISTS PYTHON_LIBRARIES)
if (lib MATCHES ${PythonRegex})
set(PythonDll "${CMAKE_MATCH_1}/${CMAKE_MATCH_3}${CMAKE_SHARED_LIBRARY_SUFFIX}")
break()
endif()
endforeach()
if (NOT PythonDll)
message(WARNING "PythonDll not found. qtcreatorcdbext will be built without Python support.")
return()
endif()
extend_qtc_target(qtcreatorcdbext
DEPENDS "${PYTHON_LIBRARIES}"
INCLUDES "${PYTHON_INCLUDE_DIR}"
DEFINES WITH_PYTHON=1
SOURCES
pycdbextmodule.cpp pycdbextmodule.h
pyfield.cpp pyfield.h
pystdoutredirect.cpp pystdoutredirect.h
pytype.cpp pytype.h
pyvalue.cpp pyvalue.h
)
install(FILES "${PythonDll}" DESTINATION lib/qtcreatorcdbext${ArchSuffix}/)
add_custom_target(copy_python_dll ALL VERBATIM)
add_custom_command(TARGET copy_python_dll POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy "${PythonDll}" "${PROJECT_BINARY_DIR}/lib/qtcreatorcdbext${ArchSuffix}/"
VERBATIM
)

View File

@@ -151,7 +151,7 @@ QString ShellCommand::displayName() const
result = tr("UNKNOWN"); result = tr("UNKNOWN");
if (!job.command.arguments().isEmpty()) if (!job.command.arguments().isEmpty())
result += ' ' + job.command.arguments().at(0); result += ' ' + job.command.splitArguments().at(0);
return result; return result;
} }

View File

@@ -39,6 +39,9 @@
#include <coreplugin/progressmanager/futureprogress.h> #include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h> #include <projectexplorer/buildmanager.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
@@ -48,6 +51,7 @@
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/outputformat.h> #include <utils/outputformat.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
@@ -59,21 +63,19 @@
#include <QFuture> #include <QFuture>
#include <QFutureInterface> #include <QFutureInterface>
#include <QLabel> #include <QLabel>
#include <QLoggingCategory>
#include <QProcess> #include <QProcess>
#include <QPushButton> #include <QPushButton>
#include <QTimer> #include <QTimer>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
#include <utils/algorithm.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
static Q_LOGGING_CATEGORY(runnerLog, "qtc.autotest.testrunner", QtWarningMsg)
static TestRunner *s_instance = nullptr; static TestRunner *s_instance = nullptr;
TestRunner *TestRunner::instance() TestRunner *TestRunner::instance()
@@ -231,6 +233,11 @@ void TestRunner::scheduleNext()
const int timeout = AutotestPlugin::settings()->timeout; const int timeout = AutotestPlugin::settings()->timeout;
QTimer::singleShot(timeout, m_currentProcess, [this]() { cancelCurrent(Timeout); }); QTimer::singleShot(timeout, m_currentProcess, [this]() { cancelCurrent(Timeout); });
qCInfo(runnerLog) << "Command:" << m_currentProcess->program();
qCInfo(runnerLog) << "Arguments:" << m_currentProcess->arguments();
qCInfo(runnerLog) << "Working directory:" << m_currentProcess->workingDirectory();
qCDebug(runnerLog) << "Environment:" << m_currentProcess->environment();
m_currentProcess->start(); m_currentProcess->start();
if (!m_currentProcess->waitForStarted()) { if (!m_currentProcess->waitForStarted()) {
reportResult(ResultType::MessageFatal, reportResult(ResultType::MessageFatal,

View File

@@ -181,7 +181,8 @@ QList<TestTreeItem *> TestTreeModel::testItemsByName(TestTreeItem *root, const Q
} }
TestTreeItem *testCase = node->findFirstLevelChild([&testName](TestTreeItem *it) { TestTreeItem *testCase = node->findFirstLevelChild([&testName](TestTreeItem *it) {
QTC_ASSERT(it, return false); QTC_ASSERT(it, return false);
return it->type() == TestTreeItem::TestFunction && it->name() == testName; return (it->type() == TestTreeItem::TestCase
|| it->type() == TestTreeItem::TestFunction) && it->name() == testName;
}); // collect only actual tests, not special functions like init, cleanup etc. }); // collect only actual tests, not special functions like init, cleanup etc.
if (testCase) if (testCase)
result << testCase; result << testCase;

View File

@@ -40,7 +40,7 @@ BareMetalGdbCommandsDeployStepWidget::BareMetalGdbCommandsDeployStepWidget(BareM
: BuildStepConfigWidget(&step), m_step(step) : BuildStepConfigWidget(&step), m_step(step)
{ {
const auto fl = new QFormLayout(this); const auto fl = new QFormLayout(this);
fl->setMargin(0); fl->setContentsMargins(0, 0, 0, 0);
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
setLayout(fl); setLayout(fl);
m_commands = new QPlainTextEdit(this); m_commands = new QPlainTextEdit(this);

View File

@@ -45,11 +45,26 @@
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <projectexplorer/deployconfiguration.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace BareMetal { namespace BareMetal {
namespace Internal { namespace Internal {
class BareMetalDeployConfigurationFactory : public DeployConfigurationFactory
{
public:
BareMetalDeployConfigurationFactory()
{
setConfigBaseId("BareMetal.DeployConfiguration");
setDefaultDisplayName(QCoreApplication::translate("BareMetalDeployConfiguration",
"Deploy to BareMetal Device"));
addSupportedTargetDeviceType(Constants::BareMetalOsType);
}
};
// BareMetalPluginPrivate // BareMetalPluginPrivate
class BareMetalPluginPrivate class BareMetalPluginPrivate
@@ -63,6 +78,7 @@ public:
BareMetalCustomRunConfigurationFactory customRunConfigurationFactory; BareMetalCustomRunConfigurationFactory customRunConfigurationFactory;
GdbServerProvidersSettingsPage gdbServerProviderSettinsPage; GdbServerProvidersSettingsPage gdbServerProviderSettinsPage;
GdbServerProviderManager gdbServerProviderManager; GdbServerProviderManager gdbServerProviderManager;
BareMetalDeployConfigurationFactory deployConfigurationFactory;
RunWorkerFactory runWorkerFactory{ RunWorkerFactory runWorkerFactory{
RunWorkerFactory::make<BareMetalDebugSupport>(), RunWorkerFactory::make<BareMetalDebugSupport>(),

View File

@@ -86,20 +86,14 @@ void KeilParser::amendDescription(const QString &desc)
++m_lines; ++m_lines;
} }
void KeilParser::stdError(const QString &line) // ARM compiler specific parsers.
bool KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
{ {
IOutputParser::stdError(line); const QRegularExpression re("^\"(.+)\", line (\\d+).*:\\s+(Warning|Error):(\\s+|.+)([#|L].+)$");
const QRegularExpressionMatch match = re.match(lne);
const QString lne = rightTrimmed(line); if (!match.hasMatch())
return false;
QRegularExpression re;
QRegularExpressionMatch match;
// ARM compiler specific patterns.
re.setPattern("^\"(.+)\", line (\\d+).*:\\s+(Warning|Error):(\\s+|.+)([#|L].+)$");
match = re.match(lne);
if (match.hasMatch()) {
enum CaptureIndex { FilePathIndex = 1, LineNumberIndex, enum CaptureIndex { FilePathIndex = 1, LineNumberIndex,
MessageTypeIndex, MessageNoteIndex, DescriptionIndex }; MessageTypeIndex, MessageNoteIndex, DescriptionIndex };
const Utils::FilePath fileName = Utils::FilePath::fromUserInput( const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
@@ -109,19 +103,106 @@ void KeilParser::stdError(const QString &line)
const QString descr = match.captured(DescriptionIndex); const QString descr = match.captured(DescriptionIndex);
const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE); const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE);
newTask(task); newTask(task);
return; return true;
} }
re.setPattern("^(Error|Fatal error):\\s(.+)$"); bool KeilParser::parseArmErrorOrFatalErorrMessage(const QString &lne)
match = re.match(lne); {
if (match.hasMatch()) { const QRegularExpression re("^(Error|Fatal error):\\s(.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
return false;
enum CaptureIndex { MessageTypeIndex = 1, DescriptionIndex }; enum CaptureIndex { MessageTypeIndex = 1, DescriptionIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex)); const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(DescriptionIndex); const QString descr = match.captured(DescriptionIndex);
const Task task(type, descr, {}, -1, Constants::TASK_CATEGORY_COMPILE); const Task task(type, descr, {}, -1, Constants::TASK_CATEGORY_COMPILE);
newTask(task); newTask(task);
return true;
}
// MCS51 compiler specific parsers.
bool KeilParser::parseMcs51WarningOrErrorDetailsMessage1(const QString &lne)
{
const QRegularExpression re("^\\*{3} (WARNING|ERROR) (\\w+) IN LINE (\\d+) OF (.+\\.\\S+): (.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
return false;
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const int lineno = match.captured(LineNumberIndex).toInt();
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return true;
}
bool KeilParser::parseMcs51WarningOrErrorDetailsMessage2(const QString &lne)
{
const QRegularExpression re("^\\*{3} (WARNING|ERROR) (#\\w+) IN (\\d+) \\((.+), LINE \\d+\\): (.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
return false;
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const int lineno = match.captured(LineNumberIndex).toInt();
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return true;
}
bool KeilParser::parseMcs51WarningOrFatalErrorMessage(const QString &lne)
{
const QRegularExpression re("^\\*{3} (WARNING|FATAL ERROR) (.+)$");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
return false;
enum CaptureIndex { MessageTypeIndex = 1, MessageDescriptionIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(MessageDescriptionIndex);
const Task task(type, descr, {}, -1, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return true;
}
bool KeilParser::parseMcs51FatalErrorMessage2(const QString &lne)
{
const QRegularExpression re("^(A|C)51 FATAL[ |-]ERROR");
const QRegularExpressionMatch match = re.match(lne);
if (!match.hasMatch())
return false;
const QString key = match.captured(1);
QString descr;
if (key == QLatin1Char('A'))
descr = "Assembler fatal error";
else if (key == QLatin1Char('C'))
descr = "Compiler fatal error";
const Task task(Task::TaskType::Error, descr, {}, -1,
Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return true;
}
void KeilParser::stdError(const QString &line)
{
IOutputParser::stdError(line);
const QString lne = rightTrimmed(line);
// Check for ARM compiler specific patterns.
if (parseArmWarningOrErrorDetailsMessage(lne))
return;
if (parseArmErrorOrFatalErorrMessage(lne))
return; return;
}
if (lne.startsWith(QLatin1Char(' '))) { if (lne.startsWith(QLatin1Char(' '))) {
amendDescription(lne); amendDescription(lne);
@@ -137,64 +218,13 @@ void KeilParser::stdOutput(const QString &line)
const QString lne = rightTrimmed(line); const QString lne = rightTrimmed(line);
QRegularExpression re; // Check for MSC51 compiler specific patterns.
QRegularExpressionMatch match; const bool parsed = parseMcs51WarningOrErrorDetailsMessage1(lne)
|| parseMcs51WarningOrErrorDetailsMessage2(lne);
// MSC51 compiler specific patterns. if (!parsed) {
if (parseMcs51WarningOrFatalErrorMessage(lne))
re.setPattern("^\\*{3} (WARNING|ERROR) (\\w+) IN LINE (\\d+) OF (.+\\.\\S+): (.+)$");
match = re.match(lne);
if (match.hasMatch()) {
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const int lineno = match.captured(LineNumberIndex).toInt();
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
}
re.setPattern("^\\*{3} (WARNING|ERROR) (#\\w+) IN (\\d+) \\((.+), LINE \\d+\\): (.+)$");
match = re.match(lne);
if (match.hasMatch()) {
enum CaptureIndex { MessageTypeIndex = 1, MessageCodeIndex, LineNumberIndex,
FilePathIndex, MessageTextIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const int lineno = match.captured(LineNumberIndex).toInt();
const Utils::FilePath fileName = Utils::FilePath::fromUserInput(
match.captured(FilePathIndex));
const QString descr = QString("%1: %2").arg(match.captured(MessageCodeIndex),
match.captured(MessageTextIndex));
const Task task(type, descr, fileName, lineno, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
}
re.setPattern("^\\*{3} (FATAL ERROR) (.+)$");
match = re.match(lne);
if (match.hasMatch()) {
enum CaptureIndex { MessageTypeIndex = 1, MessageDescriptionIndex };
const Task::TaskType type = taskType(match.captured(MessageTypeIndex));
const QString descr = match.captured(MessageDescriptionIndex);
const Task task(type, descr, {}, -1, Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return; return;
} if (parseMcs51FatalErrorMessage2(lne))
re.setPattern("^(A|C)51 FATAL[ |-]ERROR");
match = re.match(lne);
if (match.hasMatch()) {
const QString key = match.captured(1);
QString descr;
if (key == QLatin1Char('A'))
descr = "Assembler fatal error";
else if (key == QLatin1Char('C'))
descr = "Compiler fatal error";
const Task task(Task::TaskType::Error, descr, {}, -1,
Constants::TASK_CATEGORY_COMPILE);
newTask(task);
return; return;
} }
@@ -463,6 +493,21 @@ void BareMetalPlugin::testKeilOutputParsers_data()
<< QString(); << QString();
// Linker messages. // Linker messages.
QTest::newRow("MCS51: Linker warning")
<< QString::fromLatin1("*** WARNING L16: Some warning\n"
" Some detail 1")
<< OutputParserTester::STDOUT
<< QString::fromLatin1("*** WARNING L16: Some warning\n"
" Some detail 1\n")
<< QString()
<< (Tasks() << Task(Task::Warning,
QLatin1String("L16: Some warning\n"
" Some detail 1"),
Utils::FilePath(),
-1,
categoryCompile))
<< QString();
QTest::newRow("MCS51: Linker simple fatal error") QTest::newRow("MCS51: Linker simple fatal error")
<< QString::fromLatin1("*** FATAL ERROR L456: Some error") << QString::fromLatin1("*** FATAL ERROR L456: Some error")
<< OutputParserTester::STDOUT << OutputParserTester::STDOUT

View File

@@ -45,6 +45,16 @@ private:
void newTask(const ProjectExplorer::Task &task); void newTask(const ProjectExplorer::Task &task);
void amendDescription(const QString &desc); void amendDescription(const QString &desc);
// ARM compiler specific parsers.
bool parseArmWarningOrErrorDetailsMessage(const QString &lne);
bool parseArmErrorOrFatalErorrMessage(const QString &lne);
// MCS51 compiler specific parsers.
bool parseMcs51WarningOrErrorDetailsMessage1(const QString &lne);
bool parseMcs51WarningOrErrorDetailsMessage2(const QString &lne);
bool parseMcs51WarningOrFatalErrorMessage(const QString &lne);
bool parseMcs51FatalErrorMessage2(const QString &lne);
void stdError(const QString &line) final; void stdError(const QString &line) final;
void stdOutput(const QString &line) final; void stdOutput(const QString &line) final;
void doFlush() final; void doFlush() final;

View File

@@ -110,7 +110,7 @@ void SdccParser::stdError(const QString &line)
return; return;
} }
re.setPattern("^(.+\\.\\S+):(\\d+): (syntax error): (.+)$"); re.setPattern("^(.+\\.\\S+):(\\d+): (Error|error|syntax error): (.+)$");
match = re.match(lne); match = re.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
enum CaptureIndex { FilePathIndex = 1, LineNumberIndex, enum CaptureIndex { FilePathIndex = 1, LineNumberIndex,
@@ -125,7 +125,7 @@ void SdccParser::stdError(const QString &line)
return; return;
} }
re.setPattern("^at (\\d+): (error) \\d+: (.+)$"); re.setPattern("^at (\\d+): (warning|error) \\d+: (.+)$");
match = re.match(lne); match = re.match(lne);
if (match.hasMatch()) { if (match.hasMatch()) {
enum CaptureIndex { MessageCodeIndex = 1, MessageTypeIndex, MessageTextIndex }; enum CaptureIndex { MessageCodeIndex = 1, MessageTypeIndex, MessageTextIndex };
@@ -208,6 +208,18 @@ void BareMetalPlugin::testSdccOutputParsers_data()
// Compiler messages. // Compiler messages.
QTest::newRow("Assembler error")
<< QString::fromLatin1("c:\\foo\\main.c:63: Error: Some error")
<< OutputParserTester::STDERR
<< QString()
<< QString::fromLatin1("c:\\foo\\main.c:63: Error: Some error\n")
<< (Tasks() << Task(Task::Error,
QLatin1String("Some error"),
Utils::FilePath::fromUserInput(QLatin1String("c:\\foo\\main.c")),
63,
categoryCompile))
<< QString();
QTest::newRow("Compiler single line warning") QTest::newRow("Compiler single line warning")
<< QString::fromLatin1("c:\\foo\\main.c:63: warning 123: Some warning") << QString::fromLatin1("c:\\foo\\main.c:63: warning 123: Some warning")
<< OutputParserTester::STDERR << OutputParserTester::STDERR
@@ -238,6 +250,18 @@ void BareMetalPlugin::testSdccOutputParsers_data()
categoryCompile)) categoryCompile))
<< QString(); << QString();
QTest::newRow("Compiler simple single line error")
<< QString::fromLatin1("c:\\foo\\main.c:63: error: Some error")
<< OutputParserTester::STDERR
<< QString()
<< QString::fromLatin1("c:\\foo\\main.c:63: error: Some error\n")
<< (Tasks() << Task(Task::Error,
QLatin1String("Some error"),
Utils::FilePath::fromUserInput(QLatin1String("c:\\foo\\main.c")),
63,
categoryCompile))
<< QString();
QTest::newRow("Compiler single line error") QTest::newRow("Compiler single line error")
<< QString::fromLatin1("c:\\foo\\main.c:63: error 123: Some error") << QString::fromLatin1("c:\\foo\\main.c:63: error 123: Some error")
<< OutputParserTester::STDERR << OutputParserTester::STDERR
@@ -292,6 +316,18 @@ void BareMetalPlugin::testSdccOutputParsers_data()
categoryCompile)) categoryCompile))
<< QString(); << QString();
QTest::newRow("Compiler bad option warning")
<< QString::fromLatin1("at 1: warning 123: Some warning")
<< OutputParserTester::STDERR
<< QString()
<< QString::fromLatin1("at 1: warning 123: Some warning\n")
<< (Tasks() << Task(Task::Warning,
QLatin1String("Some warning"),
Utils::FilePath(),
-1,
categoryCompile))
<< QString();
QTest::newRow("Linker warning") QTest::newRow("Linker warning")
<< QString::fromLatin1("?ASlink-Warning-Couldn't find library 'foo.lib'") << QString::fromLatin1("?ASlink-Warning-Couldn't find library 'foo.lib'")
<< OutputParserTester::STDERR << OutputParserTester::STDERR

View File

@@ -328,7 +328,7 @@ DeploymentData CMakeBuildConfiguration::deploymentData() const
for (const CMakeBuildTarget &ct : m_buildTargets) { for (const CMakeBuildTarget &ct : m_buildTargets) {
if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType) { if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType) {
if (!ct.executable.isEmpty() if (!ct.executable.isEmpty()
&& !result.deployableForLocalFile(ct.executable).isValid()) { && result.deployableForLocalFile(ct.executable).localFilePath() != ct.executable) {
result.addFile(ct.executable.toString(), result.addFile(ct.executable.toString(),
deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()), deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()),
DeployableFile::TypeExecutable); DeployableFile::TypeExecutable);
@@ -652,10 +652,9 @@ QList<BuildInfo> CMakeBuildConfigurationFactory::availableBuilds(const Kit *k,
for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) { for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) {
BuildInfo info = createBuildInfo(k, path.toString(), BuildType(type)); BuildInfo info = createBuildInfo(k, path.toString(), BuildType(type));
if (forSetup) { if (forSetup) {
info.displayName = info.typeName;
info.buildDirectory = CMakeBuildConfiguration::shadowBuildDirectory(projectPath, info.buildDirectory = CMakeBuildConfiguration::shadowBuildDirectory(projectPath,
k, k,
info.displayName, info.typeName,
info.buildType); info.buildType);
} }
result << info; result << info;
@@ -676,26 +675,28 @@ BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
CMakeConfigItem buildTypeItem; CMakeConfigItem buildTypeItem;
switch (buildType) { switch (buildType) {
case BuildTypeNone: case BuildTypeNone:
info.typeName = tr("Build"); info.typeName = "Build";
info.displayName = tr("Build");
info.buildType = BuildConfiguration::Unknown;
break; break;
case BuildTypeDebug: case BuildTypeDebug:
buildTypeItem = {CMakeConfigItem("CMAKE_BUILD_TYPE", "Debug")}; info.typeName = "Debug";
info.typeName = tr("Debug"); info.displayName = tr("Debug");
info.buildType = BuildConfiguration::Debug; info.buildType = BuildConfiguration::Debug;
break; break;
case BuildTypeRelease: case BuildTypeRelease:
buildTypeItem = {CMakeConfigItem("CMAKE_BUILD_TYPE", "Release")}; info.typeName = "Release";
info.typeName = tr("Release"); info.displayName = tr("Release");
info.buildType = BuildConfiguration::Release; info.buildType = BuildConfiguration::Release;
break; break;
case BuildTypeMinSizeRel: case BuildTypeMinSizeRel:
buildTypeItem = {CMakeConfigItem("CMAKE_BUILD_TYPE", "MinSizeRel")}; info.typeName = "MinSizeRel";
info.typeName = tr("Minimum Size Release"); info.displayName = tr("Minimum Size Release");
info.buildType = BuildConfiguration::Release; info.buildType = BuildConfiguration::Release;
break; break;
case BuildTypeRelWithDebInfo: case BuildTypeRelWithDebInfo:
buildTypeItem = {CMakeConfigItem("CMAKE_BUILD_TYPE", "RelWithDebInfo")}; info.typeName = "RelWithDebInfo";
info.typeName = tr("Release with Debug Information"); info.displayName = tr("Release with Debug Information");
info.buildType = BuildConfiguration::Profile; info.buildType = BuildConfiguration::Profile;
break; break;
default: default:
@@ -703,6 +704,8 @@ BuildInfo CMakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
break; break;
} }
buildTypeItem = {CMakeConfigItem("CMAKE_BUILD_TYPE", info.typeName.toUtf8())};
if (!buildTypeItem.isNull()) if (!buildTypeItem.isNull())
extra.configuration.append(buildTypeItem); extra.configuration.append(buildTypeItem);

View File

@@ -319,6 +319,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
}); });
QModelIndex idx = m_configModel->indexForItem(item); QModelIndex idx = m_configModel->indexForItem(item);
idx = m_configTextFilterModel->mapFromSource(m_configFilterModel->mapFromSource(idx)); idx = m_configTextFilterModel->mapFromSource(m_configFilterModel->mapFromSource(idx));
m_configView->setFocus();
m_configView->scrollTo(idx); m_configView->scrollTo(idx);
m_configView->setCurrentIndex(idx); m_configView->setCurrentIndex(idx);
m_configView->edit(idx); m_configView->edit(idx);

View File

@@ -87,7 +87,7 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
if (m_buildTarget.isEmpty()) if (m_buildTarget.isEmpty())
setBuildTarget(defaultBuildTarget()); setBuildTarget(defaultBuildTarget());
setLowPriorityIfConfigured(); setLowPriority();
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged); connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
connect(project(), &Project::parsingFinished, connect(project(), &Project::parsingFinished,

View File

@@ -167,8 +167,7 @@ void CMakeTool::setFilePath(const Utils::FilePath &executable)
if (m_executable == executable) if (m_executable == executable)
return; return;
m_introspection->m_didRun = false; m_introspection = std::make_unique<Internal::IntrospectionData>();
m_introspection->m_didAttemptToRun = false;
m_executable = executable; m_executable = executable;
CMakeToolManager::notifyAboutUpdate(this); CMakeToolManager::notifyAboutUpdate(this);

View File

@@ -176,7 +176,7 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
: QIcon::Disabled; : QIcon::Disabled;
QRect iconRect(0, 0, Constants::MODEBAR_ICON_SIZE, Constants::MODEBAR_ICON_SIZE); QRect iconRect(0, 0, Constants::MODEBAR_ICON_SIZE, Constants::MODEBAR_ICON_SIZE);
const bool isTitledAction = defaultAction()->property("titledAction").toBool(); const bool isTitledAction = defaultAction() && defaultAction()->property("titledAction").toBool();
// draw popup texts // draw popup texts
if (isTitledAction && !m_iconsOnly) { if (isTitledAction && !m_iconsOnly) {
QFont normalFont(painter.font()); QFont normalFont(painter.font());
@@ -286,7 +286,7 @@ QSize FancyToolButton::sizeHint() const
} }
QSizeF buttonSize = iconSize().expandedTo(QSize(64, 38)); QSizeF buttonSize = iconSize().expandedTo(QSize(64, 38));
if (defaultAction()->property("titledAction").toBool()) { if (defaultAction() && defaultAction()->property("titledAction").toBool()) {
QFont boldFont(font()); QFont boldFont(font());
boldFont.setPointSizeF(StyleHelper::sidebarFontSize()); boldFont.setPointSizeF(StyleHelper::sidebarFontSize());
boldFont.setBold(true); boldFont.setBold(true);

View File

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

View File

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

View File

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

View File

@@ -238,6 +238,9 @@ void ModeManager::removeMode(IMode *mode)
{ {
const int index = d->m_modes.indexOf(mode); const int index = d->m_modes.indexOf(mode);
d->m_modes.remove(index); d->m_modes.remove(index);
if (d->m_startingUp)
return;
d->m_modeCommands.remove(index); d->m_modeCommands.remove(index);
d->m_modeStack->removeTab(index); d->m_modeStack->removeTab(index);

View File

@@ -115,6 +115,7 @@ IOutputPane::~IOutputPane()
const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this)); const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this));
QTC_ASSERT(i >= 0, return); QTC_ASSERT(i >= 0, return);
delete g_outputPanes.at(i).button; delete g_outputPanes.at(i).button;
g_outputPanes.removeAt(i);
delete m_zoomInButton; delete m_zoomInButton;
delete m_zoomOutButton; delete m_zoomOutButton;

View File

@@ -1813,6 +1813,7 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &
{QString::fromLatin1("ToolChain Type"), part->toolchainType.toString()}, {QString::fromLatin1("ToolChain Type"), part->toolchainType.toString()},
{QString::fromLatin1("ToolChain Target Triple"), part->toolChainTargetTriple}, {QString::fromLatin1("ToolChain Target Triple"), part->toolChainTargetTriple},
{QString::fromLatin1("ToolChain Word Width"), CMI::Utils::toString(part->toolChainWordWidth)}, {QString::fromLatin1("ToolChain Word Width"), CMI::Utils::toString(part->toolChainWordWidth)},
{QString::fromLatin1("ToolChain Install Dir"), part->toolChainInstallDir.toString()},
{QString::fromLatin1("Language Version"), CMI::Utils::toString(part->languageVersion)}, {QString::fromLatin1("Language Version"), CMI::Utils::toString(part->languageVersion)},
{QString::fromLatin1("Language Extensions"), CMI::Utils::toString(part->languageExtensions)}, {QString::fromLatin1("Language Extensions"), CMI::Utils::toString(part->languageExtensions)},
{QString::fromLatin1("Qt Version"), CMI::Utils::toString(part->qtVersion)} {QString::fromLatin1("Qt Version"), CMI::Utils::toString(part->qtVersion)}

View File

@@ -381,7 +381,7 @@ CppIncludeHierarchyWidget::CppIncludeHierarchyWidget()
m_delegate.setAnnotationRole(AnnotationRole); m_delegate.setAnnotationRole(AnnotationRole);
m_inspectedFile = new TextEditorLinkLabel(this); m_inspectedFile = new TextEditorLinkLabel(this);
m_inspectedFile->setMargin(5); m_inspectedFile->setContentsMargins(5, 5, 5, 5);
m_treeView = new CppIncludeHierarchyTreeView; m_treeView = new CppIncludeHierarchyTreeView;
m_treeView->setModel(&m_model); m_treeView->setModel(&m_model);

View File

@@ -91,7 +91,7 @@ namespace Internal {
CppTypeHierarchyWidget::CppTypeHierarchyWidget() CppTypeHierarchyWidget::CppTypeHierarchyWidget()
{ {
m_inspectedClass = new TextEditor::TextEditorLinkLabel(this); m_inspectedClass = new TextEditor::TextEditorLinkLabel(this);
m_inspectedClass->setMargin(5); m_inspectedClass->setContentsMargins(5, 5, 5, 5);
m_model = new CppTypeHierarchyModel(this); m_model = new CppTypeHierarchyModel(this);
m_treeView = new NavigationTreeView(this); m_treeView = new NavigationTreeView(this);
m_treeView->setActivationMode(SingleClickActivation); m_treeView->setActivationMode(SingleClickActivation);

View File

@@ -529,6 +529,7 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
m_out << i3 << "ToolChain Type : " << part->toolchainType.toString() << "\n"; m_out << i3 << "ToolChain Type : " << part->toolchainType.toString() << "\n";
m_out << i3 << "ToolChain Target Triple: " << part->toolChainTargetTriple << "\n"; m_out << i3 << "ToolChain Target Triple: " << part->toolChainTargetTriple << "\n";
m_out << i3 << "ToolChain Word Width : " << part->toolChainWordWidth << "\n"; m_out << i3 << "ToolChain Word Width : " << part->toolChainWordWidth << "\n";
m_out << i3 << "ToolChain Install Dir : " << part->toolChainInstallDir << "\n";
m_out << i3 << "Compiler Flags : " << part->compilerFlags.join(", ") << "\n"; m_out << i3 << "Compiler Flags : " << part->compilerFlags.join(", ") << "\n";
m_out << i3 << "Selected For Building : " << part->selectedForBuilding << "\n"; m_out << i3 << "Selected For Building : " << part->selectedForBuilding << "\n";
m_out << i3 << "Build System Target : " << part->buildSystemTarget << "\n"; m_out << i3 << "Build System Target : " << part->buildSystemTarget << "\n";

View File

@@ -167,6 +167,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
part->isMsvc2015Toolchain = tcInfo.isMsvc2015ToolChain; part->isMsvc2015Toolchain = tcInfo.isMsvc2015ToolChain;
part->toolChainWordWidth = tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit part->toolChainWordWidth = tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit
: ProjectPart::WordWidth32Bit; : ProjectPart::WordWidth32Bit;
part->toolChainInstallDir = tcInfo.installDir;
part->toolChainTargetTriple = tcInfo.targetTriple; part->toolChainTargetTriple = tcInfo.targetTriple;
part->extraCodeModelFlags = tcInfo.extraCodeModelFlags; part->extraCodeModelFlags = tcInfo.extraCodeModelFlags;
part->compilerFlags = flags.commandLineFlags; part->compilerFlags = flags.commandLineFlags;

View File

@@ -30,9 +30,12 @@
#endif #endif
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QRegularExpression> #include <QRegularExpression>
#include <utils/algorithm.h>
namespace CppTools { namespace CppTools {
using ProjectExplorer::HeaderPath; using ProjectExplorer::HeaderPath;
@@ -57,6 +60,31 @@ bool HeaderPathFilter::isProjectHeaderPath(const QString &path) const
return path.startsWith(projectDirectory) || path.startsWith(buildDirectory); return path.startsWith(projectDirectory) || path.startsWith(buildDirectory);
} }
void HeaderPathFilter::removeGccInternalIncludePaths()
{
if (projectPart.toolchainType != ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
&& projectPart.toolchainType != ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
return;
}
if (projectPart.toolChainInstallDir.isEmpty())
return;
const Utils::FilePath gccInstallDir = projectPart.toolChainInstallDir;
auto isGccInternalInclude = [gccInstallDir](const HeaderPath &headerPath){
const auto includePath = Utils::FilePath::fromString(headerPath.path);
if (includePath.isChildOf(gccInstallDir)) {
const QString remainingPath = headerPath.path.mid(gccInstallDir.toString().size());
// MinGW ships the standard library headers in "<installdir>/include/c++".
// Ensure that we do not remove include paths pointing there.
return !remainingPath.startsWith("/include/c++");
}
return false;
};
Utils::erase(builtInHeaderPaths, isGccInternalInclude);
}
void HeaderPathFilter::filterHeaderPath(const ProjectExplorer::HeaderPath &headerPath) void HeaderPathFilter::filterHeaderPath(const ProjectExplorer::HeaderPath &headerPath)
{ {
if (headerPath.path.isEmpty()) if (headerPath.path.isEmpty())
@@ -92,24 +120,19 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
#endif #endif
} }
HeaderPaths::iterator resourceIterator(HeaderPaths &headerPaths, bool isMacOs) HeaderPaths::iterator resourceIterator(HeaderPaths &headerPaths)
{ {
// include/c++, include/g++, libc++\include and libc++abi\include // include/c++, include/g++, libc++\include and libc++abi\include
static const QString cppIncludes = R"((.*\/include\/.*(g\+\+|c\+\+).*))" static const QString cppIncludes = R"((.*/include/.*(g\+\+|c\+\+).*))"
R"(|(.*libc\+\+\/include))" R"(|(.*libc\+\+/include))"
R"(|(.*libc\+\+abi\/include))"; R"(|(.*libc\+\+abi/include))"
R"(|(/usr/local/include))";
static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z"); static const QRegularExpression includeRegExp("\\A(" + cppIncludes + ")\\z");
// The same as includeRegExp but also matches /usr/local/include
static const QRegularExpression includeRegExpMac("\\A(" + cppIncludes
+ R"(|(\/usr\/local\/include))" + ")\\z");
const QRegularExpression &includePathRegEx = isMacOs ? includeRegExpMac : includeRegExp;
return std::stable_partition(headerPaths.begin(), return std::stable_partition(headerPaths.begin(),
headerPaths.end(), headerPaths.end(),
[&](const HeaderPath &headerPath) { [&](const HeaderPath &headerPath) {
return includePathRegEx.match(headerPath.path).hasMatch(); return includeRegExp.match(headerPath.path).hasMatch();
}); });
} }
@@ -120,7 +143,7 @@ bool isClangSystemHeaderPath(const HeaderPath &headerPath)
// For example GCC on macOS uses system clang include path which makes clang code model // For example GCC on macOS uses system clang include path which makes clang code model
// include incorrect system headers. // include incorrect system headers.
static const QRegularExpression clangIncludeDir( static const QRegularExpression clangIncludeDir(
R"(\A.*\/lib\d*\/clang\/\d+\.\d+(\.\d+)?\/include\z)"); R"(\A.*/lib\d*/clang/\d+\.\d+(\.\d+)?/include\z)");
return clangIncludeDir.match(headerPath.path).hasMatch(); return clangIncludeDir.match(headerPath.path).hasMatch();
} }
@@ -135,9 +158,9 @@ void removeClangSystemHeaderPaths(HeaderPaths &headerPaths)
void HeaderPathFilter::tweakHeaderPaths() void HeaderPathFilter::tweakHeaderPaths()
{ {
removeClangSystemHeaderPaths(builtInHeaderPaths); removeClangSystemHeaderPaths(builtInHeaderPaths);
removeGccInternalIncludePaths();
auto split = resourceIterator(builtInHeaderPaths, auto split = resourceIterator(builtInHeaderPaths);
projectPart.toolChainTargetTriple.contains("darwin"));
if (!clangVersion.isEmpty()) { if (!clangVersion.isEmpty()) {
const QString clangIncludePath = clangIncludeDirectory(clangVersion, clangResourceDirectory); const QString clangIncludePath = clangIncludeDirectory(clangVersion, clangResourceDirectory);

View File

@@ -57,6 +57,8 @@ private:
bool isProjectHeaderPath(const QString &path) const; bool isProjectHeaderPath(const QString &path) const;
void removeGccInternalIncludePaths();
static QString ensurePathWithSlashEnding(const QString &path); static QString ensurePathWithSlashEnding(const QString &path);
public: public:

View File

@@ -42,6 +42,7 @@
#include <cplusplus/Token.h> #include <cplusplus/Token.h>
#include <utils/cpplanguage_details.h> #include <utils/cpplanguage_details.h>
#include <utils/fileutils.h>
#include <QString> #include <QString>
#include <QSharedPointer> #include <QSharedPointer>
@@ -108,6 +109,7 @@ public:
bool isMsvc2015Toolchain = false; bool isMsvc2015Toolchain = false;
QString toolChainTargetTriple; QString toolChainTargetTriple;
ToolChainWordWidth toolChainWordWidth = WordWidth32Bit; ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
Utils::FilePath toolChainInstallDir;
ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default; ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default;
// Misc // Misc

View File

@@ -345,6 +345,7 @@ private:
Utils::PathChooser *m_pathChooserFileName; Utils::PathChooser *m_pathChooserFileName;
QLabel *m_labelLineNumber; QLabel *m_labelLineNumber;
QLineEdit *m_lineEditLineNumber; QLineEdit *m_lineEditLineNumber;
QCheckBox *m_checkBoxPropagate;
QLabel *m_labelEnabled; QLabel *m_labelEnabled;
QCheckBox *m_checkBoxEnabled; QCheckBox *m_checkBoxEnabled;
QLabel *m_labelAddress; QLabel *m_labelAddress;
@@ -501,6 +502,11 @@ BreakpointDialog::BreakpointDialog(unsigned int enabledParts, QWidget *parent)
m_labelThreadSpec = new QLabel(tr("&Thread specification:"), groupBoxAdvanced); m_labelThreadSpec = new QLabel(tr("&Thread specification:"), groupBoxAdvanced);
m_labelThreadSpec->setBuddy(m_lineEditThreadSpec); m_labelThreadSpec->setBuddy(m_lineEditThreadSpec);
m_checkBoxPropagate = new QCheckBox(tr("Propagate Change to Preset Breakpoint"), this);
m_checkBoxPropagate->setCheckable(true);
m_checkBoxPropagate->setChecked(true);
m_checkBoxPropagate->setVisible(false); // FIXME: Make it work.
m_buttonBox = new QDialogButtonBox(this); m_buttonBox = new QDialogButtonBox(this);
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
@@ -538,6 +544,8 @@ BreakpointDialog::BreakpointDialog(unsigned int enabledParts, QWidget *parent)
verticalLayout->addSpacing(10); verticalLayout->addSpacing(10);
verticalLayout->addWidget(groupBoxAdvanced); verticalLayout->addWidget(groupBoxAdvanced);
verticalLayout->addSpacing(10); verticalLayout->addSpacing(10);
verticalLayout->addWidget(m_checkBoxPropagate);
verticalLayout->addSpacing(10);
verticalLayout->addWidget(m_buttonBox); verticalLayout->addWidget(m_buttonBox);
verticalLayout->setStretchFactor(groupBoxAdvanced, 10); verticalLayout->setStretchFactor(groupBoxAdvanced, 10);

View File

@@ -832,7 +832,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(const QStringList &arguments)
QTC_ASSERT(vbox, return); QTC_ASSERT(vbox, return);
auto label = new QLabel(widget); auto label = new QLabel(widget);
label->setText(text); label->setText(text);
label->setMargin(6); label->setContentsMargins(6, 6, 6, 6);
vbox->insertWidget(0, label); vbox->insertWidget(0, label);
}; };

View File

@@ -567,6 +567,7 @@ void LogWindow::doOutput()
if (m_queuedOutput.isEmpty()) if (m_queuedOutput.isEmpty())
return; return;
if (theGlobalLog)
theGlobalLog->doOutput(m_queuedOutput); theGlobalLog->doOutput(m_queuedOutput);
QTextCursor cursor = m_combinedText->textCursor(); QTextCursor cursor = m_combinedText->textCursor();
@@ -706,6 +707,7 @@ GlobalLogWindow::GlobalLogWindow()
GlobalLogWindow::~GlobalLogWindow() GlobalLogWindow::~GlobalLogWindow()
{ {
theGlobalLog = nullptr;
} }
void GlobalLogWindow::doOutput(const QString &output) void GlobalLogWindow::doOutput(const QString &output)

View File

@@ -27,7 +27,6 @@
#include "helpconstants.h" #include "helpconstants.h"
#include "helpmanager.h" #include "helpmanager.h"
#include <coreplugin/helpmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <QFileDialog> #include <QFileDialog>
@@ -244,7 +243,7 @@ void DocSettingsPage::addDocumentation()
void DocSettingsPage::apply() void DocSettingsPage::apply()
{ {
Core::HelpManager::unregisterDocumentation(m_filesToUnregister.keys()); HelpManager::unregisterNamespaces(m_filesToUnregister.keys());
QStringList files; QStringList files;
auto it = m_filesToRegisterUserManaged.constBegin(); auto it = m_filesToRegisterUserManaged.constBegin();
while (it != m_filesToRegisterUserManaged.constEnd()) { while (it != m_filesToRegisterUserManaged.constEnd()) {

View File

@@ -172,7 +172,7 @@ void HelpManager::registerDocumentationNow(QFutureInterface<bool> &futureInterfa
futureInterface.reportResult(docsChanged); futureInterface.reportResult(docsChanged);
} }
void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) void HelpManager::unregisterNamespaces(const QStringList &nameSpaces)
{ {
if (d->m_needsSetup) { if (d->m_needsSetup) {
for (const QString &name : nameSpaces) for (const QString &name : nameSpaces)
@@ -372,7 +372,7 @@ void HelpManager::setupHelpManager()
d->cleanUpDocumentation(); d->cleanUpDocumentation();
if (!d->m_nameSpacesToUnregister.isEmpty()) { if (!d->m_nameSpacesToUnregister.isEmpty()) {
m_instance->unregisterDocumentation(Utils::toList(d->m_nameSpacesToUnregister)); m_instance->unregisterNamespaces(Utils::toList(d->m_nameSpacesToUnregister));
d->m_nameSpacesToUnregister.clear(); d->m_nameSpacesToUnregister.clear();
} }

View File

@@ -49,7 +49,8 @@ public:
static QString collectionFilePath(); static QString collectionFilePath();
void registerDocumentation(const QStringList &fileNames) override; void registerDocumentation(const QStringList &fileNames) override;
void unregisterDocumentation(const QStringList &nameSpaces) override;
static void unregisterNamespaces(const QStringList &nameSpaces);
static void registerUserDocumentation(const QStringList &filePaths); static void registerUserDocumentation(const QStringList &filePaths);
static QSet<QString> userDocumentationPaths(); static QSet<QString> userDocumentationPaths();

View File

@@ -311,79 +311,113 @@ signals:
void changed(); void changed();
}; };
McuSupportOptions::McuSupportOptions(QObject *parent) static PackageOptions* createQulPackage()
: QObject(parent)
{ {
auto qulPackage = new PackageOptions( auto result = new PackageOptions(
McuSupportOptionsPage::tr("Qt MCU SDK"), McuSupportOptionsPage::tr("Qt MCU SDK"),
QDir::homePath(), QDir::homePath(),
Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"), Utils::HostOsInfo::withExecutableSuffix("bin/qmltocpp"),
"qulSdk"); "qulSdk");
qulPackage->setEnvironmentVariableName("Qul_DIR"); result->setEnvironmentVariableName("Qul_DIR");
return result;
}
const QString armGccDefaultPath = static PackageOptions* createArmGccPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ? Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)")) QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles(x86)"))
+ "/GNU Tools ARM Embedded/" + "/GNU Tools ARM Embedded/"
: QString("%{Env:ARMGCC_DIR}"); : QString("%{Env:ARMGCC_DIR}");
auto armGcc = new PackageOptions( auto result = new PackageOptions(
McuSupportOptionsPage::tr("GNU Arm Embedded Toolchain"), McuSupportOptionsPage::tr("GNU Arm Embedded Toolchain"),
armGccDefaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"), Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"),
Constants::SETTINGS_KEY_PACKAGE_ARMGCC); Constants::SETTINGS_KEY_PACKAGE_ARMGCC);
armGcc->setDownloadUrl( result->setDownloadUrl(
QUrl::fromUserInput("https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads")); QUrl::fromUserInput("https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads"));
armGcc->setEnvironmentVariableName("ARMGCC_DIR"); result->setEnvironmentVariableName("ARMGCC_DIR");
toolchainPackage = armGcc; return result;
}
auto stm32CubeFwF7Sdk = new PackageOptions( static PackageOptions* createStm32CubeFwF7SdkPackage()
{
auto result = new PackageOptions(
McuSupportOptionsPage::tr("STM32Cube SDK"), McuSupportOptionsPage::tr("STM32Cube SDK"),
"%{Env:STM32Cube_FW_F7_SDK_PATH}", "%{Env:STM32Cube_FW_F7_SDK_PATH}",
"Drivers/STM32F7xx_HAL_Driver", "Drivers/STM32F7xx_HAL_Driver",
"stm32CubeFwF7Sdk"); "stm32CubeFwF7Sdk");
stm32CubeFwF7Sdk->setDownloadUrl( 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")); QUrl::fromUserInput("https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef7.html"));
stm32CubeFwF7Sdk->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH"); result->setEnvironmentVariableName("STM32Cube_FW_F7_SDK_PATH");
return result;
}
const QString stm32CubeProgrammerDefaultPath = static PackageOptions* createStm32CubeProgrammerPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ? Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles")) QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles"))
+ "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
: QDir::homePath(); : QDir::homePath();
auto stm32CubeProgrammer = new PackageOptions( auto result = new PackageOptions(
McuSupportOptionsPage::tr("STM32CubeProgrammer"), McuSupportOptionsPage::tr("STM32CubeProgrammer"),
stm32CubeProgrammerDefaultPath, defaultPath,
"bin", "bin",
"stm32CubeProgrammer"); "stm32CubeProgrammer");
stm32CubeProgrammer->setDownloadUrl( result->setDownloadUrl(
QUrl::fromUserInput("https://www.st.com/en/development-tools/stm32cubeprog.html")); QUrl::fromUserInput("https://www.st.com/en/development-tools/stm32cubeprog.html"));
stm32CubeProgrammer->setAddToPath(true); result->setAddToPath(true);
return result;
}
auto evkbImxrt1050Sdk = new PackageOptions( static PackageOptions* createEvkbImxrt1050SdkPackage()
{
auto result = new PackageOptions(
McuSupportOptionsPage::tr("NXP EVKB-IMXRT1050 SDK"), McuSupportOptionsPage::tr("NXP EVKB-IMXRT1050 SDK"),
"%{Env:EVKB_IMXRT1050_SDK_PATH}", "%{Env:EVKB_IMXRT1050_SDK_PATH}",
"EVKB-IMXRT1050_manifest_v3_5.xml", "EVKB-IMXRT1050_manifest_v3_5.xml",
"evkbImxrt1050Sdk"); "evkbImxrt1050Sdk");
evkbImxrt1050Sdk->setDownloadUrl( result->setDownloadUrl(
QUrl::fromUserInput("https://mcuxpresso.nxp.com/en/welcome")); QUrl::fromUserInput("https://mcuxpresso.nxp.com/en/welcome"));
return result;
}
const QString seggerJLinkDefaultPath = static PackageOptions* createSeggerJLinkPackage()
{
const QString defaultPath =
Utils::HostOsInfo::isWindowsHost() ? Utils::HostOsInfo::isWindowsHost() ?
QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles")) + "/SEGGER/JLink" QDir::fromNativeSeparators(qEnvironmentVariable("ProgramFiles")) + "/SEGGER/JLink"
: QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}"); : QString("%{Env:SEGGER_JLINK_SOFTWARE_AND_DOCUMENTATION_PATH}");
auto seggerJLink = new PackageOptions( auto result = new PackageOptions(
McuSupportOptionsPage::tr("SEGGER JLink"), McuSupportOptionsPage::tr("SEGGER JLink"),
seggerJLinkDefaultPath, defaultPath,
Utils::HostOsInfo::withExecutableSuffix("JLink"), Utils::HostOsInfo::withExecutableSuffix("JLink"),
"seggerJLink"); "seggerJLink");
seggerJLink->setDownloadUrl( result->setDownloadUrl(
QUrl::fromUserInput("https://www.segger.com/downloads/jlink")); QUrl::fromUserInput("https://www.segger.com/downloads/jlink"));
return result;
}
auto stmPackages = {armGcc, stm32CubeFwF7Sdk, stm32CubeProgrammer, qulPackage}; McuSupportOptions::McuSupportOptions(QObject *parent)
auto nxpPackages = {armGcc, evkbImxrt1050Sdk, seggerJLink, qulPackage}; : QObject(parent)
packages = {armGcc, stm32CubeFwF7Sdk, stm32CubeProgrammer, {
evkbImxrt1050Sdk, seggerJLink, 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}; qulPackage};
auto nxpPackages = {armGccPackage, evkbImxrt1050SdkPackage, seggerJLinkPackage,
qulPackage};
packages = {armGccPackage, stm32CubeFwF7SdkPackage, stm32CubeProgrammerPackage,
evkbImxrt1050SdkPackage, seggerJLinkPackage, qulPackage};
boards.append(new BoardOptions( boards.append(new BoardOptions(
"stm32f7508", "CMake/stm32f7508-discovery.cmake", stmPackages)); "stm32f7508", "CMake/stm32f7508-discovery.cmake", stmPackages));

View File

@@ -33,6 +33,8 @@
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/runcontrol.h> #include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <cmakeprojectmanager/cmakekitinformation.h>
#include <cmakeprojectmanager/cmaketool.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
@@ -42,9 +44,17 @@ namespace Internal {
static CommandLine flashAndRunCommand(Target *target) static CommandLine flashAndRunCommand(Target *target)
{ {
BuildConfiguration *bc = target->activeBuildConfiguration(); const QString projectName = target->project()->displayName();
return CommandLine(bc->environment().searchInPath("cmake"), {}); const CMakeProjectManager::CMakeTool *tool =
CMakeProjectManager::CMakeKitAspect::cmakeTool(target->kit());
return CommandLine(tool->filePath(), {
"--build",
".",
"--target",
QString("flash_%1_and_bootloader").arg(projectName)
});
} }
class FlashAndRunConfiguration : public ProjectExplorer::RunConfiguration class FlashAndRunConfiguration : public ProjectExplorer::RunConfiguration
@@ -57,6 +67,17 @@ public:
effectiveFlashAndRunCall->setLabelText(tr("Effective flash and run call:")); effectiveFlashAndRunCall->setLabelText(tr("Effective flash and run call:"));
effectiveFlashAndRunCall->setDisplayStyle(BaseStringAspect::TextEditDisplay); effectiveFlashAndRunCall->setDisplayStyle(BaseStringAspect::TextEditDisplay);
effectiveFlashAndRunCall->setReadOnly(true); effectiveFlashAndRunCall->setReadOnly(true);
auto updateConfiguration = [target, effectiveFlashAndRunCall] {
effectiveFlashAndRunCall->setValue(flashAndRunCommand(target).toUserOutput());
};
updateConfiguration();
connect(target->activeBuildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
this, updateConfiguration);
connect(target->project(), &Project::displayNameChanged,
this, updateConfiguration);
} }
}; };
@@ -67,8 +88,11 @@ public:
: SimpleTargetRunner(runControl) : SimpleTargetRunner(runControl)
{ {
setStarter([this, runControl] { setStarter([this, runControl] {
CommandLine cmd = flashAndRunCommand(runControl->target()); ProjectExplorer::Target *target = runControl->target();
const CommandLine cmd = flashAndRunCommand(target);
Runnable r; Runnable r;
r.workingDirectory =
target->activeBuildConfiguration()->buildDirectory().toUserOutput();
r.setCommandLine(cmd); r.setCommandLine(cmd);
SimpleTargetRunner::doStart(r, {}); SimpleTargetRunner::doStart(r, {});
}); });

View File

@@ -5,6 +5,6 @@ project(%{ProjectName} VERSION 0.0.1 LANGUAGES CXX)
find_package(Qul) find_package(Qul)
add_executable(%{ProjectName}) add_executable(%{ProjectName})
QUL_ADD_QML(%{ProjectName} %{MainQmlFile}) qul_target_qml_sources(%{ProjectName} %{MainQmlFile})
target_link_libraries(%{ProjectName} Qul::QuickUltralite) target_link_libraries(%{ProjectName} Qul::QuickUltralite)

View File

@@ -1,5 +1,5 @@
pragma main; pragma main;
import QtQuick import QtQuick 2.0
Rectangle { Rectangle {
width: 480 width: 480
@@ -9,5 +9,6 @@ Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
color: "salmon" color: "salmon"
text: "Hello World!" text: "Hello World!"
font.pixelSize: 14
} }
} }

View File

@@ -188,7 +188,10 @@ void AbiWidget::setAbis(const Abis &abiList, const Abi &currentAbi)
setCustomAbiComboBoxes(defaultAbi); setCustomAbiComboBoxes(defaultAbi);
} }
emitAbiChanged(defaultAbi);
// Update disabled state according to new automatically selected item in main ABI combobox.
// This will call emitAbiChanged with the actual selected ABI.
mainComboBoxChanged();
} }
Abis AbiWidget::supportedAbis() const Abis AbiWidget::supportedAbis() const

View File

@@ -230,7 +230,7 @@ void AbstractProcessStep::doRun()
d->m_process->setWorkingDirectory(wd.absolutePath()); d->m_process->setWorkingDirectory(wd.absolutePath());
d->m_process->setEnvironment(d->m_param.environment()); d->m_process->setEnvironment(d->m_param.environment());
d->m_process->setCommand(effectiveCommand); d->m_process->setCommand(effectiveCommand);
if (d->m_lowPriority) if (d->m_lowPriority && ProjectExplorerPlugin::projectExplorerSettings().lowBuildPriority)
d->m_process->setLowPriority(); d->m_process->setLowPriority();
connect(d->m_process.get(), &QProcess::readyReadStandardOutput, connect(d->m_process.get(), &QProcess::readyReadStandardOutput,
@@ -251,9 +251,8 @@ void AbstractProcessStep::doRun()
processStarted(); processStarted();
} }
void AbstractProcessStep::setLowPriorityIfConfigured() void AbstractProcessStep::setLowPriority()
{ {
if (ProjectExplorerPlugin::projectExplorerSettings().lowBuildPriority)
d->m_lowPriority = true; d->m_lowPriority = true;
} }

View File

@@ -57,7 +57,7 @@ protected:
~AbstractProcessStep() override; ~AbstractProcessStep() override;
bool init() override; bool init() override;
void doRun() override; void doRun() override;
void setLowPriorityIfConfigured(); void setLowPriority();
virtual void finish(bool success); virtual void finish(bool success);
virtual void processStarted(); virtual void processStarted();

View File

@@ -57,8 +57,15 @@ void DeploymentData::addFile(const QString &localFilePath, const QString &remote
DeployableFile DeploymentData::deployableForLocalFile(const Utils::FilePath &localFilePath) const DeployableFile DeploymentData::deployableForLocalFile(const Utils::FilePath &localFilePath) const
{ {
return Utils::findOrDefault(m_files, const DeployableFile f = Utils::findOrDefault(m_files,
Utils::equal(&DeployableFile::localFilePath, localFilePath)); Utils::equal(&DeployableFile::localFilePath,
localFilePath));
if (f.isValid())
return f;
const QString localFileName = localFilePath.fileName();
return Utils::findOrDefault(m_files, [&localFileName](const DeployableFile &d) {
return d.localFilePath().fileName() == localFileName;
});
} }
bool DeploymentData::operator==(const DeploymentData &other) const bool DeploymentData::operator==(const DeploymentData &other) const

View File

@@ -232,6 +232,23 @@ static QString gccVersion(const FilePath &path, const QStringList &env)
return QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed(); return QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed();
} }
static Utils::FilePath gccInstallDir(const FilePath &path, const QStringList &env)
{
const QStringList arguments("-print-search-dirs");
QString output = QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed();
// Expected output looks like this:
// install: /usr/lib/gcc/x86_64-linux-gnu/7/
// ...
// Note that clang also supports "-print-search-dirs". However, the
// install dir is not part of the output (tested with clang-8/clang-9).
const QString prefix = "install: ";
const QString line = QTextStream(&output).readLine();
if (!line.startsWith(prefix))
return {};
return Utils::FilePath::fromString(QDir::cleanPath(line.mid(prefix.size())));
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// GccToolChain // GccToolChain
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -269,6 +286,15 @@ void GccToolChain::setOriginalTargetTriple(const QString &targetTriple)
toolChainUpdated(); toolChainUpdated();
} }
void GccToolChain::setInstallDir(const Utils::FilePath &installDir)
{
if (m_installDir == installDir)
return;
m_installDir = installDir;
toolChainUpdated();
}
QString GccToolChain::defaultDisplayName() const QString GccToolChain::defaultDisplayName() const
{ {
QString type = typeDisplayName(); QString type = typeDisplayName();
@@ -310,6 +336,13 @@ QString GccToolChain::version() const
return m_version; return m_version;
} }
FilePath GccToolChain::installDir() const
{
if (m_installDir.isEmpty())
m_installDir = detectInstallDir();
return m_installDir;
}
void GccToolChain::setTargetAbi(const Abi &abi) void GccToolChain::setTargetAbi(const Abi &abi)
{ {
if (abi == m_targetAbi) if (abi == m_targetAbi)
@@ -715,6 +748,7 @@ void GccToolChain::resetToolChain(const FilePath &path)
const DetectedAbisResult detectedAbis = detectSupportedAbis(); const DetectedAbisResult detectedAbis = detectSupportedAbis();
m_supportedAbis = detectedAbis.supportedAbis; m_supportedAbis = detectedAbis.supportedAbis;
m_originalTargetTriple = detectedAbis.originalTargetTriple; m_originalTargetTriple = detectedAbis.originalTargetTriple;
m_installDir = installDir();
m_targetAbi = Abi(); m_targetAbi = Abi();
if (!m_supportedAbis.isEmpty()) { if (!m_supportedAbis.isEmpty()) {
@@ -856,6 +890,13 @@ QString GccToolChain::detectVersion() const
return gccVersion(findLocalCompiler(m_compilerCommand, env), env.toStringList()); return gccVersion(findLocalCompiler(m_compilerCommand, env), env.toStringList());
} }
Utils::FilePath GccToolChain::detectInstallDir() const
{
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
return gccInstallDir(findLocalCompiler(m_compilerCommand, env), env.toStringList());
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// GccToolChainFactory // GccToolChainFactory
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -1119,6 +1160,9 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescr
const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath, const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath,
systemEnvironment.toStringList(), systemEnvironment.toStringList(),
macros); macros);
const Utils::FilePath installDir = gccInstallDir(localCompilerPath,
systemEnvironment.toStringList());
for (const Abi &abi : detectedAbis.supportedAbis) { for (const Abi &abi : detectedAbis.supportedAbis) {
std::unique_ptr<GccToolChain> tc(dynamic_cast<GccToolChain *>(create())); std::unique_ptr<GccToolChain> tc(dynamic_cast<GccToolChain *>(create()));
if (!tc) if (!tc)
@@ -1134,6 +1178,7 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescr
tc->setSupportedAbis(detectedAbis.supportedAbis); tc->setSupportedAbis(detectedAbis.supportedAbis);
tc->setTargetAbi(abi); tc->setTargetAbi(abi);
tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple); tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple);
tc->setInstallDir(installDir);
tc->setDisplayName(tc->defaultDisplayName()); // reset displayname tc->setDisplayName(tc->defaultDisplayName()); // reset displayname
if (!checker || checker(tc.get())) if (!checker || checker(tc.get()))
result.append(tc.release()); result.append(tc.release());
@@ -1192,6 +1237,7 @@ void GccToolChainConfigWidget::applyImpl()
tc->setSupportedAbis(m_abiWidget->supportedAbis()); tc->setSupportedAbis(m_abiWidget->supportedAbis());
tc->setTargetAbi(m_abiWidget->currentAbi()); tc->setTargetAbi(m_abiWidget->currentAbi());
} }
tc->setInstallDir(tc->detectInstallDir());
tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple); tc->setOriginalTargetTriple(tc->detectSupportedAbis().originalTargetTriple);
tc->setDisplayName(displayName); // reset display name tc->setDisplayName(displayName); // reset display name
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text())); tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));

View File

@@ -71,6 +71,7 @@ public:
Abi targetAbi() const override; Abi targetAbi() const override;
QString originalTargetTriple() const override; QString originalTargetTriple() const override;
Utils::FilePath installDir() const override;
QString version() const; QString version() const;
Abis supportedAbis() const override; Abis supportedAbis() const override;
void setTargetAbi(const Abi &); void setTargetAbi(const Abi &);
@@ -129,6 +130,7 @@ protected:
void setCompilerCommand(const Utils::FilePath &path); void setCompilerCommand(const Utils::FilePath &path);
void setSupportedAbis(const Abis &abis); void setSupportedAbis(const Abis &abis);
void setOriginalTargetTriple(const QString &targetTriple); void setOriginalTargetTriple(const QString &targetTriple);
void setInstallDir(const Utils::FilePath &installDir);
void setMacroCache(const QStringList &allCxxflags, const Macros &macroCache) const; void setMacroCache(const QStringList &allCxxflags, const Macros &macroCache) const;
Macros macroCache(const QStringList &allCxxflags) const; Macros macroCache(const QStringList &allCxxflags) const;
@@ -137,6 +139,7 @@ protected:
virtual DetectedAbisResult detectSupportedAbis() const; virtual DetectedAbisResult detectSupportedAbis() const;
virtual QString detectVersion() const; virtual QString detectVersion() const;
virtual Utils::FilePath detectInstallDir() const;
// Reinterpret options for compiler drivers inheriting from GccToolChain (e.g qcc) to apply -Wp option // Reinterpret options for compiler drivers inheriting from GccToolChain (e.g qcc) to apply -Wp option
// that passes the initial options directly down to the gcc compiler // that passes the initial options directly down to the gcc compiler
@@ -196,6 +199,7 @@ private:
mutable QString m_originalTargetTriple; mutable QString m_originalTargetTriple;
mutable HeaderPaths m_headerPaths; mutable HeaderPaths m_headerPaths;
mutable QString m_version; mutable QString m_version;
mutable Utils::FilePath m_installDir;
friend class Internal::GccToolChainConfigWidget; friend class Internal::GccToolChainConfigWidget;
friend class Internal::GccToolChainFactory; friend class Internal::GccToolChainFactory;

View File

@@ -65,7 +65,7 @@ MakeStep::MakeStep(BuildStepList *parent, Core::Id id)
m_userJobCount(defaultJobCount()) m_userJobCount(defaultJobCount())
{ {
setDefaultDisplayName(defaultDisplayName()); setDefaultDisplayName(defaultDisplayName());
setLowPriorityIfConfigured(); setLowPriority();
} }
void MakeStep::setBuildTarget(const QString &buildTarget) void MakeStep::setBuildTarget(const QString &buildTarget)

View File

@@ -725,7 +725,7 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
m_kitAreaWidget = new KitAreaWidget(this); m_kitAreaWidget = new KitAreaWidget(this);
m_summaryLabel = new QLabel(this); m_summaryLabel = new QLabel(this);
m_summaryLabel->setMargin(3); m_summaryLabel->setContentsMargins(3, 3, 3, 3);
m_summaryLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); m_summaryLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
m_summaryLabel->setStyleSheet(QString::fromLatin1("background: %1;") m_summaryLabel->setStyleSheet(QString::fromLatin1("background: %1;")
.arg(creatorTheme()->color(Theme::MiniProjectTargetSelectorSummaryBackgroundColor).name())); .arg(creatorTheme()->color(Theme::MiniProjectTargetSelectorSummaryBackgroundColor).name()));

View File

@@ -776,6 +776,8 @@ void MsvcToolChain::updateEnvironmentModifications(Utils::EnvironmentItems modif
void MsvcToolChain::detectInstalledAbis() void MsvcToolChain::detectInstalledAbis()
{ {
if (!m_supportedAbis.isEmpty()) // Build Tools 2015
return;
static QMap<QString, Abis> abiCache; static QMap<QString, Abis> abiCache;
const QString vcVarsBase const QString vcVarsBase
= QDir::fromNativeSeparators(m_vcvarsBat).left(m_vcvarsBat.lastIndexOf('/')); = QDir::fromNativeSeparators(m_vcvarsBat).left(m_vcvarsBat.lastIndexOf('/'));
@@ -1251,6 +1253,13 @@ void MsvcToolChain::resetVarsBat()
m_varsBatArg.clear(); m_varsBatArg.clear();
} }
void MsvcToolChain::setSupportedAbi(const Abi &abi)
{
// Hack for Build Tools 2015 only.
QTC_CHECK(m_supportedAbis.isEmpty());
m_supportedAbis = { abi };
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// MsvcBasedToolChainConfigWidget: Creates a simple GUI without error label // MsvcBasedToolChainConfigWidget: Creates a simple GUI without error label
// to display name and varsBat. Derived classes should add the error label and // to display name and varsBat. Derived classes should add the error label and
@@ -1855,6 +1864,7 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
tc->setDisplayName(name + QLatin1String(e.postFix)); tc->setDisplayName(name + QLatin1String(e.postFix));
tc->setDetection(ToolChain::AutoDetection); tc->setDetection(ToolChain::AutoDetection);
tc->setLanguage(language); tc->setLanguage(language);
tc->setSupportedAbi(abi);
list->append(tc); list->append(tc);
} }
} }

View File

@@ -95,6 +95,8 @@ public:
void setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg); void setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg);
void resetVarsBat(); void resetVarsBat();
void setSupportedAbi(const Abi &abi);
bool operator==(const ToolChain &) const override; bool operator==(const ToolChain &) const override;
bool isJobCountSupported() const override { return false; } bool isJobCountSupported() const override { return false; }

View File

@@ -2772,6 +2772,8 @@ QPair<bool, QString> ProjectExplorerPluginPrivate::buildSettingsEnabledForSessio
bool ProjectExplorerPlugin::coreAboutToClose() bool ProjectExplorerPlugin::coreAboutToClose()
{ {
if (!m_instance)
return true;
if (BuildManager::isBuilding()) { if (BuildManager::isBuilding()) {
QMessageBox box; QMessageBox box;
QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole); QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);

View File

@@ -184,6 +184,7 @@ ToolChainInfo::ToolChainInfo(const ToolChain *toolChain,
wordWidth = toolChain->targetAbi().wordWidth(); wordWidth = toolChain->targetAbi().wordWidth();
targetTriple = toolChain->originalTargetTriple(); targetTriple = toolChain->originalTargetTriple();
extraCodeModelFlags = toolChain->extraCodeModelFlags(); extraCodeModelFlags = toolChain->extraCodeModelFlags();
installDir = toolChain->installDir();
// ...and save the potentially expensive operations for later so that // ...and save the potentially expensive operations for later so that
// they can be run from a worker thread. // they can be run from a worker thread.

View File

@@ -36,6 +36,7 @@
#include <utils/cpplanguage_details.h> #include <utils/cpplanguage_details.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h>
#include <QPointer> #include <QPointer>
@@ -152,6 +153,7 @@ public:
bool isMsvc2015ToolChain = false; bool isMsvc2015ToolChain = false;
unsigned wordWidth = 0; unsigned wordWidth = 0;
QString targetTriple; QString targetTriple;
Utils::FilePath installDir;
QStringList extraCodeModelFlags; QStringList extraCodeModelFlags;
QString sysRootPath; // For headerPathsRunner. QString sysRootPath; // For headerPathsRunner.

View File

@@ -99,15 +99,15 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
m_gridLayout->setContentsMargins(0, 20, 0, 0); m_gridLayout->setContentsMargins(0, 20, 0, 0);
m_gridLayout->setHorizontalSpacing(6); m_gridLayout->setHorizontalSpacing(6);
m_gridLayout->setVerticalSpacing(8); m_gridLayout->setVerticalSpacing(8);
m_gridLayout->addWidget(deployTitle, 0, 0, 1, 6); m_gridLayout->addWidget(deployTitle, 0, 0, 1, -1);
m_gridLayout->addWidget(deployLabel, 1, 0, 1, 1); m_gridLayout->addWidget(deployLabel, 1, 0, 1, 1);
m_gridLayout->addWidget(m_deployConfigurationCombo, 1, 1, 1, 1); m_gridLayout->addWidget(m_deployConfigurationCombo, 1, 1, 1, 1);
m_gridLayout->addWidget(m_addDeployToolButton, 1, 2, 1, 1); m_gridLayout->addWidget(m_addDeployToolButton, 1, 2, 1, 1);
m_gridLayout->addWidget(m_removeDeployToolButton, 1, 3, 1, 1); m_gridLayout->addWidget(m_removeDeployToolButton, 1, 3, 1, 1);
m_gridLayout->addWidget(m_renameDeployButton, 1, 4, 1, 1); m_gridLayout->addWidget(m_renameDeployButton, 1, 4, 1, 1);
m_gridLayout->addWidget(deployWidget, 2, 0, 1, 6); m_gridLayout->addWidget(deployWidget, 2, 0, 1, -1);
m_gridLayout->addWidget(runTitle, 3, 0, 1, 6); m_gridLayout->addWidget(runTitle, 3, 0, 1, -1);
m_gridLayout->addWidget(runLabel, 4, 0, 1, 1); m_gridLayout->addWidget(runLabel, 4, 0, 1, 1);
m_gridLayout->addWidget(m_runConfigurationCombo, 4, 1, 1, 1); m_gridLayout->addWidget(m_runConfigurationCombo, 4, 1, 1, 1);
m_gridLayout->addWidget(m_addRunToolButton, 4, 2, 1, 1); m_gridLayout->addWidget(m_addRunToolButton, 4, 2, 1, 1);
@@ -115,7 +115,7 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
m_gridLayout->addWidget(m_renameRunButton, 4, 4, 1, 1); m_gridLayout->addWidget(m_renameRunButton, 4, 4, 1, 1);
m_gridLayout->addWidget(m_cloneRunButton, 4, 5, 1, 1); m_gridLayout->addWidget(m_cloneRunButton, 4, 5, 1, 1);
m_gridLayout->addItem(spacer1, 4, 6, 1, 1); m_gridLayout->addItem(spacer1, 4, 6, 1, 1);
m_gridLayout->addWidget(runWidget, 5, 0, 1, 6); m_gridLayout->addWidget(runWidget, 5, 0, 1, -1);
m_gridLayout->addItem(spacer2, 6, 0, 1, 1); m_gridLayout->addItem(spacer2, 6, 0, 1, 1);
// deploy part // deploy part

View File

@@ -156,6 +156,8 @@ SessionManager::SessionManager(QObject *parent) : QObject(parent)
SessionManager::~SessionManager() SessionManager::~SessionManager()
{ {
EditorManager::setWindowTitleAdditionHandler({});
EditorManager::setSessionTitleHandler({});
emit m_instance->aboutToUnloadSession(d->m_sessionName); emit m_instance->aboutToUnloadSession(d->m_sessionName);
delete d->m_writer; delete d->m_writer;
delete d; delete d;

View File

@@ -359,6 +359,7 @@ void Target::setDeploymentData(const DeploymentData &deploymentData)
if (d->m_deploymentData != deploymentData) { if (d->m_deploymentData != deploymentData) {
d->m_deploymentData = deploymentData; d->m_deploymentData = deploymentData;
emit deploymentDataChanged(); emit deploymentDataChanged();
emit applicationTargetsChanged();
} }
} }

View File

@@ -117,18 +117,11 @@ private:
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
} }
void kitUpdated(ProjectExplorer::Kit *k)
{
if (k == KitManager::defaultKit())
updateNoteText();
}
void completeChanged() void completeChanged()
{ {
m_configureButton->setEnabled(m_targetSetupPage && m_targetSetupPage->isComplete()); m_configureButton->setEnabled(m_targetSetupPage && m_targetSetupPage->isComplete());
} }
void updateNoteText();
void addTargetSetupPage(); void addTargetSetupPage();
Project * const m_project; Project * const m_project;
@@ -161,41 +154,6 @@ TargetSetupPageWrapper::TargetSetupPageWrapper(Project *project)
this, &TargetSetupPageWrapper::done); this, &TargetSetupPageWrapper::done);
} }
void TargetSetupPageWrapper::updateNoteText()
{
if (!m_targetSetupPage)
return;
Kit *k = KitManager::defaultKit();
QString text;
bool showHint = false;
if (!k) {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
"%2 cannot parse the project, because no kit "
"has been set up.")
.arg(m_project->displayName(), Core::Constants::IDE_DISPLAY_NAME);
showHint = true;
} else if (k->isValid()) {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
"%2 uses the kit <b>%3</b> to parse the project.")
.arg(m_project->displayName())
.arg(Core::Constants::IDE_DISPLAY_NAME)
.arg(k->displayName());
showHint = false;
} else {
text = tr("The project <b>%1</b> is not yet configured.<br/>"
"%2 uses the <b>invalid</b> kit <b>%3</b> to parse the project.")
.arg(m_project->displayName())
.arg(Core::Constants::IDE_DISPLAY_NAME)
.arg(k->displayName());
showHint = true;
}
m_targetSetupPage->setNoteText(text);
m_targetSetupPage->showOptionsHint(showHint);
}
void TargetSetupPageWrapper::addTargetSetupPage() void TargetSetupPageWrapper::addTargetSetupPage()
{ {
m_targetSetupPage = new TargetSetupPage(this); m_targetSetupPage = new TargetSetupPage(this);
@@ -207,16 +165,11 @@ void TargetSetupPageWrapper::addTargetSetupPage()
m_targetSetupPage->initializePage(); m_targetSetupPage->initializePage();
m_targetSetupPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); m_targetSetupPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_setupPageContainer->addWidget(m_targetSetupPage); m_setupPageContainer->addWidget(m_targetSetupPage);
updateNoteText();
completeChanged(); completeChanged();
connect(m_targetSetupPage, &QWizardPage::completeChanged, connect(m_targetSetupPage, &QWizardPage::completeChanged,
this, &TargetSetupPageWrapper::completeChanged); this, &TargetSetupPageWrapper::completeChanged);
connect(KitManager::instance(), &KitManager::defaultkitChanged,
this, &TargetSetupPageWrapper::updateNoteText);
connect(KitManager::instance(), &KitManager::kitUpdated,
this, &TargetSetupPageWrapper::kitUpdated);
} }
// //
@@ -264,7 +217,7 @@ void TargetGroupItemPrivate::ensureWidget()
f.setPointSizeF(f.pointSizeF() * 1.4); f.setPointSizeF(f.pointSizeF() * 1.4);
f.setBold(true); f.setBold(true);
label->setFont(f); label->setFont(f);
label->setMargin(10); label->setContentsMargins(10, 10, 10, 10);
label->setAlignment(Qt::AlignTop); label->setAlignment(Qt::AlignTop);
auto layout = new QVBoxLayout(m_noKitLabel); auto layout = new QVBoxLayout(m_noKitLabel);
@@ -795,10 +748,8 @@ TargetItem *TargetGroupItem::currentTargetItem() const
TargetItem *TargetGroupItem::targetItem(Target *target) const TargetItem *TargetGroupItem::targetItem(Target *target) const
{ {
if (target) { if (target)
Id needle = target->id(); // Unconfigured project have no active target. return findFirstLevelChild([target](TargetItem *item) { return item->target() == target; });
return findFirstLevelChild([needle](TargetItem *item) { return item->m_kitId == needle; });
}
return nullptr; return nullptr;
} }

View File

@@ -86,18 +86,13 @@ public:
QWidget *scrollAreaWidget; QWidget *scrollAreaWidget;
QScrollArea *scrollArea; QScrollArea *scrollArea;
QLabel *headerLabel; QLabel *headerLabel;
QLabel *descriptionLabel;
QLabel *noValidKitLabel; QLabel *noValidKitLabel;
QLabel *optionHintLabel;
QCheckBox *allKitsCheckBox; QCheckBox *allKitsCheckBox;
FancyLineEdit *kitFilterLineEdit; FancyLineEdit *kitFilterLineEdit;
void setupUi(TargetSetupPage *q) void setupUi(TargetSetupPage *q)
{ {
auto setupTargetPage = new QWidget(q); auto setupTargetPage = new QWidget(q);
descriptionLabel = new QLabel(setupTargetPage);
descriptionLabel->setWordWrap(true);
descriptionLabel->setVisible(false);
headerLabel = new QLabel(setupTargetPage); headerLabel = new QLabel(setupTargetPage);
headerLabel->setWordWrap(true); headerLabel->setWordWrap(true);
@@ -105,16 +100,11 @@ public:
noValidKitLabel = new QLabel(setupTargetPage); noValidKitLabel = new QLabel(setupTargetPage);
noValidKitLabel->setWordWrap(true); noValidKitLabel->setWordWrap(true);
noValidKitLabel->setText(TargetSetupPage::tr("<span style=\" font-weight:600;\">No valid kits found.</span>")); noValidKitLabel->setText(TargetSetupPage::tr("<span style=\" font-weight:600;\">No suitable kits found.</span><br/>"
optionHintLabel = new QLabel(setupTargetPage);
optionHintLabel->setWordWrap(true);
optionHintLabel->setText(TargetSetupPage::tr(
"Please add a kit in the <a href=\"buildandrun\">options</a> " "Please add a kit in the <a href=\"buildandrun\">options</a> "
"or via the maintenance tool of the SDK.")); "or via the maintenance tool of the SDK."));
optionHintLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); noValidKitLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
optionHintLabel->setVisible(false); noValidKitLabel->setVisible(false);
allKitsCheckBox = new QCheckBox(setupTargetPage); allKitsCheckBox = new QCheckBox(setupTargetPage);
allKitsCheckBox->setTristate(true); allKitsCheckBox->setTristate(true);
@@ -146,10 +136,8 @@ public:
auto verticalLayout_2 = new QVBoxLayout(setupTargetPage); auto verticalLayout_2 = new QVBoxLayout(setupTargetPage);
verticalLayout_2->addWidget(headerLabel); verticalLayout_2->addWidget(headerLabel);
verticalLayout_2->addWidget(descriptionLabel);
verticalLayout_2->addWidget(kitFilterLineEdit); verticalLayout_2->addWidget(kitFilterLineEdit);
verticalLayout_2->addWidget(noValidKitLabel); verticalLayout_2->addWidget(noValidKitLabel);
verticalLayout_2->addWidget(optionHintLabel);
verticalLayout_2->addWidget(allKitsCheckBox); verticalLayout_2->addWidget(allKitsCheckBox);
verticalLayout_2->addWidget(centralWidget); verticalLayout_2->addWidget(centralWidget);
verticalLayout_2->addWidget(scrollAreaWidget); verticalLayout_2->addWidget(scrollAreaWidget);
@@ -158,7 +146,7 @@ public:
verticalLayout_3->setContentsMargins(0, 0, 0, -1); verticalLayout_3->setContentsMargins(0, 0, 0, -1);
verticalLayout_3->addWidget(setupTargetPage); verticalLayout_3->addWidget(setupTargetPage);
QObject::connect(optionHintLabel, &QLabel::linkActivated, QObject::connect(noValidKitLabel, &QLabel::linkActivated,
q, &TargetSetupPage::openOptions); q, &TargetSetupPage::openOptions);
QObject::connect(allKitsCheckBox, &QAbstractButton::clicked, QObject::connect(allKitsCheckBox, &QAbstractButton::clicked,
@@ -213,6 +201,8 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) :
connect(km, &KitManager::kitUpdated, this, &TargetSetupPage::handleKitUpdate); connect(km, &KitManager::kitUpdated, this, &TargetSetupPage::handleKitUpdate);
connect(m_importWidget, &ImportWidget::importFrom, connect(m_importWidget, &ImportWidget::importFrom,
this, [this](const FilePath &dir) { import(dir); }); this, [this](const FilePath &dir) { import(dir); });
connect(KitManager::instance(), &KitManager::kitsChanged,
this, &TargetSetupPage::updateVisibility);
setProperty(SHORT_TITLE_PROPERTY, tr("Kits")); setProperty(SHORT_TITLE_PROPERTY, tr("Kits"));
} }
@@ -224,6 +214,7 @@ void TargetSetupPage::initializePage()
setupWidgets(); setupWidgets();
setupImports(); setupImports();
selectAtLeastOneKit(); selectAtLeastOneKit();
updateVisibility();
} }
void TargetSetupPage::setRequiredKitPredicate(const Kit::Predicate &predicate) void TargetSetupPage::setRequiredKitPredicate(const Kit::Predicate &predicate)
@@ -348,18 +339,6 @@ bool TargetSetupPage::importLineEditHasFocus() const
return m_importWidget->ownsReturnKey(); return m_importWidget->ownsReturnKey();
} }
void TargetSetupPage::setNoteText(const QString &text)
{
m_ui->descriptionLabel->setText(text);
m_ui->descriptionLabel->setVisible(!text.isEmpty());
}
void TargetSetupPage::showOptionsHint(bool show)
{
m_forceOptionHint = show;
updateVisibility();
}
void TargetSetupPage::setupImports() void TargetSetupPage::setupImports()
{ {
if (!m_importer || m_projectPath.isEmpty()) if (!m_importer || m_projectPath.isEmpty())
@@ -446,10 +425,9 @@ void TargetSetupPage::updateVisibility()
m_ui->scrollAreaWidget->setVisible(m_baseLayout == m_ui->scrollArea->widget()->layout()); m_ui->scrollAreaWidget->setVisible(m_baseLayout == m_ui->scrollArea->widget()->layout());
m_ui->centralWidget->setVisible(m_baseLayout == m_ui->centralWidget->layout()); m_ui->centralWidget->setVisible(m_baseLayout == m_ui->centralWidget->layout());
bool hasKits = m_widgets.size() > 0; const bool hasUsableKits = KitManager::kit([this](const Kit *k) { return isUsable(k); });
m_ui->noValidKitLabel->setVisible(!hasKits); m_ui->noValidKitLabel->setVisible(!hasUsableKits);
m_ui->optionHintLabel->setVisible(m_forceOptionHint || !hasKits); m_ui->allKitsCheckBox->setVisible(hasUsableKits);
m_ui->allKitsCheckBox->setVisible(hasKits);
emit completeChanged(); emit completeChanged();
} }

View File

@@ -81,10 +81,6 @@ public:
bool setupProject(Project *project); bool setupProject(Project *project);
QList<Core::Id> selectedKits() const; QList<Core::Id> selectedKits() const;
/// Overrides the summary text of the targetsetuppage
void setNoteText(const QString &text);
void showOptionsHint(bool show);
void openOptions(); void openOptions();
void changeAllKitsSelections(); void changeAllKitsSelections();
@@ -139,7 +135,6 @@ private:
QSpacerItem *m_spacer; QSpacerItem *m_spacer;
QList<QWidget *> m_potentialWidgets; QList<QWidget *> m_potentialWidgets;
bool m_forceOptionHint = false;
bool m_widgetsWereSetUp = false; bool m_widgetsWereSetUp = false;
}; };

View File

@@ -38,6 +38,7 @@
#include <utils/cpplanguage_details.h> #include <utils/cpplanguage_details.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h>
#include <QObject> #include <QObject>
#include <QSet> #include <QSet>
@@ -114,6 +115,7 @@ public:
virtual ProjectExplorer::Abis supportedAbis() const; virtual ProjectExplorer::Abis supportedAbis() const;
virtual QString originalTargetTriple() const { return QString(); } virtual QString originalTargetTriple() const { return QString(); }
virtual QStringList extraCodeModelFlags() const { return QStringList(); } virtual QStringList extraCodeModelFlags() const { return QStringList(); }
virtual Utils::FilePath installDir() const { return Utils::FilePath(); }
virtual bool isValid() const = 0; virtual bool isValid() const = 0;

View File

@@ -27,6 +27,7 @@
#include "qbsbuildconfiguration.h" #include "qbsbuildconfiguration.h"
#include "qbsbuildstep.h" #include "qbsbuildstep.h"
#include "qbsinstallstep.h"
#include "qbslogsink.h" #include "qbslogsink.h"
#include "qbspmlogging.h" #include "qbspmlogging.h"
#include "qbsprojectimporter.h" #include "qbsprojectimporter.h"
@@ -52,6 +53,7 @@
#include <projectexplorer/buildinfo.h> #include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h> #include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/deploymentdata.h> #include <projectexplorer/deploymentdata.h>
#include <projectexplorer/headerpath.h> #include <projectexplorer/headerpath.h>
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
@@ -464,6 +466,16 @@ FilePath QbsProject::installRoot()
{ {
if (!activeTarget()) if (!activeTarget())
return FilePath(); return FilePath();
const auto dc = activeTarget()->activeDeployConfiguration();
if (dc) {
const QList<BuildStep *> steps = dc->stepList()->steps();
for (const BuildStep * const step : steps) {
if (!step->enabled())
continue;
if (const auto qbsInstallStep = qobject_cast<const QbsInstallStep *>(step))
return FilePath::fromString(qbsInstallStep->installRoot());
}
}
const auto * const bc const auto * const bc
= qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration()); = qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
if (!bc) if (!bc)

View File

@@ -76,7 +76,7 @@ QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Constants::Q
{ {
//: QMakeStep default display name //: QMakeStep default display name
setDefaultDisplayName(tr("qmake")); setDefaultDisplayName(tr("qmake"));
setLowPriorityIfConfigured(); setLowPriority();
} }
QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const

View File

@@ -231,6 +231,7 @@ extend_qtc_plugin(QmlDesigner
snapper.cpp snapper.h snapper.cpp snapper.h
snappinglinecreator.cpp snappinglinecreator.h snappinglinecreator.cpp snappinglinecreator.h
toolbox.cpp toolbox.h toolbox.cpp toolbox.h
option3daction.cpp option3daction.h
) )
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner

View File

@@ -53,10 +53,21 @@
#include <texteditor/syntaxhighlighter.h> #include <texteditor/syntaxhighlighter.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <metainfo.h>
#include <qmlmodelnodeproxy.h>
#include <variantproperty.h>
#include <bindingproperty.h>
#include <nodeabstractproperty.h>
#include <nodelistproperty.h>
#include <propertyeditorvalue.h>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QPushButton>
#include <QDebug> #include <QDebug>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QPlainTextEdit>
namespace QmlDesigner { namespace QmlDesigner {
@@ -69,7 +80,7 @@ BindingEditorWidget::BindingEditorWidget()
{ {
Core::ICore::addContextObject(m_context); Core::ICore::addContextObject(m_context);
Core::Context context(BINDINGEDITOR_CONTEXT_ID); const Core::Context context(BINDINGEDITOR_CONTEXT_ID);
/* /*
* We have to register our own active auto completion shortcut, because the original short cut will * We have to register our own active auto completion shortcut, because the original short cut will
@@ -77,8 +88,12 @@ BindingEditorWidget::BindingEditorWidget()
*/ */
m_completionAction = new QAction(tr("Trigger Completion"), this); m_completionAction = new QAction(tr("Trigger Completion"), this);
Core::Command *command = Core::ActionManager::registerAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS, context); Core::Command *command = Core::ActionManager::registerAction(
command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? tr("Meta+Space") : tr("Ctrl+Space"))); m_completionAction, TextEditor::Constants::COMPLETE_THIS, context);
command->setDefaultKeySequence(QKeySequence(
Core::useMacShortcuts
? tr("Meta+Space")
: tr("Ctrl+Space")));
connect(m_completionAction, &QAction::triggered, [this]() { connect(m_completionAction, &QAction::triggered, [this]() {
invokeAssist(TextEditor::Completion); invokeAssist(TextEditor::Completion);
@@ -95,18 +110,34 @@ BindingEditorWidget::~BindingEditorWidget()
void BindingEditorWidget::unregisterAutoCompletion() void BindingEditorWidget::unregisterAutoCompletion()
{ {
if (m_completionAction) if (m_completionAction) {
{
Core::ActionManager::unregisterAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS); Core::ActionManager::unregisterAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS);
delete m_completionAction; delete m_completionAction;
m_completionAction = nullptr; m_completionAction = nullptr;
} }
} }
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const bool BindingEditorWidget::event(QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
emit returnKeyClicked();
return true;
} else {
return QmlJSEditor::QmlJSEditorWidget::event(event);
}
}
return QmlJSEditor::QmlJSEditorWidget::event(event);
}
TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
{ {
Q_UNUSED(assistKind); Q_UNUSED(assistKind);
return new QmlJSEditor::QmlJSCompletionAssistInterface(document(), position(), QString(), assistReason, qmljsdocument->semanticInfo()); return new QmlJSEditor::QmlJSCompletionAssistInterface(
document(), position(), QString(),
assistReason, qmljsdocument->semanticInfo());
} }
class BindingDocument : public QmlJSEditor::QmlJSEditorDocument class BindingDocument : public QmlJSEditor::QmlJSEditorDocument
@@ -122,18 +153,16 @@ protected:
{ {
TextDocument::applyFontSettings(); TextDocument::applyFontSettings();
m_semanticHighlighter->updateFontSettings(fontSettings()); m_semanticHighlighter->updateFontSettings(fontSettings());
if (!isSemanticInfoOutdated()) { if (!isSemanticInfoOutdated())
m_semanticHighlighter->rerun(semanticInfo()); m_semanticHighlighter->rerun(semanticInfo());
} }
}
void triggerPendingUpdates() void triggerPendingUpdates()
{ {
TextDocument::triggerPendingUpdates(); // calls applyFontSettings if necessary TextDocument::triggerPendingUpdates(); // calls applyFontSettings if necessary
if (!isSemanticInfoOutdated()) { if (!isSemanticInfoOutdated())
m_semanticHighlighter->rerun(semanticInfo()); m_semanticHighlighter->rerun(semanticInfo());
} }
}
private: private:
QmlJSEditor::SemanticHighlighter *m_semanticHighlighter = nullptr; QmlJSEditor::SemanticHighlighter *m_semanticHighlighter = nullptr;
@@ -142,7 +171,8 @@ private:
class BindingEditorFactory : public TextEditor::TextEditorFactory class BindingEditorFactory : public TextEditor::TextEditorFactory
{ {
public: public:
BindingEditorFactory() { BindingEditorFactory()
{
setId(BINDINGEDITOR_CONTEXT_ID); setId(BINDINGEDITOR_CONTEXT_ID);
setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID)); setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID));
@@ -162,17 +192,14 @@ public:
static void decorateEditor(TextEditor::TextEditorWidget *editor) static void decorateEditor(TextEditor::TextEditorWidget *editor)
{ {
editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter); editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter);
editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter(editor->textDocument()->document())); editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter(
editor->textDocument()->document()));
editor->setAutoCompleter(new QmlJSEditor::AutoCompleter); editor->setAutoCompleter(new QmlJSEditor::AutoCompleter);
} }
}; };
BindingEditorDialog::BindingEditorDialog(QWidget *parent) BindingEditorDialog::BindingEditorDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
, m_editor(nullptr)
, m_editorWidget(nullptr)
, m_verticalLayout(nullptr)
, m_buttonBox(nullptr)
{ {
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Binding Editor")); setWindowTitle(tr("Binding Editor"));
@@ -185,12 +212,24 @@ BindingEditorDialog::BindingEditorDialog(QWidget *parent)
this, &BindingEditorDialog::accepted); this, &BindingEditorDialog::accepted);
QObject::connect(m_buttonBox, &QDialogButtonBox::rejected, QObject::connect(m_buttonBox, &QDialogButtonBox::rejected,
this, &BindingEditorDialog::rejected); this, &BindingEditorDialog::rejected);
QObject::connect(m_editorWidget, &BindingEditorWidget::returnKeyClicked,
this, &BindingEditorDialog::accepted);
QObject::connect(m_comboBoxItem, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &BindingEditorDialog::itemIDChanged);
QObject::connect(m_comboBoxProperty, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &BindingEditorDialog::propertyIDChanged);
QObject::connect(m_editorWidget, &QPlainTextEdit::textChanged,
this, &BindingEditorDialog::textChanged);
} }
BindingEditorDialog::~BindingEditorDialog() BindingEditorDialog::~BindingEditorDialog()
{ {
delete m_editor; //m_editorWidget is handled by basetexteditor destructor delete m_editor; //m_editorWidget is handled by basetexteditor destructor
delete m_buttonBox; delete m_buttonBox;
delete m_comboBoxItem;
delete m_comboBoxProperty;
delete m_comboBoxLayout;
delete m_verticalLayout; delete m_verticalLayout;
} }
@@ -216,6 +255,55 @@ void BindingEditorDialog::setEditorValue(const QString &text)
m_editorWidget->document()->setPlainText(text); m_editorWidget->document()->setPlainText(text);
} }
void BindingEditorDialog::setAllBindings(QList<BindingEditorDialog::BindingOption> bindings)
{
m_lock = true;
m_bindings = bindings;
setupComboBoxes();
adjustProperties();
m_lock = false;
}
void BindingEditorDialog::adjustProperties()
{
const QString expression = editorValue();
QString item;
QString property;
QStringList expressionElements = expression.split(".");
if (!expressionElements.isEmpty()) {
const int itemIndex = m_bindings.indexOf(expressionElements.at(0));
if (itemIndex != -1) {
item = expressionElements.at(0);
expressionElements.removeFirst();
if (!expressionElements.isEmpty()) {
const QString sum = expressionElements.join(".");
if (m_bindings.at(itemIndex).properties.contains(sum))
property = sum;
}
}
}
if (item.isEmpty()) {
item = undefinedString;
if (m_comboBoxItem->findText(item) == -1)
m_comboBoxItem->addItem(item);
}
m_comboBoxItem->setCurrentText(item);
if (property.isEmpty()) {
property = undefinedString;
if (m_comboBoxProperty->findText(property) == -1)
m_comboBoxProperty->addItem(property);
}
m_comboBoxProperty->setCurrentText(property);
}
void BindingEditorDialog::unregisterAutoCompletion() void BindingEditorDialog::unregisterAutoCompletion()
{ {
if (m_editorWidget) if (m_editorWidget)
@@ -237,7 +325,6 @@ void BindingEditorDialog::setupJSEditor()
m_editorWidget->qmljsdocument = qobject_cast<QmlJSEditor::QmlJSEditorWidget *>( m_editorWidget->qmljsdocument = qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
qmlDesignerEditor->widget())->qmlJsEditorDocument(); qmlDesignerEditor->widget())->qmlJsEditorDocument();
m_editorWidget->setParent(this);
m_editorWidget->setLineNumbersVisible(false); m_editorWidget->setLineNumbersVisible(false);
m_editorWidget->setMarksVisible(false); m_editorWidget->setMarksVisible(false);
@@ -245,24 +332,87 @@ void BindingEditorDialog::setupJSEditor()
m_editorWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_editorWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_editorWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_editorWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_editorWidget->setTabChangesFocus(true); m_editorWidget->setTabChangesFocus(true);
m_editorWidget->show();
} }
void BindingEditorDialog::setupUIComponents() void BindingEditorDialog::setupUIComponents()
{ {
m_verticalLayout = new QVBoxLayout(this); m_verticalLayout = new QVBoxLayout(this);
m_comboBoxLayout = new QHBoxLayout;
m_comboBoxItem = new QComboBox(this);
m_comboBoxProperty = new QComboBox(this);
m_editorWidget->setParent(this);
m_editorWidget->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
m_editorWidget->show();
m_buttonBox = new QDialogButtonBox(this); m_buttonBox = new QDialogButtonBox(this);
m_buttonBox->setOrientation(Qt::Horizontal); m_buttonBox->setOrientation(Qt::Horizontal);
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
m_editorWidget->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_comboBoxLayout->addWidget(m_comboBoxItem);
m_comboBoxLayout->addWidget(m_comboBoxProperty);
m_verticalLayout->addLayout(m_comboBoxLayout);
m_verticalLayout->addWidget(m_editorWidget); m_verticalLayout->addWidget(m_editorWidget);
m_verticalLayout->addWidget(m_buttonBox); m_verticalLayout->addWidget(m_buttonBox);
this->resize(600,200); this->resize(660, 240);
} }
void BindingEditorDialog::setupComboBoxes()
{
m_comboBoxItem->clear();
m_comboBoxProperty->clear();
for (auto bind : m_bindings)
m_comboBoxItem->addItem(bind.item);
}
void BindingEditorDialog::itemIDChanged(int itemID)
{
const QString previousProperty = m_comboBoxProperty->currentText();
m_comboBoxProperty->clear();
if (m_bindings.size() > itemID && itemID != -1) {
m_comboBoxProperty->addItems(m_bindings.at(itemID).properties);
if (!m_lock)
if (m_comboBoxProperty->findText(previousProperty) != -1)
m_comboBoxProperty->setCurrentText(previousProperty);
const int undefinedItem = m_comboBoxItem->findText(undefinedString);
if ((undefinedItem != -1) && (m_comboBoxItem->itemText(itemID) != undefinedString))
m_comboBoxItem->removeItem(undefinedItem);
}
}
void BindingEditorDialog::propertyIDChanged(int propertyID)
{
const int itemID = m_comboBoxItem->currentIndex();
if (!m_lock)
if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString))
setEditorValue(m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID));
const int undefinedProperty = m_comboBoxProperty->findText(undefinedString);
if ((undefinedProperty != -1) && (m_comboBoxProperty->itemText(propertyID) != undefinedString))
m_comboBoxProperty->removeItem(undefinedProperty);
}
void BindingEditorDialog::textChanged()
{
if (m_lock)
return;
m_lock = true;
adjustProperties();
m_lock = false;
}
BindingEditor::BindingEditor(QObject *) BindingEditor::BindingEditor(QObject *)
{ {
} }
@@ -320,5 +470,74 @@ void BindingEditor::setBindingValue(const QString &text)
m_dialog->setEditorValue(text); m_dialog->setEditorValue(text);
} }
void BindingEditor::setBackendValue(const QVariant &backendValue)
{
if (!backendValue.isNull() && backendValue.isValid()) {
m_backendValue = backendValue;
const QObject *backendValueObj = backendValue.value<QObject*>();
const PropertyEditorValue *propertyEditorValue = qobject_cast<const PropertyEditorValue *>(backendValueObj);
m_backendValueTypeName = propertyEditorValue->modelNode().metaInfo().propertyTypeName(
propertyEditorValue->name());
emit backendValueChanged();
}
}
void BindingEditor::setModelNodeBackend(const QVariant &modelNodeBackend)
{
if (!modelNodeBackend.isNull() && modelNodeBackend.isValid()) {
m_modelNodeBackend = modelNodeBackend;
emit modelNodeBackendChanged();
}
}
void BindingEditor::prepareBindings()
{
if (m_backendValue.isNull() || m_modelNodeBackend.isNull())
return;
if (!(m_backendValue.isValid() && m_modelNodeBackend.isValid()))
return;
const auto modelNodeBackendObject = m_modelNodeBackend.value<QObject*>();
const auto backendObjectCasted =
qobject_cast<const QmlDesigner::QmlModelNodeProxy *>(modelNodeBackendObject);
if (backendObjectCasted) {
const QmlDesigner::ModelNode a = backendObjectCasted->qmlObjectNode().modelNode();
const QList<QmlDesigner::ModelNode> allNodes = a.view()->allModelNodes();
QList<BindingEditorDialog::BindingOption> bindings;
for (auto objnode : allNodes) {
BindingEditorDialog::BindingOption binding;
for (auto propertyName : objnode.metaInfo().propertyNames())
if (m_backendValueTypeName == objnode.metaInfo().propertyTypeName(propertyName))
binding.properties.append(QString::fromUtf8(propertyName));
if (!binding.properties.isEmpty() && objnode.hasId()) {
binding.item = objnode.displayName();
bindings.append(binding);
}
}
if (!bindings.isEmpty() && !m_dialog.isNull())
m_dialog->setAllBindings(bindings);
}
}
QVariant BindingEditor::backendValue() const
{
return m_backendValue;
}
QVariant BindingEditor::modelNodeBackend() const
{
return m_modelNodeBackend;
}
} }

View File

@@ -42,6 +42,8 @@ QT_BEGIN_NAMESPACE
class QTextEdit; class QTextEdit;
class QDialogButtonBox; class QDialogButtonBox;
class QVBoxLayout; class QVBoxLayout;
class QHBoxLayout;
class QComboBox;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmlDesigner { namespace QmlDesigner {
@@ -49,6 +51,7 @@ namespace QmlDesigner {
class BindingEditorContext : public Core::IContext class BindingEditorContext : public Core::IContext
{ {
Q_OBJECT Q_OBJECT
public: public:
BindingEditorContext(QWidget *parent) : Core::IContext(parent) BindingEditorContext(QWidget *parent) : Core::IContext(parent)
{ {
@@ -59,14 +62,22 @@ public:
class BindingEditorWidget : public QmlJSEditor::QmlJSEditorWidget class BindingEditorWidget : public QmlJSEditor::QmlJSEditorWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
BindingEditorWidget(); BindingEditorWidget();
~BindingEditorWidget(); ~BindingEditorWidget() override;
void unregisterAutoCompletion(); void unregisterAutoCompletion();
TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const; bool event(QEvent *event) override;
TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind,
TextEditor::AssistReason assistReason) const override;
signals:
void returnKeyClicked();
public:
QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr; QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr;
BindingEditorContext *m_context = nullptr; BindingEditorContext *m_context = nullptr;
QAction *m_completionAction = nullptr; QAction *m_completionAction = nullptr;
@@ -76,6 +87,19 @@ class BindingEditorDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public:
struct BindingOption
{
BindingOption() {}
BindingOption(const QString &value) { item = value; }
bool operator==(const QString &value) const { return value == item; }
bool operator==(const BindingOption &value) const { return value.item == item; }
QString item;
QStringList properties;
};
public: public:
BindingEditorDialog(QWidget *parent = nullptr); BindingEditorDialog(QWidget *parent = nullptr);
~BindingEditorDialog() override; ~BindingEditorDialog() override;
@@ -85,17 +109,32 @@ public:
QString editorValue() const; QString editorValue() const;
void setEditorValue(const QString &text); void setEditorValue(const QString &text);
void setAllBindings(QList<BindingEditorDialog::BindingOption> bindings);
void adjustProperties();
void unregisterAutoCompletion(); void unregisterAutoCompletion();
private: private:
void setupJSEditor(); void setupJSEditor();
void setupUIComponents(); void setupUIComponents();
void setupComboBoxes();
public slots:
void itemIDChanged(int);
void propertyIDChanged(int);
void textChanged();
private: private:
TextEditor::BaseTextEditor *m_editor = nullptr; TextEditor::BaseTextEditor *m_editor = nullptr;
BindingEditorWidget *m_editorWidget = nullptr; BindingEditorWidget *m_editorWidget = nullptr;
QVBoxLayout *m_verticalLayout = nullptr; QVBoxLayout *m_verticalLayout = nullptr;
QDialogButtonBox *m_buttonBox = nullptr; QDialogButtonBox *m_buttonBox = nullptr;
QHBoxLayout *m_comboBoxLayout = nullptr;
QComboBox *m_comboBoxItem = nullptr;
QComboBox *m_comboBoxProperty = nullptr;
QList<BindingEditorDialog::BindingOption> m_bindings;
bool m_lock = false;
const QString undefinedString = {"[Undefined]"};
}; };
class BindingEditor : public QObject class BindingEditor : public QObject
@@ -103,6 +142,8 @@ class BindingEditor : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString text READ bindingValue WRITE setBindingValue) Q_PROPERTY(QString text READ bindingValue WRITE setBindingValue)
Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
public: public:
BindingEditor(QObject *parent = nullptr); BindingEditor(QObject *parent = nullptr);
@@ -116,13 +157,26 @@ public:
QString bindingValue() const; QString bindingValue() const;
void setBindingValue(const QString &text); void setBindingValue(const QString &text);
void setBackendValue(const QVariant &backendValue);
void setModelNodeBackend(const QVariant &modelNodeBackend);
Q_INVOKABLE void prepareBindings();
signals: signals:
void accepted(); void accepted();
void rejected(); void rejected();
void backendValueChanged();
void modelNodeBackendChanged();
private:
QVariant backendValue() const;
QVariant modelNodeBackend() const;
private: private:
QPointer<BindingEditorDialog> m_dialog; QPointer<BindingEditorDialog> m_dialog;
QVariant m_backendValue;
QVariant m_modelNodeBackend;
TypeName m_backendValueTypeName;
}; };
} }

View File

@@ -36,7 +36,8 @@ SOURCES += formeditoritem.cpp \
bindingindicatorgraphicsitem.cpp \ bindingindicatorgraphicsitem.cpp \
contentnoteditableindicator.cpp \ contentnoteditableindicator.cpp \
backgroundaction.cpp \ backgroundaction.cpp \
formeditortoolbutton.cpp formeditortoolbutton.cpp \
option3daction.cpp
HEADERS += formeditorscene.h \ HEADERS += formeditorscene.h \
formeditorwidget.h \ formeditorwidget.h \
@@ -75,6 +76,7 @@ HEADERS += formeditorscene.h \
bindingindicatorgraphicsitem.h \ bindingindicatorgraphicsitem.h \
contentnoteditableindicator.h \ contentnoteditableindicator.h \
backgroundaction.h \ backgroundaction.h \
formeditortoolbutton.h formeditortoolbutton.h \
option3daction.h
RESOURCES += formeditor.qrc RESOURCES += formeditor.qrc

View File

@@ -26,6 +26,7 @@
#include "formeditorview.h" #include "formeditorview.h"
#include "selectiontool.h" #include "selectiontool.h"
#include "movetool.h" #include "movetool.h"
#include "option3daction.h"
#include "resizetool.h" #include "resizetool.h"
#include "dragtool.h" #include "dragtool.h"
#include "formeditorwidget.h" #include "formeditorwidget.h"
@@ -45,6 +46,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QDebug> #include <QDebug>
#include <QPair> #include <QPair>
@@ -83,6 +85,7 @@ void FormEditorView::modelAttached(Model *model)
setupFormEditorItemTree(rootModelNode()); setupFormEditorItemTree(rootModelNode());
m_formEditorWidget->updateActions(); m_formEditorWidget->updateActions();
setupOption3DAction();
if (!rewriterView()->errors().isEmpty()) if (!rewriterView()->errors().isEmpty())
formEditorWidget()->showErrorMessageBox(rewriterView()->errors()); formEditorWidget()->showErrorMessageBox(rewriterView()->errors());
@@ -178,6 +181,22 @@ void FormEditorView::temporaryBlockView()
}); });
} }
void FormEditorView::setupOption3DAction()
{
auto import = Import::createLibraryImport("QtQuick3D", "1.0");
auto action = m_formEditorWidget->option3DAction();
if (model() && model()->hasImport(import, true, true)) {
bool enabled = true;
if (rootModelNode().hasAuxiliaryData("3d-view"))
enabled = rootModelNode().auxiliaryData("3d-view").toBool();
action->set3DEnabled(enabled);
action->setEnabled(true);
} else {
action->set3DEnabled(false);
action->setEnabled(false);
}
}
void FormEditorView::nodeCreated(const ModelNode &node) void FormEditorView::nodeCreated(const ModelNode &node)
{ {
//If the node has source for components/custom parsers we ignore it. //If the node has source for components/custom parsers we ignore it.
@@ -567,6 +586,16 @@ void FormEditorView::exportAsImage()
m_formEditorWidget->exportAsImage(m_scene->rootFormEditorItem()->boundingRect()); m_formEditorWidget->exportAsImage(m_scene->rootFormEditorItem()->boundingRect());
} }
void FormEditorView::toggle3DViewEnabled(bool enabled)
{
QTC_ASSERT(model(), return);
QTC_ASSERT(rootModelNode().isValid(), return);
if (enabled)
rootModelNode().removeAuxiliaryData("3d-view");
else
rootModelNode().setAuxiliaryData("3d-view", false);
}
QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode) QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode)
{ {
QmlObjectNode qmlObjectNode = firstQmlObjectNode; QmlObjectNode qmlObjectNode = firstQmlObjectNode;
@@ -629,6 +658,8 @@ void FormEditorView::delayedReset()
m_scene->clearFormEditorItems(); m_scene->clearFormEditorItems();
if (isAttached() && QmlItemNode::isValidQmlItemNode(rootModelNode())) if (isAttached() && QmlItemNode::isValidQmlItemNode(rootModelNode()))
setupFormEditorItemTree(rootModelNode()); setupFormEditorItemTree(rootModelNode());
setupOption3DAction();
} }
} }

View File

@@ -118,6 +118,8 @@ public:
void exportAsImage(); void exportAsImage();
void toggle3DViewEnabled(bool enabled);
protected: protected:
void reset(); void reset();
void delayedReset(); void delayedReset();
@@ -129,6 +131,7 @@ private: //functions
void hideNodeFromScene(const QmlItemNode &qmlItemNode); void hideNodeFromScene(const QmlItemNode &qmlItemNode);
void createFormEditorWidget(); void createFormEditorWidget();
void temporaryBlockView(); void temporaryBlockView();
void setupOption3DAction();
private: //variables private: //variables
QPointer<FormEditorWidget> m_formEditorWidget; QPointer<FormEditorWidget> m_formEditorWidget;

View File

@@ -34,24 +34,25 @@
#include <model.h> #include <model.h>
#include <theme.h> #include <theme.h>
#include <QWheelEvent> #include <backgroundaction.h>
#include <QVBoxLayout>
#include <QActionGroup>
#include <toolbox.h>
#include <zoomaction.h>
#include <formeditorgraphicsview.h> #include <formeditorgraphicsview.h>
#include <formeditorscene.h> #include <formeditorscene.h>
#include <formeditorview.h> #include <formeditorview.h>
#include <lineeditaction.h> #include <lineeditaction.h>
#include <backgroundaction.h> #include <option3daction.h>
#include <zoomaction.h>
#include <toolbox.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QActionGroup>
#include <QFileDialog> #include <QFileDialog>
#include <QPainter> #include <QPainter>
#include <QVBoxLayout>
#include <QWheelEvent>
namespace QmlDesigner { namespace QmlDesigner {
@@ -143,6 +144,15 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
upperActions.append(m_backgroundAction.data()); upperActions.append(m_backgroundAction.data());
m_toolBox->addRightSideAction(m_backgroundAction.data()); m_toolBox->addRightSideAction(m_backgroundAction.data());
m_option3DAction = new Option3DAction(m_toolActionGroup.data());
addAction(m_option3DAction.data());
upperActions.append(m_option3DAction.data());
m_toolBox->addRightSideAction(m_option3DAction.data());
connect(m_option3DAction.data(), &Option3DAction::enabledChanged,
m_formEditorView.data(), &FormEditorView::toggle3DViewEnabled);
connect(m_option3DAction.data(), &Option3DAction::activated,
this, &FormEditorWidget::resetNodeInstanceView);
m_zoomAction = new ZoomAction(m_toolActionGroup.data()); m_zoomAction = new ZoomAction(m_toolActionGroup.data());
connect(m_zoomAction.data(), &ZoomAction::zoomLevelChanged, connect(m_zoomAction.data(), &ZoomAction::zoomLevelChanged,
this, &FormEditorWidget::setZoomLevel); this, &FormEditorWidget::setZoomLevel);
@@ -285,6 +295,11 @@ ZoomAction *FormEditorWidget::zoomAction() const
return m_zoomAction.data(); return m_zoomAction.data();
} }
Option3DAction *FormEditorWidget::option3DAction() const
{
return m_option3DAction.data();
}
QAction *FormEditorWidget::showBoundingRectAction() const QAction *FormEditorWidget::showBoundingRectAction() const
{ {
return m_showBoundingRectAction.data(); return m_showBoundingRectAction.data();

View File

@@ -40,6 +40,7 @@ namespace QmlDesigner {
class ZoomAction; class ZoomAction;
class LineEditAction; class LineEditAction;
class BackgroundAction; class BackgroundAction;
class Option3DAction;
class FormEditorView; class FormEditorView;
class FormEditorScene; class FormEditorScene;
class FormEditorGraphicsView; class FormEditorGraphicsView;
@@ -54,6 +55,7 @@ public:
FormEditorWidget(FormEditorView *view); FormEditorWidget(FormEditorView *view);
ZoomAction *zoomAction() const; ZoomAction *zoomAction() const;
Option3DAction *option3DAction() const;
QAction *showBoundingRectAction() const; QAction *showBoundingRectAction() const;
QAction *snappingAction() const; QAction *snappingAction() const;
QAction *snappingAndAnchoringAction() const; QAction *snappingAndAnchoringAction() const;
@@ -112,6 +114,7 @@ private:
QPointer<LineEditAction> m_rootWidthAction; QPointer<LineEditAction> m_rootWidthAction;
QPointer<LineEditAction> m_rootHeightAction; QPointer<LineEditAction> m_rootHeightAction;
QPointer<BackgroundAction> m_backgroundAction; QPointer<BackgroundAction> m_backgroundAction;
QPointer<Option3DAction> m_option3DAction;
QPointer<QAction> m_resetAction; QPointer<QAction> m_resetAction;
QPointer<DocumentWarningWidget> m_documentErrorWidget; QPointer<DocumentWarningWidget> m_documentErrorWidget;
}; };

View File

@@ -0,0 +1,66 @@
/****************************************************************************
**
** 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 "option3daction.h"
#include <QComboBox>
#include <QPainter>
namespace QmlDesigner {
Option3DAction::Option3DAction(QObject *parent) :
QWidgetAction(parent)
{
}
void Option3DAction::set3DEnabled(bool enabled)
{
m_comboBox->setCurrentIndex(enabled ? 1 : 0);
}
QWidget *Option3DAction::createWidget(QWidget *parent)
{
m_comboBox = new QComboBox(parent);
m_comboBox->setFixedWidth(82);
m_comboBox->addItem(tr("2D"));
m_comboBox->addItem(tr("2D/3D"));
m_comboBox->setCurrentIndex(0);
connect(m_comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [this](){
emit enabledChanged(m_comboBox->currentIndex() != 0);
});
connect(m_comboBox, QOverload<int>::of(&QComboBox::activated),
this, [this](){
emit activated();
});
m_comboBox->setProperty("hideborder", true);
m_comboBox->setToolTip(tr("Enable/Disable 3D edit mode."));
return m_comboBox;
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,52 @@
/****************************************************************************
**
** 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 <QWidgetAction>
QT_FORWARD_DECLARE_CLASS(QComboBox)
namespace QmlDesigner {
class Option3DAction : public QWidgetAction
{
Q_OBJECT
public:
explicit Option3DAction(QObject *parent);
void set3DEnabled(bool enabled);
signals:
void enabledChanged(bool enabled);
void activated();
protected:
QWidget *createWidget(QWidget *parent) override;
private:
QComboBox *m_comboBox = nullptr;
};
} // namespace QmlDesigner

View File

@@ -44,6 +44,7 @@
#include <QtWidgets/qspinbox.h> #include <QtWidgets/qspinbox.h>
#include <QtWidgets/qscrollbar.h> #include <QtWidgets/qscrollbar.h>
#include <QtWidgets/qtabbar.h> #include <QtWidgets/qtabbar.h>
#include <QtWidgets/qscrollarea.h>
namespace QmlDesigner { namespace QmlDesigner {
@@ -62,6 +63,8 @@ static void addFormattedMessage(Utils::OutputFormatter *formatter, const QString
formatter->plainTextEdit()->verticalScrollBar()->maximum()); formatter->plainTextEdit()->verticalScrollBar()->maximum());
} }
static const int rowHeight = 26;
} }
ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &importFiles, ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &importFiles,
@@ -140,36 +143,135 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
} }
m_quick3DImportPath = candidatePath; m_quick3DImportPath = candidatePath;
// Create UI controls for options if (!m_quick3DFiles.isEmpty()) {
if (!importFiles.isEmpty()) { const QHash<QString, QVariantMap> allOptions = m_importer.allOptions();
QJsonObject supportedOptions = QJsonObject::fromVariantMap( const QHash<QString, QStringList> supportedExtensions = m_importer.supportedExtensions();
m_importer.supportedOptions(importFiles[0])); QVector<QJsonObject> groups;
m_importOptions = supportedOptions.value("options").toObject();
const QJsonObject groups = supportedOptions.value("groups").toObject();
const int labelWidth = 210; auto optIt = allOptions.constBegin();
const int valueWidth = 75; int optIndex = 0;
const int groupIndent = 10; while (optIt != allOptions.constEnd()) {
const int columnSpacing = 10; QJsonObject options = QJsonObject::fromVariantMap(optIt.value());
const int rowHeight = 26; m_importOptions << options.value("options").toObject();
groups << options.value("groups").toObject();
const auto &exts = optIt.key().split(':');
for (const auto &ext : exts)
m_extToImportOptionsMap.insert(ext, optIndex);
++optIt;
++optIndex;
}
// Create tab for each supported extension group that also has files included in the import
QMap<QString, int> tabMap; // QMap used for alphabetical order
for (const auto &file : qAsConst(m_quick3DFiles)) {
auto extIt = supportedExtensions.constBegin();
QString ext = QFileInfo(file).suffix();
while (extIt != supportedExtensions.constEnd()) {
if (!tabMap.contains(extIt.key()) && extIt.value().contains(ext)) {
tabMap.insert(extIt.key(), m_extToImportOptionsMap.value(ext));
break;
}
++extIt;
}
}
ui->tabWidget->clear();
auto tabIt = tabMap.constBegin();
while (tabIt != tabMap.constEnd()) {
createTab(tabIt.key(), tabIt.value(), groups[tabIt.value()]);
++tabIt;
}
// Pad all tabs to same height
for (int i = 0; i < ui->tabWidget->count(); ++i) {
auto optionsArea = qobject_cast<QScrollArea *>(ui->tabWidget->widget(i));
if (optionsArea && optionsArea->widget()) {
auto grid = qobject_cast<QGridLayout *>(optionsArea->widget()->layout());
if (grid) {
int rows = grid->rowCount();
for (int j = rows; j < m_optionsRows; ++j) {
grid->addWidget(new QWidget(optionsArea->widget()), j, 0);
grid->setRowMinimumHeight(j, rowHeight);
}
}
}
}
ui->tabWidget->setCurrentIndex(0);
}
connect(ui->buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked,
this, &ItemLibraryAssetImportDialog::onClose);
connect(ui->tabWidget, &QTabWidget::currentChanged,
this, &ItemLibraryAssetImportDialog::updateUi);
connect(&m_importer, &ItemLibraryAssetImporter::errorReported,
this, &ItemLibraryAssetImportDialog::addError);
connect(&m_importer, &ItemLibraryAssetImporter::warningReported,
this, &ItemLibraryAssetImportDialog::addWarning);
connect(&m_importer, &ItemLibraryAssetImporter::infoReported,
this, &ItemLibraryAssetImportDialog::addInfo);
connect(&m_importer, &ItemLibraryAssetImporter::importNearlyFinished,
this, &ItemLibraryAssetImportDialog::onImportNearlyFinished);
connect(&m_importer, &ItemLibraryAssetImporter::importFinished,
this, &ItemLibraryAssetImportDialog::onImportFinished);
connect(&m_importer, &ItemLibraryAssetImporter::progressChanged,
this, &ItemLibraryAssetImportDialog::setImportProgress);
addInfo(tr("Select import options and press \"Import\" to import the following files:"));
for (const auto &file : m_quick3DFiles)
addInfo(file);
QTimer::singleShot(0, [this]() {
ui->tabWidget->setMaximumHeight(m_optionsHeight + ui->tabWidget->tabBar()->height() + 10);
updateUi();
});
}
ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog()
{
delete ui;
}
void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int optionsIndex,
const QJsonObject &groups)
{
const int checkBoxColWidth = 18;
const int labelMinWidth = 130;
const int controlMinWidth = 65;
const int columnSpacing = 16;
int rowIndex[2] = {0, 0}; int rowIndex[2] = {0, 0};
QJsonObject &options = m_importOptions[optionsIndex];
// First index has ungrouped widgets, rest are groups // First index has ungrouped widgets, rest are groups
// First item in each real group is group label // First item in each real group is group label
QVector<QVector<QPair<QWidget *, QWidget *>>> widgets; QVector<QVector<QPair<QWidget *, QWidget *>>> widgets;
QHash<QString, int> groupIndexMap; QHash<QString, int> groupIndexMap;
QHash<QString, QPair<QWidget *, QWidget *>> optionToWidgetsMap; QHash<QString, QPair<QWidget *, QWidget *>> optionToWidgetsMap;
QHash<QString, QJsonArray> conditionMap; QHash<QString, QJsonArray> conditionMap;
QHash<QWidget *, QWidget *> conditionalWidgetMap;
QHash<QString, QString> optionToGroupMap; QHash<QString, QString> optionToGroupMap;
auto layout = new QGridLayout(ui->optionsAreaContents); auto optionsArea = new QScrollArea(ui->tabWidget);
layout->setColumnMinimumWidth(0, groupIndent); optionsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
layout->setColumnMinimumWidth(1, labelWidth); auto optionsAreaContents = new QWidget(optionsArea);
layout->setColumnMinimumWidth(2, valueWidth);
auto layout = new QGridLayout(optionsAreaContents);
layout->setColumnMinimumWidth(0, checkBoxColWidth);
layout->setColumnMinimumWidth(1, labelMinWidth);
layout->setColumnMinimumWidth(2, controlMinWidth);
layout->setColumnMinimumWidth(3, columnSpacing); layout->setColumnMinimumWidth(3, columnSpacing);
layout->setColumnMinimumWidth(4, groupIndent); layout->setColumnMinimumWidth(4, checkBoxColWidth);
layout->setColumnMinimumWidth(5, labelWidth); layout->setColumnMinimumWidth(5, labelMinWidth);
layout->setColumnMinimumWidth(6, valueWidth); layout->setColumnMinimumWidth(6, controlMinWidth);
layout->setColumnStretch(0, 0);
layout->setColumnStretch(1, 4);
layout->setColumnStretch(2, 2);
layout->setColumnStretch(3, 0);
layout->setColumnStretch(4, 0);
layout->setColumnStretch(5, 4);
layout->setColumnStretch(6, 2);
widgets.append(QVector<QPair<QWidget *, QWidget *>>()); widgets.append(QVector<QPair<QWidget *, QWidget *>>());
@@ -178,7 +280,7 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
const QJsonArray items = group.toObject().value("items").toArray(); const QJsonArray items = group.toObject().value("items").toArray();
for (const auto item : items) for (const auto item : items)
optionToGroupMap.insert(item.toString(), name); optionToGroupMap.insert(item.toString(), name);
auto groupLabel = new QLabel(name, ui->optionsAreaContents); auto groupLabel = new QLabel(name, optionsAreaContents);
QFont labelFont = groupLabel->font(); QFont labelFont = groupLabel->font();
labelFont.setBold(true); labelFont.setBold(true);
groupLabel->setFont(labelFont); groupLabel->setFont(labelFont);
@@ -186,9 +288,9 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
groupIndexMap.insert(name, widgets.size() - 1); groupIndexMap.insert(name, widgets.size() - 1);
} }
const auto optKeys = m_importOptions.keys(); const auto optKeys = options.keys();
for (const auto &optKey : optKeys) { for (const auto &optKey : optKeys) {
QJsonObject optObj = m_importOptions.value(optKey).toObject(); QJsonObject optObj = options.value(optKey).toObject();
const QString optName = optObj.value("name").toString(); const QString optName = optObj.value("name").toString();
const QString optDesc = optObj.value("description").toString(); const QString optDesc = optObj.value("description").toString();
const QString optType = optObj.value("type").toString(); const QString optType = optObj.value("type").toString();
@@ -198,17 +300,18 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
QWidget *optControl = nullptr; QWidget *optControl = nullptr;
if (optType == "Boolean") { if (optType == "Boolean") {
auto *optCheck = new QCheckBox(ui->optionsAreaContents); auto *optCheck = new QCheckBox(optionsAreaContents);
optCheck->setChecked(optValue.toBool()); optCheck->setChecked(optValue.toBool());
optControl = optCheck; optControl = optCheck;
QObject::connect(optCheck, &QCheckBox::toggled, [this, optCheck, optKey]() { QObject::connect(optCheck, &QCheckBox::toggled,
QJsonObject optObj = m_importOptions.value(optKey).toObject(); [this, optCheck, optKey, optionsIndex]() {
QJsonObject optObj = m_importOptions[optionsIndex].value(optKey).toObject();
QJsonValue value(optCheck->isChecked()); QJsonValue value(optCheck->isChecked());
optObj.insert("value", value); optObj.insert("value", value);
m_importOptions.insert(optKey, optObj); m_importOptions[optionsIndex].insert(optKey, optObj);
}); });
} else if (optType == "Real") { } else if (optType == "Real") {
auto *optSpin = new QDoubleSpinBox(ui->optionsAreaContents); auto *optSpin = new QDoubleSpinBox(optionsAreaContents);
double min = -999999999.; double min = -999999999.;
double max = 999999999.; double max = 999999999.;
double step = 1.; double step = 1.;
@@ -230,13 +333,14 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
optSpin->setDecimals(decimals); optSpin->setDecimals(decimals);
optSpin->setValue(optValue.toDouble()); optSpin->setValue(optValue.toDouble());
optSpin->setSingleStep(step); optSpin->setSingleStep(step);
optSpin->setMinimumWidth(controlMinWidth);
optControl = optSpin; optControl = optSpin;
QObject::connect(optSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), QObject::connect(optSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
[this, optSpin, optKey]() { [this, optSpin, optKey, optionsIndex]() {
QJsonObject optObj = m_importOptions.value(optKey).toObject(); QJsonObject optObj = m_importOptions[optionsIndex].value(optKey).toObject();
QJsonValue value(optSpin->value()); QJsonValue value(optSpin->value());
optObj.insert("value", value); optObj.insert("value", value);
m_importOptions.insert(optKey, optObj); m_importOptions[optionsIndex].insert(optKey, optObj);
}); });
} else { } else {
qWarning() << __FUNCTION__ << "Unsupported option type:" << optType; qWarning() << __FUNCTION__ << "Unsupported option type:" << optType;
@@ -246,7 +350,7 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
if (!conditions.isEmpty()) if (!conditions.isEmpty())
conditionMap.insert(optKey, conditions); conditionMap.insert(optKey, conditions);
auto *optLabel = new QLabel(ui->optionsAreaContents); auto *optLabel = new QLabel(optionsAreaContents);
optLabel->setText(optName); optLabel->setText(optName);
optLabel->setToolTip(optDesc); optLabel->setToolTip(optDesc);
optControl->setToolTip(optDesc); optControl->setToolTip(optDesc);
@@ -259,37 +363,9 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
optionToWidgetsMap.insert(optKey, {optLabel, optControl}); optionToWidgetsMap.insert(optKey, {optLabel, optControl});
} }
// Add option widgets to layout. Grouped options are added to the tops of the columns
for (int i = 1; i < widgets.size(); ++i) {
int col = rowIndex[1] < rowIndex[0] ? 1 : 0;
const auto &groupWidgets = widgets[i];
if (!groupWidgets.isEmpty()) {
// First widget in each group is the group label
layout->addWidget(groupWidgets[0].first, rowIndex[col], col * 4, 1, 3);
layout->setRowMinimumHeight(rowIndex[col],rowHeight);
++rowIndex[col];
for (int j = 1; j < groupWidgets.size(); ++j) {
layout->addWidget(groupWidgets[j].first, rowIndex[col], col * 4 + 1);
layout->addWidget(groupWidgets[j].second, rowIndex[col], col * 4 + 2);
layout->setRowMinimumHeight(rowIndex[col],rowHeight);
++rowIndex[col];
}
}
}
// Ungrouped options are spread evenly under the groups
int totalRowCount = (rowIndex[0] + rowIndex[1] + widgets[0].size() + 1) / 2;
for (const auto &rowWidgets : qAsConst(widgets[0])) {
int col = rowIndex[0] < totalRowCount ? 0 : 1;
layout->addWidget(rowWidgets.first, rowIndex[col], col * 4, 1, 2);
layout->addWidget(rowWidgets.second, rowIndex[col], col * 4 + 2);
layout->setRowMinimumHeight(rowIndex[col],rowHeight);
++rowIndex[col];
}
// Handle conditions // Handle conditions
QHash<QString, QJsonArray>::const_iterator it = conditionMap.begin(); auto it = conditionMap.constBegin();
while (it != conditionMap.end()) { while (it != conditionMap.constEnd()) {
const QString &option = it.key(); const QString &option = it.key();
const QJsonArray &conditions = it.value(); const QJsonArray &conditions = it.value();
const auto &conWidgets = optionToWidgetsMap.value(option); const auto &conWidgets = optionToWidgetsMap.value(option);
@@ -327,6 +403,10 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
w2->setEnabled(enable); w2->setEnabled(enable);
}; };
enableConditionally(optCb, conLabel, conControl, mode); enableConditionally(optCb, conLabel, conControl, mode);
if (conditionalWidgetMap.contains(optCb))
conditionalWidgetMap.insert(optCb, nullptr);
else
conditionalWidgetMap.insert(optCb, conControl);
QObject::connect( QObject::connect(
optCb, &QCheckBox::toggled, optCb, &QCheckBox::toggled,
[optCb, conLabel, conControl, mode, enableConditionally]() { [optCb, conLabel, conControl, mode, enableConditionally]() {
@@ -361,50 +441,125 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
++it; ++it;
} }
ui->optionsAreaContents->setLayout(layout); // Combine options where a non-boolean option depends on a boolean option that no other
ui->optionsAreaContents->resize( // option depends on
groupIndent * 2 + labelWidth * 2 + valueWidth * 2 + columnSpacing, auto condIt = conditionalWidgetMap.constBegin();
rowHeight * qMax(rowIndex[0], rowIndex[1])); while (condIt != conditionalWidgetMap.constEnd()) {
if (condIt.value()) {
// Find and fix widget pairs
for (int i = 0; i < widgets.size(); ++i) {
auto &groupWidgets = widgets[i];
auto widgetIt = groupWidgets.begin();
while (widgetIt != groupWidgets.end()) {
if (widgetIt->second == condIt.value()
&& !qobject_cast<QCheckBox *>(condIt.value())) {
if (widgetIt->first)
widgetIt->first->hide();
groupWidgets.erase(widgetIt);
} else {
++widgetIt;
}
}
// If group was left with less than two actual members, disband the group
// and move the remaining member to ungrouped options
// Note: <= 2 instead of < 2 because each group has group label member
if (i != 0 && groupWidgets.size() <= 2) {
widgets[0].prepend(groupWidgets[1]);
groupWidgets[0].first->hide(); // hide group label
groupWidgets.clear();
}
}
}
++condIt;
} }
ui->optionsArea->setStyleSheet("QScrollArea {background-color: transparent}"); auto incrementColIndex = [&](int col) {
ui->optionsAreaContents->setStyleSheet( layout->setRowMinimumHeight(rowIndex[col], rowHeight);
++rowIndex[col];
};
auto insertOptionToLayout = [&](int col, const QPair<QWidget *, QWidget *> &optionWidgets) {
layout->addWidget(optionWidgets.first, rowIndex[col], col * 4 + 1, 1, 2);
int adj = qobject_cast<QCheckBox *>(optionWidgets.second) ? 0 : 2;
layout->addWidget(optionWidgets.second, rowIndex[col], col * 4 + adj);
if (!adj) {
// Check box option may have additional conditional value field
QWidget *condWidget = conditionalWidgetMap.value(optionWidgets.second);
if (condWidget)
layout->addWidget(condWidget, rowIndex[col], col * 4 + 2);
}
incrementColIndex(col);
};
if (widgets.size() == 1 && widgets[0].isEmpty()) {
layout->addWidget(new QLabel(tr("No options available for this type."),
optionsAreaContents), 0, 0, 2, 7, Qt::AlignCenter);
incrementColIndex(0);
incrementColIndex(0);
}
// Add option widgets to layout. Grouped options are added to the tops of the columns
for (int i = 1; i < widgets.size(); ++i) {
int col = rowIndex[1] < rowIndex[0] ? 1 : 0;
const auto &groupWidgets = widgets[i];
if (!groupWidgets.isEmpty()) {
// First widget in each group is the group label
layout->addWidget(groupWidgets[0].first, rowIndex[col], col * 4, 1, 3);
incrementColIndex(col);
for (int j = 1; j < groupWidgets.size(); ++j)
insertOptionToLayout(col, groupWidgets[j]);
// Add a separator line after each group
auto *separator = new QFrame(optionsAreaContents);
separator->setMaximumHeight(1);
separator->setFrameShape(QFrame::HLine);
separator->setFrameShadow(QFrame::Sunken);
separator->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
layout->addWidget(separator, rowIndex[col], col * 4, 1, 3);
incrementColIndex(col);
}
}
// Ungrouped options are spread evenly under the groups
int totalRowCount = (rowIndex[0] + rowIndex[1] + widgets[0].size() + 1) / 2;
for (const auto &rowWidgets : qAsConst(widgets[0])) {
int col = rowIndex[0] < totalRowCount ? 0 : 1;
insertOptionToLayout(col, rowWidgets);
}
int optionRows = qMax(rowIndex[0], rowIndex[1]);
m_optionsRows = qMax(m_optionsRows, optionRows);
m_optionsHeight = qMax(rowHeight * optionRows + 16, m_optionsHeight);
layout->setContentsMargins(8, 8, 8, 8);
optionsAreaContents->setContentsMargins(0, 0, 0, 0);
optionsAreaContents->setLayout(layout);
optionsAreaContents->setMinimumWidth(
(checkBoxColWidth + labelMinWidth + controlMinWidth) * 2 + columnSpacing);
optionsAreaContents->setObjectName("optionsAreaContents"); // For stylesheet
optionsArea->setWidget(optionsAreaContents);
optionsArea->setStyleSheet("QScrollArea {background-color: transparent}");
optionsAreaContents->setStyleSheet(
"QWidget#optionsAreaContents {background-color: transparent}"); "QWidget#optionsAreaContents {background-color: transparent}");
connect(ui->buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, ui->tabWidget->addTab(optionsArea, tr("%1 options").arg(tabLabel));
this, &ItemLibraryAssetImportDialog::onClose);
connect(&m_importer, &ItemLibraryAssetImporter::errorReported,
this, &ItemLibraryAssetImportDialog::addError);
connect(&m_importer, &ItemLibraryAssetImporter::warningReported,
this, &ItemLibraryAssetImportDialog::addWarning);
connect(&m_importer, &ItemLibraryAssetImporter::infoReported,
this, &ItemLibraryAssetImportDialog::addInfo);
connect(&m_importer, &ItemLibraryAssetImporter::importNearlyFinished,
this, &ItemLibraryAssetImportDialog::onImportNearlyFinished);
connect(&m_importer, &ItemLibraryAssetImporter::importFinished,
this, &ItemLibraryAssetImportDialog::onImportFinished);
connect(&m_importer, &ItemLibraryAssetImporter::progressChanged,
this, &ItemLibraryAssetImportDialog::setImportProgress);
addInfo(tr("Select import options and press \"Import\" to import the following files:"));
for (const auto &file : m_quick3DFiles)
addInfo(file);
} }
ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog() void ItemLibraryAssetImportDialog::updateUi()
{ {
delete ui; auto optionsArea = qobject_cast<QScrollArea *>(ui->tabWidget->currentWidget());
if (optionsArea) {
auto optionsAreaContents = optionsArea->widget();
int scrollBarWidth = optionsArea->verticalScrollBar()->isVisible()
? optionsArea->verticalScrollBar()->width() : 0;
optionsAreaContents->resize(optionsArea->contentsRect().width()
- scrollBarWidth - 8, m_optionsHeight);
}
} }
void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event) void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
int scrollBarHeight = ui->optionsArea->horizontalScrollBar()->isVisible() updateUi();
? ui->optionsArea->horizontalScrollBar()->height() : 0;
ui->tabWidget->setMaximumHeight(ui->optionsAreaContents->height() + scrollBarHeight
+ ui->tabWidget->tabBar()->height() + 8);
ui->optionsArea->resize(ui->tabWidget->currentWidget()->size());
} }
void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing) void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing)
@@ -436,7 +591,7 @@ void ItemLibraryAssetImportDialog::onImport()
if (!m_quick3DFiles.isEmpty()) { if (!m_quick3DFiles.isEmpty()) {
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath, m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
m_importOptions.toVariantMap()); m_importOptions, m_extToImportOptionsMap);
} }
} }
@@ -481,4 +636,5 @@ void ItemLibraryAssetImportDialog::onClose()
deleteLater(); deleteLater();
} }
} }
} }

View File

@@ -66,12 +66,18 @@ private:
void onImportFinished(); void onImportFinished();
void onClose(); void onClose();
void createTab(const QString &tabLabel, int optionsIndex, const QJsonObject &groups);
void updateUi();
Ui::ItemLibraryAssetImportDialog *ui = nullptr; Ui::ItemLibraryAssetImportDialog *ui = nullptr;
Utils::OutputFormatter *m_outputFormatter = nullptr; Utils::OutputFormatter *m_outputFormatter = nullptr;
QStringList m_quick3DFiles; QStringList m_quick3DFiles;
QString m_quick3DImportPath; QString m_quick3DImportPath;
ItemLibraryAssetImporter m_importer; ItemLibraryAssetImporter m_importer;
QJsonObject m_importOptions; QVector<QJsonObject> m_importOptions;
QHash<QString, int> m_extToImportOptionsMap;
int m_optionsHeight = 0;
int m_optionsRows = 0;
}; };
} }

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>631</width> <width>631</width>
<height>711</height> <height>750</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -32,47 +32,6 @@
<attribute name="title"> <attribute name="title">
<string>Import Options</string> <string>Import Options</string>
</attribute> </attribute>
<widget class="QScrollArea" name="optionsArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>611</width>
<height>351</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>false</bool>
</property>
<widget class="QWidget" name="optionsAreaContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>0</width>
<height>0</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
</widget>
</widget>
</widget> </widget>
</widget> </widget>
</item> </item>

View File

@@ -32,6 +32,7 @@
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h> #include <QtCore/qdiriterator.h>
#include <QtCore/qsavefile.h> #include <QtCore/qsavefile.h>
#include <QtCore/qfile.h>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#include <QtCore/qtemporarydir.h> #include <QtCore/qtemporarydir.h>
#include <QtWidgets/qapplication.h> #include <QtWidgets/qapplication.h>
@@ -63,7 +64,8 @@ ItemLibraryAssetImporter::~ItemLibraryAssetImporter() {
void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles, void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
const QString &importPath, const QString &importPath,
const QVariantMap &options) const QVector<QJsonObject> &options,
const QHash<QString, int> &extToImportOptionsMap)
{ {
if (m_isImporting) if (m_isImporting)
cancelImport(); cancelImport();
@@ -79,7 +81,7 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
m_importPath = importPath; m_importPath = importPath;
parseFiles(inputFiles, options); parseFiles(inputFiles, options, extToImportOptionsMap);
if (!isCancelled()) { if (!isCancelled()) {
// Don't allow cancel anymore as existing asset overwrites are not trivially recoverable. // Don't allow cancel anymore as existing asset overwrites are not trivially recoverable.
@@ -162,15 +164,17 @@ void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &sr
bool ItemLibraryAssetImporter::isQuick3DAsset(const QString &fileName) const bool ItemLibraryAssetImporter::isQuick3DAsset(const QString &fileName) const
{ {
#ifdef IMPORT_QUICK3D_ASSETS
static QStringList quick3DExt; static QStringList quick3DExt;
if (quick3DExt.isEmpty()) { if (quick3DExt.isEmpty()) {
quick3DExt << QString(Constants::FbxExtension) const auto exts = m_quick3DAssetImporter->getSupportedExtensions();
<< QString(Constants::ColladaExtension) for (const auto &ext : exts)
<< QString(Constants::ObjExtension) quick3DExt << ext;
<< QString(Constants::BlenderExtension)
<< QString(Constants::GltfExtension);
} }
return quick3DExt.contains(QFileInfo(fileName).suffix()); return quick3DExt.contains(QFileInfo(fileName).suffix());
#else
return false;
#endif
} }
QVariantMap ItemLibraryAssetImporter::supportedOptions(const QString &modelFile) const QVariantMap ItemLibraryAssetImporter::supportedOptions(const QString &modelFile) const
@@ -182,6 +186,24 @@ QVariantMap ItemLibraryAssetImporter::supportedOptions(const QString &modelFile)
#endif #endif
} }
QHash<QString, QVariantMap> ItemLibraryAssetImporter::allOptions() const
{
#ifdef IMPORT_QUICK3D_ASSETS
return m_quick3DAssetImporter->getAllOptions();
#else
return {};
#endif
}
QHash<QString, QStringList> ItemLibraryAssetImporter::supportedExtensions() const
{
#ifdef IMPORT_QUICK3D_ASSETS
return m_quick3DAssetImporter->getSupportedExtensions();
#else
return {};
#endif
}
void ItemLibraryAssetImporter::notifyFinished() void ItemLibraryAssetImporter::notifyFinished()
{ {
m_isImporting = false; m_isImporting = false;
@@ -201,7 +223,9 @@ void ItemLibraryAssetImporter::reset()
#endif #endif
} }
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths, const QVariantMap &options) void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
const QVector<QJsonObject> &options,
const QHash<QString, int> &extToImportOptionsMap)
{ {
if (isCancelled()) if (isCancelled())
return; return;
@@ -216,8 +240,11 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths, const QV
for (const QString &file : filePaths) { for (const QString &file : filePaths) {
if (isCancelled()) if (isCancelled())
return; return;
if (isQuick3DAsset(file)) if (isQuick3DAsset(file)) {
parseQuick3DAsset(file, options); QVariantMap varOpts;
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
parseQuick3DAsset(file, options[index].toVariantMap());
}
notifyProgress(qRound(++count * quota), progressTitle); notifyProgress(qRound(++count * quota), progressTitle);
} }
notifyProgress(100, progressTitle); notifyProgress(100, progressTitle);
@@ -276,31 +303,70 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
return; return;
} }
// Generate qmldir file // Generate qmldir file if importer doesn't already make one
outDir.setNameFilters({QStringLiteral("*.qml")});
const QFileInfoList qmlFiles = outDir.entryInfoList(QDir::Files);
if (!qmlFiles.isEmpty()) {
QString qmldirFileName = outDir.absoluteFilePath(QStringLiteral("qmldir")); QString qmldirFileName = outDir.absoluteFilePath(QStringLiteral("qmldir"));
if (!QFileInfo(qmldirFileName).exists()) {
QSaveFile qmldirFile(qmldirFileName); QSaveFile qmldirFile(qmldirFileName);
QString version = QStringLiteral("1.0"); QString version = QStringLiteral("1.0");
// Note: Currently Quick3D importers only generate externally usable qml files on the top
// level of the import directory, so we don't search subdirectories. The qml files in
// subdirs assume they are used within the context of the toplevel qml files.
QDirIterator qmlIt(outDir.path(), {QStringLiteral("*.qml")}, QDir::Files);
if (qmlIt.hasNext()) {
outDir.mkdir(Constants::QUICK_3D_ASSET_ICON_DIR);
if (qmldirFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (qmldirFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
for (const auto &fi : qmlFiles) {
QString qmlInfo; QString qmlInfo;
qmlInfo.append("module ");
qmlInfo.append(m_importPath.split('/').last());
qmlInfo.append(".");
qmlInfo.append(assetName);
qmlInfo.append('\n');
while (qmlIt.hasNext()) {
qmlIt.next();
QFileInfo fi = QFileInfo(qmlIt.filePath());
qmlInfo.append(fi.baseName()); qmlInfo.append(fi.baseName());
qmlInfo.append(QLatin1Char(' ')); qmlInfo.append(' ');
qmlInfo.append(version); qmlInfo.append(version);
qmlInfo.append(QLatin1Char(' ')); qmlInfo.append(' ');
qmlInfo.append(fi.fileName()); qmlInfo.append(outDir.relativeFilePath(qmlIt.filePath()));
qmldirFile.write(qmlInfo.toUtf8()); qmlInfo.append('\n');
// Generate item library icon for qml file based on root component
QFile qmlFile(qmlIt.filePath());
if (qmlFile.open(QIODevice::ReadOnly)) {
QString iconFileName = outDir.path() + '/'
+ Constants::QUICK_3D_ASSET_ICON_DIR + '/' + fi.baseName()
+ Constants::QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX;
QString iconFileName2x = iconFileName + "@2x";
QByteArray content = qmlFile.readAll();
int braceIdx = content.indexOf('{');
if (braceIdx != -1) {
int nlIdx = content.lastIndexOf('\n', braceIdx);
QByteArray rootItem = content.mid(nlIdx, braceIdx - nlIdx).trimmed();
if (rootItem == "Node") {
QFile::copy(":/ItemLibrary/images/item-3D_model-icon.png",
iconFileName);
QFile::copy(":/ItemLibrary/images/item-3D_model-icon@2x.png",
iconFileName2x);
} else {
QFile::copy(":/ItemLibrary/images/item-default-icon.png",
iconFileName);
QFile::copy(":/ItemLibrary/images/item-default-icon@2x.png",
iconFileName2x);
} }
}
}
}
qmldirFile.write(qmlInfo.toUtf8());
qmldirFile.commit(); qmldirFile.commit();
} else { } else {
addError(tr("Failed to create qmldir file for asset: \"%1\"").arg(assetName)); addError(tr("Failed to create qmldir file for asset: \"%1\"").arg(assetName));
} }
} }
}
// Gather generated files // Gather all generated files
const int outDirPathSize = outDir.path().size(); const int outDirPathSize = outDir.path().size();
QDirIterator dirIt(outDir.path(), QDir::Files, QDirIterator::Subdirectories); QDirIterator dirIt(outDir.path(), QDir::Files, QDirIterator::Subdirectories);
QHash<QString, QString> assetFiles; QHash<QString, QString> assetFiles;
@@ -314,7 +380,7 @@ void ItemLibraryAssetImporter::parseQuick3DAsset(const QString &file, const QVar
// Copy the original asset into a subdirectory // Copy the original asset into a subdirectory
assetFiles.insert(sourceInfo.absoluteFilePath(), assetFiles.insert(sourceInfo.absoluteFilePath(),
targetDirPath + QStringLiteral("/source model/") + sourceInfo.fileName()); targetDirPath + QStringLiteral("/source scene/") + sourceInfo.fileName());
m_importFiles.insert(assetFiles); m_importFiles.insert(assetFiles);
#else #else

View File

@@ -27,6 +27,7 @@
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#include <QtCore/qjsonobject.h>
#include "import.h" #include "import.h"
@@ -46,7 +47,8 @@ public:
~ItemLibraryAssetImporter(); ~ItemLibraryAssetImporter();
void importQuick3D(const QStringList &inputFiles, const QString &importPath, void importQuick3D(const QStringList &inputFiles, const QString &importPath,
const QVariantMap &options); const QVector<QJsonObject> &options,
const QHash<QString, int> &extToImportOptionsMap);
bool isImporting() const; bool isImporting() const;
void cancelImport(); void cancelImport();
@@ -58,6 +60,8 @@ public:
bool isQuick3DAsset(const QString &fileName) const; bool isQuick3DAsset(const QString &fileName) const;
QVariantMap supportedOptions(const QString &modelFile) const; QVariantMap supportedOptions(const QString &modelFile) const;
QHash<QString, QVariantMap> allOptions() const;
QHash<QString, QStringList> supportedExtensions() const;
signals: signals:
void errorReported(const QString &, const QString &) const; void errorReported(const QString &, const QString &) const;
@@ -70,7 +74,8 @@ signals:
private: private:
void notifyFinished(); void notifyFinished();
void reset(); void reset();
void parseFiles(const QStringList &filePaths, const QVariantMap &options); void parseFiles(const QStringList &filePaths, const QVector<QJsonObject> &options,
const QHash<QString, int> &extToImportOptionsMap);
void parseQuick3DAsset(const QString &file, const QVariantMap &options); void parseQuick3DAsset(const QString &file, const QVariantMap &options);
void copyImportedFiles(); void copyImportedFiles();

View File

@@ -51,6 +51,10 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
#ifdef IMPORT_QUICK3D_ASSETS
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
#endif
#include <QApplication> #include <QApplication>
#include <QDrag> #include <QDrag>
#include <QFileDialog> #include <QFileDialog>
@@ -196,15 +200,20 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
return true; return true;
}; };
const QString category = tr("3D Models"); auto add3DHandler = [&](const QString &category, const QString &ext) {
const QString filter = QStringLiteral("*.%1").arg(ext);
auto add3DHandler = [&actionManager, &handle3DModel, &category](const char *ext) {
const QString filter = QStringLiteral("*.%1").arg(QString::fromLatin1(ext));
actionManager->registerAddResourceHandler( actionManager->registerAddResourceHandler(
AddResourceHandler(category, filter, handle3DModel, 10)); AddResourceHandler(category, filter, handle3DModel, 10));
}; };
// Skip if 3D model handlers have already been added QSSGAssetImportManager importManager;
QHash<QString, QStringList> supportedExtensions = importManager.getSupportedExtensions();
// All things importable by QSSGAssetImportManager are considered to be in the same category
// so we don't get multiple separate import dialogs when different file types are imported.
const QString category = tr("3D Assets");
// Skip if 3D asset handlers have already been added
const QList<AddResourceHandler> handlers = actionManager->addResourceHandler(); const QList<AddResourceHandler> handlers = actionManager->addResourceHandler();
bool categoryAlreadyAdded = false; bool categoryAlreadyAdded = false;
for (const auto &handler : handlers) { for (const auto &handler : handlers) {
@@ -215,11 +224,12 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
} }
if (!categoryAlreadyAdded) { if (!categoryAlreadyAdded) {
add3DHandler(Constants::FbxExtension); const auto groups = supportedExtensions.keys();
add3DHandler(Constants::ColladaExtension); for (const auto &group : groups) {
add3DHandler(Constants::ObjExtension); const auto extensions = supportedExtensions[group];
add3DHandler(Constants::BlenderExtension); for (const auto &ext : extensions)
add3DHandler(Constants::GltfExtension); add3DHandler(category, ext);
}
} }
#endif #endif

View File

@@ -607,10 +607,7 @@ bool NavigatorTreeModel::setData(const QModelIndex &index, const QVariant &value
QTC_ASSERT(m_view, return false); QTC_ASSERT(m_view, return false);
m_view->handleChangedExport(modelNode, value.toInt() != 0); m_view->handleChangedExport(modelNode, value.toInt() != 0);
} else if (index.column() == 2 && role == Qt::CheckStateRole) { } else if (index.column() == 2 && role == Qt::CheckStateRole) {
if (value.toInt() == 0) QmlVisualNode(modelNode).setVisibilityOverride(value.toInt() == 0);
modelNode.setAuxiliaryData("invisible", true);
else
modelNode.removeAuxiliaryData("invisible");
} }
return true; return true;

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