Merge remote-tracking branch 'origin/7.0'

Conflicts:
	src/plugins/webassembly/webassemblytoolchain.cpp

Change-Id: Ia75c783e3ecab1f97de2b5c73a0979c49da82009
This commit is contained in:
Eike Ziller
2022-03-18 15:57:59 +01:00
52 changed files with 355 additions and 199 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -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

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -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.

View File

@@ -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:

View File

@@ -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

View File

@@ -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
}

View File

@@ -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()))) {

View File

@@ -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};

View File

@@ -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;

View File

@@ -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: {

View File

@@ -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)
}

View File

@@ -479,7 +479,8 @@ bool checkParameters(const QSsh::SshConnectionParameters &params)
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"

View File

@@ -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
*/

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -170,6 +170,8 @@ private: // functions
NodeInstance loadNode(const ModelNode &node);
void clearErrors();
void removeAllInstanceNodeRelationships();
void removeRecursiveChildRelationship(const ModelNode &removedNode);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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'}

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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'}"),

View File

@@ -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")

View File

@@ -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)

View File

@@ -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")

View File

@@ -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")