Merge remote-tracking branch 'origin/7.0'

Conflicts:
	src/plugins/android/androiddevice.cpp
	src/plugins/docker/dockerdevice.cpp

Change-Id: Id16ba0d9993c9f608242622aceae0a2a6691e05e
This commit is contained in:
Eike Ziller
2022-03-17 08:48:28 +01:00
47 changed files with 727 additions and 275 deletions

57
dist/changes-7.0.0.md vendored
View File

@@ -22,6 +22,8 @@ General
* Added `Tools > Debug Qt Creator > Show Logs` for viewing Qt Creator debug logs
* Moved C++ code model and language client inspectors to `Tools > Debug Qt
Creator`
* Fixed persistence of `Show Folders on Top` in `File System`
(QTCREATORBUG-27131)
Editing
-------
@@ -30,23 +32,33 @@ Editing
* Added support for choosing external editor as default editor
(QTCREATORBUG-13880)
* Fixed copy action in text editing macros (QTCREATORBUG-26363)
* Fixed cursor position after backspace and going up or down
(QTCREATORBUG-27035)
### C++
* Switched to LLVM 14 in binary packages
* Switched to Clangd by default (QTCREATORBUG-22917)
* Fixed that compilation errors appeared below code model errors in `Issues`
pane (QTCREATORBUG-23655)
* Fixed that duplication files did not adapt header guard (QTCREATORBUG-26654)
* Fixed highlighting and indentation of raw string literals (QTCREATORBUG-26211)
* Fixed performance issue in global indexer (QTCREATORBUG-26841)
* Fixed tiny refactoring icon on HiDPI screens (QTCREATORBUG-26905)
* Fixed dot to arrow conversion with extra characters (QTCREATORBUG-27034)
* clang-format
* Moved settings to `Code Style` editor
* Added synchronization between `clang-format` settings and custom code style
* Clangd
* Added support for parse contexts (QTCREATORBUG-27009)
* Added memory usage inspector to language client inspector
* Added highlighting of `Q_PROPERTY` declarations
* Improved display of diagnostic messages
* Fixed access type categorization for functions
* Fixed highlighting issues (QTCREATORBUG-27059, QTCREATORBUG-27111)
* Fixed generating `Q_PROPERTY` members (QTCREATORBUG-27063)
* Fixed display of outdated diagnostics (QTCREATORBUG-26585)
* Fixed that `Unknown argument` diagnostics were shown (QTCREATORBUG-27113)
### QML
@@ -64,6 +76,7 @@ Editing
(QTCREATORBUG-26624)
* Fixed that outdated diagnostic could be shown (QTCREATORBUG-26585)
* Fixed issue with re-highlighting (QTCREATORBUG-26624)
* Fixed crash when rapidly closing documents (QTCREATORBUG-26534)
### FakeVim
@@ -76,7 +89,11 @@ Projects
* Added multiple selection to `Issues` pane (QTCREATORBUG-25547,
QTCREATORBUG-26720)
* Improved automatic (re-)detection of toolchains (QTCREATORBUG-26460)
* Changed default C++ standard for project wizards to C++17 (QTCREATORBUG-27045)
* Fixed unnecessary toolchain calls at startup
* Fixed warning that file is not part of any project (QTCREATORBUG-26987)
* Fixed that leading spaces could break custom output parsers
(QTCREATORBUG-26892)
### CMake
@@ -92,6 +109,12 @@ Projects
* Added context menu actions for resolving mismatches between kit, initial and
current configuration
* Added `Help` to context menu for variable names
* Fixed that CMake was unnecessarily run after Kit update
* Fixed crash when Kit has no toolchain (QTCREATORBUG-26777)
### Qbs
* Fixed that `cpp.cFlags` and `cpp.cxxFlags` were not considered for code model
### Generic
@@ -101,6 +124,10 @@ Projects
* Fixed parsing of `SUBDIRS`
### Mercurial
* Fixed saving of settings (QTCREATORBUG-27091)
Debugging
---------
@@ -143,11 +170,23 @@ Test Integration
Platforms
---------
### Windows
* Fixed auto-detection of MinGW compiler (QTCREATORBUG-27057)
* Fixed missing compile `Issues` for MSVC (QTCREATORBUG-27056)
* Fixed wrong path separator when using `-client` (QTCREATORBUG-27075)
### Linux
* Added Wayland backend (QTCREATORBUG-26867)
### macOS
* Fixed that macOS dark mode was not used for dark themes (QTCREATORBUG-22477)
* Fixed that user applications inherited access permissions from Qt Creator
(QTCREATORBUG-26743)
* Fixed key repeat (QTCREATORBUG-26925)
* Fixed environment when opening `Terminal` with `zsh`
### Android
@@ -159,10 +198,14 @@ Platforms
(QTCREATORBUG-26709)
* Fixed detection of available NDK platforms for recent NDKs
(QTCREATORBUG-26772)
* Fixed naming of devices that are connected via USB and WiFi at the same time
* Fixed deployment if Kit fails to determine ABI (QTCREATORBUG-27103)
### Remote Linux
* Fixed UI state after stopping remote applications (QTCREATORBUG-26848)
* Fixed missing error message in `Application Output` when remote application
crashes (QTCREATORBUG-27007)
### WebAssembly
@@ -181,20 +224,26 @@ Platforms
Credits for these changes go to:
--------------------------------
Aaron Barany
Aleksei German
Alessandro Portale
Alexander Drozdov
Allan Sandfeld Jensen
Andre Hartmann
André Pönitz
Anton Alimoff
Antti Määttä
Artem Sokolovskii
Assam Boudjelthia
Björn Schäpers
Christiaan Janssen
Christian Kandeler
Christian Stenger
Christian Strømme
Cristian Adam
Cristián Maureira-Fredes
David Schulz
Eike Ziller
Erik Verbruggen
Fawzi Mohamed
Henning Gruendl
Huixiong Cao
@@ -209,20 +258,28 @@ Knud Dollereder
Leena Miettinen
Mahmoud Badri
Marco Bubke
Mats Honkamaa
Maximilian Goldstein
Miikka Heikkinen
Morten Johan Sørvig
Orgad Shaneh
Oswald Buddenhagen
Petar Perisin
Piotr Mikolajczyk
Piotr Mućko
Rafael Roquetto
Robert Löhning
Samuel Ghinet
Tapani Mattila
Tasuku Suzuki
Thiago Macieira
Thomas Hartmann
Tim Jenssen
Tony Leinonen
Topi Reinio
Tor Arne Vestbø
Tuomo Pelkonen
Ulf Hermann
Ville Nummela
Xiaofeng Wang
XutaxKamay

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -34,7 +34,7 @@
development. In this manual, we indicate which components are supported at
the time of writing.
To develop for MCUs, \l{Using Project Wizards}{create an MCU project}. Only
To develop for MCUs, \l{Creating a Project}{create an MCU project}. Only
the components available on MCUs are displayed in \l Components. Only a
subset of properties is supported for the supported components. The
properties that are not available on MCUs are marked in the \l Properties

View File

@@ -37,35 +37,27 @@
Creating a project enables you to:
\list
\li Group files together
\li Group files together.
\li Include \l{UI Files}{UI files} (.ui.qml), component files (.qml),
and assets files
\li Specify settings for previewing UIs
and assets files.
\li Specify settings for previewing UIs.
\endlist
Setting up a new project in \QDS is aided by a wizard that guides you
step-by-step through the project creation process. The wizard templates
prompt you to enter the settings needed for a particular type of project
and create the necessary files for you.
Setting up a new project in \QDS is aided by a wizard with a set of
presets that you can choose from. You can adjust project settings and save
custom presets. When you create a project, all necessary files are created.
To test how well your designs work, you can preview the
UIs on the desktop, embedded Linux devices, or Android devices. For more
information, see \l{Validating with Target Hardware}.
\image studio-project-wizards.png "A list of project wizards"
You can export designs from other design tools and import them to projects
or create them from scratch using the following wizard presets:
The following presets are available:
\table
\header
\li Category
\li Wizard Preset
\li Preset
\li Purpose
\row
\li Recents
\li
\li Lists the most recent presets that you have used.
\li Lists your most recently used presets.
\row
\li {1,2} General
\li Empty
@@ -100,15 +92,30 @@
\li Launcher
\li Creates a project that uses default components such as rectangles,
images, and text, and defines a launcher application.
\row
\li Custom
\li
\li Lists your saved custom presets.
\note This tab is not visible if there are no saved custom presets.
\endtable
\section1 Using Project Wizards
\image studio-project-wizards.png "The Create Project wizard"
To create a new project:
To test how well your designs work, you can preview the
UIs on the desktop, embedded Linux devices, or Android devices. For more
information, see \l{Validating with Target Hardware}.
You can export designs from other design tools and import them to projects.
For more information, see \l{Exporting from Design Tools} and
\l{Importing Designs From Other Design Tools}.
\section1 Creating a Project
To create a project:
\list 1
\li Select \uicontrol File > \uicontrol {New Project}.
\li In the \uicontrol Presets tab, select a wizard preset.
\li In the \uicontrol Presets tab, select a preset.
\li In the \uicontrol Details tab:
\list
\li Enter a name for the project. Keep in mind that projects
@@ -167,9 +174,24 @@
\uicontrol Assets > \inlineimage icons/plus.png
.
\section1 Using Custom Presets
You can save project settings as custom presets. All saved custom presets
are available on the \uicontrol Custom tab in the
\uicontrol {Create Project} wizard. You cannot modify custom presets once
you have created them.
To create a custom preset:
\list 1
\li In the \uicontrol {Create Project} wizard, set the details and style
that you want to use.
\li Select \uicontrol {Save Custom Preset} and give a name for the custom
preset.
\endlist
\section1 Adding Files to Projects
You can use wizard templates also to add individual files to projects.
You can use wizard templates to add individual files to projects.
The wizard templates in the \uicontrol {Qt Quick Controls} category create
stylable versions of the components in the \uicontrol {Qt Quick Controls}

View File

@@ -130,7 +130,7 @@
\li \l {Textures}{Texture} (four instances)
\endlist
We start by creating a \l{Using Project Wizards}{Qt Quick 3D Application}
We start by creating a \l{Creating a Project}{Qt Quick 3D Application}
project and adding the assets to it. We then follow the instructions above
to add the \uicontrol {Particle System} component instance, which provides
us with our first \uicontrol Emitter, \uicontrol {Sprite Particle}, and

View File

@@ -37,7 +37,7 @@ View3D {
function fitToViewPort()
{
// The magic number is the distance from camera default pos to origin
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, importScene, root,
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, sourceModel, root,
1040);
}
@@ -65,7 +65,7 @@ View3D {
Model {
id: model
source: sourceModel.source
source: _generalHelper.resolveAbsoluteSourceUrl(sourceModel)
geometry: sourceModel.geometry
materials: [

View File

@@ -42,6 +42,7 @@
#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
#include <QtQuick3DUtils/private/qssgbounds3_p.h>
#include <QtQuick3DUtils/private/qssgutils_p.h>
#include <QtQml/qqml.h>
#include <QtQuick/qquickwindow.h>
#include <QtQuick/qquickitem.h>
#include <QtCore/qmath.h>
@@ -93,6 +94,26 @@ QString GeneralHelper::generateUniqueName(const QString &nameRoot)
return QStringLiteral("%1_%2").arg(nameRoot).arg(count);
}
// Resolves absolute model source path
QUrl GeneralHelper::resolveAbsoluteSourceUrl(const QQuick3DModel *sourceModel)
{
if (!sourceModel)
return {};
const QUrl source = sourceModel->source();
if (source.hasFragment()) {
// Fragment is part of the url separated by '#', check if it is an index or primitive
bool isNumber = false;
source.fragment().toInt(&isNumber);
// If it wasn't an index, then it was a primitive and we can return it as-is
if (!isNumber)
return source;
}
QQmlContext *context = qmlContext(sourceModel);
return context ? context->resolvedUrl(source) : source;
}
void GeneralHelper::orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
const QVector3D &lookAtPoint, const QVector3D &pressPos,
const QVector3D &currentPos)

View File

@@ -33,6 +33,7 @@
#include <QPointer>
#include <QQuaternion>
#include <QTimer>
#include <QUrl>
#include <QVariant>
#include <QVector3D>
#include <QtQuick3D/private/qquick3dpickresult_p.h>
@@ -58,6 +59,7 @@ public:
Q_INVOKABLE void requestOverlayUpdate();
Q_INVOKABLE QString generateUniqueName(const QString &nameRoot);
Q_INVOKABLE QUrl resolveAbsoluteSourceUrl(const QQuick3DModel *sourceModel);
Q_INVOKABLE void orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
const QVector3D &lookAtPoint, const QVector3D &pressPos,

View File

@@ -1091,9 +1091,15 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
m_modelNode3DImageViewData.window->resize(renderSize);
m_modelNode3DImageViewData.rootItem->setSize(renderSize);
if (createdFromComponent) {
QMetaObject::invokeMethod(
m_modelNode3DImageViewData.rootItem, "createViewForNode",
Q_ARG(QVariant, objectToVariant(instanceObj)));
} else {
QMetaObject::invokeMethod(
m_modelNode3DImageViewData.rootItem, "createViewForObject",
Q_ARG(QVariant, objectToVariant(instanceObj)));
}
// Need to render twice, first render updates spatial nodes
for (int i = 0; i < 2; ++i) {

View File

@@ -204,11 +204,22 @@ Item {
font.weight: Font.DemiBold
font.pixelSize: DialogValues.viewHeaderPixelSize
verticalAlignment: Text.AlignVCenter
color: tabBarRow.currIndex === index ? DialogValues.textColorInteraction
color: {
var color = tabBarRow.currIndex === index
? DialogValues.textColorInteraction
: DialogValues.textColor
return tabItemMouseArea.containsMouse
? Qt.darker(color, 1.5)
: color
}
Behavior on color { ColorAnimation { duration: tabBar.animDur } }
MouseArea {
id: tabItemMouseArea
hoverEnabled: true
anchors.fill: parent
onClicked: {
tabBar.selectTab(index)

View File

@@ -286,12 +286,8 @@ Item {
realStepSize: 10
font.pixelSize: DialogValues.defaultPixelSize
onRealValueChanged: {
if (widthField.realValue >= heightField.realValue)
orientationButton.setHorizontal()
else
orientationButton.setVertical()
}
onRealValueChanged: orientationButton.isHorizontal =
widthField.realValue >= heightField.realValue
} // Width Text Field
Binding {
@@ -311,12 +307,8 @@ Item {
realStepSize: 10
font.pixelSize: DialogValues.defaultPixelSize
onRealValueChanged: {
if (widthField.realValue >= heightField.realValue)
orientationButton.setHorizontal()
else
orientationButton.setVertical()
}
onRealValueChanged: orientationButton.isHorizontal =
widthField.realValue >= heightField.realValue
} // Height Text Field
Binding {
@@ -327,69 +319,69 @@ Item {
Item { Layout.fillWidth: true }
Button {
Item {
id: orientationButton
implicitWidth: 100
implicitHeight: 50
checked: false
hoverEnabled: false
background: Rectangle {
width: parent.width
height: parent.height
color: "transparent"
property bool isHorizontal: false
Row {
Item {
width: orientationButton.width / 2
height: orientationButton.height
spacing: orientationButton.width / 4
function computeColor(barId) {
var color = DialogValues.textColor
if (barId === horizontalBar) {
color = orientationButton.isHorizontal
? DialogValues.textColorInteraction
: DialogValues.textColor
} else {
color = orientationButton.isHorizontal
? DialogValues.textColor
: DialogValues.textColorInteraction
}
if (orientationButtonMouseArea.containsMouse)
color = Qt.darker(color, 1.5)
return color
}
Rectangle {
id: horizontalBar
color: "white"
width: parent.width
color: parent.computeColor(horizontalBar)
width: orientationButton.width / 2
height: orientationButton.height / 2
anchors.verticalCenter: parent.verticalCenter
radius: 3
}
}
Item {
width: orientationButton.width / 4
height: orientationButton.height
}
Rectangle {
id: verticalBar
color: parent.computeColor(verticalBar)
width: orientationButton.width / 4
height: orientationButton.height
color: "white"
radius: 3
}
}
}
MouseArea {
id: orientationButtonMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (widthField.realValue && heightField.realValue) {
[widthField.realValue, heightField.realValue] = [heightField.realValue, widthField.realValue]
orientationButton.checked = !orientationButton.checked
if (widthField.realValue === heightField.realValue)
orientationButton.checked ? setVertical() : setHorizontal()
orientationButton.isHorizontal = !orientationButton.isHorizontal
else
orientationButton.isHorizontal = widthField.realValue > heightField.realValue
}
}
function setHorizontal() {
orientationButton.checked = false
horizontalBar.color = DialogValues.textColorInteraction
verticalBar.color = "white"
}
function setVertical() {
orientationButton.checked = true
horizontalBar.color = "white"
verticalBar.color = DialogValues.textColorInteraction
}
} // Orientation button
} // GridLayout: orientation + width + height
Rectangle {
@@ -507,6 +499,8 @@ Item {
presetNameTextField.text = text.trim()
presetNameTextField.text = text.replace(/\s+/g, " ")
}
onAccepted: savePresetDialog.accept()
}
Binding {

View File

@@ -160,8 +160,17 @@ Item {
+ 2 * DialogValues.styleImageBorderWidth
height: DialogValues.styleImageHeight
+ 2 * DialogValues.styleImageBorderWidth
border.color: index === stylesList.currentIndex ? DialogValues.textColorInteraction : "transparent"
border.width: index === stylesList.currentIndex ? DialogValues.styleImageBorderWidth : 0
border.color: itemRectMouseArea.containsMouse
? DialogValues.textColor
: (index === stylesList.currentIndex
? DialogValues.textColorInteraction
: "transparent")
border.width: index === stylesList.currentIndex || itemRectMouseArea.containsMouse
? DialogValues.styleImageBorderWidth
: 0
color: "transparent"
Image {
@@ -173,6 +182,12 @@ Item {
asynchronous: false
source: "image://newprojectdialog_library/" + BackendApi.styleModel.iconId(model.index)
}
MouseArea {
id: itemRectMouseArea
anchors.fill: parent
hoverEnabled: true
}
} // Rectangle
Text {

View File

@@ -1,12 +1,12 @@
cmake_minimum_required(VERSION 3.18)
project(%{ProjectName} LANGUAGES CXX)
project(%{ProjectName}App LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt6 COMPONENTS Gui Qml Quick)
add_executable(%{ProjectExecutableName} src/main.cpp)
qt_add_executable(%{ProjectExecutableName} src/main.cpp)
qt_add_resources(%{ProjectExecutableName} "configuration"
PREFIX "/"

View File

@@ -84,7 +84,7 @@ bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (data(index, role) != value) {
// FIXME: Implement me!
emit dataChanged(index, index, QVector<int>() << role);
emit dataChanged(index, index, {role});
return true;
}
return false;
@@ -95,7 +95,7 @@ Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEditable; // FIXME: Implement me!
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; // FIXME: Implement me!
}
@endif
@if %{AddData}
@@ -105,6 +105,7 @@ bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
beginInsertRows(parent, row, row + count - 1);
// FIXME: Implement me!
endInsertRows();
return true;
}
bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
@@ -112,6 +113,7 @@ bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
beginInsertColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endInsertColumns();
return true;
}
@endif
@if %{RemoveData}
@@ -121,6 +123,7 @@ bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
beginRemoveRows(parent, row, row + count - 1);
// FIXME: Implement me!
endRemoveRows();
return true;
}
bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
@@ -128,6 +131,7 @@ bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
beginRemoveColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endRemoveColumns();
return true;
}
@endif
%{JS: Cpp.closeNamespaces('%{Class}')}\

View File

@@ -68,7 +68,7 @@ bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (data(index, role) != value) {
// FIXME: Implement me!
emit dataChanged(index, index, QVector<int>() << role);
emit dataChanged(index, index, {role});
return true;
}
return false;
@@ -79,7 +79,7 @@ Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEditable; // FIXME: Implement me!
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; // FIXME: Implement me!
}
@endif
@if %{AddData}
@@ -89,6 +89,7 @@ bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
beginInsertRows(parent, row, row + count - 1);
// FIXME: Implement me!
endInsertRows();
return true;
}
@endif
@if %{RemoveData}
@@ -98,6 +99,7 @@ bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
beginRemoveRows(parent, row, row + count - 1);
// FIXME: Implement me!
endRemoveRows();
return true;
}
@endif
%{JS: Cpp.closeNamespaces('%{Class}')}\

View File

@@ -75,7 +75,7 @@ bool %{CN}::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (data(index, role) != value) {
// FIXME: Implement me!
emit dataChanged(index, index, QVector<int>() << role);
emit dataChanged(index, index, {role});
return true;
}
return false;
@@ -86,7 +86,7 @@ Qt::ItemFlags %{CN}::flags(const QModelIndex &index) const
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEditable; // FIXME: Implement me!
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; // FIXME: Implement me!
}
@endif
@if %{AddData}
@@ -96,6 +96,7 @@ bool %{CN}::insertRows(int row, int count, const QModelIndex &parent)
beginInsertRows(parent, row, row + count - 1);
// FIXME: Implement me!
endInsertRows();
return true;
}
bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
@@ -103,6 +104,7 @@ bool %{CN}::insertColumns(int column, int count, const QModelIndex &parent)
beginInsertColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endInsertColumns();
return true;
}
@endif
@if %{RemoveData}
@@ -112,6 +114,7 @@ bool %{CN}::removeRows(int row, int count, const QModelIndex &parent)
beginRemoveRows(parent, row, row + count - 1);
// FIXME: Implement me!
endRemoveRows();
return true;
}
bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
@@ -119,6 +122,7 @@ bool %{CN}::removeColumns(int column, int count, const QModelIndex &parent)
beginRemoveColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endRemoveColumns();
return true;
}
@endif
%{JS: Cpp.closeNamespaces('%{Class}')}\

View File

@@ -281,11 +281,11 @@ Utils::optional<Utils::variant<QString, bool> >
ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::changeNotifications() const
{
using RetType = Utils::variant<QString, bool>;
const QJsonValue &provider = value(implementationProviderKey);
if (provider.isUndefined())
const QJsonValue &change = value(changeNotificationsKey);
if (change.isUndefined())
return Utils::nullopt;
return Utils::make_optional(provider.isBool() ? RetType(provider.toBool())
: RetType(provider.toString()));
return Utils::make_optional(change.isBool() ? RetType(change.toBool())
: RetType(change.toString()));
}
void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::setChangeNotifications(

View File

@@ -4,7 +4,13 @@ Project {
name: "QtcSsh"
QtcLibrary {
cpp.defines: base.concat("QTCSSH_LIBRARY")
cpp.defines: {
var defines = base;
defines.push("QTCSSH_LIBRARY");
if (project.withAutotests && !defines.contains("WITH_TESTS"))
defines.push("WITH_TESTS");
return defines;
}
cpp.enableExceptions: true
Depends { name: "Qt"; submodules: ["widgets", "network" ] }

View File

@@ -404,4 +404,95 @@ SftpTransferPtr SshConnection::setupTransfer(
d->connectionArgs(SshSettings::sftpFilePath())));
}
#ifdef WITH_TESTS
namespace SshTest {
const QString getHostFromEnvironment()
{
const QString host = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_HOST"));
if (host.isEmpty() && qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
return QString("127.0.0.1");
return host;
}
quint16 getPortFromEnvironment()
{
const int port = qEnvironmentVariableIntValue("QTC_SSH_TEST_PORT");
return port != 0 ? quint16(port) : 22;
}
const QString getUserFromEnvironment()
{
return QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_USER"));
}
const QString getKeyFileFromEnvironment()
{
const FilePath defaultKeyFile = FileUtils::homePath() / ".ssh/id_rsa";
const QString keyFile = QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_KEYFILE"));
if (keyFile.isEmpty()) {
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
return defaultKeyFile.toString();
}
return keyFile;
}
const QString userAtHost()
{
QString userMidFix = getUserFromEnvironment();
if (!userMidFix.isEmpty())
userMidFix.append('@');
return userMidFix + getHostFromEnvironment();
}
SshConnectionParameters getParameters()
{
SshConnectionParameters params;
if (!qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS")) {
params.setUserName(getUserFromEnvironment());
params.privateKeyFile = Utils::FilePath::fromUserInput(getKeyFileFromEnvironment());
}
params.setHost(getHostFromEnvironment());
params.setPort(getPortFromEnvironment());
params.timeout = 10;
params.authenticationType = !params.privateKeyFile.isEmpty()
? QSsh::SshConnectionParameters::AuthenticationTypeSpecificKey
: QSsh::SshConnectionParameters::AuthenticationTypeAll;
return params;
}
bool checkParameters(const QSsh::SshConnectionParameters &params)
{
if (qEnvironmentVariableIsSet("QTC_SSH_TEST_DEFAULTS"))
return true;
if (params.host().isEmpty()) {
qWarning("No hostname provided. Set QTC_SSH_TEST_HOST.");
return false;
}
if (params.userName().isEmpty())
qWarning("No user name provided - test may fail with empty default. Set QTC_SSH_TEST_USER.");
if (params.privateKeyFile.isEmpty()) {
qWarning("No key file provided. Set QTC_SSH_TEST_KEYFILE.");
return false;
}
return true;
}
void printSetupHelp()
{
qInfo() << "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"
" ssh-keygen -t ecdsa\n"
"3. Make your public key known to the server (needed only once):\n"
" ssh-copy-id -i [full path to your public key] [user@host]\n"
"4. Set the env variables before executing test:\n"
" QTC_SSH_TEST_HOST=127.0.0.1\n"
" QTC_SSH_TEST_KEYFILE=[full path to your private key]\n"
" QTC_SSH_TEST_USER=[your user name]\n";
}
} // namespace SshTest
#endif
} // namespace QSsh

View File

@@ -139,6 +139,19 @@ private:
SshConnectionPrivate * const d;
};
#ifdef WITH_TESTS
namespace SshTest {
const QString QSSH_EXPORT getHostFromEnvironment();
quint16 QSSH_EXPORT getPortFromEnvironment();
const QString QSSH_EXPORT getUserFromEnvironment();
const QString QSSH_EXPORT getKeyFileFromEnvironment();
const QSSH_EXPORT QString userAtHost();
SshConnectionParameters QSSH_EXPORT getParameters();
bool QSSH_EXPORT checkParameters(const SshConnectionParameters &params);
void QSSH_EXPORT printSetupHelp();
} // namespace SshTest
#endif
} // namespace QSsh
Q_DECLARE_METATYPE(QSsh::SshConnectionParameters::AuthenticationType)

View File

@@ -88,7 +88,7 @@ const QMetaObject *TipLabel::metaObject() const
struct qt_meta_stringdata_Utils_t {
const uint offsetsAndSize[2];
char stringdata0[24];
} qt_meta_stringdata = { 8, sizeof("QTipLabel"), "QTipLabel" };
} qt_meta_stringdata = { {8, sizeof("QTipLabel")}, "QTipLabel" };
static const QMetaObject tipMetaObject {
&QLabel::staticMetaObject, // SuperData superdata

View File

@@ -624,7 +624,7 @@ void AndroidDeviceManager::HandleAvdsListChange()
}
QVector<Id> connectedDevs;
for (auto item : m_avdsFutureWatcher.result()) {
for (const AndroidDeviceInfo &item : m_avdsFutureWatcher.result()) {
const Utils::Id deviceId = AndroidDevice::idFromDeviceInfo(item);
const QString displayName = AndroidDevice::displayNameFromInfo(item);
IDevice::ConstPtr dev = devMgr->find(deviceId);

View File

@@ -51,6 +51,7 @@
#include <utils/environment.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/infolabel.h>
#include <utils/layoutbuilder.h>
#include <utils/overridecursor.h>
#include <utils/pathlisteditor.h>
@@ -324,13 +325,26 @@ public:
data.useLocalUidGid = on;
});
m_pathsListLabel = new InfoLabel(tr("Paths to mount:"));
// FIXME: 8.0: use
//m_pathsListLabel->setToolTip(tr("Source directory list should not be empty"));
m_pathsListEdit = new PathListEditor;
// FIXME: 8.0: use
//m_pathsListEdit->setPlaceholderText(tr("Host directories to mount into the container"));
m_pathsListEdit->setToolTip(tr("Maps paths in this list one-to-one to the "
"docker container."));
m_pathsListEdit->setPathList(data.mounts);
connect(m_pathsListEdit, &PathListEditor::changed, this, [dockerDevice, this]() {
auto markupMounts = [this] {
const bool isEmpty = m_pathsListEdit->pathList().isEmpty();
m_pathsListLabel->setType(isEmpty ? InfoLabel::Warning : InfoLabel::None);
};
markupMounts();
connect(m_pathsListEdit, &PathListEditor::changed, this, [dockerDevice, markupMounts, this] {
dockerDevice->setMounts(m_pathsListEdit->pathList());
markupMounts();
});
auto logView = new QTextBrowser;
@@ -346,6 +360,8 @@ public:
searchDirsComboBox->addItem(tr("Search in Selected Directories"));
auto searchDirsLineEdit = new FancyLineEdit;
// FIXME: 8.0: use
//searchDirsLineEdit->setPlaceholderText(tr("Semicolon-separated list of directories"));
searchDirsLineEdit->setToolTip(
tr("Select the paths in the docker image that should be scanned for kit entries."));
searchDirsLineEdit->setHistoryCompleter("DockerMounts", true);
@@ -397,7 +413,7 @@ public:
daemonStateLabel, m_daemonReset, m_daemonState, Break(),
m_runAsOutsideUser, Break(),
Column {
new QLabel(tr("Paths to mount:")),
m_pathsListLabel,
m_pathsListEdit,
}, Break(),
Column {
@@ -437,7 +453,8 @@ private:
QToolButton *m_daemonReset;
QLabel *m_daemonState;
QCheckBox *m_runAsOutsideUser;
Utils::PathListEditor *m_pathsListEdit;
InfoLabel *m_pathsListLabel;
PathListEditor *m_pathsListEdit;
KitDetector m_kitItemDetector;
};
@@ -1545,12 +1562,19 @@ public:
m_log = new QTextBrowser;
m_log->setVisible(false);
const QString fail = QString{"Docker: "}
+ QCoreApplication::translate("Debugger::Internal::GdbEngine",
"Process failed to start.");
auto errorLabel = new Utils::InfoLabel(fail, Utils::InfoLabel::Error, this);
errorLabel->setVisible(false);
m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
using namespace Layouting;
Column {
m_view,
m_log,
errorLabel,
m_buttons,
}.attachTo(this);
@@ -1588,6 +1612,13 @@ public:
m_log->append(DockerDevice::tr("Error: %1").arg(out));
});
connect(m_process, &Utils::QtcProcess::finished,
this, [this, errorLabel]() {
if (m_process->exitCode() != 0) {
errorLabel->setVisible(true);
}
});
connect(m_view->selectionModel(), &QItemSelectionModel::selectionChanged, [this] {
const QModelIndexList selectedRows = m_view->selectionModel()->selectedRows();
QTC_ASSERT(selectedRows.size() == 1, return);

View File

@@ -281,4 +281,20 @@ bool NavigatorTreeView::viewportEvent(QEvent *event)
return QTreeView::viewportEvent(event);
}
void NavigatorTreeView::mousePressEvent(QMouseEvent *event)
{
// Block drag from starting if press was on an item that is not draggable.
// This is necessary as it is the selected items that are dragged and the pressed item may not
// be a selected item, e.g. when pressing on locked item, leading to unexpected drags.
m_dragAllowed = model()->flags(indexAt(event->pos())) & Qt::ItemIsDragEnabled;
QTreeView::mousePressEvent(event);
}
void NavigatorTreeView::startDrag(Qt::DropActions supportedActions)
{
if (m_dragAllowed)
QTreeView::startDrag(supportedActions);
}
}

View File

@@ -40,8 +40,13 @@ public:
static void drawSelectionBackground(QPainter *painter, const QStyleOption &option);
bool viewportEvent(QEvent *event) override;
protected:
void mousePressEvent(QMouseEvent *event) override;
void startDrag(Qt::DropActions supportedActions) override;
private:
PreviewToolTip *m_previewToolTip = nullptr;
qint32 m_previewToolTipNodeId = -1;
bool m_dragAllowed = true;
};
}

View File

@@ -32,9 +32,9 @@
#include <coreplugin/messagebox.h>
#include "pluginmanager/widgetpluginmanager.h"
#include <QDebug>
#include <QMessageBox>
#include <QMutex>
enum {
debug = false
@@ -107,6 +107,7 @@ void MetaInfoPrivate::parseItemLibraryDescriptions()
using QmlDesigner::Internal::MetaInfoPrivate;
MetaInfo MetaInfo::s_global;
QMutex s_lock;
QStringList MetaInfo::s_pluginDirs;
@@ -157,6 +158,8 @@ ItemLibraryInfo *MetaInfo::itemLibraryInfo() const
*/
MetaInfo MetaInfo::global()
{
QMutexLocker locker(&s_lock);
if (!s_global.m_p->m_isInitialized) {
s_global.m_p = QSharedPointer<MetaInfoPrivate>(new MetaInfoPrivate(&s_global));
s_global.m_p->initialize();

View File

@@ -42,19 +42,23 @@ enum FoundLicense {
enterprise
};
FoundLicense checkLicense() {
namespace Internal {
ExtensionSystem::IPlugin *licenseCheckerPlugin()
{
const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(
ExtensionSystem::PluginManager::plugins(),
Utils::equal(&ExtensionSystem::PluginSpec::name, QString("LicenseChecker")));
if (!pluginSpec)
return community;
if (pluginSpec)
return pluginSpec->plugin();
return nullptr;
}
} // namespace Internal
ExtensionSystem::IPlugin *plugin = pluginSpec->plugin();
if (!plugin)
return community;
FoundLicense checkLicense()
{
if (auto plugin = Internal::licenseCheckerPlugin()) {
bool retVal = false;
bool success = QMetaObject::invokeMethod(plugin,
"qdsEnterpriseLicense",
@@ -62,7 +66,24 @@ FoundLicense checkLicense() {
Q_RETURN_ARG(bool, retVal));
if (success && retVal)
return enterprise;
else
return professional;
}
return community;
}
QString licensee()
{
if (auto plugin = Internal::licenseCheckerPlugin()) {
QString retVal;
bool success = QMetaObject::invokeMethod(plugin,
"licensee",
Qt::DirectConnection,
Q_RETURN_ARG(QString, retVal));
if (success)
return retVal;
}
return {};
}
} // namespace Utils

View File

@@ -35,6 +35,7 @@
#include "qmldesignerconstants.h"
#include "qmldesignerprojectmanager.h"
#include "settingspage.h"
#include "dynamiclicensecheck.h"
#include <metainfo.h>
#include <connectionview.h>
@@ -312,14 +313,24 @@ bool QmlDesignerPlugin::delayedInitialize()
d->viewManager.registerFormEditorTool(std::make_unique<QmlDesigner::TransitionTool>());
if (QmlProjectManager::QmlProject::isQtDesignStudio()) {
d->mainWidget.initialize();
emitUsageStatistics("StandaloneMode");
if (QmlProjectManager::QmlProject::isQtDesignStudioStartedFromQtC())
emitUsageStatistics("QDSlaunchedFromQtC");
emitUsageStatistics("QDSstartupCount");
FoundLicense license = checkLicense();
if (license == FoundLicense::enterprise)
Core::ICore::appendAboutInformation(tr("License: Enterprise"));
else if (license == FoundLicense::professional)
Core::ICore::appendAboutInformation(tr("License: Professional"));
if (!licensee().isEmpty())
Core::ICore::appendAboutInformation(tr("Licensee: %1").arg(licensee()));
}
if (QmlProjectManager::QmlProject::isQtDesignStudio())
d->mainWidget.initialize();
MetaInfo::global();
return true;
}

View File

@@ -210,7 +210,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
QmlJS::ModelManagerInterface *modelManager
= QmlJS::ModelManagerInterface::instance();
if (!editor)
if (!editor || !modelManager)
return;
if (d->lastMessageBox)

View File

@@ -41,10 +41,12 @@ using namespace Utils;
namespace RemoteLinux {
namespace Internal {
static const char TEST_IP[] = "127.0.0.1";
static const char TEST_DIR[] = "/tmp/testdir";
static const FilePath baseFilePath = FilePath::fromString("ssh://" + QString(TEST_IP)
+ QString(TEST_DIR));
static const FilePath baseFilePath()
{
return FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + QString(TEST_DIR));
}
TestLinuxDeviceFactory::TestLinuxDeviceFactory()
: IDeviceFactory("test")
@@ -54,11 +56,9 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
setConstructionFunction(&LinuxDevice::create);
setCreator([] {
LinuxDevice::Ptr newDev = LinuxDevice::create();
qDebug() << "device : " << newDev->type();
newDev->setType("test");
QSsh::SshConnectionParameters sshParams = newDev->sshParameters();
sshParams.setHost(TEST_IP);
sshParams.setPort(22);
qDebug() << "device : " << newDev->type();
QSsh::SshConnectionParameters sshParams = QSsh::SshTest::getParameters();
newDev->setSshParameters(sshParams);
return newDev;
});
@@ -66,15 +66,28 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
FilePath createFile(const QString &name)
{
FilePath testFilePath = baseFilePath / name;
FilePath dummyFilePath = FilePath::fromString("ssh://" + QString(TEST_IP) + "/dev/null");
FilePath testFilePath = baseFilePath() / name;
FilePath dummyFilePath = FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + "/dev/null");
dummyFilePath.copyFile(testFilePath);
return testFilePath;
}
void FileSystemAccessTest::initTestCase()
{
FilePath filePath = baseFilePath;
const QSsh::SshConnectionParameters params = QSsh::SshTest::getParameters();
qDebug() << "Using following SSH parameter:"
<< "\nHost:" << params.host()
<< "\nPort:" << params.port()
<< "\nUser:" << params.userName()
<< "\nSSHKey:" << params.privateKeyFile;
if (!QSsh::SshTest::checkParameters(params)) {
m_skippedAtWhole = true;
QSsh::SshTest::printSetupHelp();
QSKIP("Ensure you have added your default ssh public key to your own authorized keys and "
"environment QTC_REMOTELINUX_SSH_DEFAULTS set or follow setup help above.");
return;
}
FilePath filePath = baseFilePath();
if (DeviceManager::deviceForPath(filePath) == nullptr) {
DeviceManager *const devMgr = DeviceManager::instance();
@@ -87,13 +100,15 @@ void FileSystemAccessTest::initTestCase()
void FileSystemAccessTest::cleanupTestCase()
{
QVERIFY(baseFilePath.exists());
QVERIFY(baseFilePath.removeRecursively());
if (m_skippedAtWhole) // no need to clean up either
return;
QVERIFY(baseFilePath().exists());
QVERIFY(baseFilePath().removeRecursively());
}
void FileSystemAccessTest::testDirStatuses()
{
FilePath filePath = baseFilePath;
FilePath filePath = baseFilePath();
QVERIFY(filePath.exists());
QVERIFY(filePath.isDir());
QVERIFY(filePath.isWritableDir());
@@ -120,7 +135,7 @@ void FileSystemAccessTest::testDirStatuses()
void FileSystemAccessTest::testBytesAvailable()
{
FilePath testFilePath = FilePath::fromString("ssh://" + QString(TEST_IP) + "/tmp");
FilePath testFilePath = FilePath::fromString("ssh://" + QSsh::SshTest::userAtHost() + "/tmp");
QVERIFY(testFilePath.exists());
QVERIFY(testFilePath.bytesAvailable() > 0);
}
@@ -143,9 +158,9 @@ void FileSystemAccessTest::testFileActions()
// ToDo: remove ".contains", make fileContents exact equal content
QVERIFY(testFilePath.fileContents().contains(content));
QVERIFY(testFilePath.renameFile(baseFilePath / "test1"));
QVERIFY(testFilePath.renameFile(baseFilePath() / "test1"));
// It is Ok that FilePath doesn't change itself after rename.
FilePath newTestFilePath = baseFilePath / "test1";
FilePath newTestFilePath = baseFilePath() / "test1";
QVERIFY(newTestFilePath.exists());
QVERIFY(!testFilePath.removeFile());
QVERIFY(newTestFilePath.exists());

View File

@@ -53,6 +53,7 @@ private slots:
private:
TestLinuxDeviceFactory m_testLinuxDeviceFactory;
bool m_skippedAtWhole = false;
};
} // Internal

View File

@@ -61,4 +61,9 @@ void SnippetEditorWidget::focusOutEvent(QFocusEvent *event)
TextEditorWidget::focusOutEvent(event);
}
void SnippetEditorWidget::contextMenuEvent(QContextMenuEvent *e)
{
QPlainTextEdit::contextMenuEvent(e);
}
} // namespace

View File

@@ -42,6 +42,7 @@ signals:
protected:
void focusOutEvent(QFocusEvent *event) override;
void contextMenuEvent(QContextMenuEvent *e) override;
int extraAreaWidth(int * /* markWidthPtr */ = nullptr) const override { return 0; }
};

View File

@@ -3,6 +3,7 @@ file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_L
add_qtc_test(tst_ssh
DEFINES "TEST_RELATIVE_LIBEXEC_PATH=\"${TEST_RELATIVE_LIBEXEC_PATH}\""
WITH_TESTS
DEPENDS Utils QtcSsh
SOURCES tst_ssh.cpp
)

View File

@@ -11,6 +11,7 @@ QtcAutotest {
qtc.ide_libexec_path);
var relLibExecPath = FileInfo.relativePath(destinationDirectory, absLibExecPath);
defines.push('TEST_RELATIVE_LIBEXEC_PATH="' + relLibExecPath + '"');
defines.push("WITH_TESTS");
return defines;
}
}

View File

@@ -47,73 +47,8 @@
#include <cstdlib>
/*
In order to run this test properly it requires some setup (example for fedora):
1. Run a server:
systemctl start sshd
2. Create your own ssh key (needed only once). For fedora it needs ecdsa type:
ssh-keygen -t ecdsa
3. Make your public key known to the server (needed only once):
ssh-copy-id -i [full path to your public key]
4. Set the env variables before executing test:
QTC_SSH_TEST_HOST=127.0.0.1
QTC_SSH_TEST_KEYFILE=[full path to your private key]
QTC_SSH_TEST_USER=[your user name]
*/
using namespace QSsh;
static QString getHostFromEnvironment()
{
return QString::fromLocal8Bit(qgetenv("QTC_SSH_TEST_HOST"));
}
static const char *portVar() { return "QTC_SSH_TEST_PORT"; }
static const char *userVar() { return "QTC_SSH_TEST_USER"; }
static const char *keyFileVar() { return "QTC_SSH_TEST_KEYFILE"; }
static quint16 getPortFromEnvironment()
{
const int port = qEnvironmentVariableIntValue(portVar());
return port != 0 ? quint16(port) : 22;
}
static QString getUserFromEnvironment()
{
return QString::fromLocal8Bit(qgetenv(userVar()));
}
static QString getKeyFileFromEnvironment()
{
return QString::fromLocal8Bit(qgetenv(keyFileVar()));
}
static SshConnectionParameters getParameters()
{
SshConnectionParameters params;
params.setHost(getHostFromEnvironment());
params.setPort(getPortFromEnvironment());
params.setUserName(getUserFromEnvironment());
params.timeout = 10;
params.privateKeyFile = Utils::FilePath::fromUserInput(getKeyFileFromEnvironment());
params.authenticationType = !params.privateKeyFile.isEmpty()
? SshConnectionParameters::AuthenticationTypeSpecificKey
: SshConnectionParameters::AuthenticationTypeAll;
return params;
}
#define CHECK_PARAMS(params) \
do { \
if (params.host().isEmpty()) { \
QSKIP("No hostname provided. Set QTC_SSH_TEST_HOST."); \
} \
if (params.userName().isEmpty()) \
QSKIP(qPrintable(QString::fromLatin1("No user name provided. Set %1.") \
.arg(QString::fromUtf8(userVar())))); \
if (params.privateKeyFile.isEmpty()) \
QSKIP(qPrintable(QString::fromLatin1("No key file provided. Set %1.") \
.arg(QString::fromUtf8(keyFileVar())))); \
} while (false)
class tst_Ssh : public QObject
{
Q_OBJECT
@@ -137,6 +72,10 @@ private:
void tst_Ssh::initTestCase()
{
const SshConnectionParameters params = SshTest::getParameters();
if (!SshTest::checkParameters(params))
SshTest::printSetupHelp();
Utils::LauncherInterface::setPathToLauncher(qApp->applicationDirPath() + '/'
+ QLatin1String(TEST_RELATIVE_LIBEXEC_PATH));
Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath()
@@ -154,10 +93,10 @@ void tst_Ssh::errorHandling_data()
QTest::newRow("no host")
<< QString("hgdfxgfhgxfhxgfchxgcf") << quint16(12345)
<< SshConnectionParameters::AuthenticationTypeAll << QString("egal") << QString();
const QString theHost = getHostFromEnvironment();
const QString theHost = SshTest::getHostFromEnvironment();
if (theHost.isEmpty())
return;
const quint16 thePort = getPortFromEnvironment();
const quint16 thePort = SshTest::getPortFromEnvironment();
QTest::newRow("non-existing key file")
<< theHost << thePort << SshConnectionParameters::AuthenticationTypeSpecificKey
<< QString("root") << QString("somefilenamethatwedontexpecttocontainavalidkey");
@@ -228,8 +167,9 @@ void tst_Ssh::remoteProcess_data()
void tst_Ssh::remoteProcess()
{
const SshConnectionParameters params = getParameters();
CHECK_PARAMS(params);
const SshConnectionParameters params = SshTest::getParameters();
if (!SshTest::checkParameters(params))
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
QFETCH(QByteArray, commandLine);
QFETCH(bool, isBlocking);
@@ -287,8 +227,9 @@ void tst_Ssh::remoteProcess()
void tst_Ssh::remoteProcessChannels()
{
const SshConnectionParameters params = getParameters();
CHECK_PARAMS(params);
const SshConnectionParameters params = SshTest::getParameters();
if (!SshTest::checkParameters(params))
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
SshConnection connection(params);
QVERIFY(waitForConnection(connection));
@@ -325,8 +266,9 @@ void tst_Ssh::remoteProcessChannels()
void tst_Ssh::remoteProcessInput()
{
const SshConnectionParameters params = getParameters();
CHECK_PARAMS(params);
const SshConnectionParameters params = SshTest::getParameters();
if (!SshTest::checkParameters(params))
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
SshConnection connection(params);
QVERIFY(waitForConnection(connection));
@@ -369,8 +311,9 @@ void tst_Ssh::remoteProcessInput()
void tst_Ssh::sftp()
{
// Connect to server
const SshConnectionParameters params = getParameters();
CHECK_PARAMS(params);
const SshConnectionParameters params = SshTest::getParameters();
if (!SshTest::checkParameters(params))
QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables.");
SshConnection connection(params);
QVERIFY(waitForConnection(connection));

View File

@@ -28,9 +28,15 @@
uid=$(id -u)
gid=$(id -g)
repo=b2qt-qemuarm64
tag=6.0.0
tcdir=/opt/toolchain
envfile=environment-setup-skylake-64-poky-linux
qtcconf=configure-qtcreator.sh
if [ ! -e toolchain.sh ]; then
host=http://ci-files02-hki.intra.qt.io
dir=/packages/jenkins/enterprise/b2qt/yocto/6.2/
dir=/packages/jenkins/enterprise/b2qt/yocto/dev/intel-skylake-64
file=b2qt-x86_64-meta-toolchain-b2qt-embedded-qt6-sdk-intel-skylake-64.sh
curl $host/$dir/$file -o $file || exit 1
ln -s $file toolchain.sh
@@ -38,4 +44,118 @@ fi
sed -e "s/<UID>/${uid}/" -e "s/<GID>/${gid}/" Dockerfile.in > Dockerfile
docker build -f Dockerfile . -t b2qt-qemuarm64:6.0.0
docker build -f Dockerfile . -t $repo:$tag
ABI="x86-linux-poky-elf-64bit"
OECORE_NATIVE_SYSROOT=/opt/toolchain/sysroots/x86_64-pokysdk-linux
PREFIX="docker://$repo:$tag/opt/toolchain/sysroots/x86_64-pokysdk-linux"
CC="${PREFIX}/usr/bin/x86_64-poky-linux/x86_64-poky-linux-gcc"
CXX="${PREFIX}/usr/bin/x86_64-poky-linux/x86_64-poky-linux-g++"
GDB="${PREFIX}/usr/bin/x86_64-poky-linux/x86_64-poky-linux-gdb"
QMAKE="${PREFIX}/usr/bin/qmake"
CMAKE="${PREFIX}/usr/bin/cmake"
SDKTOOL="../../../../libexec/qtcreator/sdktool"
MACHINE="intel-skylake-64"
if [ ! -x ${SDKTOOL} ]; then
echo "Cannot find 'sdktool' from QtCreator"
exit 1
fi
#MKSPEC=$(qmake -query QMAKE_XSPEC)
MKSPEC=linux-oe-g++
#RELEASE=$(qmake -query QT_VERSION)
RELEASE=$tag
NAME=${NAME:-"Custom Qt ${RELEASE} ${MACHINE}"}
BASEID="byos.${RELEASE}.${MACHINE}"
${SDKTOOL} rmKit --id ${BASEID}.kit 2>/dev/null || true
${SDKTOOL} rmQt --id ${BASEID}.qt || true
${SDKTOOL} rmTC --id ProjectExplorer.ToolChain.Gcc:${BASEID}.gcc || true
${SDKTOOL} rmTC --id ProjectExplorer.ToolChain.Gcc:${BASEID}.g++ || true
${SDKTOOL} rmDebugger --id ${BASEID}.gdb 2>/dev/null || true
${SDKTOOL} rmCMake --id ${BASEID}.cmake 2>/dev/null || true
${SDKTOOL} rmDev --id "$repo:$tag" 2>/dev/null || true
if [ -n "${REMOVEONLY}" ]; then
echo "Kit removed: ${NAME}"
exit 0
fi
${SDKTOOL} addAbiFlavor \
--flavor poky \
--oses linux 2>/dev/null || true
${SDKTOOL} addDev \
--id "$repo:$tag" \
--type 1 \
--name "Docker $repo:$tag" \
--dockerRepo $repo \
--dockerTag $tag \
--dockerMappedPaths '/data' \
--osType DockerDeviceType
${SDKTOOL} addTC \
--id "ProjectExplorer.ToolChain.Gcc:${BASEID}.gcc" \
--name "GCC ${NAME}" \
--path "${CC}" \
--abi "${ABI}" \
--language C
${SDKTOOL} addTC \
--id "ProjectExplorer.ToolChain.Gcc:${BASEID}.g++" \
--name "G++ ${NAME}" \
--path "${CXX}" \
--abi "${ABI}" \
--language Cxx
${SDKTOOL} addDebugger \
--id "${BASEID}.gdb" \
--name "GDB ${NAME}" \
--engine 1 \
--binary "${GDB}" \
--abis "${ABI}"
${SDKTOOL} addQt \
--id "${BASEID}.qt" \
--name "${NAME}" \
--type "Qdb.EmbeddedLinuxQt" \
--qmake ${QMAKE} \
--abis "${ABI}"
${SDKTOOL} addCMake \
--id "${BASEID}.cmake" \
--name "CMake ${NAME}" \
--path ${CMAKE}
${SDKTOOL} addKit \
--id "${BASEID}.kit" \
--name "${NAME}" \
--qt "${BASEID}.qt" \
--debuggerid "${BASEID}.gdb" \
--sysroot "docker://$repo:$tag/opt/toolchain/sysroots/skylake-64-poky-linux" \
--devicetype "DockerDeviceType" \
--device "$repo:$tag" \
--builddevice "$repo:$tag" \
--Ctoolchain "ProjectExplorer.ToolChain.Gcc:${BASEID}.gcc" \
--Cxxtoolchain "ProjectExplorer.ToolChain.Gcc:${BASEID}.g++" \
--icon ":/boot2qt/images/B2Qt_QtC_icon.png" \
--mkspec "" \
--cmake "${BASEID}.cmake" \
--cmake-config "CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}" \
--cmake-config "CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}" \
--cmake-config "CMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX}" \
--cmake-config "QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}" \
--cmake-config "CMAKE_TOOLCHAIN_FILE:FILEPATH=${OECORE_NATIVE_SYSROOT}/usr/lib/cmake/Qt6/qt.toolchain.cmake" \
--cmake-config "CMAKE_MAKE_PROGRAM:FILEPATH=ninja" \
--cmake-generator "Ninja"
echo "Configured Qt Creator with new kit: ${NAME}"

View File

@@ -22,7 +22,6 @@
: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'}
:Additional arguments:_QWidget {buddy=':Qt Creator.Additional arguments:_QLabel' type='QWidget' unnamed='1' visible='1'}
: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'}
@@ -118,15 +117,12 @@
:QML Debugging.No_QPushButton {text='No' type='QPushButton' unnamed='1' visible='1' window=':QML Debugging_QMessageBox'}
:QML Debugging_QMessageBox {text='The option will only take effect if the project is recompiled. Do you want to recompile now?' type='QMessageBox' unnamed='1' visible='1'}
:Qt Creator.Add Bookmark_QToolButton {text='Add Bookmark' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Additional arguments:_QLabel {text='Additional arguments:' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.CloseDoc_QToolButton {toolTip?='Close Document *' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.CloseFind_QToolButton {name='close' type='QToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Compile Output_Core::OutputWindow {type='Core::OutputWindow' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Compile Output'}
:Qt Creator.Configure Project_QPushButton {text='Configure Project' type='QPushButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.DebugModeWidget_QSplitter {name='DebugModeWidget' type='QSplitter' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.DragDoc_QToolButton {toolTip='Drag to drag documents between splits' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Effective qmake call:_QLabel {text='Effective qmake call:' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Effective qmake call:_QTextEdit {aboveWidget=':Additional arguments:_QWidget' leftWidget=':Qt Creator.Effective qmake call:_QLabel' type='QTextEdit' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Events_QDockWidget {name='QmlProfiler.Statistics.DockDockWidget' type='QDockWidget' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Events_QTabBar {aboveWidget=':Qt Creator.Events_QDockWidget' type='QTabBar' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator.Issues_QListView {type='QListView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Issues'}

View File

@@ -163,13 +163,17 @@ def selectBuildConfig(wantedKit, configName, afterSwitchTo=ViewConstants.EDIT):
test.warning("Don't know where you trying to switch to (%s)" % afterSwitchTo)
# This will not trigger a rebuild. If needed, caller has to do this.
def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShadowBuild=False, enableQmlDebug=False):
def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShadowBuild=False,
enableQmlDebug=False, buildSystem=None):
selectBuildConfig(currentTarget, configName, None)
ensureChecked(waitForObject(":scrollArea.Details_Utils::DetailsButton"))
if buildSystem == "qmake":
ensureChecked("{leftWidget={text='Shadow build:' type='QLabel' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'} "
"type='QCheckBox' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", enableShadowBuild)
buildCfCombo = waitForObject("{leftWidget=':scrollArea.Edit build configuration:_QLabel' "
"type='QComboBox' unnamed='1' visible='1'}")
if shouldBeDebug:
@@ -184,10 +188,14 @@ def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShad
pass
# Since waitForObject waits for the object to be enabled,
# it will wait here until compilation of the debug libraries has finished.
runCMakeButton = ("{type='QPushButton' text='Run CMake' unnamed='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}")
if currentTarget not in (Targets.DESKTOP_4_8_7_DEFAULT, Targets.EMBEDDED_LINUX):
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
if selectFromCombo(qmlDebuggingCombo, 'Enable'):
# Don't rebuild now
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
clickButton(waitForObject(runCMakeButton))
elif buildSystem == "qmake": # Don't rebuild now
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
try:
problemFound = waitForObject("{window=':Qt Creator_Core::Internal::MainWindow' "
@@ -201,7 +209,9 @@ def verifyBuildConfig(currentTarget, configName, shouldBeDebug=False, enableShad
qmlDebuggingCombo = findObject(':Qt Creator.QML debugging and profiling:_QComboBox')
if selectFromCombo(qmlDebuggingCombo, "Disable"):
test.log("Qml debugging libraries are available - unchecked qml debugging.")
# Don't rebuild now
if buildSystem is None or buildSystem == "CMake": # re-run cmake to apply
clickButton(waitForObject(runCMakeButton))
elif buildSystem == "qmake": # Don't rebuild now
clickButton(waitForObject(":QML Debugging.No_QPushButton", 5000))
clickButton(waitForObject(":scrollArea.Details_Utils::DetailsButton"))
switchViewTo(ViewConstants.EDIT)

View File

@@ -84,7 +84,7 @@ def setBreakpointsForCurrentProject(filesAndLines):
editor = getEditorForFileSuffix(curFile, True)
if not placeCursorToLine(editor, curLine, True):
return None
invokeMenuItem("Debug", "Toggle Breakpoint")
invokeMenuItem("Debug", "Enable or Disable Breakpoint")
filePath = str(waitForObjectExists(":Qt Creator_FilenameQComboBox").toolTip)
breakPointList.append({filePath:lineNumberWithCursor(editor)})
test.log('Set breakpoint in %s' % curFile, curLine)
@@ -175,8 +175,24 @@ def doSimpleDebugging(currentKit, currentConfigName, expectedBPOrder=[], enableQ
def isMsvcConfig(currentKit):
switchViewTo(ViewConstants.PROJECTS)
switchToBuildOrRunSettingsFor(currentKit, ProjectSettings.BUILD)
clickButton(waitForObject(":scrollArea.Details_Utils::DetailsButton"))
isMsvc = " -spec win32-msvc" in str(waitForObject(":Qt Creator.Effective qmake call:_QTextEdit").plainText)
waitForObject(":Projects.ProjectNavigationTreeView")
bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView")
wantedKitName = Targets.getStringForTarget(currentKit)
wantedKitIndexString = getQModelIndexStr("text='%s'" % wantedKitName, bAndRIndex)
if not test.verify(__kitIsActivated__(findObject(wantedKitIndexString)),
"Verifying target '%s' is enabled." % wantedKitName):
raise Exception("Kit '%s' is not activated in the project." % wantedKitName)
index = waitForObject(wantedKitIndexString)
toolTip = str(index.data(Qt.ToolTipRole).toString())
compilerPattern = re.compile("<tr><td><b>Compiler:</b></td><td>(?P<compiler>.+)</td></tr>")
match = compilerPattern.search(toolTip)
if match is None:
test.warning("UI seems to have changed - failed to check for compiler.")
return False
compiler = str(match.group("compiler"))
isMsvc = compiler.startswith("MSVC") or compiler.startswith("Microsoft Visual C")
switchViewTo(ViewConstants.EDIT)
return isMsvc

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.
@@ -69,10 +69,8 @@ def openCmakeProject(projectPath, buildDir):
invokeMenuItem("File", "Open File or Project...")
selectFromFileDialog(projectPath)
__chooseTargets__([]) # uncheck all
targetToChoose = Targets.DESKTOP_4_8_7_DEFAULT # FIXME make the intended target a parameter
if not qt4Available:
targetToChoose = Targets.DESKTOP_5_14_1_DEFAULT
__chooseTargets__([targetToChoose], additionalFunc=additionalFunction)
# FIXME make the intended target a parameter
__chooseTargets__([Targets.DESKTOP_5_14_1_DEFAULT], additionalFunc=additionalFunction)
clickButton(waitForObject(":Qt Creator.Configure Project_QPushButton"))
return True
@@ -224,22 +222,31 @@ def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
if Qt5Path.toVersionTuple(found.group(1)) < Qt5Path.toVersionTuple(requiredQt):
available.discard(currentItem)
def __getProjectFileName__(projectName, buildSystem):
if buildSystem is None or buildSystem == "CMake":
return "CMakeLists.txt"
else:
return projectName + (".pro" if buildSystem == "qmake" else ".qbs")
# Creates a Qt GUI project
# param path specifies where to create the project
# param projectName is the name for the new project
# param checks turns tests in the function on if set to True
def createProject_Qt_GUI(path, projectName, checks = True, addToVersionControl = "<None>"):
# param addToVersionControl selects the specified VCS from Creator's wizard
# param buildSystem selects the specified build system from Creator's wizard
def createProject_Qt_GUI(path, projectName, checks=True, addToVersionControl="<None>",
buildSystem=None):
template = "Qt Widgets Application"
available = __createProjectOrFileSelectType__(" Application (Qt)", template)
__createProjectSetNameAndPath__(path, projectName, checks)
buildSystem = __handleBuildSystem__(None)
buildSystem = __handleBuildSystem__(buildSystem)
if checks:
exp_filename = "mainwindow"
h_file = exp_filename + ".h"
cpp_file = exp_filename + ".cpp"
ui_file = exp_filename + ".ui"
pro_file = projectName + ".pro"
projectFile = __getProjectFileName__(projectName, buildSystem)
waitFor("object.exists(':headerFileLineEdit_Utils::FileNameValidatingLineEdit')", 20000)
waitFor("object.exists(':sourceFileLineEdit_Utils::FileNameValidatingLineEdit')", 20000)
@@ -259,7 +266,7 @@ def createProject_Qt_GUI(path, projectName, checks = True, addToVersionControl =
path = os.path.abspath(path)
path = os.path.join(path, projectName)
expectedFiles = [path]
expectedFiles.extend(__sortFilenamesOSDependent__(["main.cpp", cpp_file, h_file, ui_file, pro_file]))
expectedFiles.extend(__sortFilenamesOSDependent__(["main.cpp", cpp_file, h_file, ui_file, projectFile]))
__createProjectHandleLastPage__(expectedFiles, addToVersionControl)
waitForProjectParsing()
@@ -283,9 +290,9 @@ def createProject_Qt_Console(path, projectName, checks = True, buildSystem = Non
path = os.path.abspath(path)
path = os.path.join(path, projectName)
cpp_file = "main.cpp"
pro_file = projectName + ".pro"
projectFile = __getProjectFileName__(projectName, buildSystem)
expectedFiles = [path]
expectedFiles.extend(__sortFilenamesOSDependent__([cpp_file, pro_file]))
expectedFiles.extend(__sortFilenamesOSDependent__([cpp_file, projectFile]))
__createProjectHandleLastPage__(expectedFiles)
waitForProjectParsing()
@@ -375,7 +382,8 @@ def createNewNonQtProject(workingDir, projectName, target, plainC=False, buildSy
__createProjectHandleLastPage__()
return projectName
def createNewCPPLib(projectDir, projectName, className, target, isStatic):
def createNewCPPLib(projectDir, projectName, className, target, isStatic, buildSystem=None):
available = __createProjectOrFileSelectType__(" Library", "C++ Library", False, True)
if isStatic:
libType = LibType.STATIC
@@ -384,7 +392,7 @@ def createNewCPPLib(projectDir, projectName, className, target, isStatic):
if projectDir == None:
projectDir = tempDir()
projectName = __createProjectSetNameAndPath__(projectDir, projectName, False)
__handleBuildSystem__(None)
__handleBuildSystem__(buildSystem)
selectFromCombo(waitForObject("{name='Type' type='QComboBox' visible='1' "
"window=':New_ProjectExplorer::JsonWizard'}"),
LibType.getStringForLib(libType))
@@ -396,10 +404,12 @@ def createNewCPPLib(projectDir, projectName, className, target, isStatic):
__createProjectHandleLastPage__()
return projectName, className
def createNewQtPlugin(projectDir, projectName, className, target, baseClass="QGenericPlugin"):
def createNewQtPlugin(projectDir, projectName, className, target, baseClass="QGenericPlugin",
buildSystem=None):
available = __createProjectOrFileSelectType__(" Library", "C++ Library", False, True)
projectName = __createProjectSetNameAndPath__(projectDir, projectName, False)
__handleBuildSystem__(None)
__handleBuildSystem__(buildSystem)
selectFromCombo(waitForObject("{name='Type' type='QComboBox' visible='1' "
"window=':New_ProjectExplorer::JsonWizard'}"),
LibType.getStringForLib(LibType.QT_PLUGIN))

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.
@@ -31,7 +31,7 @@ def main():
# warnings from the clang code model in "issues" view
if not startCreatorVerifyingClang(False):
return
createProject_Qt_GUI(tempDir(), "SampleApp")
createProject_Qt_GUI(tempDir(), "SampleApp", buildSystem="qmake")
# run project for debug and release and verify results
runVerify()
#close Qt Creator

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.
@@ -30,7 +30,7 @@ def main():
startQC()
if not startedWithoutPluginError():
return
createNewQtQuickApplication(tempDir(), "SampleApp")
createNewQtQuickApplication(tempDir(), "SampleApp", buildSystem="qmake")
# run project for debug and release and verify results
runVerify()
#close Qt Creator

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.
@@ -65,9 +65,9 @@ def handleInsertVirtualFunctions(expected, toAdd):
def checkSimpleCppLib(projectName, static):
projectName, className = createNewCPPLib(tempDir(), projectName, "MyClass",
Targets.desktopTargetClasses(),
static)
static, buildSystem="qmake")
for kit, config in iterateBuildConfigs("Release"):
verifyBuildConfig(kit, config, False, True)
verifyBuildConfig(kit, config, False, True, buildSystem="qmake")
invokeMenuItem('Build', 'Build Project "%s"' % projectName)
waitForCompile(10000)
checkCompile()
@@ -87,10 +87,11 @@ def main():
checkSimpleCppLib("SampleApp2", True)
pluginTargets = (Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT)
projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin", pluginTargets)
projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin", pluginTargets,
buildSystem="qmake")
virtualFunctionsAdded = False
for kit, config in iterateBuildConfigs("Debug"):
verifyBuildConfig(kit, config, True, True)
verifyBuildConfig(kit, config, True, True, buildSystem="qmake")
invokeMenuItem('Build', 'Build Project "%s"' % projectName)
waitForCompile(10000)
if not virtualFunctionsAdded:

View File

@@ -98,7 +98,7 @@ def __handleAppOutputWaitForDebuggerFinish__():
def performDebugging(projectName):
for kit, config in iterateBuildConfigs("Debug"):
test.log("Selecting '%s' as build config" % config)
verifyBuildConfig(kit, config, True, True)
verifyBuildConfig(kit, config, True, True, buildSystem="qmake")
waitForObject(":*Qt Creator.Build Project_Core::Internal::FancyToolButton")
selectFromLocator("t rebuild", "Rebuild (Rebuild All Projects)")
waitForCompile()
@@ -111,7 +111,7 @@ def performDebugging(projectName):
editor = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget")
placeCursorToLine(editor, "int main.*", True)
type(editor, "<Down>")
invokeMenuItem("Debug", "Toggle Breakpoint")
invokeMenuItem("Debug", "Enable or Disable Breakpoint")
clickButton(waitForObject(":*Qt Creator.Start Debugging_Core::Internal::FancyToolButton"))
handleDebuggerWarnings(config, isMsvc)
clickButton(waitForObject(":*Qt Creator.Continue_Core::Internal::FancyToolButton"))

View File

@@ -44,8 +44,8 @@ def main():
'onTriggered: console.log("Break here")'])
invokeMenuItem("File", "Save All")
filesAndLines = [
{ "%s.Sources.main\\.cpp" % projectName : "QQmlApplicationEngine engine;" },
{ "%s.Resources.qml\.qrc./.main\\.qml" % projectName : 'onTriggered.*' }
{ "%s.%s.Source Files.main\\.cpp" % (projectName, projectName) : "QQmlApplicationEngine engine;" },
{ "%s.%s.qml\.qrc./.main\\.qml" % (projectName, projectName) : 'onTriggered.*' }
]
test.log("Setting breakpoints")
expectedBreakpointsOrder = setBreakpointsForCurrentProject(filesAndLines)

View File

@@ -41,10 +41,7 @@ def main():
startQC()
if not startedWithoutPluginError():
return
targetToChoose = Targets.DESKTOP_4_8_7_DEFAULT
if not qt4Available:
targetToChoose = Targets.DESKTOP_5_14_1_DEFAULT
openQmakeProject(SpeedCrunchPath, [targetToChoose])
openQmakeProject(SpeedCrunchPath, [Targets.DESKTOP_5_14_1_DEFAULT])
waitForProjectParsing()
fancyToolButton = waitForObject(":*Qt Creator_Core::Internal::FancyToolButton")