aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2020-03-23 09:35:54 +0100
committerEike Ziller <eike.ziller@qt.io>2020-03-23 09:35:54 +0100
commitee2840d5b8d37979ece2126055baf4678df8b312 (patch)
tree5847c57c571e905d2e1a54ce3244de1d47ce6ecc
parent80a766a2cbffdedc975f6ed3ebe225bfcfb433d9 (diff)
parente3581a3961dd4298122a8ede9488af11f2acfa08 (diff)
Merge remote-tracking branch 'origin/4.12'
-rw-r--r--.github/workflows/build_cmake.yml2
-rw-r--r--CMakeLists.txt4
-rwxr-xr-xscripts/build.py2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp27
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp5
-rw-r--r--share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml25
-rw-r--r--share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml2
-rw-r--r--src/app/app_version.h.cmakein2
-rw-r--r--src/app/app_version.h.in6
-rw-r--r--src/plugins/coreplugin/documentmanager.cpp250
-rw-r--r--src/plugins/coreplugin/documentmanager.h6
-rw-r--r--src/plugins/coreplugin/versiondialog.cpp3
-rw-r--r--src/plugins/debugger/debuggerrunconfigurationaspect.cpp1
-rw-r--r--src/plugins/nim/project/nimblebuildconfiguration.cpp9
-rw-r--r--src/plugins/nim/project/nimblebuildconfiguration.h2
-rw-r--r--src/plugins/nim/project/nimblebuildstepwidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp4
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dview.cpp88
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dview.h5
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp44
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dwidget.h6
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp3
-rw-r--r--src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp6
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelmerger.cpp10
-rw-r--r--src/plugins/qmldesigner/qmldesignerconstants.h9
-rw-r--r--src/plugins/vcsbase/vcsoutputformatter.cpp3
-rw-r--r--tests/system/suite_CSUP/tst_CSUP01/test.py18
28 files changed, 361 insertions, 187 deletions
diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml
index 5722143c04..f409216afb 100644
--- a/.github/workflows/build_cmake.yml
+++ b/.github/workflows/build_cmake.yml
@@ -333,7 +333,7 @@ jobs:
-D WITH_TESTS=ON
-D IDE_REVISION=TRUE
-D IDE_REVISION_STR=$ENV{GITHUB_SHA}
- -D IDE_REVISION_URL_STR=https://github.com/$ENV{GITHUB_REPOSITORY}/commits/$ENV{GITHUB_SHA}
+ -D IDE_REVISION_URL=https://github.com/$ENV{GITHUB_REPOSITORY}/commits/$ENV{GITHUB_SHA}
RESULT_VARIABLE result
COMMAND_ECHO STDOUT
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb79a450f0..9cf66c74aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,9 +8,9 @@ include(QtCreatorIDEBranding)
set(IDE_REVISION FALSE CACHE BOOL "Marks the presence of IDE revision string.")
set(IDE_REVISION_STR "" CACHE STRING "The IDE revision string.")
-set(IDE_REVISION_URL_STR "" CACHE STRING "The IDE revision Url string.")
+set(IDE_REVISION_URL "" CACHE STRING "The IDE revision Url string.")
-mark_as_advanced(IDE_REVISION IDE_REVISION_STR IDE_REVISION_URL_STR)
+mark_as_advanced(IDE_REVISION IDE_REVISION_STR IDE_REVISION_URL)
project(QtCreator VERSION ${IDE_VERSION})
diff --git a/scripts/build.py b/scripts/build.py
index ec50a21b8e..3c48136239 100755
--- a/scripts/build.py
+++ b/scripts/build.py
@@ -131,7 +131,7 @@ def build_qtcreator(args, paths):
if ide_revision:
cmake_args += ['-DIDE_REVISION=ON',
'-DIDE_REVISION_STR=' + ide_revision,
- '-DIDE_REVISION_URL_STR=https://code.qt.io/cgit/qt-creator/qt-creator.git/log/?id=' + ide_revision]
+ '-DIDE_REVISION_URL=https://code.qt.io/cgit/qt-creator/qt-creator.git/log/?id=' + ide_revision]
common.check_print_call(cmake_args + [paths.src], paths.build)
common.check_print_call(['cmake', '--build', '.'], paths.build)
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp
index 8b6d0b1fde..621508c499 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.cpp
@@ -95,9 +95,9 @@ void SelectionBoxGeometry::setTargetNode(QQuick3DNode *targetNode)
if (auto model = qobject_cast<QQuick3DModel *>(m_targetNode)) {
QObject::connect(model, &QQuick3DModel::sourceChanged,
- this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ this, &SelectionBoxGeometry::targetMeshUpdated, Qt::QueuedConnection);
QObject::connect(model, &QQuick3DModel::geometryChanged,
- this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
+ this, &SelectionBoxGeometry::targetMeshUpdated, Qt::QueuedConnection);
}
if (m_targetNode) {
QObject::connect(m_targetNode, &QQuick3DNode::parentChanged,
@@ -132,6 +132,14 @@ void SelectionBoxGeometry::setView3D(QQuick3DViewport *view)
QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
{
+ // If target node mesh has been updated, we need to defer updating the box geometry
+ // to the next frame to ensure target node geometry has been updated
+ if (m_meshUpdatePending) {
+ QTimer::singleShot(0, this, &SelectionBoxGeometry::update);
+ m_meshUpdatePending = false;
+ return node;
+ }
+
node = QQuick3DGeometry::updateSpatialNode(node);
QSSGRenderGeometry *geometry = static_cast<QSSGRenderGeometry *>(node);
@@ -163,10 +171,13 @@ QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphOb
rootRN->localTransform = m;
rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
rootRN->calculateGlobalVariables();
- m_asyncUpdatePending = false;
- } else if (!m_asyncUpdatePending) {
- m_asyncUpdatePending = true;
+ m_spatialNodeUpdatePending = false;
+ } else if (!m_spatialNodeUpdatePending) {
+ m_spatialNodeUpdatePending = true;
// A necessary spatial node doesn't yet exist. Defer selection box creation one frame.
+ // Note: We don't share pending flag with target mesh update, which is checked and
+ // cleared at the beginning of this method, as there would be potential for an endless
+ // loop in case we can't ever resolve one of the spatial nodes.
QTimer::singleShot(0, this, &SelectionBoxGeometry::update);
return node;
}
@@ -376,6 +387,12 @@ void SelectionBoxGeometry::trackNodeChanges(QQuick3DNode *node)
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
}
+void SelectionBoxGeometry::targetMeshUpdated()
+{
+ m_meshUpdatePending = true;
+ update();
+}
+
}
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h
index a267a47585..6cf9a153c2 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/selectionboxgeometry.h
@@ -74,6 +74,7 @@ private:
void appendVertexData(const QMatrix4x4 &m, QByteArray &vertexData, QByteArray &indexData,
const QVector3D &minBounds, const QVector3D &maxBounds);
void trackNodeChanges(QQuick3DNode *node);
+ void targetMeshUpdated();
QQuick3DNode *m_targetNode = nullptr;
QQuick3DViewport *m_view3D = nullptr;
@@ -81,7 +82,8 @@ private:
bool m_isEmpty = true;
QVector<QMetaObject::Connection> m_connections;
QSSGBounds3 m_bounds;
- bool m_asyncUpdatePending = false;
+ bool m_spatialNodeUpdatePending = false;
+ bool m_meshUpdatePending = false;
};
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index e3d97db879..253147de02 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -1158,6 +1158,7 @@ void Qt5InformationNodeInstanceServer::inputEvent(const InputEventCommand &comma
void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &command)
{
QVariantMap updatedState;
+ int renderCount = 1;
switch (command.type()) {
case View3DActionCommand::MoveTool:
@@ -1177,6 +1178,8 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
break;
case View3DActionCommand::CameraToggle:
updatedState.insert("usePerspective", command.isEnabled());
+ // It can take a couple frames to properly update icon gizmo positions, so render 3 frames
+ renderCount = 3;
break;
case View3DActionCommand::OrientationToggle:
updatedState.insert("globalOrientation", command.isEnabled());
@@ -1194,7 +1197,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
Q_ARG(QVariant, QVariant::fromValue(false)));
}
- render3DEditView();
+ render3DEditView(renderCount);
}
void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
index 135740c01d..1d1d65bed7 100644
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
+++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
@@ -41,7 +41,7 @@ Rectangle {
property string delegateWhenConditionString
readonly property bool isDefaultState: isDefault
- color: (isDefaultState || (isBaseState && !modelHasDefaultState)) ? Qt.lighter(baseColor, 1.5) : baseColor
+ color: baseColor
border.color: Theme.qmlDesignerBorderColor()
function autoComplete(text, pos, explicitComplete, filter) {
@@ -81,7 +81,12 @@ Rectangle {
width: 16
visible: !isBaseState
- onClicked: root.deleteState(internalNodeId)
+ onClicked: {
+ if (isDefaultState)
+ statesEditorModel.resetDefaultState()
+
+ root.deleteState(internalNodeId)
+ }
}
Image {
@@ -155,7 +160,17 @@ Rectangle {
anchors.leftMargin: 4
anchors.right: removeStateButton.left
anchors.rightMargin: 4
- style: DesignerTextFieldStyle {}
+ style: DesignerTextFieldStyle {
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: font.pixelSize + padding.top + padding.bottom
+ color: ((isBaseState && modelHasDefaultState) ? "transparent"
+ : Theme.color(Theme.FancyToolButtonSelectedColor))
+ border.color: ((isBaseState && !modelHasDefaultState) || isDefaultState) ? "#ffd700"
+ : (isBaseState && modelHasDefaultState) ? "transparent"
+ : Theme.qmlDesignerBackgroundColorDarker()
+ }
+ }
readOnly: isBaseState
onActiveFocusChanged: {
@@ -165,8 +180,6 @@ Rectangle {
Component.onCompleted: {
text = delegateStateName
- if (isBaseState)
- __panel.visible = false
}
property string oldValue
@@ -184,7 +197,7 @@ Rectangle {
Item {
id: stateImageArea
- anchors.topMargin: 4
+ anchors.topMargin: 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: stateNameField.bottom
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml
index a1fce752bd..c512b7098a 100644
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml
+++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesList.qml
@@ -41,7 +41,7 @@ FocusScope {
property int delegateWidth: stateImageSize + 44
property int padding: 2
property int delegateHeight: root.height - padding * 2 + 1
- property int innerSpacing: -1
+ property int innerSpacing: 0
property int currentStateInternalId : 0
property bool expanded: true
diff --git a/src/app/app_version.h.cmakein b/src/app/app_version.h.cmakein
index 6d69f0d5de..49abfc4ec8 100644
--- a/src/app/app_version.h.cmakein
+++ b/src/app/app_version.h.cmakein
@@ -45,7 +45,7 @@ const char IDE_CASED_ID[] = "${IDE_CASED_ID}";
const char IDE_VERSION_DISPLAY[] = "${IDE_VERSION_DISPLAY}";
const char IDE_VERSION_COMPAT[] = "${IDE_VERSION_COMPAT}";
const char IDE_REVISION_STR[] = "${IDE_REVISION_STR}";
-const char IDE_REVISION_URL_STR[] = "${IDE_REVISION_URL_STR}";
+const char IDE_REVISION_URL[] = "${IDE_REVISION_URL}";
// changes the path where the settings are saved to
const char IDE_SETTINGSVARIANT_STR[] = "${IDE_SETTINGSVARIANT}";
diff --git a/src/app/app_version.h.in b/src/app/app_version.h.in
index 4682d282ef..7a525bf211 100644
--- a/src/app/app_version.h.in
+++ b/src/app/app_version.h.in
@@ -56,11 +56,7 @@ const char IDE_REVISION_STR[] = STRINGIFY(IDE_REVISION);
const char IDE_REVISION_STR[] = \"\";
#endif
-#ifdef IDE_REVISION_URL
-const char IDE_REVISION_URL_STR[] = STRINGIFY(IDE_REVISION_URL);
-#else
-const char IDE_REVISION_URL_STR[] = \"\";
-#endif
+const char IDE_REVISION_URL[] = \"$${IDE_REVISION_URL}\";
// changes the path where the settings are saved to
#ifdef IDE_SETTINGSVARIANT
diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp
index 993c2244fb..f7a8340d9e 100644
--- a/src/plugins/coreplugin/documentmanager.cpp
+++ b/src/plugins/coreplugin/documentmanager.cpp
@@ -71,29 +71,47 @@ static Q_LOGGING_CATEGORY(log, "qtc.core.documentmanager", QtWarningMsg)
/*!
\class Core::DocumentManager
- \mainclass
+ \ingroup mainclasses
+ \inmodule QtCreator
\inheaderfile documentmanager.h
- \brief The DocumentManager class manages a set of IDocument objects.
-
- The DocumentManager service monitors a set of IDocument objects. Plugins
- should register files they work with at the service. The files the IDocument
- objects point to will be monitored at filesystem level. If a file changes,
- the status of the IDocument object
- will be adjusted accordingly. Furthermore, on application exit the user will
- be asked to save all modified files.
+ \brief The DocumentManager class manages a set of documents.
+
+ The DocumentManager service monitors a set of IDocument objects.
+
+ This section uses the following terminology:
+
+ \list
+ \li A \e file means a collection of data stored on a disk under a name
+ (that is, the usual meaning of the term \e file in computing).
+ \li A \e document holds content open in Qt Creator. If it corresponds to a
+ file, it might differ from it, because it was modified. But a document
+ might not correspond to a file at all. For example, diff viewer
+ documents or Git blame or log records are created and displayed by
+ Qt Creator upon request.
+ \li An \a editor provides a view into a document that is actually visible
+ to the user and potentially allows editing the document. Multiple
+ editors can open views into the same document.
+ \endlist
+
+ Plugins should register documents they work with at the document management
+ service. The files the IDocument objects point to will be monitored at
+ file system level. If a file changes on disk, the status of the IDocument
+ object will be adjusted accordingly. On application exit the user will be
+ asked to save all modified documents.
Different IDocument objects in the set can point to the same file in the
- filesystem. The monitoring for an IDocument can be blocked by
- \c blockFileChange(), and enabled again by \c unblockFileChange().
+ file system. The monitoring for an IDocument can be blocked by
+ using the \l Core::FileChangeBlocker class.
The functions \c expectFileChange() and \c unexpectFileChange() mark a file change
as expected. On expected file changes all IDocument objects are notified to reload
themselves.
- The DocumentManager service also provides two convenience functions for saving
- files: \c saveModifiedFiles() and \c saveModifiedFilesSilently(). Both take a list
- of FileInterfaces as an argument, and return the list of files which were
- _not_ saved.
+ The DocumentManager service also provides convenience functions
+ for saving documents, such as \l saveModifiedDocuments() and
+ \l saveModifiedDocumentsSilently(). They present users with a
+ dialog that lists all modified documents and asks them which
+ documents should be saved.
The service also manages the list of recent files to be shown to the user.
@@ -315,9 +333,9 @@ static void addFileInfo(IDocument *document)
}
/*!
- Adds a list of IDocument's to the collection. If \a addWatcher is true (the default),
- the files are added to a file system watcher that notifies the file manager
- about file changes.
+ Adds a list of \a documents to the collection. If \a addWatcher is \c true
+ (the default), the documents' files are added to a file system watcher that
+ notifies the document manager about file changes.
*/
void DocumentManager::addDocuments(const QList<IDocument *> &documents, bool addWatcher)
{
@@ -411,15 +429,17 @@ static void dump()
*/
/*!
- Tells the file manager that a file has been renamed on disk from within \QC.
+ Tells the document manager that a file has been renamed from \a from to
+ \a to on disk from within \QC.
Needs to be called right after the actual renaming on disk (that is, before
- the file system
- watcher can report the event during the next event loop run). \a from needs to be an absolute file path.
+ the file system watcher can report the event during the next event loop run).
+
+ \a from needs to be an absolute file path.
This will notify all IDocument objects pointing to that file of the rename
- by calling \c IDocument::rename(), and update the cached time and permission
- information to avoid annoying the user with "file has been removed"
- popups.
+ by calling \l IDocument::setFilePath(), and update the cached time and
+ permission information to avoid annoying the user with \e {the file has
+ been removed} popups.
*/
void DocumentManager::renamedFile(const QString &from, const QString &to)
{
@@ -454,10 +474,9 @@ void DocumentManager::filePathChanged(const FilePath &oldName, const FilePath &n
}
/*!
- Adds an IDocument object to the collection. If \a addWatcher is \c true
- (the default),
- the file is added to a file system watcher that notifies the file manager
- about file changes.
+ Adds \a document to the collection. If \a addWatcher is \c true
+ (the default), the document's file is added to a file system watcher
+ that notifies the document manager about file changes.
*/
void DocumentManager::addDocument(IDocument *document, bool addWatcher)
{
@@ -473,10 +492,10 @@ void DocumentManager::documentDestroyed(QObject *obj)
}
/*!
- Removes an IDocument object from the collection.
+ Removes \a document from the collection.
- Returns \c true if the file specified by \a document had the \a addWatcher
- argument to \a addDocument() set.
+ Returns \c true if the document had the \c addWatcher argument to
+ addDocument() set.
*/
bool DocumentManager::removeDocument(IDocument *document)
{
@@ -494,7 +513,7 @@ bool DocumentManager::removeDocument(IDocument *document)
}
/* Slot reacting on IDocument::changed. We need to check if the signal was sent
- because the file was saved under different name. */
+ because the document was saved under different name. */
void DocumentManager::checkForNewFileName()
{
auto document = qobject_cast<IDocument *>(sender());
@@ -528,8 +547,8 @@ QString DocumentManager::cleanAbsoluteFilePath(const QString &filePath, ResolveM
/*!
Returns a representation of \a filePath that can be used as a key for maps.
- (A cleaned absolute file path in portable form, that is all lowercase
- if the file system is case insensitive (in the host OS settings).)
+ It is a cleaned absolute file path in portable form, that is all lowercase
+ if the file system is case insensitive in the host OS settings.
Resolves symlinks if \a resolveMode is ResolveLinks.
*/
QString DocumentManager::filePathKey(const QString &filePath, ResolveMode resolveMode)
@@ -563,9 +582,9 @@ QList<IDocument *> DocumentManager::modifiedDocuments()
}
/*!
- Any subsequent change to \a fileName is treated as an expected file change.
+ Treats any subsequent change to \a fileName as an expected file change.
- \see DocumentManager::unexpectFileChange(const QString &fileName)
+ \sa unexpectFileChange()
*/
void DocumentManager::expectFileChange(const QString &fileName)
{
@@ -587,9 +606,9 @@ static void updateExpectedState(const QString &filePathKey)
}
/*!
- Any changes to \a fileName are unexpected again.
+ Considers all changes to \a fileName unexpected again.
- \see DocumentManager::expectFileChange(const QString &fileName)
+ \sa expectFileChange()
*/
void DocumentManager::unexpectFileChange(const QString &fileName)
{
@@ -808,7 +827,7 @@ QString DocumentManager::getSaveFileNameWithExtension(const QString &title, cons
}
/*!
- Asks the user for a new file name (\gui {Save File As}) for \a document.
+ Asks the user for a new file name (\uicontrol {Save File As}) for \a document.
*/
QString DocumentManager::getSaveAsFileName(const IDocument *document)
{
@@ -842,15 +861,15 @@ QString DocumentManager::getSaveAsFileName(const IDocument *document)
}
/*!
- Silently saves all documents and will return true if all modified documents were saved
- successfully.
+ Silently saves all documents and returns \c true if all modified documents
+ are saved successfully.
- This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
- a file is not writeable).
+ This method tries to avoid showing dialogs to the user, but can do so anyway
+ (e.g. if a file is not writeable).
- \a Canceled will be set if the user canceled any of the dialogs that he interacted with.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
+ If users canceled any of the dialogs they interacted with, \a canceled
+ is set. If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
*/
bool DocumentManager::saveAllModifiedDocumentsSilently(bool *canceled,
QList<IDocument *> *failedToClose)
@@ -859,14 +878,15 @@ bool DocumentManager::saveAllModifiedDocumentsSilently(bool *canceled,
}
/*!
- Silently saves \a documents and will return true if all of them were saved successfully.
+ Silently saves \a documents and returns \c true if all of them were saved
+ successfully.
- This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
- a file is not writeable).
+ This method tries to avoid showing dialogs to the user, but can do so anyway
+ (e.g. if a file is not writeable).
- \a Canceled will be set if the user canceled any of the dialogs that he interacted with.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
+ If users canceled any of the dialogs they interacted with, \a canceled
+ is set. If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
*/
bool DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &documents,
bool *canceled,
@@ -882,14 +902,15 @@ bool DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &do
}
/*!
- Silently saves a \a document and will return true if it was saved successfully.
+ Silently saves \a document and returns \c true if it was saved successfully.
- This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
- a file is not writeable).
+ This method tries to avoid showing dialogs to the user, but can do so anyway
+ (e.g. if a file is not writeable).
+
+ If users canceled any of the dialogs they interacted with, \a canceled
+ is set. If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
- \a Canceled will be set if the user canceled any of the dialogs that he interacted with.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
*/
bool DocumentManager::saveModifiedDocumentSilently(IDocument *document, bool *canceled,
QList<IDocument *> *failedToClose)
@@ -898,17 +919,21 @@ bool DocumentManager::saveModifiedDocumentSilently(IDocument *document, bool *ca
}
/*!
- Presents a dialog with all modified documents to the user and will ask him which of these
- should be saved.
+ Presents a dialog with all modified documents to users and asks them which
+ of these should be saved.
+
+ This method may show additional dialogs to the user, e.g. if a file is
+ not writeable.
- This method may show additional dialogs to the user, e.g. if a file is not writeable).
+ The dialog text can be set using \a message. If users canceled any
+ of the dialogs they interacted with, \a canceled is set and the
+ method returns \c false.
- The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
- of the dialogs that he interacted with (the method will also return false in this case).
- The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
- this checkbox will be written into \a alwaysSave if set.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
+ The \a alwaysSaveMessage shows an additional checkbox in the dialog.
+ The state of this checkbox is written into \a alwaysSave if set.
+
+ If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
*/
bool DocumentManager::saveAllModifiedDocuments(const QString &message, bool *canceled,
const QString &alwaysSaveMessage, bool *alwaysSave,
@@ -919,16 +944,21 @@ bool DocumentManager::saveAllModifiedDocuments(const QString &message, bool *can
}
/*!
- Presents a dialog with \a documents to the user and will ask him which of these should be saved.
+ Presents a dialog with \a documents to users and asks them which
+ of these should be saved.
+
+ This method may show additional dialogs to the user, e.g. if a file is
+ not writeable.
- This method may show additional dialogs to the user, e.g. if a file is not writeable).
+ The dialog text can be set using \a message. If users canceled any
+ of the dialogs they interacted with, \a canceled is set and the
+ method returns \c false.
- The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
- of the dialogs that he interacted with (the method will also return false in this case).
- The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
- this checkbox will be written into \a alwaysSave if set.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
+ The \a alwaysSaveMessage shows an additional checkbox in the dialog.
+ The state of this checkbox is written into \a alwaysSave if set.
+
+ If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
*/
bool DocumentManager::saveModifiedDocuments(const QList<IDocument *> &documents,
const QString &message, bool *canceled,
@@ -940,17 +970,21 @@ bool DocumentManager::saveModifiedDocuments(const QList<IDocument *> &documents,
}
/*!
- Presents a dialog with the one \a document to the user and will ask him whether he wants it
- saved.
+ Presents a dialog with the \a document to users and asks them whether
+ it should be saved.
+
+ This method may show additional dialogs to the user, e.g. if a file is
+ not writeable.
- This method may show additional dialogs to the user, e.g. if the file is not writeable).
+ The dialog text can be set using \a message. If users canceled any
+ of the dialogs they interacted with, \a canceled is set and the
+ method returns \c false.
- The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
- of the dialogs that he interacted with (the method will also return false in this case).
- The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
- this checkbox will be written into \a alwaysSave if set.
- \a FailedToClose will contain a list of documents that could not be saved if passed into the
- method.
+ The \a alwaysSaveMessage shows an additional checkbox in the dialog.
+ The state of this checkbox is written into \a alwaysSave if set.
+
+ If passed to the method, \a failedToClose returns a list of
+ documents that could not be saved.
*/
bool DocumentManager::saveModifiedDocument(IDocument *document, const QString &message, bool *canceled,
const QString &alwaysSaveMessage, bool *alwaysSave,
@@ -969,7 +1003,7 @@ void DocumentManager::showFilePropertiesDialog(const FilePath &filePath)
/*!
Asks the user for a set of file names to be opened. The \a filters
and \a selectedFilter arguments are interpreted like in
- \c QFileDialog::getOpenFileNames(). \a pathIn specifies a path to open the
+ QFileDialog::getOpenFileNames(). \a pathIn specifies a path to open the
dialog in if that is not overridden by the user's policy.
*/
@@ -1259,7 +1293,7 @@ void DocumentManager::checkForReload()
/*!
Adds the \a fileName to the list of recent files. Associates the file to
be reopened with the editor that has the specified \a editorId, if possible.
- \a editorId defaults to the empty id, which lets \QC figure out
+ \a editorId defaults to the empty ID, which lets \QC figure out
the best editor itself.
*/
void DocumentManager::addToRecentFiles(const QString &fileName, Id editorId)
@@ -1346,12 +1380,11 @@ void readSettings()
/*!
- Returns the initial directory for a new file dialog. If there is
- a current file, uses that, otherwise if there is a default location for
- new files, uses that, otherwise uses the last visited directory.
+ Returns the initial directory for a new file dialog. If there is a current
+ document associated with a file, uses that. Or if there is a default location
+ for new files, uses that. Otherwise, uses the last visited directory.
- \sa setFileDialogLastVisitedDirectory
- \sa setDefaultLocationForNewFiles
+ \sa setFileDialogLastVisitedDirectory(), setDefaultLocationForNewFiles()
*/
QString DocumentManager::fileDialogInitialDirectory()
@@ -1366,9 +1399,9 @@ QString DocumentManager::fileDialogInitialDirectory()
/*!
- Sets the default location for new files
+ Returns the default location for new files.
- \sa fileDialogInitialDirectory
+ \sa fileDialogInitialDirectory()
*/
QString DocumentManager::defaultLocationForNewFiles()
{
@@ -1376,7 +1409,7 @@ QString DocumentManager::defaultLocationForNewFiles()
}
/*!
- Returns the default location for new files
+ Sets the default \a location for new files.
*/
void DocumentManager::setDefaultLocationForNewFiles(const QString &location)
{
@@ -1387,7 +1420,7 @@ void DocumentManager::setDefaultLocationForNewFiles(const QString &location)
Returns the directory for projects. Defaults to HOME.
- \sa setProjectsDirectory, setUseProjectsDirectory
+ \sa setProjectsDirectory(), setUseProjectsDirectory()
*/
FilePath DocumentManager::projectsDirectory()
@@ -1397,9 +1430,9 @@ FilePath DocumentManager::projectsDirectory()
/*!
- Sets the directory for projects.
+ Sets the \a directory for projects.
- \sa projectsDirectory, useProjectsDirectory
+ \sa projectsDirectory(), useProjectsDirectory()
*/
void DocumentManager::setProjectsDirectory(const FilePath &directory)
@@ -1415,7 +1448,7 @@ void DocumentManager::setProjectsDirectory(const FilePath &directory)
Returns whether the directory for projects is to be used or whether the user
chose to use the current directory.
- \sa setProjectsDirectory, setUseProjectsDirectory
+ \sa setProjectsDirectory(), setUseProjectsDirectory()
*/
bool DocumentManager::useProjectsDirectory()
@@ -1425,9 +1458,10 @@ bool DocumentManager::useProjectsDirectory()
/*!
- Sets whether the directory for projects is to be used.
+ Sets whether the directory for projects is to be used to
+ \a useProjectsDirectory.
- \sa projectsDirectory, useProjectsDirectory
+ \sa projectsDirectory(), useProjectsDirectory()
*/
void DocumentManager::setUseProjectsDirectory(bool useProjectsDirectory)
@@ -1439,7 +1473,7 @@ void DocumentManager::setUseProjectsDirectory(bool useProjectsDirectory)
Returns the last visited directory of a file dialog.
- \sa setFileDialogLastVisitedDirectory, fileDialogInitialDirectory
+ \sa setFileDialogLastVisitedDirectory(), fileDialogInitialDirectory()
*/
@@ -1450,10 +1484,10 @@ QString DocumentManager::fileDialogLastVisitedDirectory()
/*!
- Sets the last visited directory of a file dialog that will be remembered
+ Sets the last visited \a directory of a file dialog that will be remembered
for the next one.
- \sa fileDialogLastVisitedDirectory, fileDialogInitialDirectory
+ \sa fileDialogLastVisitedDirectory(), fileDialogInitialDirectory()
*/
@@ -1469,6 +1503,16 @@ void DocumentManager::notifyFilesChangedInternally(const QStringList &files)
// -------------- FileChangeBlocker
+/*!
+ \class Core::FileChangeBlocker
+ \inmodule QtCreator
+ \brief The FileChangeBlocker class blocks all change notifications to all
+ IDocument objects that match the given filename.
+
+ Additionally, the class unblocks in the destructor. To also reload the
+ IDocument object in the destructor, set modifiedReload() to \c true.
+*/
+
FileChangeBlocker::FileChangeBlocker(const QString &fileName)
: m_fileName(fileName)
{
diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h
index 92323efdc3..66ca54cd2e 100644
--- a/src/plugins/coreplugin/documentmanager.h
+++ b/src/plugins/coreplugin/documentmanager.h
@@ -167,12 +167,6 @@ private:
friend class Core::Internal::DocumentManagerPrivate;
};
-/*! The FileChangeBlocker blocks all change notifications to all IDocument * that
- match the given filename. And unblocks in the destructor.
-
- To also reload the IDocument in the destructor class set modifiedReload to true
-
- */
class CORE_EXPORT FileChangeBlocker
{
public:
diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp
index 3ef40cb819..3730a8b8c2 100644
--- a/src/plugins/coreplugin/versiondialog.cpp
+++ b/src/plugins/coreplugin/versiondialog.cpp
@@ -57,8 +57,7 @@ VersionDialog::VersionDialog(QWidget *parent)
QString ideRev;
#ifdef IDE_REVISION
- //: This gets conditionally inserted as argument %8 into the description string.
- const QString revUrl = QString::fromLatin1(Constants::IDE_REVISION_URL_STR);
+ const QString revUrl = QString::fromLatin1(Constants::IDE_REVISION_URL);
const QString rev = QString::fromLatin1(Constants::IDE_REVISION_STR).left(10);
ideRev = tr("<br/>From revision %1<br/>")
.arg(revUrl.isEmpty() ? rev
diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
index 9317594fd9..076fd9723d 100644
--- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
+++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
@@ -105,6 +105,7 @@ void DebuggerLanguageAspect::addToLayout(LayoutBuilder &builder)
m_value = m_checkBox->isChecked() ? EnabledLanguage : DisabledLanguage;
emit changed();
});
+ builder.addItem(QString());
builder.addItem(m_checkBox.data());
if (!m_infoLabelText.isEmpty()) {
diff --git a/src/plugins/nim/project/nimblebuildconfiguration.cpp b/src/plugins/nim/project/nimblebuildconfiguration.cpp
index 10ef13bbce..6665191a2a 100644
--- a/src/plugins/nim/project/nimblebuildconfiguration.cpp
+++ b/src/plugins/nim/project/nimblebuildconfiguration.cpp
@@ -56,7 +56,7 @@ NimbleBuildConfiguration::NimbleBuildConfiguration(Target *target, Core::Id id)
appendInitialBuildStep(Constants::C_NIMBLEBUILDSTEP_ID);
setInitializer([this](const BuildInfo &info) {
- m_buildType = info.buildType;
+ setBuildType(info.buildType);
setBuildDirectory(project()->projectDirectory());
});
}
@@ -79,6 +79,13 @@ QVariantMap NimbleBuildConfiguration::toMap() const
return map;
}
+void NimbleBuildConfiguration::setBuildType(BuildConfiguration::BuildType buildType)
+{
+ if (buildType == m_buildType)
+ return;
+ m_buildType = buildType;
+ emit buildTypeChanged();
+}
NimbleBuildConfigurationFactory::NimbleBuildConfigurationFactory()
{
diff --git a/src/plugins/nim/project/nimblebuildconfiguration.h b/src/plugins/nim/project/nimblebuildconfiguration.h
index 2d3f0a93f3..3d52af523e 100644
--- a/src/plugins/nim/project/nimblebuildconfiguration.h
+++ b/src/plugins/nim/project/nimblebuildconfiguration.h
@@ -45,6 +45,8 @@ class NimbleBuildConfiguration : public ProjectExplorer::BuildConfiguration
QVariantMap toMap() const override;
private:
+ void setBuildType(BuildType buildType);
+
BuildType m_buildType;
};
diff --git a/src/plugins/nim/project/nimblebuildstepwidget.cpp b/src/plugins/nim/project/nimblebuildstepwidget.cpp
index ad841a4730..aa1981e7e2 100644
--- a/src/plugins/nim/project/nimblebuildstepwidget.cpp
+++ b/src/plugins/nim/project/nimblebuildstepwidget.cpp
@@ -49,7 +49,7 @@ NimbleBuildStepWidget::NimbleBuildStepWidget(NimbleBuildStep *bs)
QObject::connect(ui->argumentsLineEdit, &QLineEdit::textEdited, bs, &NimbleBuildStep::setArguments);
ui->resetButton->setIcon(Utils::Icons::RESET.icon());
- QObject::connect(ui->resetButton, &QToolButton::triggered, bs, &NimbleBuildStep::resetArguments);
+ QObject::connect(ui->resetButton, &QToolButton::clicked, bs, &NimbleBuildStep::resetArguments);
}
NimbleBuildStepWidget::~NimbleBuildStepWidget()
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
index 331897f08d..91aa006299 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
@@ -119,8 +119,10 @@ void Edit3DCanvas::dropEvent(QDropEvent *e)
auto modelNode = QmlVisualNode::createQml3DNode(m_parent->view(), m_itemLibraryEntry, m_activeScene).modelNode();
- if (modelNode.isValid())
+ if (modelNode.isValid()) {
+ e->accept();
m_parent->view()->setSelectedModelNode(modelNode);
+ }
}
}
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
index 5e203026d3..d06e1b299c 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
@@ -36,9 +36,10 @@
#include <qmldesignerconstants.h>
#include <viewmanager.h>
#include <qmldesignericons.h>
+#include <designmodecontext.h>
#include <utils/utilsicons.h>
#include <coreplugin/icore.h>
-#include <designmodecontext.h>
+#include <coreplugin/messagebox.h>
#include <QDebug>
@@ -62,6 +63,20 @@ void Edit3DView::createEdit3DWidget()
Core::ICore::addContextObject(editor3DContext);
}
+void Edit3DView::checkImports()
+{
+ bool has3dImport = false;
+ const QList<Import> imports = model()->imports();
+ for (const auto &import : imports) {
+ if (import.url() == "QtQuick3D") {
+ has3dImport = true;
+ break;
+ }
+ }
+
+ edit3DWidget()->showCanvas(has3dImport);
+}
+
WidgetInfo Edit3DView::widgetInfo()
{
if (!m_edit3DWidget)
@@ -130,13 +145,30 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
m_editLightAction->action()->setChecked(false);
}
+void Edit3DView::modelAttached(Model *model)
+{
+ AbstractView::modelAttached(model);
+
+ checkImports();
+}
+
void Edit3DView::modelAboutToBeDetached(Model *model)
{
Q_UNUSED(model)
- // Clear the image when model is detached (i.e. changing documents)
- QImage emptyImage;
- edit3DWidget()->canvas()->updateRenderImage(emptyImage);
+ // Hide the canvas when model is detached (i.e. changing documents)
+ edit3DWidget()->showCanvas(false);
+
+ AbstractView::modelAboutToBeDetached(model);
+}
+
+void Edit3DView::importsChanged(const QList<Import> &addedImports,
+ const QList<Import> &removedImports)
+{
+ Q_UNUSED(addedImports)
+ Q_UNUSED(removedImports)
+
+ checkImports();
}
void Edit3DView::sendInputEvent(QInputEvent *e) const
@@ -163,54 +195,54 @@ void Edit3DView::createEdit3DActions()
{
m_selectionModeAction
= new Edit3DAction(
- "Edit3DSelectionModeToggle", View3DActionCommand::SelectionModeToggle,
+ QmlDesigner::Constants::EDIT3D_SELECTION_MODE, View3DActionCommand::SelectionModeToggle,
QCoreApplication::translate("SelectionModeToggleAction", "Toggle Group/Single Selection Mode"),
QKeySequence(Qt::Key_Q), true, false, Icons::EDIT3D_SELECTION_MODE_OFF.icon(),
Icons::EDIT3D_SELECTION_MODE_ON.icon());
m_moveToolAction
= new Edit3DAction(
- "Edit3DMoveTool", View3DActionCommand::MoveTool,
+ QmlDesigner::Constants::EDIT3D_MOVE_TOOL, View3DActionCommand::MoveTool,
QCoreApplication::translate("MoveToolAction", "Activate Move Tool"),
QKeySequence(Qt::Key_W), true, true, Icons::EDIT3D_MOVE_TOOL_OFF.icon(),
Icons::EDIT3D_MOVE_TOOL_ON.icon());
m_rotateToolAction
= new Edit3DAction(
- "Edit3DRotateTool", View3DActionCommand::RotateTool,
+ QmlDesigner::Constants::EDIT3D_ROTATE_TOOL, View3DActionCommand::RotateTool,
QCoreApplication::translate("RotateToolAction", "Activate Rotate Tool"),
QKeySequence(Qt::Key_E), true, false, Icons::EDIT3D_ROTATE_TOOL_OFF.icon(),
Icons::EDIT3D_ROTATE_TOOL_ON.icon());
m_scaleToolAction
= new Edit3DAction(
- "Edit3DScaleTool", View3DActionCommand::ScaleTool,
+ QmlDesigner::Constants::EDIT3D_SCALE_TOOL, View3DActionCommand::ScaleTool,
QCoreApplication::translate("ScaleToolAction", "Activate Scale Tool"),
QKeySequence(Qt::Key_R), true, false, Icons::EDIT3D_SCALE_TOOL_OFF.icon(),
Icons::EDIT3D_SCALE_TOOL_ON.icon());
m_fitAction = new Edit3DAction(
- "Edit3DFitToView", View3DActionCommand::FitToView,
+ QmlDesigner::Constants::EDIT3D_FIT_SELECTED, View3DActionCommand::FitToView,
QCoreApplication::translate("FitToViewAction", "Fit Selected Object to View"),
QKeySequence(Qt::Key_F), false, false, Icons::EDIT3D_FIT_SELECTED_OFF.icon(), {});
m_cameraModeAction
= new Edit3DAction(
- "Edit3DCameraToggle", View3DActionCommand::CameraToggle,
+ QmlDesigner::Constants::EDIT3D_EDIT_CAMERA, View3DActionCommand::CameraToggle,
QCoreApplication::translate("CameraToggleAction", "Toggle Perspective/Orthographic Edit Camera"),
QKeySequence(Qt::Key_T), true, false, Icons::EDIT3D_EDIT_CAMERA_OFF.icon(),
Icons::EDIT3D_EDIT_CAMERA_ON.icon());
m_orientationModeAction
= new Edit3DAction(
- "Edit3DOrientationToggle", View3DActionCommand::OrientationToggle,
+ QmlDesigner::Constants::EDIT3D_ORIENTATION, View3DActionCommand::OrientationToggle,
QCoreApplication::translate("OrientationToggleAction", "Toggle Global/Local Orientation"),
QKeySequence(Qt::Key_Y), true, false, Icons::EDIT3D_ORIENTATION_OFF.icon(),
Icons::EDIT3D_ORIENTATION_ON.icon());
m_editLightAction
= new Edit3DAction(
- "Edit3DEditLightToggle", View3DActionCommand::EditLightToggle,
+ QmlDesigner::Constants::EDIT3D_EDIT_LIGHT, View3DActionCommand::EditLightToggle,
QCoreApplication::translate("EditLightToggleAction", "Toggle Edit Light On/Off"),
QKeySequence(Qt::Key_U), true, false, Icons::EDIT3D_LIGHT_OFF.icon(),
Icons::EDIT3D_LIGHT_ON.icon());
@@ -221,7 +253,7 @@ void Edit3DView::createEdit3DActions()
};
m_resetAction
= new Edit3DAction(
- "Edit3DResetView", View3DActionCommand::Empty,
+ QmlDesigner::Constants::EDIT3D_RESET_VIEW, View3DActionCommand::Empty,
QCoreApplication::translate("ResetView", "Reset View"),
QKeySequence(Qt::Key_P), false, false, Utils::Icons::RESET_TOOLBAR.icon(), {},
resetTrigger);
@@ -240,20 +272,6 @@ void Edit3DView::createEdit3DActions()
m_leftActions << m_editLightAction;
m_rightActions << m_resetAction;
-
- // TODO: Registering actions to action manager causes conflicting shortcuts in form editor.
- // Registration commented out until UX defines non-conflicting shortcuts.
- // Also, actions creation needs to be somehow triggered before action manager registers
- // actions to creator.
-// DesignerActionManager &actionManager = QmlDesignerPlugin::instance()->designerActionManager();
-// for (auto action : qAsConst(m_leftActions)) {
-// if (action)
-// actionManager.addDesignerAction(action);
-// }
-// for (auto action : qAsConst(m_rightActions)) {
-// if (action)
-// actionManager.addDesignerAction(action);
-// }
}
QVector<Edit3DAction *> Edit3DView::leftActions() const
@@ -266,5 +284,21 @@ QVector<Edit3DAction *> Edit3DView::rightActions() const
return m_rightActions;
}
+void Edit3DView::addQuick3DImport()
+{
+ const QList<Import> imports = model()->possibleImports();
+ for (const auto &import : imports) {
+ if (import.url() == "QtQuick3D") {
+ model()->changeImports({import}, {});
+
+ // Subcomponent manager update needed to make item library entries appear
+ QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
+ return;
+ }
+ }
+ Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
+ tr("Could not add QtQuick3D import to project."));
+}
+
}
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
index 8129879106..5835c89b32 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
@@ -55,7 +55,9 @@ public:
void renderImage3DChanged(const QImage &img) override;
void updateActiveScene3D(const QVariantMap &sceneState) override;
+ void modelAttached(Model *model) override;
void modelAboutToBeDetached(Model *model) override;
+ void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
void sendInputEvent(QInputEvent *e) const;
void edit3DViewResized(const QSize &size) const;
@@ -66,10 +68,13 @@ public:
QVector<Edit3DAction *> leftActions() const;
QVector<Edit3DAction *> rightActions() const;
+ void addQuick3DImport();
+
protected:
private:
void createEdit3DWidget();
+ void checkImports();
QPointer<Edit3DWidget> m_edit3DWidget;
QVector<Edit3DAction *> m_leftActions;
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
index 461613e476..9998bfc03d 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
@@ -33,6 +33,8 @@
#include "qmldesignerconstants.h"
#include "viewmanager.h"
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
#include <coreplugin/icore.h>
#include <toolbox.h>
#include <utils/utilsicons.h>
@@ -62,7 +64,7 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
// Iterate through view actions. A null action indicates a separator and a second null action
// after separator indicates an exclusive group.
- auto addActionsToToolBox = [this](const QVector<Edit3DAction *> &actions, bool left) {
+ auto addActionsToToolBox = [this, &context](const QVector<Edit3DAction *> &actions, bool left) {
bool previousWasSeparator = true;
QActionGroup *group = nullptr;
for (auto action : actions) {
@@ -75,6 +77,14 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
else
m_toolBox->addRightSideAction(action->action());
previousWasSeparator = false;
+
+ // Register action as creator command to make it configurable
+ Core::Command *command = Core::ActionManager::registerAction(
+ action->action(), action->menuId().data(), context);
+ command->setDefaultKeySequence(action->action()->shortcut());
+ command->augmentActionWithShortcutToolTip(action->action());
+ // Clear action shortcut so it doesn't conflict with command's override action
+ action->action()->setShortcut({});
} else {
if (previousWasSeparator) {
group = new QActionGroup(this);
@@ -89,14 +99,28 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
}
}
}
-
};
addActionsToToolBox(view->leftActions(), true);
addActionsToToolBox(view->rightActions(), false);
+ // Onboarding label contains instructions for new users how to get 3D content into the project
+ m_onboardingLabel = new QLabel(this);
+ QString labelText =
+ "No 3D import here yet!<br><br>"
+ "To create a 3D View you need to add the QtQuick3D import to your file.<br>"
+ "You can add the import via the QML Imports tab of the Library view, or alternatively click"
+ " <a href=\"#add_import\"><span style=\"text-decoration:none;color:%1\">here</span></a> "
+ "to add it straight away.<br><br>"
+ "If you want to import 3D assets from another tool, click on the \"Add New Assets...\" button in the Assets tab of the Library view.";
+ m_onboardingLabel->setText(labelText.arg(Utils::creatorTheme()->color(Utils::Theme::TextColorLink).name()));
+ m_onboardingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated);
+ fillLayout->addWidget(m_onboardingLabel.data());
+
// Canvas is used to render the actual edit 3d view
m_canvas = new Edit3DCanvas(this);
fillLayout->addWidget(m_canvas.data());
+ showCanvas(false);
}
void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
@@ -107,6 +131,22 @@ void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) con
callback({});
}
+void Edit3DWidget::showCanvas(bool show)
+{
+ if (!show) {
+ QImage emptyImage;
+ m_canvas->updateRenderImage(emptyImage);
+ }
+ m_canvas->setVisible(show);
+ m_onboardingLabel->setVisible(!show);
+}
+
+void Edit3DWidget::linkActivated(const QString &link)
+{
+ if (m_view)
+ m_view->addQuick3DImport();
+}
+
Edit3DCanvas *Edit3DWidget::canvas() const
{
return m_canvas.data();
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
index c5cea8836c..ca44a955f5 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
@@ -25,6 +25,7 @@
#pragma once
#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qlabel.h>
#include <QtCore/qpointer.h>
#include <coreplugin/icontext.h>
@@ -45,10 +46,15 @@ public:
Edit3DView *view() const;
void contextHelp(const Core::IContext::HelpCallback &callback) const;
+ void showCanvas(bool show);
+
private:
+ void linkActivated(const QString &link);
+
QPointer<Edit3DView> m_edit3DView;
QPointer<Edit3DView> m_view;
QPointer<Edit3DCanvas> m_canvas;
+ QPointer<QLabel> m_onboardingLabel;
QPointer<ToolBox> m_toolBox;
Core::IContext *m_context = nullptr;
};
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
index c9a98580a7..76cd389960 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
@@ -77,8 +77,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
auto layoutActionGroup = new QActionGroup(this);
layoutActionGroup->setExclusive(true);
- m_noSnappingAction = layoutActionGroup->addAction(tr("No snapping (T)."));
- m_noSnappingAction->setShortcut(Qt::Key_T);
+ m_noSnappingAction = layoutActionGroup->addAction(tr("No snapping."));
m_noSnappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
m_noSnappingAction->setCheckable(true);
m_noSnappingAction->setChecked(true);
diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
index 9674624863..8a2ca50c15 100644
--- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
+++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
@@ -253,7 +253,13 @@ void StatesEditorView::renameState(int internalNodeId, const QString &newName)
// Jump to base state for the change
QmlModelState oldState = currentState();
setCurrentState(baseState());
+ const bool updateDefault = state.isDefault();
+
state.setName(newName);
+
+ if (updateDefault)
+ state.setAsDefault();
+
setCurrentState(oldState);
}
} catch (const RewritingException &e) {
diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp
index 8517f9cb82..4034faccde 100644
--- a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp
@@ -38,6 +38,7 @@
#include <QUrl>
#include <QDebug>
+#include <QtCore/qregularexpression.h>
namespace QmlDesigner {
@@ -45,10 +46,13 @@ static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QStri
static QString fixExpression(const QString &expression, const QHash<QString, QString> &idRenamingHash)
{
+ const QString pattern("\\b%1\\b"); // Match only full ids
QString newExpression = expression;
- foreach (const QString &id, idRenamingHash.keys()) {
- if (newExpression.contains(id))
- newExpression = newExpression.replace(id, idRenamingHash.value(id));
+ const auto keys = idRenamingHash.keys();
+ for (const QString &id : keys) {
+ QRegularExpression re(pattern.arg(id));
+ if (newExpression.contains(re))
+ newExpression = newExpression.replace(re, idRenamingHash.value(id));
}
return newExpression;
}
diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h
index 132f31d2ff..b334dced8b 100644
--- a/src/plugins/qmldesigner/qmldesignerconstants.h
+++ b/src/plugins/qmldesigner/qmldesignerconstants.h
@@ -54,6 +54,15 @@ const char FORMEDITOR_SNAPPING[] = "QmlDesigner.FormEditor.Snapping";
const char FORMEDITOR_NO_SNAPPING[] = "QmlDesigner.FormEditor.NoSnapping";
const char FORMEDITOR_NO_SNAPPING_AND_ANCHORING[] = "QmlDesigner.FormEditor.NoSnappingAndAnchoring";
const char FORMEDITOR_NO_SHOW_BOUNDING_RECTANGLE[] = "QmlDesigner.FormEditor.ShowBoundingRectangle";
+const char EDIT3D_SELECTION_MODE[] = "QmlDesigner.Editor3D.SelectionModeToggle";
+const char EDIT3D_MOVE_TOOL[] = "QmlDesigner.Editor3D.MoveTool";
+const char EDIT3D_ROTATE_TOOL[] = "QmlDesigner.Editor3D.RotateTool";
+const char EDIT3D_SCALE_TOOL[] = "QmlDesigner.Editor3D.ScaleTool";
+const char EDIT3D_FIT_SELECTED[] = "QmlDesigner.Editor3D.FitSelected";
+const char EDIT3D_EDIT_CAMERA[] = "QmlDesigner.Editor3D.EditCameraToggle";
+const char EDIT3D_ORIENTATION[] = "QmlDesigner.Editor3D.OrientationToggle";
+const char EDIT3D_EDIT_LIGHT[] = "QmlDesigner.Editor3D.EditLightToggle";
+const char EDIT3D_RESET_VIEW[] = "QmlDesigner.Editor3D.ResetView";
const char QML_DESIGNER_SUBFOLDER[] = "/designer/";
const char QUICK_3D_ASSETS_FOLDER[] = "/Quick3DAssets";
diff --git a/src/plugins/vcsbase/vcsoutputformatter.cpp b/src/plugins/vcsbase/vcsoutputformatter.cpp
index 4145bd0618..b6ad20304c 100644
--- a/src/plugins/vcsbase/vcsoutputformatter.cpp
+++ b/src/plugins/vcsbase/vcsoutputformatter.cpp
@@ -38,7 +38,8 @@ VcsOutputFormatter::VcsOutputFormatter() :
m_regexp(
"(https?://\\S*)" // https://codereview.org/c/1234
"|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3
- "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,}|\\^)?)") // 789acf^ or 123abc..456cde
+ "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,}" // 789acf or 123abc..456cde
+ "|\\^+|~\\d+)?)") // or 789acf^ or 123abc~99
{
}
diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py
index 39f959b212..d7d556721c 100644
--- a/tests/system/suite_CSUP/tst_CSUP01/test.py
+++ b/tests/system/suite_CSUP/tst_CSUP01/test.py
@@ -93,21 +93,11 @@ def main():
resetLine(editorWidget)
lineWithFloat = "float fl = 2."
type(editorWidget, lineWithFloat)
- try:
- waitForObject(":popupFrame_Proposal_QListView", 5000)
- test.fail("Typing a float value triggered code completion")
- except:
- test.compare(str(lineUnderCursor(editorWidget)), " " + lineWithFloat,
- "Typing a float value does not trigger code completion")
+ test.exception("waitForObject(':popupFrame_Proposal_QListView', 5000)",
+ "Does typing a float value trigger code completion?")
triggerCompletion(editorWidget)
- try:
- waitForObject(":popupFrame_Proposal_QListView", 5000)
- if useClang and JIRA.isBugStillOpen(16607):
- test.xfail("User can trigger code completion manually in a float value")
- else:
- test.fail("User can trigger code completion manually in a float value")
- except:
- test.passes("User can't trigger code completion manually in a float value")
+ test.exception("waitForObject(':popupFrame_Proposal_QListView', 5000)",
+ "Can user trigger code completion manually in a float value?")
# Step 5: From "Tools -> Options -> Text Editor -> Completion" select Activate completion Manually,
# uncheck Autocomplete common prefix and press Apply and then Ok . Return to Edit mode.
test.log("Step 5: Change Code Completion settings")