Merge remote-tracking branch 'origin/7.0'
Conflicts: src/plugins/webassembly/webassemblytoolchain.cpp Change-Id: Ia75c783e3ecab1f97de2b5c73a0979c49da82009
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
@@ -102,7 +102,8 @@
|
||||
components in \uicontrol {Form Editor}, depending on the current page:
|
||||
|
||||
\list 1
|
||||
\li In the \l States view, select \uicontrol {Create New State}.
|
||||
\li In the \l States view, select \inlineimage icons/plus.png
|
||||
.
|
||||
\li Enter \e login as the state name.
|
||||
\image loginui3-login-state.jpg "States view"
|
||||
\li Select \e repeatPassword in \uicontrol Navigator to display its
|
||||
|
@@ -267,10 +267,10 @@
|
||||
in \uicontrol Timeline:
|
||||
|
||||
\list 1
|
||||
\li In \uicontrol States, select \uicontrol {Create New State} twice to
|
||||
add two states called \e login and \e createAccount. You don't
|
||||
need to make any property changes this time because you'll bind the
|
||||
states to property animations.
|
||||
\li In \uicontrol States, select \inlineimage icons/plus.png
|
||||
twice to add two states called \e login and \e createAccount. You
|
||||
don't need to make any property changes this time because you'll
|
||||
bind the states to property animations.
|
||||
\li In \uicontrol States, select \inlineimage icons/action-icon.png
|
||||
for \e login to open the \uicontrol Actions menu, and then
|
||||
select \uicontrol {Set as Default} to determine that the \e login
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 38 KiB |
@@ -234,7 +234,7 @@
|
||||
\section1 Using States to Change Component Property Values
|
||||
|
||||
\list 1
|
||||
\li In the \l States view, select \uicontrol {Create New State}
|
||||
\li In the \l States view, select \inlineimage icons/plus.png
|
||||
twice to create two new states.
|
||||
\image qmldesigner-borderimage-states.png "Active and inactive states"
|
||||
\li Select \uicontrol State1.
|
||||
|
@@ -38,19 +38,10 @@
|
||||
To open the \uicontrol States view, select \uicontrol View >
|
||||
\uicontrol Views > \uicontrol States.
|
||||
|
||||
To collapse or expand the \uicontrol States view, select:
|
||||
|
||||
\list
|
||||
\li Select \uicontrol View > \uicontrol Views >
|
||||
\uicontrol {Toggle States}.
|
||||
\li Press \key {Ctr+Alt+S} on Windows or \key {Cmd+Option+S} on \macOS.
|
||||
\li Right-click the view and select \uicontrol Collapse or
|
||||
\uicontrol Expand.
|
||||
\endlist
|
||||
|
||||
Initially, \uicontrol States displays a \e {base state} that shows the
|
||||
selected \l{glossary-component}{component} in its initial state. To add
|
||||
states, select \uicontrol {Create New State}.
|
||||
states, select \inlineimage icons/plus.png
|
||||
in the \uicontrol States view.
|
||||
|
||||
For more information, watch the following video:
|
||||
|
||||
|
@@ -36,7 +36,8 @@
|
||||
\title Adding States
|
||||
|
||||
You can define states for components and component instances in the
|
||||
\l States view by selecting \uicontrol {Create New State}.
|
||||
\l States view by selecting \inlineimage icons/plus.png
|
||||
.
|
||||
|
||||
\image qmldesigner-transitions.png "States view"
|
||||
|
||||
@@ -181,7 +182,7 @@
|
||||
\inlineimage icons/eye_open.png
|
||||
icon in \l Navigator to hide components on the canvas that are
|
||||
not part of a view.
|
||||
\li In \uicontrol States, select \uicontrol {Create New State} to create
|
||||
\li In \uicontrol States, select the \uicontrol + symbol to create
|
||||
a new state and give it a name. For example, \c Normal.
|
||||
\li In \l Properties (2), deselect the \uicontrol Visibility
|
||||
check box or set \uicontrol Opacity to 0 for each component that
|
||||
|
@@ -27,6 +27,9 @@ import QtQuick
|
||||
import QtQuick3D
|
||||
import QtQuick3D.Particles3D
|
||||
|
||||
// Note: This gizmo is also used to visualize Attractor3D in addition to ParticleEmitter3D,
|
||||
// as the two are very similar.
|
||||
|
||||
Node {
|
||||
id: root
|
||||
|
||||
@@ -41,6 +44,7 @@ Node {
|
||||
property bool globalShow: false
|
||||
property bool canBeVisible: activeScene === scene && targetNode && !hidden && !systemHidden
|
||||
property bool partOfActiveSystem: root.targetNode && root.targetNode.system === activeParticleSystem
|
||||
property bool isEmitter: targetNode && targetNode instanceof ParticleEmitter3D
|
||||
|
||||
opacity: 0.15
|
||||
|
||||
@@ -120,7 +124,10 @@ Node {
|
||||
|
||||
DefaultMaterial {
|
||||
id: defaultMaterial
|
||||
diffuseColor: root.selected ? "#FF0000" : partOfActiveSystem ? "#FFFF00" : "#AAAAAA"
|
||||
diffuseColor: root.selected ? "#FF0000"
|
||||
: root.partOfActiveSystem
|
||||
? root.isEmitter ? "#FFFF00" : "#0000FF"
|
||||
: "#AAAAAA"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include <QtQuick3DParticles/private/qquick3dparticlemodelshape_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticleemitter_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticletrailemitter_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticleattractor_p.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
@@ -477,11 +478,15 @@ QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitt
|
||||
QQuick3DMaterial *material) const
|
||||
{
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
auto e = qobject_cast<QQuick3DParticleEmitter *>(emitter);
|
||||
if (!e || qobject_cast<QQuick3DParticleTrailEmitter *>(e) || !material)
|
||||
if (qobject_cast<QQuick3DParticleTrailEmitter *>(emitter) || !material)
|
||||
return nullptr;
|
||||
|
||||
auto shape = qobject_cast<QQuick3DParticleModelShape *>(e->shape());
|
||||
QQuick3DParticleModelShape *shape = nullptr;
|
||||
if (auto e = qobject_cast<QQuick3DParticleEmitter *>(emitter))
|
||||
shape = qobject_cast<QQuick3DParticleModelShape *>(e->shape());
|
||||
else if (auto a = qobject_cast<QQuick3DParticleAttractor *>(emitter))
|
||||
shape = qobject_cast<QQuick3DParticleModelShape *>(a->shape());
|
||||
|
||||
if (shape && shape->delegate()) {
|
||||
if (auto model = qobject_cast<QQuick3DModel *>(
|
||||
shape->delegate()->create(shape->delegate()->creationContext()))) {
|
||||
|
@@ -1576,6 +1576,9 @@ void NodeInstanceServer::setupState(qint32 stateInstanceId)
|
||||
|
||||
void NodeInstanceServer::registerFonts(const QUrl &resourceUrl) const
|
||||
{
|
||||
if (!resourceUrl.isValid())
|
||||
return;
|
||||
|
||||
// Autoregister all fonts found inside the project
|
||||
QDirIterator it {QFileInfo(resourceUrl.toLocalFile()).absoluteFilePath(),
|
||||
{"*.ttf", "*.otf"}, QDir::Files, QDirIterator::Subdirectories};
|
||||
|
@@ -113,6 +113,7 @@
|
||||
#include <QtQuick3DParticles/private/qquick3dparticle_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticleaffector_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticleemitter_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticleattractor_p.h>
|
||||
#include <QtQuick3DParticles/private/qquick3dparticletrailemitter_p.h>
|
||||
#endif
|
||||
|
||||
@@ -775,7 +776,8 @@ void Qt5InformationNodeInstanceServer::handleNode3DDestroyed(QObject *obj)
|
||||
} else if (qobject_cast<QQuick3DParticleSystem *>(obj)) {
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseParticleSystemGizmo",
|
||||
Q_ARG(QVariant, objectToVariant(obj)));
|
||||
} else if (qobject_cast<QQuick3DParticleEmitter *>(obj)
|
||||
} else if ((qobject_cast<QQuick3DParticleEmitter *>(obj)
|
||||
|| qobject_cast<QQuick3DParticleAttractor *>(obj))
|
||||
&& !qobject_cast<QQuick3DParticleTrailEmitter *>(obj)) {
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseParticleEmitterGizmo",
|
||||
Q_ARG(QVariant, objectToVariant(obj)));
|
||||
@@ -887,7 +889,8 @@ void Qt5InformationNodeInstanceServer::resolveSceneRoots()
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateParticleSystemGizmoScene",
|
||||
Q_ARG(QVariant, objectToVariant(newRoot)),
|
||||
Q_ARG(QVariant, objectToVariant(node)));
|
||||
} else if (qobject_cast<QQuick3DParticleEmitter *>(node)
|
||||
} else if ((qobject_cast<QQuick3DParticleEmitter *>(node)
|
||||
|| qobject_cast<QQuick3DParticleAttractor *>(node))
|
||||
&& !qobject_cast<QQuick3DParticleTrailEmitter *>(node)) {
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateParticleEmitterGizmoScene",
|
||||
Q_ARG(QVariant, objectToVariant(newRoot)),
|
||||
@@ -1469,7 +1472,8 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
|
||||
lights[find3DSceneRoot(instance)] << instance.internalObject();
|
||||
} else if (instance.isSubclassOf("QQuick3DParticleSystem")) {
|
||||
particleSystems[find3DSceneRoot(instance)] << instance.internalObject();
|
||||
} else if (instance.isSubclassOf("QQuick3DParticleEmitter")
|
||||
} else if ((instance.isSubclassOf("QQuick3DParticleEmitter")
|
||||
|| instance.isSubclassOf("QQuick3DParticleAttractor"))
|
||||
&& !instance.isSubclassOf("QQuick3DParticleTrailEmitter")) {
|
||||
particleEmitters[find3DSceneRoot(instance)] << instance.internalObject();
|
||||
}
|
||||
@@ -2016,7 +2020,7 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
|| qobject_cast<QQuick3DParticleSystem *>(object)
|
||||
|| qobject_cast<QQuick3DParticleEmitter *>(object)
|
||||
|
||||
|| qobject_cast<QQuick3DParticleAttractor *>(object)
|
||||
#endif
|
||||
) {
|
||||
return true;
|
||||
|
@@ -39,7 +39,12 @@ Item {
|
||||
property string contextFilePath: ""
|
||||
property var contextDir: undefined
|
||||
property bool isDirContextMenu: false
|
||||
property var dropExtFiles: [] // array of supported externally dropped files
|
||||
|
||||
// Array of supported externally dropped files that are imported as-is
|
||||
property var dropSimpleExtFiles: []
|
||||
|
||||
// Array of supported externally dropped files that trigger custom import process
|
||||
property var dropComplexExtFiles: []
|
||||
|
||||
function clearSearchFilter()
|
||||
{
|
||||
@@ -48,18 +53,23 @@ Item {
|
||||
|
||||
function updateDropExtFiles(drag)
|
||||
{
|
||||
root.dropExtFiles = []
|
||||
root.dropSimpleExtFiles = []
|
||||
root.dropComplexExtFiles = []
|
||||
var simpleSuffixes = rootView.supportedAssetSuffixes(false);
|
||||
var complexSuffixes = rootView.supportedAssetSuffixes(true);
|
||||
for (const u of drag.urls) {
|
||||
var url = u.toString();
|
||||
if (url.startsWith("file:///")) // remove file scheme (happens on Windows)
|
||||
url = url.substr(8)
|
||||
|
||||
var ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
||||
if (rootView.supportedDropSuffixes().includes('*.' + ext))
|
||||
root.dropExtFiles.push(url)
|
||||
var ext = '*.' + url.slice(url.lastIndexOf('.') + 1).toLowerCase()
|
||||
if (simpleSuffixes.includes(ext))
|
||||
root.dropSimpleExtFiles.push(url)
|
||||
else if (complexSuffixes.includes(ext))
|
||||
root.dropComplexExtFiles.push(url)
|
||||
}
|
||||
|
||||
drag.accepted = root.dropExtFiles.length > 0
|
||||
drag.accepted = root.dropSimpleExtFiles.length > 0 || root.dropComplexExtFiles.length > 0
|
||||
}
|
||||
|
||||
DropArea { // handles external drop on empty area of the view (goes to root folder)
|
||||
@@ -73,13 +83,14 @@ Item {
|
||||
}
|
||||
|
||||
onDropped: {
|
||||
rootView.handleExtFilesDrop(root.dropExtFiles, assetsModel.rootDir().dirPath)
|
||||
rootView.handleExtFilesDrop(root.dropSimpleExtFiles, root.dropComplexExtFiles,
|
||||
assetsModel.rootDir().dirPath)
|
||||
}
|
||||
|
||||
Canvas { // marker for the drop area
|
||||
id: dropCanvas
|
||||
anchors.fill: parent
|
||||
visible: dropArea.containsDrag
|
||||
visible: dropArea.containsDrag && root.dropSimpleExtFiles.length > 0
|
||||
|
||||
onWidthChanged: dropCanvas.requestPaint()
|
||||
onHeightChanged: dropCanvas.requestPaint()
|
||||
@@ -458,50 +469,62 @@ Item {
|
||||
visible: assetsModel.isEmpty && searchBox.isEmpty()
|
||||
clip: true
|
||||
|
||||
Column {
|
||||
id: colNoAssets
|
||||
DropArea { // handles external drop (goes into default folder based on suffix)
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: 20
|
||||
x: 20
|
||||
width: root.width - 2 * x
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Text {
|
||||
text: qsTr("Looks like you don't have any assets yet.")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: 18
|
||||
width: colNoAssets.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
onEntered: (drag)=> {
|
||||
root.updateDropExtFiles(drag)
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "image://qmldesigner_assets/browse"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
scale: maBrowse.containsMouse ? 1.2 : 1
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: 300
|
||||
easing.type: Easing.OutQuad
|
||||
onDropped: {
|
||||
rootView.handleExtFilesDrop(root.dropSimpleExtFiles, root.dropComplexExtFiles)
|
||||
}
|
||||
|
||||
Column {
|
||||
id: colNoAssets
|
||||
|
||||
spacing: 20
|
||||
x: 20
|
||||
width: root.width - 2 * x
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Text {
|
||||
text: qsTr("Looks like you don't have any assets yet.")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: 18
|
||||
width: colNoAssets.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "image://qmldesigner_assets/browse"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
scale: maBrowse.containsMouse ? 1.2 : 1
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: 300
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: maBrowse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: rootView.handleAddAsset();
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: maBrowse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: rootView.handleAddAsset();
|
||||
Text {
|
||||
text: qsTr("Drag-and-drop your assets here or click the '+' button to browse assets from the file system.")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: 18
|
||||
width: colNoAssets.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Drag-and-drop your assets here or click the '+' button to browse assets from the file system.")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: 18
|
||||
width: colNoAssets.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +569,7 @@ Item {
|
||||
|
||||
onDropEnter: (drag)=> {
|
||||
root.updateDropExtFiles(drag)
|
||||
section.highlight = drag.accepted
|
||||
section.highlight = drag.accepted && root.dropSimpleExtFiles.length > 0
|
||||
}
|
||||
|
||||
onDropExit: {
|
||||
@@ -555,7 +578,9 @@ Item {
|
||||
|
||||
onDrop: {
|
||||
section.highlight = false
|
||||
rootView.handleExtFilesDrop(root.dropExtFiles, dirPath)
|
||||
rootView.handleExtFilesDrop(root.dropSimpleExtFiles,
|
||||
root.dropComplexExtFiles,
|
||||
dirPath)
|
||||
}
|
||||
|
||||
onShowContextMenu: {
|
||||
|
@@ -161,7 +161,7 @@ FocusScope {
|
||||
Text {
|
||||
text: "+"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -5
|
||||
anchors.verticalCenterOffset: -16
|
||||
font.pixelSize: parent.height * .5
|
||||
color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
|
||||
}
|
||||
|
@@ -479,7 +479,8 @@ bool checkParameters(const QSsh::SshConnectionParameters ¶ms)
|
||||
|
||||
void printSetupHelp()
|
||||
{
|
||||
qInfo() << "In order to run this test properly it requires some setup (example for fedora):\n"
|
||||
qInfo() << "\n\n"
|
||||
"In order to run this test properly it requires some setup (example for fedora):\n"
|
||||
"1. Run a server on the host to connect to:\n"
|
||||
" systemctl start sshd\n"
|
||||
"2. Create your own ssh key (needed only once). For fedora it needs ecdsa type:\n"
|
||||
|
@@ -111,6 +111,7 @@ namespace Internal {
|
||||
void popupRequested(bool focus);
|
||||
void handleExpandCollapseToolButton(bool checked);
|
||||
void updateFilterButton();
|
||||
QList<QWidget *> toolBarWidgets();
|
||||
|
||||
SearchResultWindow *q;
|
||||
QList<Internal::SearchResultWidget *> m_searchResultWidgets;
|
||||
@@ -120,9 +121,9 @@ namespace Internal {
|
||||
QAction *m_expandCollapseAction;
|
||||
static const bool m_initiallyExpand;
|
||||
QWidget *m_spacer;
|
||||
QLabel *m_historyLabel;
|
||||
QLabel *m_historyLabel = nullptr;
|
||||
QWidget *m_spacer2;
|
||||
QComboBox *m_recentSearchesBox;
|
||||
QComboBox *m_recentSearchesBox = nullptr;
|
||||
QStackedWidget *m_widget;
|
||||
QList<SearchResult *> m_searchResults;
|
||||
int m_currentIndex;
|
||||
@@ -139,20 +140,13 @@ namespace Internal {
|
||||
m_expandCollapseButton(nullptr),
|
||||
m_expandCollapseAction(new QAction(tr("Expand All"), window)),
|
||||
m_spacer(new QWidget),
|
||||
m_historyLabel(new QLabel(tr("History:"))),
|
||||
m_spacer2(new QWidget),
|
||||
m_recentSearchesBox(new QComboBox),
|
||||
m_widget(new QStackedWidget),
|
||||
m_currentIndex(0),
|
||||
m_tabWidth(8)
|
||||
{
|
||||
m_spacer->setMinimumWidth(30);
|
||||
m_spacer2->setMinimumWidth(5);
|
||||
m_recentSearchesBox->setProperty("drawleftborder", true);
|
||||
m_recentSearchesBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
m_recentSearchesBox->addItem(tr("New Search"));
|
||||
connect(m_recentSearchesBox, QOverload<int>::of(&QComboBox::activated),
|
||||
this, &SearchResultWindowPrivate::setCurrentIndexWithFocus);
|
||||
|
||||
m_widget->setWindowTitle(q->displayName());
|
||||
|
||||
@@ -194,6 +188,7 @@ namespace Internal {
|
||||
|
||||
void SearchResultWindowPrivate::setCurrentIndex(int index, bool focus)
|
||||
{
|
||||
QTC_ASSERT(m_recentSearchesBox, return );
|
||||
if (isSearchVisible())
|
||||
m_searchResultWidgets.at(visibleSearchIndex())->notifyVisibilityChanged(false);
|
||||
m_currentIndex = index;
|
||||
@@ -217,6 +212,7 @@ namespace Internal {
|
||||
|
||||
void SearchResultWindowPrivate::moveWidgetToTop()
|
||||
{
|
||||
QTC_ASSERT(m_recentSearchesBox, return );
|
||||
auto widget = qobject_cast<SearchResultWidget *>(sender());
|
||||
QTC_ASSERT(widget, return);
|
||||
const int index = m_searchResultWidgets.indexOf(widget);
|
||||
@@ -458,8 +454,7 @@ QWidget *SearchResultWindow::outputWidget(QWidget *)
|
||||
*/
|
||||
QList<QWidget*> SearchResultWindow::toolBarWidgets() const
|
||||
{
|
||||
return {d->m_expandCollapseButton, d->m_filterButton, d->m_newSearchButton, d->m_spacer,
|
||||
d->m_historyLabel, d->m_spacer2, d->m_recentSearchesBox};
|
||||
return d->toolBarWidgets();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -497,16 +492,19 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label,
|
||||
PreserveCaseMode preserveCaseMode,
|
||||
const QString &cfgGroup)
|
||||
{
|
||||
if (d->m_searchResults.size() >= MAX_SEARCH_HISTORY) {
|
||||
if (d->m_currentIndex >= d->m_recentSearchesBox->count() - 1) {
|
||||
// temporarily set the index to the last but one existing
|
||||
d->m_currentIndex = d->m_recentSearchesBox->count() - 2;
|
||||
if (QTC_GUARD(d->m_recentSearchesBox)) {
|
||||
if (d->m_searchResults.size() >= MAX_SEARCH_HISTORY) {
|
||||
if (d->m_currentIndex >= d->m_recentSearchesBox->count() - 1) {
|
||||
// temporarily set the index to the last but one existing
|
||||
d->m_currentIndex = d->m_recentSearchesBox->count() - 2;
|
||||
}
|
||||
d->m_searchResultWidgets.last()->notifyVisibilityChanged(false);
|
||||
// widget first, because that might send interesting signals to SearchResult
|
||||
delete d->m_searchResultWidgets.takeLast();
|
||||
delete d->m_searchResults.takeLast();
|
||||
d->m_recentSearchesBox->removeItem(d->m_recentSearchesBox->count() - 1);
|
||||
}
|
||||
d->m_searchResultWidgets.last()->notifyVisibilityChanged(false);
|
||||
// widget first, because that might send interesting signals to SearchResult
|
||||
delete d->m_searchResultWidgets.takeLast();
|
||||
delete d->m_searchResults.takeLast();
|
||||
d->m_recentSearchesBox->removeItem(d->m_recentSearchesBox->count()-1);
|
||||
d->m_recentSearchesBox->insertItem(1, tr("%1 %2").arg(label, searchTerm));
|
||||
}
|
||||
auto widget = new SearchResultWidget;
|
||||
connect(widget, &SearchResultWidget::filterInvalidated, this, [this, widget] {
|
||||
@@ -532,7 +530,6 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label,
|
||||
widget->setInfo(label, toolTip, searchTerm);
|
||||
auto result = new SearchResult(widget);
|
||||
d->m_searchResults.prepend(result);
|
||||
d->m_recentSearchesBox->insertItem(1, tr("%1 %2").arg(label, searchTerm));
|
||||
if (d->m_currentIndex > 0)
|
||||
++d->m_currentIndex; // so setCurrentIndex still knows about the right "currentIndex" and its widget
|
||||
d->setCurrentIndexWithFocus(1);
|
||||
@@ -544,8 +541,10 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label,
|
||||
*/
|
||||
void SearchResultWindow::clearContents()
|
||||
{
|
||||
for (int i = d->m_recentSearchesBox->count() - 1; i > 0 /* don't want i==0 */; --i)
|
||||
d->m_recentSearchesBox->removeItem(i);
|
||||
if (QTC_GUARD(d->m_recentSearchesBox)) {
|
||||
for (int i = d->m_recentSearchesBox->count() - 1; i > 0 /* don't want i==0 */; --i)
|
||||
d->m_recentSearchesBox->removeItem(i);
|
||||
}
|
||||
foreach (Internal::SearchResultWidget *widget, d->m_searchResultWidgets)
|
||||
widget->notifyVisibilityChanged(false);
|
||||
qDeleteAll(d->m_searchResultWidgets);
|
||||
@@ -642,6 +641,29 @@ void SearchResultWindowPrivate::updateFilterButton()
|
||||
&& m_searchResultWidgets.at(visibleSearchIndex())->hasFilter());
|
||||
}
|
||||
|
||||
QList<QWidget *> SearchResultWindowPrivate::toolBarWidgets()
|
||||
{
|
||||
if (!m_historyLabel)
|
||||
m_historyLabel = new QLabel(tr("History:"));
|
||||
if (!m_recentSearchesBox) {
|
||||
m_recentSearchesBox = new QComboBox;
|
||||
m_recentSearchesBox->setProperty("drawleftborder", true);
|
||||
m_recentSearchesBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
m_recentSearchesBox->addItem(tr("New Search"));
|
||||
connect(m_recentSearchesBox,
|
||||
QOverload<int>::of(&QComboBox::activated),
|
||||
this,
|
||||
&SearchResultWindowPrivate::setCurrentIndexWithFocus);
|
||||
}
|
||||
return {m_expandCollapseButton,
|
||||
m_filterButton,
|
||||
m_newSearchButton,
|
||||
m_spacer,
|
||||
m_historyLabel,
|
||||
m_spacer2,
|
||||
m_recentSearchesBox};
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
|
@@ -684,7 +684,7 @@ Toolchains KitDetectorPrivate::autoDetectToolChains()
|
||||
emit q->logOutput('\n' + tr("Searching toolchains..."));
|
||||
for (ToolChainFactory *factory : factories) {
|
||||
emit q->logOutput(tr("Searching toolchains of type %1").arg(factory->displayName()));
|
||||
const ToolchainDetector detector(alreadyKnown, m_device);
|
||||
const ToolchainDetector detector(alreadyKnown, m_device, m_searchPaths);
|
||||
const Toolchains newToolChains = factory->autoDetect(detector);
|
||||
for (ToolChain *toolChain : newToolChains) {
|
||||
emit q->logOutput(tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput()));
|
||||
@@ -1495,6 +1495,12 @@ QByteArray DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) cons
|
||||
QTC_ASSERT(m_shell && m_shell->isRunning(), return {});
|
||||
QMutexLocker l(&m_shellMutex);
|
||||
m_shell->readAllStandardOutput(); // clean possible left-overs
|
||||
const QByteArray oldError = m_shell->readAllStandardError(); // clean possible left-overs
|
||||
if (!oldError.isEmpty()) {
|
||||
LOG("Unexpected old stderr: " << oldError);
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
|
||||
const QByteArray markerWithNewLine("___QC_DOCKER_" + randomHex() + "_OUTPUT_MARKER___\n");
|
||||
m_shell->write(cmd.toUserOutput().toUtf8() + "\necho -n \"" + markerWithNewLine + "\"\n");
|
||||
QByteArray output;
|
||||
@@ -1506,6 +1512,11 @@ QByteArray DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) cons
|
||||
LOG("Run command in shell:" << cmd.toUserOutput() << "output size:" << output.size());
|
||||
if (QTC_GUARD(output.endsWith(markerWithNewLine)))
|
||||
output.chop(markerWithNewLine.size());
|
||||
const QByteArray currentError = m_shell->readAllStandardError();
|
||||
if (!currentError.isEmpty()) {
|
||||
LOG("Unexpected current stderr: " << currentError);
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@@ -365,7 +365,7 @@ static ToolChain *iarToolChain(const FilePath &path, Id language)
|
||||
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
|
||||
});
|
||||
if (iarFactory) {
|
||||
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}));
|
||||
Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}, {}));
|
||||
if (detected.isEmpty())
|
||||
detected = iarFactory->detectForImport({path, language});
|
||||
for (auto tc : detected) {
|
||||
|
@@ -1090,10 +1090,11 @@ Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd)
|
||||
return {};
|
||||
}
|
||||
|
||||
static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
|
||||
static FilePaths findCompilerCandidates(const ToolchainDetector &detector,
|
||||
const QString &compilerName,
|
||||
bool detectVariants)
|
||||
{
|
||||
const IDevice::ConstPtr device = detector.device;
|
||||
const QFileInfo fi(compilerName);
|
||||
if (device.isNull() && fi.isAbsolute() && fi.isFile())
|
||||
return {FilePath::fromString(compilerName)};
|
||||
@@ -1119,7 +1120,9 @@ static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
|
||||
|
||||
if (!device.isNull()) {
|
||||
// FIXME: Merge with block below
|
||||
FilePaths searchPaths = device->systemEnvironment().path();
|
||||
FilePaths searchPaths = detector.searchPaths;
|
||||
if (searchPaths.isEmpty())
|
||||
searchPaths = device->systemEnvironment().path();
|
||||
for (const FilePath &deviceDir : qAsConst(searchPaths)) {
|
||||
static const QRegularExpression regexp(binaryRegexp);
|
||||
const auto callBack = [&compilerPaths, compilerName](const FilePath &candidate) {
|
||||
@@ -1135,16 +1138,19 @@ static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
|
||||
}
|
||||
} else {
|
||||
// The normal, local host case.
|
||||
FilePaths searchPaths = Environment::systemEnvironment().path();
|
||||
searchPaths << gnuSearchPathsFromRegistry();
|
||||
searchPaths << atmelSearchPathsFromRegistry();
|
||||
searchPaths << renesasRl78SearchPathsFromRegistry();
|
||||
if (HostOsInfo::isAnyUnixHost()) {
|
||||
FilePath ccachePath = "/usr/lib/ccache/bin";
|
||||
if (!ccachePath.exists())
|
||||
ccachePath = "/usr/lib/ccache";
|
||||
if (ccachePath.exists() && !searchPaths.contains(ccachePath))
|
||||
searchPaths << ccachePath;
|
||||
FilePaths searchPaths = detector.searchPaths;
|
||||
if (searchPaths.isEmpty()) {
|
||||
searchPaths = Environment::systemEnvironment().path();
|
||||
searchPaths << gnuSearchPathsFromRegistry();
|
||||
searchPaths << atmelSearchPathsFromRegistry();
|
||||
searchPaths << renesasRl78SearchPathsFromRegistry();
|
||||
if (HostOsInfo::isAnyUnixHost()) {
|
||||
FilePath ccachePath = "/usr/lib/ccache/bin";
|
||||
if (!ccachePath.exists())
|
||||
ccachePath = "/usr/lib/ccache";
|
||||
if (ccachePath.exists() && !searchPaths.contains(ccachePath))
|
||||
searchPaths << ccachePath;
|
||||
}
|
||||
}
|
||||
for (const FilePath &dir : qAsConst(searchPaths)) {
|
||||
static const QRegularExpression regexp(binaryRegexp);
|
||||
@@ -1173,7 +1179,7 @@ Toolchains GccToolChainFactory::autoDetectToolchains(
|
||||
const ToolchainChecker &checker) const
|
||||
{
|
||||
const FilePaths compilerPaths =
|
||||
findCompilerCandidates(detector.device, compilerName, detectVariants == DetectVariants::Yes);
|
||||
findCompilerCandidates(detector, compilerName, detectVariants == DetectVariants::Yes);
|
||||
Toolchains existingCandidates = filtered(detector.alreadyKnown,
|
||||
[language](const ToolChain *tc) { return tc->language() == language; });
|
||||
Toolchains result;
|
||||
@@ -1748,7 +1754,7 @@ Toolchains ClangToolChainFactory::autoDetect(const ToolchainDetector &detector)
|
||||
const FilePath clang = compilerPath.parentDir().pathAppended("clang").withExecutableSuffix();
|
||||
tcs.append(autoDetectToolchains(clang.toString(), DetectVariants::No,
|
||||
Constants::C_LANGUAGE_ID, Constants::CLANG_TOOLCHAIN_TYPEID,
|
||||
ToolchainDetector(known, detector.device)));
|
||||
ToolchainDetector(known, detector.device, detector.searchPaths)));
|
||||
}
|
||||
|
||||
return tcs;
|
||||
|
@@ -673,8 +673,10 @@ void ToolChainFactory::setUserCreatable(bool userCreatable)
|
||||
m_userCreatable = userCreatable;
|
||||
}
|
||||
|
||||
ToolchainDetector::ToolchainDetector(const Toolchains &alreadyKnown, const IDevice::ConstPtr &device)
|
||||
: alreadyKnown(alreadyKnown), device(device)
|
||||
ToolchainDetector::ToolchainDetector(const Toolchains &alreadyKnown,
|
||||
const IDevice::ConstPtr &device,
|
||||
const FilePaths &searchPaths)
|
||||
: alreadyKnown(alreadyKnown), device(device), searchPaths(searchPaths)
|
||||
{}
|
||||
|
||||
BadToolchain::BadToolchain(const Utils::FilePath &filePath)
|
||||
|
@@ -250,13 +250,16 @@ public:
|
||||
class PROJECTEXPLORER_EXPORT ToolchainDetector
|
||||
{
|
||||
public:
|
||||
ToolchainDetector(const Toolchains &alreadyKnown, const IDevice::ConstPtr &device);
|
||||
ToolchainDetector(const Toolchains &alreadyKnown,
|
||||
const IDevice::ConstPtr &device,
|
||||
const Utils::FilePaths &searchPaths);
|
||||
|
||||
bool isBadToolchain(const Utils::FilePath &toolchain) const;
|
||||
void addBadToolchain(const Utils::FilePath &toolchain) const;
|
||||
|
||||
const Toolchains alreadyKnown;
|
||||
const IDevice::ConstPtr device;
|
||||
const Utils::FilePaths searchPaths; // If empty use device path and/or magic.
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT ToolChainFactory
|
||||
|
@@ -412,7 +412,7 @@ void ToolChainOptionsWidget::redetectToolchains()
|
||||
QSet<ToolChain *> toDelete;
|
||||
ToolChainManager::resetBadToolchains();
|
||||
for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) {
|
||||
const ToolchainDetector detector(knownTcs, {}); // FIXME: Pass device.
|
||||
const ToolchainDetector detector(knownTcs, {}, {}); // FIXME: Pass device and search paths
|
||||
for (ToolChain * const tc : f->autoDetect(detector)) {
|
||||
if (knownTcs.contains(tc) || toDelete.contains(tc))
|
||||
continue;
|
||||
|
@@ -205,7 +205,7 @@ Toolchains ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const
|
||||
= Utils::filtered(userFileTcs, &ToolChain::isAutoDetected);
|
||||
// FIXME: Use real device?
|
||||
const Toolchains autodetectedTcs =
|
||||
autoDetectToolChains(ToolchainDetector(autodetectedUserFileTcs, {}));
|
||||
autoDetectToolChains(ToolchainDetector(autodetectedUserFileTcs, {}, {}));
|
||||
|
||||
// merge tool chains and register those that we need to keep:
|
||||
const ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs);
|
||||
|
@@ -213,34 +213,38 @@ void AssetsLibraryWidget::handleAddAsset()
|
||||
addResources({});
|
||||
}
|
||||
|
||||
void AssetsLibraryWidget::handleExtFilesDrop(const QStringList &filesPaths, const QString &targetDirPath)
|
||||
void AssetsLibraryWidget::handleExtFilesDrop(const QStringList &simpleFilesPaths,
|
||||
const QStringList &complexFilesPaths,
|
||||
const QString &targetDirPath)
|
||||
{
|
||||
QStringList assetPaths;
|
||||
QStringList otherPaths; // as of now 3D models, and 3D Studio presentations
|
||||
std::tie(assetPaths, otherPaths) = Utils::partition(filesPaths, [](const QString &path) {
|
||||
QString suffix = "*." + path.split('.').last().toLower();
|
||||
return AssetsLibraryModel::supportedSuffixes().contains(suffix);
|
||||
});
|
||||
|
||||
AddFilesResult result = ModelNodeOperations::addFilesToProject(assetPaths, targetDirPath);
|
||||
if (result == AddFilesResult::Failed) {
|
||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
|
||||
tr("Could not add %1 to project.")
|
||||
.arg(filesPaths.join(' ')));
|
||||
if (!simpleFilesPaths.isEmpty()) {
|
||||
if (targetDirPath.isEmpty()) {
|
||||
addResources(simpleFilesPaths);
|
||||
} else {
|
||||
AddFilesResult result = ModelNodeOperations::addFilesToProject(simpleFilesPaths,
|
||||
targetDirPath);
|
||||
if (result == AddFilesResult::Failed) {
|
||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"),
|
||||
tr("Could not add %1 to project.")
|
||||
.arg(simpleFilesPaths.join(' ')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!otherPaths.empty())
|
||||
addResources(otherPaths);
|
||||
if (!complexFilesPaths.empty())
|
||||
addResources(complexFilesPaths);
|
||||
}
|
||||
|
||||
QSet<QString> AssetsLibraryWidget::supportedDropSuffixes()
|
||||
QSet<QString> AssetsLibraryWidget::supportedAssetSuffixes(bool complex)
|
||||
{
|
||||
const QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager()
|
||||
.designerActionManager().addResourceHandler();
|
||||
|
||||
QSet<QString> suffixes;
|
||||
for (const AddResourceHandler &handler : handlers)
|
||||
suffixes.insert(handler.filter);
|
||||
for (const AddResourceHandler &handler : handlers) {
|
||||
if (AssetsLibraryModel::supportedSuffixes().contains(handler.filter) != complex)
|
||||
suffixes.insert(handler.filter);
|
||||
}
|
||||
|
||||
return suffixes;
|
||||
}
|
||||
|
@@ -80,8 +80,10 @@ public:
|
||||
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
||||
Q_INVOKABLE void handleAddAsset();
|
||||
Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
|
||||
Q_INVOKABLE void handleExtFilesDrop(const QStringList &filesPaths, const QString &targetDirPath);
|
||||
Q_INVOKABLE QSet<QString> supportedDropSuffixes();
|
||||
Q_INVOKABLE void handleExtFilesDrop(const QStringList &simpleFilesPaths,
|
||||
const QStringList &complexFilesPaths,
|
||||
const QString &targetDirPath = {});
|
||||
Q_INVOKABLE QSet<QString> supportedAssetSuffixes(bool complex);
|
||||
|
||||
signals:
|
||||
void itemActivated(const QString &itemName);
|
||||
|
@@ -360,9 +360,9 @@ void Edit3DView::createEdit3DActions()
|
||||
|
||||
m_showParticleEmitterAction = new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_SHOW_PARTICLE_EMITTER, View3DActionCommand::ShowParticleEmitter,
|
||||
QCoreApplication::translate("ShowParticleEmitterAction", "Always Show Particle Emitters"),
|
||||
QCoreApplication::translate("ShowParticleEmitterAction", "Always Show Particle Emitters And Attractors"),
|
||||
QKeySequence(Qt::Key_M), true, false, {}, {}, nullptr,
|
||||
QCoreApplication::translate("ShowParticleEmitterAction", "Toggle between always showing the particle emitter visualization and only showing it when the emitter is selected."));
|
||||
QCoreApplication::translate("ShowParticleEmitterAction", "Toggle between always showing the particle emitter and attractor visualizations and only showing them when the emitter or attractor is selected."));
|
||||
|
||||
SelectionContextOperation resetTrigger = [this](const SelectionContext &) {
|
||||
m_particlesPlayAction->action()->setEnabled(particlemode);
|
||||
|
@@ -170,6 +170,8 @@ private: // functions
|
||||
|
||||
NodeInstance loadNode(const ModelNode &node);
|
||||
|
||||
void clearErrors();
|
||||
|
||||
void removeAllInstanceNodeRelationships();
|
||||
|
||||
void removeRecursiveChildRelationship(const ModelNode &removedNode);
|
||||
|
@@ -326,10 +326,17 @@ void NodeInstanceView::endPuppetTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NodeInstanceView::clearErrors()
|
||||
{
|
||||
for (NodeInstance &instance : instances()) {
|
||||
instance.setError({});
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInstanceView::restartProcess()
|
||||
{
|
||||
if (rootNodeInstance().isValid())
|
||||
rootNodeInstance().setError({});
|
||||
clearErrors();
|
||||
emitInstanceErrorChange({});
|
||||
emitDocumentMessage({}, {});
|
||||
|
||||
@@ -556,10 +563,11 @@ void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractP
|
||||
m_nodeInstanceServer->reparentInstances(
|
||||
createReparentInstancesCommand(node, newPropertyParent, oldPropertyParent));
|
||||
|
||||
// Reset puppet when particle emitter is reparented to work around issue in
|
||||
// Reset puppet when particle emitter/affector is reparented to work around issue in
|
||||
// autodetecting the particle system it belongs to. QTBUG-101157
|
||||
if (node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
||||
&& node.property("system").toBindingProperty().expression().isEmpty()) {
|
||||
if ((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
||||
|| node.isSubclassOf("QtQuick.Particles3D.Affector3D"))
|
||||
&& node.property("system").toBindingProperty().expression().isEmpty()) {
|
||||
resetPuppet();
|
||||
}
|
||||
}
|
||||
@@ -957,6 +965,8 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
||||
}
|
||||
}
|
||||
|
||||
clearErrors();
|
||||
|
||||
nodeList = filterNodesForSkipItems(nodeList);
|
||||
|
||||
QList<VariantProperty> variantPropertyList;
|
||||
|
@@ -767,12 +767,16 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
|
||||
const ObjectValue *objectValue = getObjectValue();
|
||||
if (objectValue) {
|
||||
const CppComponentValue *qmlValue = value_cast<CppComponentValue>(objectValue);
|
||||
|
||||
if (qmlValue) {
|
||||
if (m_majorVersion == -1 && m_minorVersion == -1) {
|
||||
m_majorVersion = qmlValue->componentVersion().majorVersion();
|
||||
m_minorVersion = qmlValue->componentVersion().minorVersion();
|
||||
m_qualfiedTypeName = qmlValue->moduleName().toUtf8() + '.' + qmlValue->className().toUtf8();
|
||||
} else if (m_majorVersion == qmlValue->componentVersion().majorVersion() && m_minorVersion == qmlValue->componentVersion().minorVersion()) {
|
||||
m_qualfiedTypeName = qmlValue->moduleName().toUtf8() + '.'
|
||||
+ qmlValue->className().toUtf8();
|
||||
|
||||
} else if (m_majorVersion == qmlValue->componentVersion().majorVersion()
|
||||
&& m_minorVersion == qmlValue->componentVersion().minorVersion()) {
|
||||
m_qualfiedTypeName = qmlValue->moduleName().toUtf8() + '.' + qmlValue->className().toUtf8();
|
||||
} else {
|
||||
return;
|
||||
@@ -780,10 +784,16 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
|
||||
} else {
|
||||
m_isFileComponent = true;
|
||||
const Imports *imports = context()->imports(document());
|
||||
ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data());
|
||||
if (importInfo.isValid() && importInfo.type() == ImportType::Library) {
|
||||
m_majorVersion = importInfo.version().majorVersion();
|
||||
m_minorVersion = importInfo.version().minorVersion();
|
||||
const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data());
|
||||
if (importInfo.isValid()) {
|
||||
if (importInfo.type() == ImportType::Library) {
|
||||
m_majorVersion = importInfo.version().majorVersion();
|
||||
m_minorVersion = importInfo.version().minorVersion();
|
||||
}
|
||||
bool prepandName = (importInfo.type() == ImportType::Library || importInfo.type() == ImportType::Directory)
|
||||
&& !m_qualfiedTypeName.contains('.');
|
||||
if (prepandName)
|
||||
m_qualfiedTypeName.prepend(importInfo.name().toUtf8() + '.');
|
||||
}
|
||||
}
|
||||
m_objectValue = objectValue;
|
||||
|
@@ -260,7 +260,9 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
|
||||
#else
|
||||
const auto showDebugSettings = settings.value(DesignerSettingsKey::SHOW_DEBUG_SETTINGS).toBool();
|
||||
#endif
|
||||
m_ui.debugGroupBox->setVisible(!standaloneMode || showDebugSettings);
|
||||
const bool showAdvancedFeatures = !standaloneMode || showDebugSettings;
|
||||
m_ui.emulationGroupBox->setVisible(showAdvancedFeatures);
|
||||
m_ui.debugGroupBox->setVisible(showAdvancedFeatures);
|
||||
m_ui.featureTimelineEditorCheckBox->setVisible(standaloneMode);
|
||||
}
|
||||
|
||||
|
@@ -95,7 +95,11 @@ void FileSystemAccessTest::initTestCase()
|
||||
QVERIFY(!newDev.isNull());
|
||||
devMgr->addDevice(newDev);
|
||||
}
|
||||
if (filePath.exists()) // Do initial cleanup after possible leftovers from previously failed test
|
||||
QVERIFY(filePath.removeRecursively());
|
||||
QVERIFY(!filePath.exists());
|
||||
QVERIFY(filePath.createDir());
|
||||
QVERIFY(filePath.exists());
|
||||
}
|
||||
|
||||
void FileSystemAccessTest::cleanupTestCase()
|
||||
@@ -106,7 +110,43 @@ void FileSystemAccessTest::cleanupTestCase()
|
||||
QVERIFY(baseFilePath().removeRecursively());
|
||||
}
|
||||
|
||||
void FileSystemAccessTest::testDirStatuses()
|
||||
void FileSystemAccessTest::testCreateRemoteFile_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("data");
|
||||
|
||||
QTest::newRow("Spaces") << QByteArray("Line with spaces");
|
||||
QTest::newRow("Newlines") << QByteArray("Some \n\n newlines \n");
|
||||
QTest::newRow("Carriage return") << QByteArray("Line with carriage \r return");
|
||||
QTest::newRow("Tab") << QByteArray("Line with \t tab");
|
||||
QTest::newRow("Apostrophe") << QByteArray("Line with apostrophe's character");
|
||||
QTest::newRow("Quotation marks") << QByteArray("Line with \"quotation marks\"");
|
||||
QTest::newRow("Backslash 1") << QByteArray("Line with \\ backslash");
|
||||
QTest::newRow("Backslash 2") << QByteArray("Line with \\\" backslash");
|
||||
QTest::newRow("Command output") << QByteArray("The date is: $(date +%D)");
|
||||
|
||||
const int charSize = sizeof(char) * 0x100;
|
||||
QByteArray charString(charSize, Qt::Uninitialized);
|
||||
char *data = charString.data();
|
||||
for (int c = 0; c < charSize; ++c)
|
||||
data[c] = c;
|
||||
QTest::newRow("All Characters") << charString;
|
||||
}
|
||||
|
||||
void FileSystemAccessTest::testCreateRemoteFile()
|
||||
{
|
||||
QFETCH(QByteArray, data);
|
||||
|
||||
const FilePath testFilePath = baseFilePath() / "test_file";
|
||||
|
||||
QVERIFY(!testFilePath.exists());
|
||||
QVERIFY(testFilePath.writeFileContents(data));
|
||||
QVERIFY(testFilePath.exists());
|
||||
QCOMPARE(testFilePath.fileContents(), data);
|
||||
QVERIFY(testFilePath.removeFile());
|
||||
QVERIFY(!testFilePath.exists());
|
||||
}
|
||||
|
||||
void FileSystemAccessTest::testDirStatus()
|
||||
{
|
||||
FilePath filePath = baseFilePath();
|
||||
QVERIFY(filePath.exists());
|
||||
@@ -142,7 +182,7 @@ void FileSystemAccessTest::testBytesAvailable()
|
||||
|
||||
void FileSystemAccessTest::testFileActions()
|
||||
{
|
||||
FilePath testFilePath = createFile("test");
|
||||
const FilePath testFilePath = createFile("test");
|
||||
QVERIFY(testFilePath.exists());
|
||||
QVERIFY(testFilePath.isFile());
|
||||
|
||||
@@ -153,15 +193,17 @@ void FileSystemAccessTest::testFileActions()
|
||||
QVERIFY(testFilePath.isReadableFile());
|
||||
QVERIFY(testFilePath.isExecutableFile());
|
||||
|
||||
QByteArray content("Test");
|
||||
const QByteArray content("Test");
|
||||
testFilePath.writeFileContents(content);
|
||||
// ToDo: remove ".contains", make fileContents exact equal content
|
||||
QVERIFY(testFilePath.fileContents().contains(content));
|
||||
QCOMPARE(testFilePath.fileContents(), content);
|
||||
|
||||
QVERIFY(testFilePath.renameFile(baseFilePath() / "test1"));
|
||||
const FilePath newTestFilePath = baseFilePath() / "test1";
|
||||
// It is Ok that FilePath doesn't change itself after rename.
|
||||
FilePath newTestFilePath = baseFilePath() / "test1";
|
||||
// FilePath::renameFile() is a const method!
|
||||
QVERIFY(testFilePath.renameFile(newTestFilePath));
|
||||
QVERIFY(!testFilePath.exists());
|
||||
QVERIFY(newTestFilePath.exists());
|
||||
QCOMPARE(newTestFilePath.fileContents(), content);
|
||||
QVERIFY(!testFilePath.removeFile());
|
||||
QVERIFY(newTestFilePath.exists());
|
||||
QVERIFY(newTestFilePath.removeFile());
|
||||
|
@@ -45,12 +45,15 @@ class FileSystemAccessTest : public QObject
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
void testDirStatuses();
|
||||
void testCreateRemoteFile_data();
|
||||
void testCreateRemoteFile();
|
||||
void testDirStatus();
|
||||
void testBytesAvailable();
|
||||
void testFileActions();
|
||||
|
||||
void cleanupTestCase();
|
||||
|
||||
private:
|
||||
TestLinuxDeviceFactory m_testLinuxDeviceFactory;
|
||||
bool m_skippedAtWhole = false;
|
||||
|
@@ -232,11 +232,14 @@ public:
|
||||
bool runInShell(const CommandLine &cmd, const QByteArray &data = {})
|
||||
{
|
||||
QTC_ASSERT(m_shell, return false);
|
||||
const QByteArray prefix = !data.isEmpty() ? QByteArray("echo " + data + " | ")
|
||||
: QByteArray("");
|
||||
QTC_CHECK(m_shell->readAllStandardOutput().isNull()); // clean possible left-overs
|
||||
|
||||
m_shell->readAllStandardOutput(); // clean possible left-overs
|
||||
m_shell->write(prefix + cmd.toUserOutput().toUtf8() + "\necho $?\n");
|
||||
const QByteArray prefix = !data.isEmpty()
|
||||
? QByteArray("echo '" + data.toBase64() + "' | base64 -d | ") : QByteArray("");
|
||||
const QByteArray suffix = QByteArray(" > /dev/null 2>&1\necho $?\n");
|
||||
const QByteArray command = prefix + cmd.toUserOutput().toUtf8() + suffix;
|
||||
|
||||
m_shell->write(command);
|
||||
DEBUG("RUN1 " << cmd.toUserOutput());
|
||||
m_shell->waitForReadyRead();
|
||||
const QByteArray output = m_shell->readAllStandardOutput();
|
||||
@@ -244,18 +247,19 @@ public:
|
||||
bool ok = false;
|
||||
const int result = output.toInt(&ok);
|
||||
LOG("Run command in shell:" << cmd.toUserOutput() << "result: " << output << " ==>" << result);
|
||||
return ok && result == 0;
|
||||
QTC_ASSERT(ok, return false);
|
||||
return !result;
|
||||
}
|
||||
|
||||
QByteArray outputForRunInShell(const QString &cmd)
|
||||
{
|
||||
QTC_ASSERT(m_shell, return {});
|
||||
QTC_CHECK(m_shell->readAllStandardOutput().isNull()); // clean possible left-overs
|
||||
|
||||
static int val = 0;
|
||||
const QByteArray delim = QString::number(++val, 16).toUtf8();
|
||||
|
||||
DEBUG("RUN2 " << cmd);
|
||||
m_shell->readAllStandardOutput(); // clean possible left-overs
|
||||
const QByteArray marker = "___QTC___" + delim + "_OUTPUT_MARKER___";
|
||||
DEBUG(" CMD: " << cmd.toUtf8() + "\necho " + marker + "\n");
|
||||
m_shell->write(cmd.toUtf8() + "\necho " + marker + "\n");
|
||||
@@ -342,11 +346,9 @@ LinuxDevice::LinuxDevice()
|
||||
proc->start();
|
||||
});
|
||||
|
||||
if (Utils::HostOsInfo::isAnyUnixHost()) {
|
||||
addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) {
|
||||
device->openTerminal(Environment(), FilePath());
|
||||
}});
|
||||
}
|
||||
addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) {
|
||||
device->openTerminal(Environment(), FilePath());
|
||||
}});
|
||||
}
|
||||
|
||||
LinuxDevice::~LinuxDevice()
|
||||
@@ -734,9 +736,6 @@ QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qin
|
||||
bool LinuxDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const
|
||||
{
|
||||
QTC_ASSERT(handlesFile(filePath), return {});
|
||||
|
||||
// This following would be the generic Unix solution.
|
||||
// But it doesn't pass input. FIXME: Why?
|
||||
return d->runInShell({"dd", {"of=" + filePath.path()}}, data);
|
||||
}
|
||||
|
||||
|
@@ -158,7 +158,7 @@ void WebAssemblyToolChain::registerToolChains()
|
||||
};
|
||||
|
||||
// Create new toolchains and register them
|
||||
ToolchainDetector detector({}, {});
|
||||
ToolchainDetector detector({}, {}, {});
|
||||
const Toolchains toolchains = doAutoDetect(detector);
|
||||
for (auto toolChain : toolchains)
|
||||
ToolChainManager::registerToolChain(toolChain);
|
||||
|
@@ -21,7 +21,7 @@
|
||||
:Add Bookmark.treeView_QTreeView {name='treeView' type='QTreeView' visible='1' window=':Add Bookmark_BookmarkDialog'}
|
||||
:Add Bookmark_BookmarkDialog {name='BookmarkDialog' type='BookmarkDialog' visible='1' windowTitle='Add Bookmark'}
|
||||
:Add to Version Control.No_QPushButton {text='No' type='QPushButton' unnamed='1' visible='1' window=':Add to Version Control_QMessageBox'}
|
||||
:Add to Version Control_QMessageBox {text~='Add the file.*to version control (.*)?' type='QMessageBox' unnamed='1' visible='1'}
|
||||
:Add to Version Control_QMessageBox {type='QMessageBox' unnamed='1' visible='1' windowTitle='Add to Version Control'}
|
||||
:Analyzer Toolbar.AnalyzerManagerToolBox_QComboBox {container=':DebugModeWidget.Toolbar_QDockWidget' name='PerspectiveChooser' type='QComboBox' visible='1'}
|
||||
:Analyzer Toolbar.Clear_QToolButton {container=':DebugModeWidget.Toolbar_QDockWidget' toolTip='Discard data' type='QToolButton' unnamed='1' visible='1'}
|
||||
:Analyzer Toolbar.Elapsed:_QLabel {container=':DebugModeWidget.Toolbar_QDockWidget' text~='Elapsed: \\\\d+.\\\\d s' type='QLabel' unnamed='1' visible='1'}
|
||||
|
@@ -42,7 +42,8 @@ def handleDebuggerWarnings(config, isMsvcBuild=False):
|
||||
clickButton(waitForObject("{text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Dialog_Debugger::Internal::SymbolPathsDialog'}", 10000))
|
||||
except LookupError:
|
||||
pass # No warning. Fine.
|
||||
if "Release" in config and (isMsvcBuild or platform.system() == "Linux"):
|
||||
isReleaseConfig = "Release" in config and not "with Debug Information" in config
|
||||
if isReleaseConfig and (isMsvcBuild or platform.system() == "Linux"):
|
||||
msgBox = "{type='QMessageBox' unnamed='1' visible='1' windowTitle='Warning'}"
|
||||
message = waitForObject("{name='qt_msgbox_label' type='QLabel' visible='1' window=%s}" % msgBox)
|
||||
messageText = str(message.text)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (C) 2016 The Qt Company Ltd.
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# Contact: https://www.qt.io/licensing/
|
||||
#
|
||||
# This file is part of Qt Creator.
|
||||
@@ -53,7 +53,7 @@ def main():
|
||||
checkCodeModelSettings(useClang)
|
||||
changeAutocompleteToManual(False)
|
||||
# Step 2: Open .cpp file in Edit mode.
|
||||
if not openDocument("SampleApp.Sources.main\\.cpp"):
|
||||
if not openDocument("SampleApp.SampleApp.Source Files.main\\.cpp"):
|
||||
test.fatal("Could not open main.cpp")
|
||||
invokeMenuItem("File", "Exit")
|
||||
return
|
||||
|
@@ -1,6 +1,6 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (C) 2016 The Qt Company Ltd.
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# Contact: https://www.qt.io/licensing/
|
||||
#
|
||||
# This file is part of Qt Creator.
|
||||
@@ -43,7 +43,7 @@ def main():
|
||||
createNewQtQuickApplication(tempDir(), "SampleApp")
|
||||
checkCodeModelSettings(useClang)
|
||||
# Step 2: Open .cpp file in Edit mode.
|
||||
if not openDocument("SampleApp.Sources.main\\.cpp"):
|
||||
if not openDocument("SampleApp.SampleApp.Source Files.main\\.cpp"):
|
||||
test.fatal("Could not open main.cpp")
|
||||
invokeMenuItem("File", "Exit")
|
||||
return
|
||||
|
@@ -1,6 +1,6 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (C) 2016 The Qt Company Ltd.
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# Contact: https://www.qt.io/licensing/
|
||||
#
|
||||
# This file is part of Qt Creator.
|
||||
@@ -26,9 +26,9 @@
|
||||
source("../../shared/qtcreator.py")
|
||||
|
||||
# test search in help mode and advanced search
|
||||
searchKeywordDictionary = { "abundance":True, "deplmint":False, "QODBC":True, "bldx":False }
|
||||
urlDictionary = { "abundance":"qthelp://com.trolltech.qt.487/qdoc/gettingstarted-develop.html",
|
||||
"QODBC":"qthelp://com.trolltech.qt.487/qdoc/sql-driver.html" }
|
||||
searchKeywordDictionary = { "compass":True, "deplmint":False, "QODBC":True, "bldx":False }
|
||||
urlDictionary = {"compass":"qthelp://org.qt-project.qtdoc.5141/qtdoc/mobiledevelopment.html",
|
||||
"QODBC":"qthelp://org.qt-project.qtsql.5141/qtsql/sql-driver.html" }
|
||||
|
||||
|
||||
def __getSelectedText__():
|
||||
@@ -69,8 +69,9 @@ def main():
|
||||
startQC()
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
if qt4Available:
|
||||
addHelpDocumentation([os.path.join(qt4Path, "doc", "qch", "qt.qch")])
|
||||
docFiles = ["qtdoc.qch", "qtsql.qch"]
|
||||
docFiles = [os.path.join(Qt5Path.docsPath(Targets.DESKTOP_5_14_1_DEFAULT), file) for file in docFiles]
|
||||
addHelpDocumentation(docFiles)
|
||||
# switch to help mode
|
||||
switchViewTo(ViewConstants.HELP)
|
||||
# verify that search widget is accessible
|
||||
@@ -87,9 +88,6 @@ def main():
|
||||
test.verify(waitFor("noMatch in "
|
||||
"str(resultWidget.plainText)", 2000),
|
||||
"Verifying if search did not match anything.")
|
||||
# workaround for "endless waiting cursor"
|
||||
mouseClick(waitForObject("{column='0' container=':Qt Creator_QHelpContentWidget' "
|
||||
"text='Qt Reference Documentation' type='QModelIndex'}"))
|
||||
# try to search keyword from list
|
||||
searchLineEdit = getChildByClass(waitForObject("{type='QHelpSearchQueryWidget' unnamed='1' visible='1' "
|
||||
"window=':Qt Creator_Core::Internal::MainWindow'}"),
|
||||
|
@@ -32,7 +32,7 @@ def startQtCreatorWithNewAppAtQMLEditor(projectDir, projectName, line = None):
|
||||
# create qt quick application
|
||||
createNewQtQuickApplication(projectDir, projectName)
|
||||
# open qml file
|
||||
qmlFile = projectName + ".Resources.qml\.qrc./.main\\.qml"
|
||||
qmlFile = "%s.%s.qml\.qrc./.main\\.qml" % (projectName, projectName)
|
||||
if not openDocument(qmlFile):
|
||||
test.fatal("Could not open %s" % qmlFile)
|
||||
invokeMenuItem("File", "Exit")
|
||||
|
@@ -59,7 +59,7 @@ def main():
|
||||
test.passes("Refactoring was properly applied in source file")
|
||||
else:
|
||||
test.fail("Refactoring of Text to MyComponent failed in source file. Content of editor:\n%s" % codeText)
|
||||
myCompTE = "SampleApp.Resources.qml\\.qrc./.MyComponent\\.qml"
|
||||
myCompTE = "SampleApp.SampleApp.qml\\.qrc./.MyComponent\\.qml"
|
||||
# there should be new QML file generated with name "MyComponent.qml"
|
||||
try:
|
||||
waitForObjectItem(":Qt Creator_Utils::NavigationTreeView", myCompTE, 5000)
|
||||
|
@@ -50,9 +50,10 @@ def main():
|
||||
'Waiter();'])
|
||||
# Rely on code completion for closing bracket
|
||||
invokeMenuItem("File", "Save All")
|
||||
openDocument(project + "." + project + "\\.pro")
|
||||
proEditor = waitForObject(":Qt Creator_TextEditor::TextEditorWidget")
|
||||
test.verify("CONFIG += c++11 console" in str(proEditor.plainText),
|
||||
openDocument(project + ".CMakeLists\\.txt")
|
||||
projectFileEditor = waitForObject(":Qt Creator_TextEditor::TextEditorWidget")
|
||||
projectFileContent = str(projectFileEditor.plainText)
|
||||
test.verify("Widgets" not in projectFileContent and "MACOSX_BUNDLE" not in projectFileContent,
|
||||
"Verifying that program is configured with console")
|
||||
|
||||
availableConfigs = iterateBuildConfigs()
|
||||
@@ -88,7 +89,7 @@ def main():
|
||||
|
||||
test.log("Debugging application")
|
||||
isMsvc = isMsvcConfig(kit)
|
||||
invokeMenuItem("Debug", "Start Debugging", "Start debugging of startup project")
|
||||
invokeMenuItem("Debug", "Start Debugging", "Start Debugging of Startup Project")
|
||||
handleDebuggerWarnings(config, isMsvc)
|
||||
ensureChecked(":Qt Creator_AppOutput_Core::Internal::OutputPaneToggleButton")
|
||||
outputWindow = waitForObject(":Qt Creator_Core::OutputWindow")
|
||||
|
@@ -37,7 +37,7 @@ def main():
|
||||
invokeMenuItem("File", "Exit")
|
||||
|
||||
def prepareQmlFile():
|
||||
if not openDocument("untitled.Resources.qml\.qrc./.main\\.qml"):
|
||||
if not openDocument("untitled.untitled.qml\\.qrc./.main\\.qml"):
|
||||
test.fatal("Could not open main.qml")
|
||||
return None
|
||||
editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
|
||||
|