diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml
index eaf3013fcfa..68fe9052e6e 100644
--- a/.github/workflows/build_cmake.yml
+++ b/.github/workflows/build_cmake.yml
@@ -7,7 +7,7 @@ on:
- 'doc/**'
env:
- QT_VERSION: 6.5.1
+ QT_VERSION: 6.5.2
MACOS_DEPLOYMENT_TARGET: 10.15
CLANG_VERSION: 16.0.2
ELFUTILS_VERSION: 0.175
diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake
index 42ad51bcfd6..72009ad7fc1 100644
--- a/cmake/QtCreatorIDEBranding.cmake
+++ b/cmake/QtCreatorIDEBranding.cmake
@@ -1,6 +1,6 @@
-set(IDE_VERSION "11.0.0") # The IDE version.
+set(IDE_VERSION "11.0.2") # The IDE version.
set(IDE_VERSION_COMPAT "11.0.0") # The IDE Compatibility version.
-set(IDE_VERSION_DISPLAY "11.0.0") # The IDE display version.
+set(IDE_VERSION_DISPLAY "11.0.2") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2023") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml
index 1fec2c793a6..20d6247ea9c 100644
--- a/coin/instructions/common_environment.yaml
+++ b/coin/instructions/common_environment.yaml
@@ -10,7 +10,7 @@ instructions:
variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_16.0.2-based
- type: EnvironmentVariable
variableName: QTC_QT_BASE_URL
- variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/archive/qt/6.5/6.5.1-released/Qt"
+ variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/archive/qt/6.5/6.5.2-released/Qt"
- type: EnvironmentVariable
variableName: QTC_QT_MODULES
variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquickcontrols2 qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine"
diff --git a/dist/changelog/changes-11.0.1.md b/dist/changelog/changes-11.0.1.md
new file mode 100644
index 00000000000..3c187b0c41d
--- /dev/null
+++ b/dist/changelog/changes-11.0.1.md
@@ -0,0 +1,77 @@
+Qt Creator 11.0.1
+=================
+
+Qt Creator version 11.0.1 contains bug fixes.
+
+The most important changes are listed in this document. For a complete list of
+changes, see the Git log for the Qt Creator sources that you can check out from
+the public Git repository. For example:
+
+ git clone git://code.qt.io/qt-creator/qt-creator.git
+ git log --cherry-pick --pretty=oneline origin/v11.0.0..v11.0.1
+
+General
+-------
+
+* Fixed writing configuration files with `sdktool`
+* Fixed exporting keyboard shortcut schemes
+ ([QTCREATORBUG-29431](https://bugreports.qt.io/browse/QTCREATORBUG-29431))
+
+Editing
+-------
+
+### SCXML
+
+* Fixed a crash when `onEntry`/`onExit` events and transitions where displayed
+ together
+ ([QTCREATORBUG-29429](https://bugreports.qt.io/browse/QTCREATORBUG-29429))
+
+### Beautifier
+
+* Fixed setting a customized Clang Format style
+ ([QTCREATORBUG-28525](https://bugreports.qt.io/browse/QTCREATORBUG-28525))
+
+Projects
+--------
+
+* Fixed a crash when editing kits
+ ([QTCREATORBUG-29382](https://bugreports.qt.io/browse/QTCREATORBUG-29382),
+ [QTCREATORBUG-29425](https://bugreports.qt.io/browse/QTCREATORBUG-29425))
+* Fixed a crash when manually re-detecting toolchains
+ ([QTCREATORBUG-29430](https://bugreports.qt.io/browse/QTCREATORBUG-29430))
+* Fixed the pasting of large texts in integrated terminal
+* Incredibuild
+ * Fixed missing UI in the build steps
+
+### CMake
+
+* Fixed an issue with framework paths with CMake >= 3.27
+ ([QTCREATORBUG-29450](https://bugreports.qt.io/browse/QTCREATORBUG-29450))
+
+Debugging
+---------
+
+* Fixed the button state in the dialog for loading core files
+* Fixed debugging with debuggers that still use Python 2.7
+ ([QTCREATORBUG-29440](https://bugreports.qt.io/browse/QTCREATORBUG-29440))
+* GDB
+ * Fixed `Use common locations for debug information`
+
+Version Control Systems
+-----------------------
+
+### Git
+
+* Fixed a crash when tools are not found in `PATH`
+
+Credits for these changes go to:
+--------------------------------
+Aleksei German
+André Pönitz
+Christian Kandeler
+Christian Stenger
+Cristian Adam
+Eike Ziller
+Leena Miettinen
+Marcus Tillmanns
+Robert Löhning
diff --git a/dist/changelog/changes-11.0.2.md b/dist/changelog/changes-11.0.2.md
new file mode 100644
index 00000000000..91994e79b9f
--- /dev/null
+++ b/dist/changelog/changes-11.0.2.md
@@ -0,0 +1,73 @@
+Qt Creator 11.0.2
+=================
+
+Qt Creator version 11.0.2 contains bug fixes.
+
+The most important changes are listed in this document. For a complete list of
+changes, see the Git log for the Qt Creator sources that you can check out from
+the public Git repository. For example:
+
+ git clone git://code.qt.io/qt-creator/qt-creator.git
+ git log --cherry-pick --pretty=oneline origin/v11.0.1..v11.0.2
+
+General
+-------
+
+* Allow fractional high DPI scaling without modifying the environment
+ ([QTCREATORBUG-29461](https://bugreports.qt.io/browse/QTCREATORBUG-29461))
+
+Editing
+-------
+
+### General
+
+* Fixed a potential crash when reloading a document
+ ([QTCREATORBUG-29432](https://bugreports.qt.io/browse/QTCREATORBUG-29432))
+
+### Copilot
+
+* Fixed a crash when configuring an unusable copilot agent in the settings
+
+Debug
+-----
+
+* Fixed a problem where debugging with "Run In Terminal" would fail on Linux
+ ([QTCREATORBUG-29463](https://bugreports.qt.io/browse/QTCREATORBUG-29463))
+
+Projects
+--------
+
+### CMake
+
+* Fixed code completion for ui file components for CMake based projects
+ ([QTCREATORBUG-28787](https://bugreports.qt.io/browse/QTCREATORBUG-28787))
+* Fix reading ninjaPath from QtCreator.ini
+ ([QTBUG-115754](https://bugreports.qt.io/browse/QTBUG-115754))
+* Fixed incorrect device checks when using Boot2Qt
+ ([QTCREATORBUG-29474](https://bugreports.qt.io/browse/QTCREATORBUG-29474))
+
+### QMake
+
+* Avoid cleaning the build directory after switching kits
+ ([QTCREATORBUG-29451](https://bugreports.qt.io/browse/QTCREATORBUG-29451))
+ ([QTCREATORBUG-29481](https://bugreports.qt.io/browse/QTCREATORBUG-29481))
+
+Version Control Systems
+-----------------------
+
+### Fossil
+
+* Show the correct dialog when reverting the current file
+
+Credits for these changes go to:
+--------------------------------
+Aaron Barany
+André Pönitz
+Björn Schäpers
+Christian Kandeler
+Cristian Adam
+David Schulz
+Jaroslaw Kobus
+Leena Miettinen
+Marcus Tillmanns
+Orgad Shaneh
diff --git a/doc/qtcreator/src/overview/creator-tech-support.qdoc b/doc/qtcreator/src/overview/creator-tech-support.qdoc
index d7d5f000f27..af87b414bcc 100644
--- a/doc/qtcreator/src/overview/creator-tech-support.qdoc
+++ b/doc/qtcreator/src/overview/creator-tech-support.qdoc
@@ -34,7 +34,7 @@
\if defined(qtcreator)
\row
\li View examples of what you can do with Qt
- \li \l{List of Qt Examples}
+ \li \l{Qt Examples and Tutorials}
\row
\li Develop Qt applications for desktop and \l{glossary-device}{devices}
diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs
index c2557d15af5..a0d249d777c 100644
--- a/qbs/modules/qtc/qtc.qbs
+++ b/qbs/modules/qtc/qtc.qbs
@@ -6,10 +6,10 @@ import qbs.Utilities
Module {
Depends { name: "cpp"; required: false }
- property string qtcreator_display_version: '11.0.0'
+ property string qtcreator_display_version: '11.0.2'
property string ide_version_major: '11'
property string ide_version_minor: '0'
- property string ide_version_release: '0'
+ property string ide_version_release: '2'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release
diff --git a/share/qtcreator/debugger/libcpp_stdtypes.py b/share/qtcreator/debugger/libcpp_stdtypes.py
index 1e0b852dc0b..28288bb89f3 100644
--- a/share/qtcreator/debugger/libcpp_stdtypes.py
+++ b/share/qtcreator/debugger/libcpp_stdtypes.py
@@ -163,8 +163,8 @@ def qdump__std____1__stack(d, value):
d.putBetterType(value.type)
-def GetChildMemberWithName(value: DumperBase.Value, name: str) -> DumperBase.Value:
- members: list[DumperBase.Value] = value.members(True)
+def GetChildMemberWithName(value, name):
+ members = value.members(True)
for member in members:
if member.name == name:
@@ -172,8 +172,8 @@ def GetChildMemberWithName(value: DumperBase.Value, name: str) -> DumperBase.Val
return None
-def GetIndexOfChildWithName(value: DumperBase.Value, name: str) -> int:
- members: list[DumperBase.Value] = value.members(True)
+def GetIndexOfChildWithName(value, name):
+ members = value.members(True)
for i, member in enumerate(members):
if member.name == name:
@@ -229,8 +229,8 @@ def std_1_string_dumper_v2(d, value):
if not Short_Sp:
raise Exception("Could not find __s")
- Is_Long: DumperBase.Value = GetChildMemberWithName(Short_Sp, "__is_long_")
- Size_Sp: DumperBase.Value = GetChildMemberWithName(Short_Sp, "__size_")
+ Is_Long = GetChildMemberWithName(Short_Sp, "__is_long_")
+ Size_Sp = GetChildMemberWithName(Short_Sp, "__size_")
if not Size_Sp:
raise Exception("Could not find __size_")
diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts
index ab3fd12f001..66171ce79a8 100644
--- a/share/qtcreator/translations/qtcreator_de.ts
+++ b/share/qtcreator/translations/qtcreator_de.ts
@@ -12469,23 +12469,23 @@ Siehe auch die Einstellungen für Google Test.
Choose Keil Toolset Configuration File
-
+ Wählen Sie die Konfigurationsdatei für das Keil-Toolset
Tools file path:
-
+ Pfad zur Konfiguration:
Target device:
-
+ Zielgerät:
Target driver:
-
+ Zieltreiber:
Starting %1 ...
-
+ Starte %1 ...
Choose the desired startup mode of the GDB server provider.
@@ -12561,11 +12561,11 @@ Siehe auch die Einstellungen für Google Test.
Generic
-
+ Generisch
Use GDB target extended-remote
-
+ GDB "target extended-remote" benutzen
Extended mode:
@@ -12581,7 +12581,7 @@ Siehe auch die Einstellungen für Google Test.
Connects to the board before executing any instructions.
-
+ Verbindet zum Board, bevor Anweisungen ausgeführt werden.
Transport layer type.
@@ -12601,7 +12601,8 @@ Siehe auch die Einstellungen für Google Test.
Keep unspecified
-
+ dropdown for "transport layer version" with values "V1", "V2", "Keep unspecified", for the latter no argument is passed to the corresponding command line
+ Nicht festlegen
Manage...
@@ -12621,17 +12622,19 @@ Siehe auch die Einstellungen für Google Test.
UVSC
-
+ UVSC
GDB compatible provider engine
(used together with the GDB debuggers).
-
+ GDB-kompatible Provider-Engine
+(wird zusammen mit GDB-Debuggern benutzt).
UVSC compatible provider engine
(used together with the KEIL uVision).
-
+ UVSC-kompatible Provider-Engine
+(wird zusammen mit KEIL uVision benutzt).
Name
@@ -12643,7 +12646,7 @@ Siehe auch die Einstellungen für Google Test.
Engine
-
+ Engine
Duplicate Providers Detected
@@ -12695,19 +12698,19 @@ Siehe auch die Einstellungen für Google Test.
Specify the verbosity level (0 to 7).
-
+ Geben Sie den Detailgrad an (0 bis 7).
Connect under reset (hotplug).
-
+ Verbinden unter Reset (hotplug).
Connect under reset:
-
+ Verbinden unter Reset:
Interface type.
-
+ Interface-Typ.
Type:
@@ -12715,7 +12718,7 @@ Siehe auch die Einstellungen für Google Test.
Specify the speed of the interface (120 to 8000) in kilohertz (kHz).
-
+ Geben Sie die Geschwindigkeit des Interface in Kilohertz (kHz) an (120 bis 8000).
Speed:
@@ -12723,19 +12726,19 @@ Siehe auch die Einstellungen für Google Test.
Do not use EBlink flash cache.
-
+ EBlink-Flash-Cache nicht benutzen.
Disable cache:
-
+ Cache deaktivieren:
Shut down EBlink server after disconnect.
-
+ EBlink-Server nach Trennung der Verbindung abschalten.
Auto shutdown:
-
+ Automatisch abschalten:
SWD
@@ -12755,11 +12758,11 @@ Siehe auch die Einstellungen für Google Test.
Host interface:
-
+ Host-Interface:
Target interface:
-
+ Ziel-Interface:
Default
@@ -12767,35 +12770,35 @@ Siehe auch die Einstellungen für Google Test.
USB
-
+ USB
TCP/IP
-
+ TCP/IP
Compact JTAG
-
+ Compact JTAG
Renesas RX FINE
-
+ Renesas RX FINE
ICSP
-
+ ICSP
Auto
-
+ Automatisch
Adaptive
-
+ Adaptiv
%1 kHz
-
+ %1 kHz
IP Address
@@ -12815,11 +12818,11 @@ Siehe auch die Einstellungen für Google Test.
Limit speed to real-time.
-
+ Geschwindigkeit auf Echtzeit reduzieren.
Limit speed to real-time:
-
+ Geschwindigkeit auf Echtzeit reduzieren:
uVision St-Link
@@ -12923,39 +12926,39 @@ Siehe auch die Einstellungen für Google Test.
FLASH Start
-
+ FLASH Start
FLASH Size
-
+ FLASH Größe
RAM Start
-
+ RAM Start
RAM Size
-
+ RAM Größe
Algorithm path.
-
+ Algorithmus-Pfad.
FLASH:
-
+ FLASH:
Start address.
-
+ Startadresse.
Size.
-
+ Größe.
RAM:
-
+ RAM:
Vendor:
@@ -12975,15 +12978,15 @@ Siehe auch die Einstellungen für Google Test.
Flash algorithm:
-
+ Flash-Algorithmus:
Target device not selected.
-
+ Zielgerät ist nicht ausgewählt.
Available Target Devices
-
+ Verfügbare Zielgeräte
Select Peripheral Description File
@@ -12995,11 +12998,11 @@ Siehe auch die Einstellungen für Google Test.
IAREW %1 (%2, %3)
-
+ IAREW %1 (%2, %3)
IAREW
-
+ IAREW
&Compiler path:
@@ -13027,11 +13030,11 @@ Siehe auch die Einstellungen für Google Test.
uVision JLink
-
+ uVision JLink
Adapter options:
-
+ Adapter-Optionen:
50MHz
@@ -13087,31 +13090,31 @@ Siehe auch die Einstellungen für Google Test.
Deploy to BareMetal Device
-
+ Deployment auf Bare-Metal-Gerät
Debugger CPU library (depends on a CPU core).
-
+ Debugger-CPU-Bibliothek (benötigt einen CPU-Kern).
Debugger driver library.
-
+ Debugger-Treiberbibliothek.
Driver library:
-
+ Treiberbibliothek:
CPU library:
-
+ CPU-Bibliothek:
Target driver not selected.
-
+ Zieltreiber ist nicht ausgewählt.
Available Target Drivers
-
+ Verfügbare Zieltreiber
@@ -31683,48 +31686,48 @@ Hinweis: Dies macht Sie anfällig für Man-in-the-middle-Angriffe.
QtC::Haskell
Release
- Release
+ Release
General
- Allgemein
+ Allgemein
Build directory:
- Build-Verzeichnis:
+ Build-Verzeichnis:
GHCi
-
+ GHCi
Run GHCi
-
+ GHCi ausführen
Haskell
SnippetProvider
-
+ Haskell
Executable
- Ausführbare Datei
+ Ausführbare Datei
Haskell
-
+ Haskell
Stack executable:
-
+ Ausführbare Stack-Datei:
Choose Stack Executable
-
+ Ausführbare Datei für Stack auswählen
Stack Build
-
+ Erstellen mit Stack
@@ -46079,7 +46082,7 @@ Are you sure?
Checking that files can be created in %1...
-
+ Überprüfe, ob Dateien in %1 erstellt werden können...
Files can be created in /var/run.
@@ -46087,11 +46090,11 @@ Are you sure?
An error occurred while checking that files can be created in %1.
-
+ Beim Überprüfen, ob Dateien in %1 erstellt werden können, ist ein Fehler aufgetreten.
Files cannot be created in %1.
-
+ In %1 können keine Dateien erstellt werden.
Warning: "slog2info" is not found on the device, debug output not available.
@@ -46170,34 +46173,34 @@ Möchten Sie fortfahren?
No files need to be uploaded.
- Es müssen keine Dateien hochgeladen werden.
+ Es müssen keine Dateien hochgeladen werden.
%n file(s) need to be uploaded.
-
+
Eine Datei muss hochgeladen werden.
%n Dateien müssen hochgeladen werden.
Local file "%1" does not exist.
- Es gibt keine lokale Datei "%1".
+ Es gibt keine lokale Datei "%1".
Remote chmod failed for file "%1": %2
- "chmod" für die entfernte Datei "%1" ist fehlgeschlagen: %2
+ "chmod" für die entfernte Datei "%1" ist fehlgeschlagen: %2
No device configuration set.
- Es ist keine Gerätekonfiguration eingestellt.
+ Es ist keine Gerätekonfiguration gesetzt.
No deployment action necessary. Skipping.
- Alle Dateien sind auf dem aktuellen Stand, es ist keine Installation erforderlich.
+ Alle Dateien sind auf dem aktuellen Stand, es ist keine Installation erforderlich.
All files successfully deployed.
- Alle Dateien erfolgreich versandt.
+ Deployment für alle Dateien erfolgreich.
Deploy Qt to QNX Device
@@ -46205,7 +46208,7 @@ Möchten Sie fortfahren?
Create Kit for %1
-
+ Kit für %1 erstellen
Configuration Information:
@@ -46229,11 +46232,11 @@ Möchten Sie fortfahren?
Compiler:
-
+ Compiler:
Architectures:
-
+ Architekturen:
Remove
@@ -46249,11 +46252,11 @@ Möchten Sie fortfahren?
Configuration already exists.
-
+ Konfiguration existiert bereits.
Configuration is not valid.
-
+ Konfiguration ist ungültig.
Remove QNX Configuration
@@ -46954,7 +46957,7 @@ wirklich löschen?
Key deployment failed.
-
+ Deployment des Schlüssels fehlgeschlagen.
Deployment finished successfully.
@@ -47000,7 +47003,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Uploading package to device...
-
+ Lade Paket auf das Gerät hoch...
Successfully uploaded package file.
@@ -47012,19 +47015,19 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Successfully installed package file.
-
+ Die Paketdatei wurde erfolgreich installiert.
Failed to start "stat": %1
-
+ "stat" konnte nicht gestartet werden: %1
"stat" crashed.
-
+ "stat" ist abgestürzt.
"stat" failed with exit code %1: %2
-
+ "stat" ist mit Rückgabewert %1 fehlgeschlagen: %2
Failed to retrieve remote timestamp for file "%1". Incremental deployment will not work. Error message was: %2
@@ -47063,7 +47066,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Ignore missing files
-
+ Fehlende Dateien ignorieren
Upload files via SFTP
@@ -47071,19 +47074,19 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Sending echo to device...
-
+ Sende Echo zum Gerät...
echo failed: %1
-
+ Echo fehlgeschlagen: %1
echo failed.
-
+ Echo fehlgeschlagen.
Device replied to echo with expected contents.
-
+ Das Gerät hat mit dem erwarteten Inhalt auf das Echo geantwortet.
Checking kernel version...
@@ -47107,7 +47110,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Device replied to echo with unexpected contents: "%1"
-
+ Das Gerät hat auf das Echo mit unerwartetem Inhalt geantwortet: "%1"
The following specified ports are currently in use: %1
@@ -47116,56 +47119,62 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Some tools will not work out of the box.
-
+ Einige Werkzeuge werden nicht ohne weitere Einstellungen funktionieren.
+
Checking whether "%1" works...
-
+ Überprüfe, ob "%1" funktioniert...
Failed to start "%1": %2
-
+ "%1" konnte nicht gestartet werden: %2
+
"%1" crashed.
-
+ "%1" ist abgestürzt.
+
"%1" failed with exit code %2: %3
-
+ "%1" ist mit Rückgabewert %2 fehlgeschlagen: %3
+
"%1" is functional.
-
+ "%1" funktioniert.
+
"%1" will be used for deployment, because "%2" and "%3" are not available.
-
+ "%1" wird für das Deployment benutzt, da "%2" und "%3" nicht verfügbar sind.
+
Checking if required commands are available...
-
+ Überprüfe Verfügbarkeit der benötigten Kommandos...
%1...
-
+ %1...
%1 found.
- %1 gefunden.
+ %1 gefunden.
An error occurred while checking for %1.
- Bei der Prüfung von %1 trat ein Fehler auf.
+ Bei der Überprüfung von %1 trat ein Fehler auf.
%1 not found.
- %1 nicht gefunden.
+ %1 nicht gefunden.
Deployment to this device will not work out of the box.
@@ -47179,7 +47188,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Deploy to Remote Linux Host
- Auf Linux-Mobilgerät ausführen
+ Deployment auf entferntes Linuxgerät
Installing package failed.
@@ -47287,7 +47296,7 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
The device's SSH port number:
-
+ SSH-Port des Geräts:
The username to log into the device:
@@ -47323,11 +47332,12 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Source %1 and %2
-
+ Source (verb) /etc/profile and $HOME/.profile
+ %1 und %2 einbeziehen
Direct
-
+ Direkt
&Username:
@@ -47335,11 +47345,12 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
QML runtime executable:
-
+ Ausführbare Datei der QML-Runtime:
Access via:
-
+ drop down with devices
+ Zugriff über:
Physical Device
@@ -47399,62 +47410,65 @@ Zusätzlich wird die Verbindung zum Gerät getestet.
Cannot establish SSH connection: ssh binary "%1" does not exist.
- SSH-Verbindung kann nicht aufgebaut werden: Eine ausführbare SSH-Datei "%1" existiert nicht.
+ SSH-Verbindung kann nicht hergestellt werden: Eine ausführbare SSH-Datei "%1" existiert nicht.
Cannot establish SSH connection: Failed to create temporary directory for control socket: %1
- SSH-Verbindung kann nicht aufgebaut werden: Es konnte kein temporäres Verzeichnis für den Steuer-Socket angelegt werden: %1
+ SSH-Verbindung kann nicht hergestellt werden: Es konnte kein temporäres Verzeichnis für den Steuer-Socket angelegt werden: %1
Cannot establish SSH connection.
Control process failed to start.
-
+ SSH-Verbindung kann nicht hergestellt werden.
+Der Kontrollprozess konnte nicht gestartet werden.
SSH connection failure.
- SSH-Verbindungsfehler.
+ SSH-Verbindungsfehler.
SSH connection failure:
-
+ SSH-Verbindungsfehler:
Remote Linux
-
+ Entferntes Linuxgerät
Failed: %1
-
+ Fehlgeschlagen: %1
Remote Linux Device
-
+ Entferntes Linuxgerät
"%1" failed to start: %2
- "%1" konnte nicht gestartet werden: %2
+ "%1" konnte nicht gestartet werden: %2
"%1" crashed.
- "%1" ist abgestürzt.
+ "%1" ist abgestürzt.
"sftp" binary "%1" does not exist.
-
+ Ausführbare "sftp"-Datei "%1" existiert nicht.
Creating directory: %1
-
+ Erstelle Verzeichnis: %1
+
Failed.
- Fehlgeschlagen.
+ Fehlgeschlagen.
Copying %1/%2: %3 -> %4
-
+ Kopiere %1/%2: %3 -> %4
+
Clean Environment
@@ -47556,7 +47570,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
Deploy via rsync: failed to create remote directories:
-
+ Deployment über rsync: Erstellen von entfernten Verzeichnissen ist fehlgeschlagen:
rsync failed to start: %1
@@ -47580,7 +47594,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
rsync is only supported for transfers between different devices.
-
+ rsync wird nur für das Übertragen zwischen unterschiedlichen Geräten unterstützt.
Deploy files via rsync
@@ -47588,7 +47602,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
Command:
-
+ Kommando:
Install root:
@@ -47596,43 +47610,43 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
Clean install root first:
-
+ Install-Root zuerst bereinigen:
Full command line:
-
+ Vollständige Kommandozeile:
Custom command line:
-
+ Benutzerdefinierte Kommandozeile:
Use custom command line instead:
-
+ Benutzerdefinierte Kommandozeile verwenden:
Install into temporary host directory
-
+ In temporäres Host-Verzeichnis installieren
You must provide an install root.
-
+ Sie müssen ein Installationsverzeichnis angeben.
The install root "%1" could not be cleaned.
-
+ Das Installationsverzeichnis "%1" konnte nicht bereinigt werden.
The install root "%1" could not be created.
-
+ Das Installationsverzeichnis "%1" konnte nicht erstellt werden.
The "make install" step should probably not be last in the list of deploy steps. Consider moving it up.
-
+ Der "make install"-Schritt sollte wahrscheinlich nicht der letzte Deployment-Schritt sein. Ziehen Sie in Betracht, ihn nach oben zu verschieben.
You need to add an install statement to your CMakeLists.txt file for deployment to work.
-
+ Sie müssen zu Ihrer CMakeLists.txt-Datei eine "install"-Anweisung hinzufügen, damit das Deployment funktioniert.
Executable on device:
@@ -47648,59 +47662,59 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
New Remote Linux Device Configuration Setup
-
+ Einrichtung der Konfiguration für neues entferntes Linuxgerät
SSH Key Configuration
- SSH-Schlüsselkonfiguration
+ SSH-Schlüsselkonfiguration
&RSA
- &RSA
+ &RSA
ECDSA
- ECDSA
+ ECDSA
&Generate And Save Key Pair
- &Erzeuge und speichere Schlüsselpaar
+ &Erzeuge und speichere Schlüsselpaar
Options
- Einstellungen
+ Einstellungen
Key algorithm:
- Schlüsselalgorithmus:
+ Schlüsselalgorithmus:
Key &size:
- Schlüssel&länge:
+ Schlüssel&länge:
Public key file:
- Öffentliche Schlüsseldatei:
+ Öffentliche Schlüsseldatei:
The ssh-keygen tool was not found.
- Das Programm "ssh-keygen" wurde nicht gefunden.
+ Das Programm "ssh-keygen" wurde nicht gefunden.
Refusing to overwrite existing private key file "%1".
- Die private Schlüsseldatei "%1" wird nicht überschrieben.
+ Die private Schlüsseldatei "%1" wird nicht überschrieben.
The ssh-keygen tool at "%1" failed: %2
- Das Programm "ssh-keygen" in "%1" hat einen Fehler festgestellt: %2
+ Das Programm "ssh-keygen" in "%1" hat einen Fehler festgestellt: %2
Choose Private Key File Name
- Name der privaten Schlüsseldatei auswählen
+ Private Schlüsseldatei auswählen
Key Generation Failed
- Fehler bei Erzeugung der Schlüssel
+ Schlüsselerzeugung ist fehlgeschlagen
@@ -48633,30 +48647,30 @@ Zeile: %4, Spalte: %5
None
- Keine
+ Keine
LF
- LF
+ LF
CR
- CR
+ CR
CRLF
- CRLF
+ CRLF
QtC::SilverSearcher
Search Options (optional)
- Sucheinstellungen (optional)
+ Sucheinstellungen (optional)
Silver Searcher is not available on the system.
- Silver Searcher ist auf dem System nicht verfügbar.
+ Silver Searcher ist auf dem System nicht verfügbar.
@@ -55648,88 +55662,92 @@ should a repository require SSH-authentication (see documentation on SSH and the
QtC::WebAssembly
Web Browser
-
+ Webbrowser
WebAssembly Runtime
-
+ WebAssembly-Runtime
Emscripten SDK path:
-
+ Pfad zum Emscripten-SDK:
Select the root directory of an installed %1. Ensure that the activated SDK version is compatible with the %2 or %3 version that you plan to develop against.
-
+ %1=Emscripten SDK, %2=Qt 5, %3=Qt 6
+ Wählen Sie das Wurzelverzeichnis einer Installation von %1. Stellen Sie sicher, dass die eingestellte SDK-Version mit der von Ihnen für das Entwickeln geplanten %2- oder %3-Version kompatibel ist.
Emscripten SDK environment:
-
+ Umgebung für Emscripten-SDK:
Note: %1 supports Qt %2 for WebAssembly and higher. Your installed lower Qt version(s) are not supported.
-
+ %1=the QtC-Version, %2=minimumSupportedQtVersion
+ Hinweis: %1 unterstützt für WebAssembly nur Qt %2 und höher. Ihre älteren installierten Qt-Versionen werden nicht unterstützt.
Adding directories to PATH:
-
+ Füge Verzeichnisse zu PATH hinzu:
Setting environment variables:
-
+ Setze Umgebungsvariablen:
The activated version %1 is not supported by %2. Activate version %3 or higher.
-
+ %1=sdkVersion, %2=QtC-Version, %3=minVersion
+ Die aktivierte Version %1 wird von %2 nicht unterstützt. Benutzen Sie Version %3 oder höher.
Activated version: %1
-
+ Aktivierte Version: %1
WebAssembly
-
+ WebAssembly
Setup Emscripten SDK for WebAssembly? To do it later, select Edit > Preferences > Devices > WebAssembly.
-
+ Emscripten-SDK für WebAssembly einrichten? Dies geht auch später unter Bearbeiten > Einstellungen > Geräte > WebAssembly.
Setup Emscripten SDK
-
+ Emscripten-SDK einrichten
WebAssembly
Qt Version is meant for WebAssembly
-
+ WebAssembly
%1 does not support Qt for WebAssembly below version %2.
-
+ %1=QtC-Version
+ %1 unterstützt Qt für WebAssembly nicht unter Version %2.
Effective emrun call:
-
+ Resultierender emrun-Aufruf:
Default Browser
-
+ Vorgabe-Browser
Web browser:
-
+ Webbrowser:
Emscripten Compiler
-
+ Emscripten-Compiler
Emscripten Compiler %1 for %2
-
+ Emscripten-Compiler %1 für %2
Emscripten
-
+ Emscripten
@@ -58290,35 +58308,35 @@ Are you sure you want to remove the material?
QtC::Vcpkg
Search package...
-
+ Paket suchen...
Vcpkg Manifest Editor
-
+ Vcpkg Manifest-Editor
Name:
-
+ Name:
Version:
- Version:
+ Version:
License:
- Lizenz:
+ Lizenz:
Description:
- Beschreibung:
+ Beschreibung:
Homepage:
-
+ Homepage:
Vcpkg installation
-
+ Vcpkg-Installation
diff --git a/src/app/main.cpp b/src/app/main.cpp
index d4c4a47b8c8..46233ba19ca 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -278,26 +278,16 @@ static Utils::QtcSettings *createUserSettings()
static void setHighDpiEnvironmentVariable()
{
- if (Utils::HostOsInfo::isMacHost())
+ if (Utils::HostOsInfo::isMacHost() || qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY"))
return;
std::unique_ptr settings(createUserSettings());
const bool defaultValue = Utils::HostOsInfo::isWindowsHost();
const bool enableHighDpiScaling = settings->value("Core/EnableHighDpiScaling", defaultValue).toBool();
-
- static const char ENV_VAR_QT_DEVICE_PIXEL_RATIO[] = "QT_DEVICE_PIXEL_RATIO";
- if (enableHighDpiScaling
- && !qEnvironmentVariableIsSet(ENV_VAR_QT_DEVICE_PIXEL_RATIO) // legacy in 5.6, but still functional
- && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR")
- && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR")
- && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) {
- return;
- }
-
- if (!qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY"))
- QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
- Qt::HighDpiScaleFactorRoundingPolicy::Floor);
+ const auto policy = enableHighDpiScaling ? Qt::HighDpiScaleFactorRoundingPolicy::PassThrough
+ : Qt::HighDpiScaleFactorRoundingPolicy::Floor;
+ QGuiApplication::setHighDpiScaleFactorRoundingPolicy(policy);
}
void setPixmapCacheLimit()
diff --git a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
index 8c018daf8c0..4c67ee28fb0 100644
--- a/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
+++ b/src/libs/3rdparty/libptyqt/unixptyprocess.cpp
@@ -54,6 +54,10 @@ bool UnixPtyProcess::startProcess(const QString &shellPath,
int rc = 0;
m_shellProcess.m_handleMaster = ::posix_openpt(O_RDWR | O_NOCTTY);
+
+ int flags = fcntl(m_shellProcess.m_handleMaster, F_GETFL, 0);
+ fcntl(m_shellProcess.m_handleMaster, F_SETFL, flags | O_NONBLOCK);
+
if (m_shellProcess.m_handleMaster <= 0) {
m_lastError = QString("UnixPty Error: unable to open master -> %1").arg(QLatin1String(strerror(errno)));
kill();
@@ -308,10 +312,7 @@ QByteArray UnixPtyProcess::readAll()
qint64 UnixPtyProcess::write(const QByteArray &byteArray)
{
- int result = ::write(m_shellProcess.m_handleMaster, byteArray.constData(), byteArray.size());
- Q_UNUSED(result)
-
- return byteArray.size();
+ return ::write(m_shellProcess.m_handleMaster, byteArray.constData(), byteArray.size());
}
bool UnixPtyProcess::isAvailable()
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index 9059a37ecc3..3995ddde3a7 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -204,7 +204,27 @@ FilePath FilePath::currentWorkingPath()
bool FilePath::isRootPath() const
{
- // FIXME: Make host-independent
+ if (needsDevice()) {
+ QStringView path = pathView();
+ if (osType() != OsTypeWindows)
+ return path == QLatin1String("/");
+
+ // Remote windows paths look like this: "/c:/", so we remove the leading '/'
+ if (path.startsWith('/'))
+ path = path.mid(1);
+
+ if (path.length() > 3)
+ return false;
+
+ if (!startsWithDriveLetter())
+ return false;
+
+ if (path.length() == 3 && path[2] != QLatin1Char('/'))
+ return false;
+
+ return true;
+ }
+
return *this == FilePath::fromString(QDir::rootPath());
}
@@ -1269,7 +1289,16 @@ FilePath FilePath::fromSettings(const QVariant &variant)
const QUrl url = variant.toUrl();
return FilePath::fromParts(url.scheme(), url.host(), url.path());
}
- return FilePath::fromUserInput(variant.toString());
+
+ // The installer sometimes fails and adds "docker:/..." instead of "docker://...
+ // So we fix these paths here in those cases.
+ QString data = variant.toString();
+ if (data.length() > 8 && data.startsWith("docker:/") && data[8] != '/') {
+ qWarning() << "Broken path in settings:" << data << ", applying workaround.";
+ data.insert(8, '/');
+ }
+
+ return FilePath::fromUserInput(data);
}
QVariant FilePath::toSettings() const
@@ -1337,15 +1366,15 @@ bool FilePath::contains(const QString &s) const
/*!
\brief Checks whether the FilePath starts with a drive letter.
-
- Defaults to \c false if it is a non-Windows host or represents a path on device
-
Returns whether FilePath starts with a drive letter
*/
bool FilePath::startsWithDriveLetter() const
{
- const QStringView p = pathView();
- return !needsDevice() && p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
+ QStringView p = pathView();
+ if (needsDevice() && !p.isEmpty())
+ p = p.mid(1);
+
+ return p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
}
/*!
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index 0c6a321c714..4f67ee8105a 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -722,8 +722,7 @@ bool FileUtils::copyRecursively(
bool FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath)
{
QTC_ASSERT(srcFilePath.exists(), return false);
- QTC_ASSERT(srcFilePath.scheme() == tgtFilePath.scheme(), return false);
- QTC_ASSERT(srcFilePath.host() == tgtFilePath.host(), return false);
+ QTC_ASSERT(srcFilePath.isSameDevice(tgtFilePath), return false);
if (tgtFilePath.exists()) {
const QDateTime srcModified = srcFilePath.lastModified();
diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp
index 43d57ded891..8721d6c4214 100644
--- a/src/libs/utils/process.cpp
+++ b/src/libs/utils/process.cpp
@@ -1204,7 +1204,7 @@ FilePath Process::workingDirectory() const
void Process::setWorkingDirectory(const FilePath &dir)
{
if (dir.needsDevice() && d->m_setup.m_commandLine.executable().needsDevice()) {
- QTC_CHECK(dir.host() == d->m_setup.m_commandLine.executable().host());
+ QTC_CHECK(dir.isSameDevice(d->m_setup.m_commandLine.executable()));
}
d->m_setup.m_workingDirectory = dir;
}
@@ -1564,9 +1564,11 @@ qint64 Process::writeRaw(const QByteArray &input)
QTC_ASSERT(state() == QProcess::Running, return -1);
QTC_ASSERT(QThread::currentThread() == thread(), return -1);
qint64 result = -1;
- QMetaObject::invokeMethod(d->m_process.get(), [this, input] {
- d->m_process->write(input);
- }, d->connectionType(), &result);
+ QMetaObject::invokeMethod(
+ d->m_process.get(),
+ [this, input] { return d->m_process->write(input); },
+ d->connectionType(),
+ &result);
return result;
}
diff --git a/src/plugins/beautifier/clangformat/clangformatsettings.cpp b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
index cd1f5e20d23..629e4932403 100644
--- a/src/plugins/beautifier/clangformat/clangformatsettings.cpp
+++ b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
@@ -59,9 +59,6 @@ ClangFormatSettings::ClangFormatSettings()
fallbackStyle.addOption("WebKit");
fallbackStyle.setDefaultValue("Default");
- predefinedStyle.setSettingsKey("predefinedStyle");
- predefinedStyle.setDefaultValue("LLVM");
-
customStyle.setSettingsKey("customStyle");
documentationFilePath = Core::ICore::userResourcePath(Constants::SETTINGS_DIRNAME)
@@ -254,7 +251,8 @@ public:
connect(styleButtonGroup, &QButtonGroup::buttonClicked, this, updateEnabled);
connect(&s.predefinedStyle, &SelectionAspect::volatileValueChanged, this, updateEnabled);
- setOnApply([settings, configurations] {
+ setOnApply([settings, configurations, customizedStyleButton] {
+ settings->usePredefinedStyle.setValue(!customizedStyleButton->isChecked());
settings->customStyle.setValue(configurations->currentConfiguration());
settings->save();
});
diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp
index 928d30d241e..1aae91a186f 100644
--- a/src/plugins/clangformat/clangformatutils.cpp
+++ b/src/plugins/clangformat/clangformatutils.cpp
@@ -161,7 +161,9 @@ clang::format::FormatStyle qtcStyle()
style.SpaceAfterTemplateKeyword = false;
style.SpaceBeforeAssignmentOperators = true;
style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
+#if LLVM_VERSION_MAJOR < 17
style.SpaceInEmptyParentheses = false;
+#endif
style.SpacesBeforeTrailingComments = 1;
#if LLVM_VERSION_MAJOR >= 13
style.SpacesInAngles = FormatStyle::SIAS_Never;
@@ -169,8 +171,12 @@ clang::format::FormatStyle qtcStyle()
style.SpacesInAngles = false;
#endif
style.SpacesInContainerLiterals = false;
+#if LLVM_VERSION_MAJOR >= 17
+ style.SpacesInParens = FormatStyle::SIPO_Never;
+#else
style.SpacesInCStyleCastParentheses = false;
style.SpacesInParentheses = false;
+#endif
style.SpacesInSquareBrackets = false;
addQtcStatementMacros(style);
style.Standard = FormatStyle::LS_Cpp11;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 94f2bf912d6..f52db4b6912 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -14,6 +14,8 @@
#include
+#include
+
#include
#include
@@ -188,6 +190,8 @@ static bool supportsStageForInstallation(const Kit *kit)
return runDevice->id() != buildDevice->id()
&& runDevice->type() != Android::Constants::ANDROID_DEVICE_TYPE
&& runDevice->type() != Ios::Constants::IOS_DEVICE_TYPE
+ && runDevice->type() != Ios::Constants::IOS_SIMULATOR_TYPE
+ && runDevice->type() != BareMetal::Constants::BareMetalOsType
&& runDevice->type() != WebAssembly::Constants::WEBASSEMBLY_DEVICE_TYPE;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
index 9abb3597d15..c5e307cfb70 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -654,9 +654,31 @@ FilePaths CMakeBuildSystem::filesGeneratedFrom(const FilePath &sourceFile) const
FilePath generatedFilePath = buildConfiguration()->buildDirectory().resolvePath(relativePath);
if (sourceFile.suffix() == "ui") {
- generatedFilePath = generatedFilePath
- .pathAppended("ui_" + sourceFile.completeBaseName() + ".h");
- return {generatedFilePath};
+ const QString generatedFileName = "ui_" + sourceFile.completeBaseName() + ".h";
+
+ auto targetNode = this->project()->nodeForFilePath(sourceFile);
+ while (!dynamic_cast(targetNode))
+ targetNode = targetNode->parentFolderNode();
+
+ FilePaths generatedFilePaths;
+ if (targetNode) {
+ const QString autogenSignature = targetNode->buildKey() + "_autogen/include";
+
+ // If AUTOUIC reports the generated header file name, use that path
+ generatedFilePaths = this->project()->files(
+ [autogenSignature, generatedFileName](const Node *n) {
+ const FilePath filePath = n->filePath();
+ if (!filePath.contains(autogenSignature))
+ return false;
+
+ return Project::GeneratedFiles(n) && filePath.endsWith(generatedFileName);
+ });
+ }
+
+ if (generatedFilePaths.empty())
+ generatedFilePaths = {generatedFilePath.pathAppended(generatedFileName)};
+
+ return generatedFilePaths;
}
if (sourceFile.suffix() == "scxml") {
generatedFilePath = generatedFilePath.pathAppended(sourceFile.completeBaseName());
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
index 1455cbf88b9..f38eb2c628f 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
@@ -79,7 +79,7 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList &
}
if (buildDirectory.needsDevice()) {
- if (cmake->cmakeExecutable().host() != buildDirectory.host()) {
+ if (!cmake->cmakeExecutable().isSameDevice(buildDirectory)) {
const QString msg = ::CMakeProjectManager::Tr::tr(
"CMake executable \"%1\" and build directory \"%2\" must be on the same device.")
.arg(cmake->cmakeExecutable().toUserOutput(), buildDirectory.toUserOutput());
diff --git a/src/plugins/cmakeprojectmanager/cmakespecificsettings.cpp b/src/plugins/cmakeprojectmanager/cmakespecificsettings.cpp
index 1fe948cc72a..17d4534ff8a 100644
--- a/src/plugins/cmakeprojectmanager/cmakespecificsettings.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakespecificsettings.cpp
@@ -61,6 +61,12 @@ CMakeSpecificSettings::CMakeSpecificSettings()
// never save this to the settings:
ninjaPath.setToSettingsTransformation(
[](const QVariant &) { return QVariant::fromValue(QString()); });
+ ninjaPath.setFromSettingsTransformation([](const QVariant &from) {
+ // Sometimes the installer appends the same ninja path to the qtcreator.ini file
+ const QString path = from.canConvert() ? from.toStringList().last()
+ : from.toString();
+ return FilePath::fromUserInput(path).toVariant();
+ });
packageManagerAutoSetup.setSettingsKey("PackageManagerAutoSetup");
packageManagerAutoSetup.setDefaultValue(true);
diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
index e4dca5c9b26..2e63a56cee0 100644
--- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp
+++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
@@ -486,6 +486,26 @@ static std::vector extractFragments(const QJsonObj
});
}
+static void addIncludeInfo(std::vector *includes,
+ const QJsonObject &compileGroups,
+ const QString §ion)
+{
+ const std::vector add
+ = transform(compileGroups.value(section).toArray(), [](const QJsonValue &v) {
+ const QJsonObject i = v.toObject();
+ const QString path = i.value("path").toString();
+ const bool isSystem = i.value("isSystem").toBool();
+ const ProjectExplorer::HeaderPath hp(path,
+ isSystem
+ ? ProjectExplorer::HeaderPathType::System
+ : ProjectExplorer::HeaderPathType::User);
+
+ return IncludeInfo{ProjectExplorer::RawProjectPart::frameworkDetectionHeuristic(hp),
+ i.value("backtrace").toInt(-1)};
+ });
+ std::copy(add.cbegin(), add.cend(), std::back_inserter(*includes));
+}
+
static TargetDetails extractTargetDetails(const QJsonObject &root, QString &errorMessage)
{
TargetDetails t;
@@ -581,6 +601,10 @@ static TargetDetails extractTargetDetails(const QJsonObject &root, QString &erro
const QJsonArray compileGroups = root.value("compileGroups").toArray();
t.compileGroups = transform(compileGroups, [](const QJsonValue &v) {
const QJsonObject o = v.toObject();
+ std::vector includes;
+ addIncludeInfo(&includes, o, "includes");
+ // new in CMake 3.27+:
+ addIncludeInfo(&includes, o, "frameworks");
return CompileInfo{
transform(o.value("sourceIndexes").toArray(),
[](const QJsonValue &v) { return v.toInt(-1); }),
@@ -590,21 +614,7 @@ static TargetDetails extractTargetDetails(const QJsonObject &root, QString &erro
const QJsonObject o = v.toObject();
return o.value("fragment").toString();
}),
- transform(
- o.value("includes").toArray(),
- [](const QJsonValue &v) {
- const QJsonObject i = v.toObject();
- const QString path = i.value("path").toString();
- const bool isSystem = i.value("isSystem").toBool();
- const ProjectExplorer::HeaderPath
- hp(path,
- isSystem ? ProjectExplorer::HeaderPathType::System
- : ProjectExplorer::HeaderPathType::User);
-
- return IncludeInfo{
- ProjectExplorer::RawProjectPart::frameworkDetectionHeuristic(hp),
- i.value("backtrace").toInt(-1)};
- }),
+ includes,
transform(o.value("defines").toArray(),
[](const QJsonValue &v) {
const QJsonObject d = v.toObject();
diff --git a/src/plugins/copilot/authwidget.cpp b/src/plugins/copilot/authwidget.cpp
index 559dee30cf9..4052ce600a7 100644
--- a/src/plugins/copilot/authwidget.cpp
+++ b/src/plugins/copilot/authwidget.cpp
@@ -95,14 +95,19 @@ void AuthWidget::updateClient(const Utils::FilePath &nodeJs, const Utils::FilePa
m_client = nullptr;
setState(Tr::tr("Sign In"), false);
m_button->setEnabled(false);
- if (!nodeJs.isExecutableFile() || !agent.exists()) {
+ if (!nodeJs.isExecutableFile() || !agent.exists())
return;
- }
setState(Tr::tr("Sign In"), true);
m_client = new CopilotClient(nodeJs, agent);
connect(m_client, &Client::initialized, this, &AuthWidget::checkStatus);
+ connect(m_client, &QObject::destroyed, this, [destroyedClient = m_client, this]() {
+ if (destroyedClient != m_client)
+ return;
+ m_client = nullptr;
+ m_progressIndicator->hide();
+ });
}
void AuthWidget::signIn()
diff --git a/src/plugins/coreplugin/actionmanager/commandsfile.cpp b/src/plugins/coreplugin/actionmanager/commandsfile.cpp
index 7b69e3da916..f0a1db98608 100644
--- a/src/plugins/coreplugin/actionmanager/commandsfile.cpp
+++ b/src/plugins/coreplugin/actionmanager/commandsfile.cpp
@@ -49,6 +49,36 @@ CommandsFile::CommandsFile(const FilePath &filename)
}
+// XML attributes cannot contain these characters, and
+// QXmlStreamWriter just bails out with an error.
+// QKeySequence::toString() should probably not result in these
+// characters, but it currently does, see QTCREATORBUG-29431
+static bool containsInvalidCharacters(const QString &s)
+{
+ const auto end = s.constEnd();
+ for (auto it = s.constBegin(); it != end; ++it) {
+ // from QXmlStreamWriterPrivate::writeEscaped
+ if (*it == u'\v' || *it == u'\f' || *it <= u'\x1F' || *it >= u'\uFFFE') {
+ return true;
+ }
+ }
+ return false;
+}
+
+static QString toAttribute(const QString &s)
+{
+ if (containsInvalidCharacters(s))
+ return "0x" + QString::fromUtf8(s.toUtf8().toHex());
+ return s;
+}
+
+static QString fromAttribute(const QStringView &s)
+{
+ if (s.startsWith(QLatin1String("0x")))
+ return QString::fromUtf8(QByteArray::fromHex(s.sliced(2).toUtf8()));
+ return s.toString();
+}
+
/*!
\internal
*/
@@ -77,7 +107,7 @@ QMap> CommandsFile::importCommands() const
QTC_ASSERT(!currentId.isEmpty(), continue);
const QXmlStreamAttributes attributes = r.attributes();
if (attributes.hasAttribute(ctx.valueAttribute)) {
- const QString keyString = attributes.value(ctx.valueAttribute).toString();
+ const QString keyString = fromAttribute(attributes.value(ctx.valueAttribute));
QList keys = result.value(currentId);
result.insert(currentId, keys << QKeySequence(keyString));
}
@@ -94,7 +124,6 @@ QMap> CommandsFile::importCommands() const
/*!
\internal
*/
-
bool CommandsFile::exportCommands(const QList &items)
{
FileSaver saver(m_filePath, QIODevice::Text);
@@ -119,7 +148,7 @@ bool CommandsFile::exportCommands(const QList &items)
w.writeAttribute(ctx.idAttribute, id.toString());
for (const QKeySequence &k : item->m_keys) {
w.writeEmptyElement(ctx.keyElement);
- w.writeAttribute(ctx.valueAttribute, k.toString());
+ w.writeAttribute(ctx.valueAttribute, toAttribute(k.toString()));
}
w.writeEndElement(); // Shortcut
}
@@ -127,7 +156,8 @@ bool CommandsFile::exportCommands(const QList &items)
w.writeEndElement();
w.writeEndDocument();
- saver.setResult(&w);
+ if (!saver.setResult(&w))
+ qWarning() << saver.errorString();
}
return saver.finalize();
}
diff --git a/src/plugins/coreplugin/idocument.cpp b/src/plugins/coreplugin/idocument.cpp
index 5dcff9d3fc1..7be7e410116 100644
--- a/src/plugins/coreplugin/idocument.cpp
+++ b/src/plugins/coreplugin/idocument.cpp
@@ -343,10 +343,10 @@ IDocument::OpenResult IDocument::open(QString *errorString, const Utils::FilePat
*/
bool IDocument::save(QString *errorString, const Utils::FilePath &filePath, bool autoSave)
{
- emit aboutToSave(filePath, autoSave);
+ emit aboutToSave(filePath.isEmpty() ? this->filePath() : filePath, autoSave);
const bool success = saveImpl(errorString, filePath, autoSave);
if (success)
- emit saved(filePath, autoSave);
+ emit saved(filePath.isEmpty() ? this->filePath() : filePath, autoSave);
return success;
}
diff --git a/src/plugins/cppeditor/compileroptionsbuilder.cpp b/src/plugins/cppeditor/compileroptionsbuilder.cpp
index 8b7dd11b2d7..317cf7b25dd 100644
--- a/src/plugins/cppeditor/compileroptionsbuilder.cpp
+++ b/src/plugins/cppeditor/compileroptionsbuilder.cpp
@@ -64,6 +64,13 @@ static QString defineDirectiveToDefineOption(const Macro ¯o)
return QString::fromUtf8(option);
}
+static QStringList cpuBlacklist()
+{
+ QStringList blacklist = qtcEnvironmentVariable("QTC_CLANGD_CPU_BLACKLIST")
+ .split(':', Qt::SkipEmptyParts);
+ return blacklist << "cortex-a72.cortex-a53"; // See QTCREATORBUG-29304
+}
+
QStringList XclangArgs(const QStringList &args)
{
QStringList options;
@@ -270,6 +277,7 @@ void CompilerOptionsBuilder::addPicIfCompilerFlagsContainsIt()
void CompilerOptionsBuilder::addCompilerFlags()
{
add(m_compilerFlags.flags);
+ removeUnsupportedCpuFlags();
}
void CompilerOptionsBuilder::addMsvcExceptions()
@@ -375,6 +383,17 @@ void CompilerOptionsBuilder::addIncludeFile(const QString &file)
}
}
+void CompilerOptionsBuilder::removeUnsupportedCpuFlags()
+{
+ const QStringList blacklist = cpuBlacklist();
+ for (auto it = m_options.begin(); it != m_options.end();) {
+ if (it->startsWith("-mcpu=") && blacklist.contains(it->mid(6)))
+ it = m_options.erase(it);
+ else
+ ++it;
+ }
+}
+
void CompilerOptionsBuilder::addIncludedFiles(const QStringList &files)
{
for (const QString &file : files) {
diff --git a/src/plugins/cppeditor/compileroptionsbuilder.h b/src/plugins/cppeditor/compileroptionsbuilder.h
index d47a7e87e3d..55d775120aa 100644
--- a/src/plugins/cppeditor/compileroptionsbuilder.h
+++ b/src/plugins/cppeditor/compileroptionsbuilder.h
@@ -87,6 +87,7 @@ private:
QStringList wrappedMingwHeadersIncludePath() const;
QByteArray msvcVersion() const;
void addIncludeFile(const QString &file);
+ void removeUnsupportedCpuFlags();
private:
const ProjectPart &m_projectPart;
diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp
index bb34174d06a..f27c0ce83c4 100644
--- a/src/plugins/cppeditor/cpprefactoringchanges.cpp
+++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp
@@ -124,6 +124,9 @@ bool CppRefactoringFile::isCursorOn(unsigned tokenIndex) const
bool CppRefactoringFile::isCursorOn(const AST *ast) const
{
+ if (!ast)
+ return false;
+
QTextCursor tc = cursor();
int cursorBegin = tc.selectionStart();
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index ed4a34f3067..1902bf86810 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -749,7 +749,7 @@ bool DebuggerRunTool::fixupParameters()
}
}
- if (!debuggerSettings()->autoEnrichParameters.value()) {
+ if (debuggerSettings()->autoEnrichParameters.value()) {
const FilePath sysroot = rp.sysRoot;
if (rp.debugInfoLocation.isEmpty())
rp.debugInfoLocation = sysroot / "/usr/lib/debug";
diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp
index e192a7d90ac..6c57b593e13 100644
--- a/src/plugins/debugger/loadcoredialog.cpp
+++ b/src/plugins/debugger/loadcoredialog.cpp
@@ -161,7 +161,10 @@ AttachCoreDialog::~AttachCoreDialog()
int AttachCoreDialog::exec()
{
- connect(d->symbolFileName, &PathChooser::textChanged, this, &AttachCoreDialog::changed);
+ connect(d->symbolFileName, &PathChooser::validChanged, this, &AttachCoreDialog::changed);
+ connect(d->coreFileName, &PathChooser::validChanged, this, [this] {
+ coreFileChanged(d->coreFileName->rawFilePath());
+ });
connect(d->coreFileName, &PathChooser::textChanged, this, [this] {
coreFileChanged(d->coreFileName->rawFilePath());
});
diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp
index 1f6f7d93064..bc854a218d3 100644
--- a/src/plugins/fossil/fossilplugin.cpp
+++ b/src/plugins/fossil/fossilplugin.cpp
@@ -247,8 +247,10 @@ class RevertDialog : public QDialog
{
public:
RevertDialog(const QString &title, QWidget *parent = nullptr);
+ QString revision() const { return m_revisionLineEdit->text(); }
- QLineEdit *m_revisionLineEdit;
+private:
+ QLineEdit *m_revisionLineEdit = nullptr;
};
FossilPlugin::~FossilPlugin()
@@ -429,15 +431,11 @@ void FossilPluginPrivate::revertCurrentFile()
const VcsBase::VcsBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return);
- QDialog dialog(Core::ICore::dialogParent());
-
- auto revisionLineEdit = new QLineEdit;
-
- if (dialog.exec() != QDialog::Accepted)
- return;
- m_client.revertFile(state.currentFileTopLevel(),
- state.relativeCurrentFile(),
- revisionLineEdit->text());
+ RevertDialog dialog(Tr::tr("Revert"), Core::ICore::dialogParent());
+ if (dialog.exec() == QDialog::Accepted) {
+ m_client.revertFile(state.currentFileTopLevel(), state.relativeCurrentFile(),
+ dialog.revision());
+ }
}
void FossilPluginPrivate::statusCurrentFile()
@@ -512,7 +510,7 @@ void FossilPluginPrivate::revertAll()
RevertDialog dialog(Tr::tr("Revert"), Core::ICore::dialogParent());
if (dialog.exec() == QDialog::Accepted)
- m_client.revertAll(state.topLevel(), dialog.m_revisionLineEdit->text());
+ m_client.revertAll(state.topLevel(), dialog.revision());
}
void FossilPluginPrivate::statusMulti()
@@ -628,7 +626,7 @@ void FossilPluginPrivate::update()
RevertDialog dialog(Tr::tr("Update"), Core::ICore::dialogParent());
if (dialog.exec() == QDialog::Accepted)
- m_client.update(state.topLevel(), dialog.m_revisionLineEdit->text());
+ m_client.update(state.topLevel(), dialog.revision());
}
void FossilPluginPrivate::configureRepository()
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index c5f30fa036f..3c1affca33f 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -421,9 +421,10 @@ public:
QVector m_projectActions;
QVector m_repositoryActions;
ParameterAction *m_applyCurrentFilePatchAction = nullptr;
- Gerrit::Internal::GerritPlugin m_gerritPlugin;
GitClient m_gitClient;
+ Gerrit::Internal::GerritPlugin m_gerritPlugin;
+
QPointer m_stashDialog;
BranchViewFactory m_branchViewFactory;
QPointer m_remoteDialog;
diff --git a/src/plugins/incredibuild/commandbuilderaspect.cpp b/src/plugins/incredibuild/commandbuilderaspect.cpp
index 5cfbac953b1..3eced7c144f 100644
--- a/src/plugins/incredibuild/commandbuilderaspect.cpp
+++ b/src/plugins/incredibuild/commandbuilderaspect.cpp
@@ -61,7 +61,8 @@ public:
};
CommandBuilderAspect::CommandBuilderAspect(BuildStep *step)
- : d(new CommandBuilderAspectPrivate(step))
+ : BaseAspect(step)
+ , d(new CommandBuilderAspectPrivate(step))
{
}
diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp
index c5c86122fcd..62daa1457c4 100644
--- a/src/plugins/languageclient/languageclientcompletionassist.cpp
+++ b/src/plugins/languageclient/languageclientcompletionassist.cpp
@@ -287,8 +287,13 @@ public:
void setProposal(IAssistProposal *proposal, const QString &prefix)
{
- if (!proposal)
+ if (!proposal) {
+ // Close the proposal if we have no running processor otherwise ignore the empty
+ // proposal and wait for the processor to finish
+ if (!m_processor || !m_processor->running())
+ closeProposal();
return;
+ }
if (proposal->id() != TextEditor::Constants::GENERIC_PROPOSAL_ID) {
// We received something else than a generic proposal so we cannot update the model
closeProposal();
@@ -305,13 +310,14 @@ public:
GenericProposalWidget::updateProposal(std::move(interface));
return;
}
- auto processor = m_provider->createProcessor(interface.get());
- QTC_ASSERT(processor, return);
+ m_processor = m_provider->createProcessor(interface.get());
+ QTC_ASSERT(m_processor, return);
const QString prefix = interface->textAt(m_basePosition,
interface->position() - m_basePosition);
- processor->setAsyncCompletionAvailableHandler([this, processor, prefix](IAssistProposal *proposal) {
+ m_processor->setAsyncCompletionAvailableHandler([this, processor = m_processor, prefix](
+ IAssistProposal *proposal) {
QTC_ASSERT(processor == m_processor, return);
if (!processor->running()) {
// do not delete this processor directly since this function is called from within the processor
@@ -324,11 +330,11 @@ public:
setProposal(proposal, prefix);
});
- setProposal(processor->start(std::move(interface)), prefix);
- if (processor->running())
- m_processor = processor;
- else
- delete processor;
+ setProposal(m_processor->start(std::move(interface)), prefix);
+ if (!m_processor->running()) {
+ delete m_processor;
+ m_processor = nullptr;
+ }
}
private:
diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp
index f41b1193387..1c079eebdfb 100644
--- a/src/plugins/mcusupport/mcupackage.cpp
+++ b/src/plugins/mcusupport/mcupackage.cpp
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -447,7 +448,8 @@ static ToolChain *iarToolChain(const FilePath &path, Id language)
== BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID;
});
if (iarFactory) {
- Toolchains detected = iarFactory->autoDetect(ToolchainDetector({}, {}, {}));
+ Toolchains detected = iarFactory->autoDetect(
+ {{}, DeviceManager::defaultDesktopDevice(), {}});
if (detected.isEmpty())
detected = iarFactory->detectForImport({path, language});
for (auto tc : detected) {
diff --git a/src/plugins/projectexplorer/devicesupport/sshsettings.cpp b/src/plugins/projectexplorer/devicesupport/sshsettings.cpp
index b5f247609e7..be863437f80 100644
--- a/src/plugins/projectexplorer/devicesupport/sshsettings.cpp
+++ b/src/plugins/projectexplorer/devicesupport/sshsettings.cpp
@@ -107,10 +107,10 @@ static FilePath filePathValue(const FilePath &value, const QStringList &candidat
{
if (!value.isEmpty())
return value;
- const FilePaths additionalSearchPaths = sshSettings->searchPathRetriever();
+ Environment env = Environment::systemEnvironment();
+ env.prependToPath(sshSettings->searchPathRetriever());
for (const QString &candidate : candidateFileNames) {
- const FilePath filePath = Environment::systemEnvironment()
- .searchInPath(candidate, additionalSearchPaths);
+ const FilePath filePath = env.searchInPath(candidate);
if (!filePath.isEmpty())
return filePath;
}
diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp
index ea900407bf9..e28264d72b2 100644
--- a/src/plugins/projectexplorer/kitinformation.cpp
+++ b/src/plugins/projectexplorer/kitinformation.cpp
@@ -1377,6 +1377,17 @@ void BuildDeviceKitAspect::devicesChanged()
// --------------------------------------------------------------------------
// EnvironmentKitAspect:
// --------------------------------------------------------------------------
+static EnvironmentItem forceMSVCEnglishItem()
+{
+ static EnvironmentItem item("VSLANG", "1033");
+ return item;
+}
+
+static bool enforcesMSVCEnglish(const EnvironmentItems &changes)
+{
+ return changes.contains(forceMSVCEnglishItem());
+}
+
namespace Internal {
class EnvironmentKitAspectWidget final : public KitAspectWidget
{
@@ -1411,7 +1422,7 @@ private:
void refresh() override
{
- const EnvironmentItems changes = currentEnvironment();
+ const EnvironmentItems changes = envWithoutMSVCEnglishEnforcement();
const QString shortSummary = EnvironmentItem::toStringList(changes).join("; ");
m_summaryLabel->setText(shortSummary.isEmpty() ? Tr::tr("No changes to apply.") : shortSummary);
}
@@ -1423,32 +1434,29 @@ private:
VariableChooser::addSupportForChildWidgets(w, expander);
};
auto changes = EnvironmentDialog::getEnvironmentItems(m_summaryLabel,
- currentEnvironment(),
+ envWithoutMSVCEnglishEnforcement(),
QString(),
polisher);
if (!changes)
return;
if (HostOsInfo::isWindowsHost()) {
- const EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
- if (m_vslangCheckbox->isChecked() && changes->indexOf(forceMSVCEnglishItem) < 0)
- changes->append(forceMSVCEnglishItem);
+ // re-add what envWithoutMSVCEnglishEnforcement removed
+ // or update vslang checkbox if user added it manually
+ if (m_vslangCheckbox->isChecked() && !enforcesMSVCEnglish(*changes))
+ changes->append(forceMSVCEnglishItem());
+ else if (enforcesMSVCEnglish(*changes))
+ m_vslangCheckbox->setChecked(true);
}
-
EnvironmentKitAspect::setEnvironmentChanges(m_kit, *changes);
}
- EnvironmentItems currentEnvironment() const
+ EnvironmentItems envWithoutMSVCEnglishEnforcement() const
{
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
- if (HostOsInfo::isWindowsHost()) {
- const EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
- if (changes.indexOf(forceMSVCEnglishItem) >= 0) {
- m_vslangCheckbox->setCheckState(Qt::Checked);
- changes.removeAll(forceMSVCEnglishItem);
- }
- }
+ if (HostOsInfo::isWindowsHost())
+ changes.removeAll(forceMSVCEnglishItem());
return sorted(std::move(changes), [](const EnvironmentItem &lhs, const EnvironmentItem &rhs)
{ return QString::localeAwareCompare(lhs.name, rhs.name) < 0; });
@@ -1461,13 +1469,14 @@ private:
m_vslangCheckbox->setToolTip(Tr::tr("Either switches MSVC to English or keeps the language and "
"just forces UTF-8 output (may vary depending on the used MSVC "
"compiler)."));
- connect(m_vslangCheckbox, &QCheckBox::toggled, this, [this](bool checked) {
+ if (enforcesMSVCEnglish(EnvironmentKitAspect::environmentChanges(m_kit)))
+ m_vslangCheckbox->setChecked(true);
+ connect(m_vslangCheckbox, &QCheckBox::clicked, this, [this](bool checked) {
EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
- const EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
- if (!checked && changes.indexOf(forceMSVCEnglishItem) >= 0)
- changes.removeAll(forceMSVCEnglishItem);
- if (checked && changes.indexOf(forceMSVCEnglishItem) < 0)
- changes.append(forceMSVCEnglishItem);
+ if (!checked && changes.indexOf(forceMSVCEnglishItem()) >= 0)
+ changes.removeAll(forceMSVCEnglishItem());
+ if (checked && changes.indexOf(forceMSVCEnglishItem()) < 0)
+ changes.append(forceMSVCEnglishItem());
EnvironmentKitAspect::setEnvironmentChanges(m_kit, changes);
});
}
diff --git a/src/plugins/projectexplorer/taskmodel.h b/src/plugins/projectexplorer/taskmodel.h
index 5fa37c02d1a..64df152cdf9 100644
--- a/src/plugins/projectexplorer/taskmodel.h
+++ b/src/plugins/projectexplorer/taskmodel.h
@@ -117,8 +117,12 @@ public:
bool filterIncludesErrors() const { return m_includeErrors; }
void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); }
- QList filteredCategories() const { return m_categoryIds; }
- void setFilteredCategories(const QList &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); }
+ QSet filteredCategories() const { return m_categoryIds; }
+ void setFilteredCategories(const QSet &categoryIds)
+ {
+ m_categoryIds = categoryIds;
+ invalidateFilter();
+ }
Task task(const QModelIndex &index) const { return taskModel()->task(mapToSource(index)); }
Tasks tasks(const QModelIndexList &indexes) const;
@@ -144,7 +148,7 @@ private:
bool m_filterStringIsRegexp = false;
bool m_filterIsInverted = false;
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
- QList m_categoryIds;
+ QSet m_categoryIds;
QString m_filterText;
QRegularExpression m_filterRegexp;
};
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index 703a277f159..7bad834230d 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -327,19 +327,20 @@ void TaskWindow::setCategoryVisibility(Id categoryId, bool visible)
if (!categoryId.isValid())
return;
- QList categories = d->m_filter->filteredCategories();
+ QSet categories = d->m_filter->filteredCategories();
if (visible)
- categories.removeOne(categoryId);
+ categories.remove(categoryId);
else
- categories.append(categoryId);
+ categories.insert(categoryId);
d->m_filter->setFilteredCategories(categories);
}
void TaskWindow::saveSettings()
{
- QStringList categories = Utils::transform(d->m_filter->filteredCategories(), &Id::toString);
+ const QStringList categories = Utils::toList(
+ Utils::transform(d->m_filter->filteredCategories(), &Id::toString));
SessionManager::setValue(QLatin1String(SESSION_FILTER_CATEGORIES), categories);
SessionManager::setValue(QLatin1String(SESSION_FILTER_WARNINGS), d->m_filter->filterIncludesWarnings());
}
@@ -348,7 +349,8 @@ void TaskWindow::loadSettings()
{
QVariant value = SessionManager::value(QLatin1String(SESSION_FILTER_CATEGORIES));
if (value.isValid()) {
- QList categories = Utils::transform(value.toStringList(), &Id::fromString);
+ const QSet categories = Utils::toSet(
+ Utils::transform(value.toStringList(), &Id::fromString));
d->m_filter->setFilteredCategories(categories);
}
value = SessionManager::value(QLatin1String(SESSION_FILTER_WARNINGS));
@@ -369,8 +371,8 @@ void TaskWindow::addCategory(Id categoryId, const QString &displayName, bool vis
{
d->m_model->addCategory(categoryId, displayName, priority);
if (!visible) {
- QList filters = d->m_filter->filteredCategories();
- filters += categoryId;
+ QSet filters = d->m_filter->filteredCategories();
+ filters.insert(categoryId);
d->m_filter->setFilteredCategories(filters);
}
}
@@ -469,7 +471,7 @@ void TaskWindow::updateCategoriesMenu()
d->m_categoriesMenu->clear();
- const QList filteredCategories = d->m_filter->filteredCategories();
+ const QSet filteredCategories = d->m_filter->filteredCategories();
QMap nameToIds;
const QList ids = d->m_model->categoryIds();
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp
index e0717ab7804..0c87f248dbb 100644
--- a/src/plugins/projectexplorer/toolchainoptionspage.cpp
+++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp
@@ -3,10 +3,11 @@
#include "toolchainoptionspage.h"
-#include "toolchain.h"
#include "abi.h"
+#include "devicesupport/devicemanager.h"
#include "projectexplorerconstants.h"
#include "projectexplorertr.h"
+#include "toolchain.h"
#include "toolchainconfigwidget.h"
#include "toolchainmanager.h"
@@ -404,7 +405,7 @@ void ToolChainOptionsWidget::redetectToolchains()
QSet toDelete;
ToolChainManager::resetBadToolchains();
for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) {
- const ToolchainDetector detector(knownTcs, {}, {}); // FIXME: Pass device and search paths
+ const ToolchainDetector detector(knownTcs, DeviceManager::defaultDesktopDevice(), {}); // FIXME: Pass search paths
for (ToolChain * const tc : f->autoDetect(detector)) {
if (knownTcs.contains(tc) || toDelete.contains(tc))
continue;
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 93e13f71f0c..2c2f5695c96 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -512,7 +512,9 @@ QWidget *QMakeStep::createConfigWidget()
connect(abisListWidget, &QListWidget::itemChanged, this, [this] {
if (m_ignoreChanges.isLocked())
return;
- handleAbiWidgetChange();
+ updateAbiWidgets();
+ if (QmakeBuildConfiguration *bc = qmakeBuildConfiguration())
+ BuildManager::buildLists({bc->cleanSteps()});
});
connect(widget, &QObject::destroyed, this, [this] {
@@ -704,7 +706,7 @@ void QMakeStep::updateAbiWidgets()
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
item->setCheckState(selectedAbis.contains(param) ? Qt::Checked : Qt::Unchecked);
}
- handleAbiWidgetChange();
+ abisChanged();
}
}
@@ -713,13 +715,6 @@ void QMakeStep::updateEffectiveQMakeCall()
m_effectiveCall->setValue(effectiveQMakeCall());
}
-void QMakeStep::handleAbiWidgetChange()
-{
- abisChanged();
- if (QmakeBuildConfiguration *bc = qmakeBuildConfiguration())
- BuildManager::buildLists({bc->cleanSteps()});
-}
-
void QMakeStep::recompileMessageBoxFinished(int button)
{
if (button == QMessageBox::Yes) {
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h
index d977eedd904..f72c48d4612 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.h
+++ b/src/plugins/qmakeprojectmanager/qmakestep.h
@@ -155,7 +155,6 @@ private:
void updateAbiWidgets();
void updateEffectiveQMakeCall();
- void handleAbiWidgetChange();
Utils::CommandLine m_qmakeCommand;
Utils::CommandLine m_makeCommand;
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 1562d13b0e4..7cac4c49349 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -1675,8 +1675,8 @@ void DesignerActionManager::createDefaultDesignerActions()
setFlowStartDisplayName,
{},
flowCategory,
- 2,
{},
+ 2,
&setFlowStartItem,
&isFlowItem,
&flowOptionVisible));
diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
index 94bfbfb981f..652a03cdf09 100644
--- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp
@@ -29,8 +29,11 @@ FileTransferMethod defaultTransferMethod(Kit *kit)
return FileTransferMethod::Rsync;
}
- if (runDevice && runDevice->extraData(Constants::SupportsSftp).toBool())
- return FileTransferMethod::Sftp;
+ if (runDevice) {
+ const QVariant sftpInfo = runDevice->extraData(Constants::SupportsSftp);
+ if (!sftpInfo.isValid() || sftpInfo.toBool())
+ return FileTransferMethod::Sftp;
+ }
return FileTransferMethod::GenericCopy;
}
diff --git a/src/plugins/scxmleditor/plugin_interface/eventitem.cpp b/src/plugins/scxmleditor/plugin_interface/eventitem.cpp
index f61517f7cf6..af0827257f3 100644
--- a/src/plugins/scxmleditor/plugin_interface/eventitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/eventitem.cpp
@@ -18,7 +18,7 @@ EventItem::EventItem(const QPointF &pos, BaseItem *parent)
{
m_eventNameItem = new TextItem(this);
m_eventNameItem->setParentItem(this);
- QFont serifFont("Times", 13, QFont::Normal);
+ QFont serifFont("Times", 10, QFont::Normal);
m_eventNameItem->setFont(serifFont);
QString color = editorInfo("fontColor");
@@ -49,7 +49,7 @@ OnEntryExitItem::OnEntryExitItem(BaseItem *parent)
{
m_eventNameItem = new TextItem(this);
m_eventNameItem->setParentItem(this);
- QFont serifFont("Times", 13, QFont::Normal);
+ QFont serifFont("Times", 10, QFont::Normal);
m_eventNameItem->setFont(serifFont);
m_eventNameItem->setDefaultTextColor(Qt::black);
m_eventNameItem->setTextInteractionFlags(Qt::NoTextInteraction);
diff --git a/src/plugins/scxmleditor/plugin_interface/stateitem.cpp b/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
index e53bd8c894e..0dc525e6443 100644
--- a/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/stateitem.cpp
@@ -232,6 +232,9 @@ void StateItem::transitionsChanged()
}
m_transitionRect = rectInternalTransitions;
+ positionOnEntryItems();
+ positionOnExitItems();
+
updateBoundingRect();
}
@@ -437,8 +440,7 @@ void StateItem::updatePolygon()
f.setPixelSize(m_titleRect.height() * 0.65);
m_stateNameItem->setFont(f);
- if (m_onEntryItem)
- m_onEntryItem->setPos(m_titleRect.x(), m_titleRect.bottom());
+ positionOnEntryItems();
positionOnExitItems();
updateTextPositions();
@@ -552,7 +554,7 @@ void StateItem::addChild(ScxmlTag *child)
item->setTag(child);
item->finalizeCreation();
item->updateAttributes();
- m_onEntryItem->setPos(m_titleRect.x(), m_titleRect.bottom());
+ positionOnEntryItems();
} else if (child->tagName() == "onexit") {
OnEntryExitItem *item = new OnEntryExitItem(this);
m_onExitItem = item;
@@ -566,8 +568,18 @@ void StateItem::addChild(ScxmlTag *child)
void StateItem::positionOnExitItems()
{
int offset = m_onEntryItem ? m_onEntryItem->boundingRect().height() : 0;
- if (m_onExitItem)
- m_onExitItem->setPos(m_titleRect.x(), m_titleRect.bottom() + offset);
+ if (m_onExitItem) {
+ auto x = m_transitionRect.isValid() ? m_transitionRect.right() : m_titleRect.x();
+ m_onExitItem->setPos(x, m_titleRect.bottom() + offset);
+ }
+}
+
+void StateItem::positionOnEntryItems()
+{
+ if (m_onEntryItem) {
+ auto x = m_transitionRect.isValid() ? m_transitionRect.right() : m_titleRect.x();
+ m_onEntryItem->setPos(x, m_titleRect.bottom());
+ }
}
QString StateItem::itemId() const
diff --git a/src/plugins/scxmleditor/plugin_interface/stateitem.h b/src/plugins/scxmleditor/plugin_interface/stateitem.h
index beaebe9ebd7..ad3617cc3d5 100644
--- a/src/plugins/scxmleditor/plugin_interface/stateitem.h
+++ b/src/plugins/scxmleditor/plugin_interface/stateitem.h
@@ -75,6 +75,7 @@ private:
void checkParentBoundingRect();
void checkWarningItems();
void positionOnExitItems();
+ void positionOnEntryItems();
TextItem *m_stateNameItem;
StateWarningItem *m_stateWarningItem = nullptr;
diff --git a/src/plugins/terminal/terminalsurface.cpp b/src/plugins/terminal/terminalsurface.cpp
index ea994302318..698f3589b56 100644
--- a/src/plugins/terminal/terminalsurface.cpp
+++ b/src/plugins/terminal/terminalsurface.cpp
@@ -11,6 +11,7 @@
#include
#include
+#include
namespace Terminal::Internal {
@@ -21,6 +22,8 @@ QColor toQColor(const VTermColor &c)
return QColor(qRgb(c.rgb.red, c.rgb.green, c.rgb.blue));
};
+constexpr int batchFlushSize = 256;
+
struct TerminalSurfacePrivate
{
TerminalSurfacePrivate(TerminalSurface *surface,
@@ -33,13 +36,64 @@ struct TerminalSurfacePrivate
, q(surface)
{}
+ void flush()
+ {
+ if (m_writeBuffer.isEmpty())
+ return;
+
+ QByteArray data = m_writeBuffer.left(batchFlushSize);
+ qint64 result = m_writeToPty(data);
+
+ if (result != data.size()) {
+ // Not all data was written, remove the unwritten data from the array
+ data.resize(qMax(0, result));
+ }
+
+ // Remove the written data from the buffer
+ if (data.size() > 0)
+ m_writeBuffer = m_writeBuffer.mid(data.size());
+
+ if (!m_writeBuffer.isEmpty())
+ m_delayWriteTimer.start();
+ }
+
void init()
{
+ m_delayWriteTimer.setInterval(1);
+ m_delayWriteTimer.setSingleShot(true);
+
+ QObject::connect(&m_delayWriteTimer, &QTimer::timeout, &m_delayWriteTimer, [this] {
+ flush();
+ });
+
vterm_set_utf8(m_vterm.get(), true);
static auto writeToPty = [](const char *s, size_t len, void *user) {
auto p = static_cast(user);
- emit p->q->writeToPty(QByteArray(s, static_cast(len)));
+ QByteArray d(s, len);
+
+ // If its just a couple of chars, or we already have data in the writeBuffer,
+ // add the new data to the write buffer and start the delay timer
+ if (d.size() < batchFlushSize || !p->m_writeBuffer.isEmpty()) {
+ p->m_writeBuffer.append(d);
+ p->m_delayWriteTimer.start();
+ return;
+ }
+
+ // Try to write the data ...
+ qint64 result = p->m_writeToPty(d);
+
+ if (result != d.size()) {
+ // if writing failed, append the data to the writeBuffer and start the delay timer
+
+ // Check if partial data may have already been written ...
+ if (result <= 0)
+ p->m_writeBuffer.append(d);
+ else
+ p->m_writeBuffer.append(d.mid(result));
+
+ p->m_delayWriteTimer.start();
+ }
};
vterm_output_set_callback(m_vterm.get(), writeToPty, this);
@@ -313,6 +367,10 @@ struct TerminalSurfacePrivate
ShellIntegration *m_shellIntegration{nullptr};
TerminalSurface *q;
+ QTimer m_delayWriteTimer;
+ QByteArray m_writeBuffer;
+
+ TerminalSurface::WriteToPty m_writeToPty;
};
TerminalSurface::TerminalSurface(QSize initialGridSize, ShellIntegration *shellIntegration)
@@ -385,7 +443,7 @@ void TerminalSurface::clearAll()
vterm_input_write(d->m_vterm.get(), data.constData(), data.size());
// Send Ctrl+L which will clear the screen
- emit writeToPty(QByteArray("\f"));
+ d->m_writeToPty(QByteArray("\f"));
}
void TerminalSurface::resize(QSize newSize)
@@ -419,8 +477,14 @@ void TerminalSurface::pasteFromClipboard(const QString &clipboardText)
return;
vterm_keyboard_start_paste(d->m_vterm.get());
- for (unsigned int ch : clipboardText.toUcs4())
+ for (unsigned int ch : clipboardText.toUcs4()) {
+ // Workaround for weird nano behavior to correctly paste newlines
+ // see: http://savannah.gnu.org/bugs/?49176
+ // and: https://github.com/kovidgoyal/kitty/issues/994
+ if (ch == '\n')
+ ch = '\r';
vterm_keyboard_unichar(d->m_vterm.get(), ch, VTERM_MOD_NONE);
+ }
vterm_keyboard_end_paste(d->m_vterm.get());
if (!d->m_altscreen) {
@@ -487,6 +551,11 @@ ShellIntegration *TerminalSurface::shellIntegration() const
return d->m_shellIntegration;
}
+void TerminalSurface::setWriteToPty(WriteToPty writeToPty)
+{
+ d->m_writeToPty = writeToPty;
+}
+
CellIterator TerminalSurface::begin() const
{
auto res = CellIterator(this, {0, 0});
diff --git a/src/plugins/terminal/terminalsurface.h b/src/plugins/terminal/terminalsurface.h
index a6fc7425d48..3b737836f6b 100644
--- a/src/plugins/terminal/terminalsurface.h
+++ b/src/plugins/terminal/terminalsurface.h
@@ -95,8 +95,9 @@ public:
ShellIntegration *shellIntegration() const;
+ using WriteToPty = std::function;
+ void setWriteToPty(WriteToPty writeToPty);
signals:
- void writeToPty(const QByteArray &data);
void invalidated(QRect grid);
void fullSizeChanged(QSize newSize);
void cursorChanged(Cursor oldCursor, Cursor newCursor);
diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp
index 4b6442753e1..dd105223536 100644
--- a/src/plugins/terminal/terminalwidget.cpp
+++ b/src/plugins/terminal/terminalwidget.cpp
@@ -327,10 +327,12 @@ void TerminalWidget::closeTerminal()
deleteLater();
}
-void TerminalWidget::writeToPty(const QByteArray &data)
+qint64 TerminalWidget::writeToPty(const QByteArray &data)
{
if (m_process && m_process->isRunning())
- m_process->writeRaw(data);
+ return m_process->writeRaw(data);
+
+ return data.size();
}
void TerminalWidget::setupSurface()
@@ -351,10 +353,8 @@ void TerminalWidget::setupSurface()
}
});
- connect(m_surface.get(),
- &Internal::TerminalSurface::writeToPty,
- this,
- &TerminalWidget::writeToPty);
+ m_surface->setWriteToPty([this](const QByteArray &data) { return writeToPty(data); });
+
connect(m_surface.get(), &Internal::TerminalSurface::fullSizeChanged, this, [this] {
updateScrollBars();
});
diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h
index 11cd9335cc9..2d0f6b16df7 100644
--- a/src/plugins/terminal/terminalwidget.h
+++ b/src/plugins/terminal/terminalwidget.h
@@ -129,7 +129,7 @@ protected:
void setupColors();
void setupActions();
- void writeToPty(const QByteArray &data);
+ qint64 writeToPty(const QByteArray &data);
int paintCell(QPainter &p,
const QRectF &cellRect,
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index f8512e9a111..98a3eda4a1e 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -837,7 +837,7 @@ bool TextDocument::reload(QString *errorString, const FilePath &realFilePath)
auto documentLayout =
qobject_cast(d->m_document.documentLayout());
if (documentLayout)
- documentLayout->documentAboutToReload(); // removes text marks non-permanently
+ documentLayout->documentAboutToReload(this); // removes text marks non-permanently
bool success = openImpl(errorString, filePath(), realFilePath, /*reload =*/true)
== OpenResult::Success;
diff --git a/src/plugins/texteditor/textdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp
index 08c1e21117b..d16befe9ab5 100644
--- a/src/plugins/texteditor/textdocumentlayout.cpp
+++ b/src/plugins/texteditor/textdocumentlayout.cpp
@@ -4,9 +4,16 @@
#include "textdocumentlayout.h"
#include "fontsettings.h"
#include "textdocument.h"
+#include "texteditorplugin.h"
#include "texteditorsettings.h"
+
#include
+#include
+
#include
+#ifdef WITH_TESTS
+#include
+#endif
namespace TextEditor {
@@ -667,11 +674,15 @@ TextMarks TextDocumentLayout::documentClosing()
return marks;
}
-void TextDocumentLayout::documentAboutToReload()
+void TextDocumentLayout::documentAboutToReload(TextDocument *baseTextDocument)
{
m_reloadMarks = documentClosing();
- for (TextMark *mark : std::as_const(m_reloadMarks))
- mark->setDeleteCallback([this, mark] { m_reloadMarks.removeOne(mark); });
+ for (TextMark *mark : std::as_const(m_reloadMarks)) {
+ mark->setDeleteCallback([this, mark, baseTextDocument] {
+ baseTextDocument->removeMarkFromMarksCache(mark);
+ m_reloadMarks.removeOne(mark);
+ });
+ }
}
void TextDocumentLayout::documentReloaded(TextDocument *baseTextDocument)
@@ -860,4 +871,23 @@ TextSuggestion::TextSuggestion()
TextSuggestion::~TextSuggestion() = default;
+#ifdef WITH_TESTS
+
+void Internal::TextEditorPlugin::testDeletingMarkOnReload()
+{
+ auto doc = new TextDocument();
+ doc->setFilePath(Utils::TemporaryDirectory::masterDirectoryFilePath() / "TestMarkDoc.txt");
+ doc->setPlainText("asd");
+ auto documentLayout = qobject_cast(doc->document()->documentLayout());
+ QVERIFY(documentLayout);
+ auto mark = new TextMark(doc, 1, TextMarkCategory{"testMark","testMark"});
+ QVERIFY(doc->marks().contains(mark));
+ documentLayout->documentAboutToReload(doc); // removes text marks non-permanently
+ delete mark;
+ documentLayout->documentReloaded(doc); // re-adds text marks
+ QVERIFY(!doc->marks().contains(mark));
+}
+
+#endif
+
} // namespace TextEditor
diff --git a/src/plugins/texteditor/textdocumentlayout.h b/src/plugins/texteditor/textdocumentlayout.h
index 33387093da7..427500a8326 100644
--- a/src/plugins/texteditor/textdocumentlayout.h
+++ b/src/plugins/texteditor/textdocumentlayout.h
@@ -246,7 +246,7 @@ public:
QRectF blockBoundingRect(const QTextBlock &block) const override;
TextMarks documentClosing();
- void documentAboutToReload();
+ void documentAboutToReload(TextDocument *baseTextDocument);
void documentReloaded(TextDocument *baseextDocument);
void updateMarksLineNumber();
void updateMarksBlock(const QTextBlock &block);
diff --git a/src/plugins/texteditor/texteditorplugin.h b/src/plugins/texteditor/texteditorplugin.h
index 3df46c0b578..f5725061950 100644
--- a/src/plugins/texteditor/texteditorplugin.h
+++ b/src/plugins/texteditor/texteditorplugin.h
@@ -40,6 +40,8 @@ private slots:
void testFormatting_data();
void testFormatting();
+
+ void testDeletingMarkOnReload();
#endif
};
diff --git a/src/shared/qbs b/src/shared/qbs
index d75d1e8f1a1..d8c97a5f0b1 160000
--- a/src/shared/qbs
+++ b/src/shared/qbs
@@ -1 +1 @@
-Subproject commit d75d1e8f1a18fd77ec9b80724c6d30ad6b8e064e
+Subproject commit d8c97a5f0b1f85e79829dbcc63b82bc5b1d83233
diff --git a/src/tools/process_stub/main.cpp b/src/tools/process_stub/main.cpp
index 00312b833f6..dfd9ce5613d 100644
--- a/src/tools/process_stub/main.cpp
+++ b/src/tools/process_stub/main.cpp
@@ -24,6 +24,7 @@
#ifdef Q_OS_LINUX
#include
+#include
#endif
#include
@@ -221,7 +222,23 @@ void onInferiorStarted()
if (!debugMode)
sendPid(inferiorId);
#else
+ qCInfo(log) << "Detaching ...";
ptrace(PTRACE_DETACH, inferiorId, 0, SIGSTOP);
+
+ // Wait until the process actually finished detaching
+ int status = 0;
+ waitpid(inferiorId, &status, WUNTRACED);
+ if (log().isInfoEnabled()) {
+ if (WIFEXITED(status))
+ qCInfo(log) << "inferior exited, status=" << WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ qCInfo(log) << "inferior killed by signal" << WTERMSIG(status);
+ else if (WIFSTOPPED(status))
+ qCInfo(log) << "inferior stopped by signal" << WSTOPSIG(status);
+ else if (WIFCONTINUED(status))
+ qCInfo(log) << "inferior continued";
+ }
+
sendPid(inferiorId);
#endif
}
diff --git a/src/tools/sdktool/addqtoperation.cpp b/src/tools/sdktool/addqtoperation.cpp
index 61e19855ff6..6b372b1efd9 100644
--- a/src/tools/sdktool/addqtoperation.cpp
+++ b/src/tools/sdktool/addqtoperation.cpp
@@ -252,6 +252,15 @@ void AddQtOperation::unittest()
QCOMPARE(version1.value(QLatin1String(QMAKE)).toString(), QLatin1String("/tmp/test/qmake2"));
QVERIFY(version1.contains(QLatin1String("extraData")));
QCOMPARE(version1.value(QLatin1String("extraData")).toString(), QLatin1String("extraValue"));
+
+ // Docker paths
+ qtData.m_id = "testId3";
+ qtData.m_qmake = "docker://image///path/to//some/qmake";
+
+ map = qtData.addQt(map);
+ QVariantMap version2 = map.value(QLatin1String("QtVersion.2")).toMap();
+ QVERIFY(version2.contains(QLatin1String(QMAKE)));
+ QCOMPARE(version2.value(QLatin1String(QMAKE)).toString(), QLatin1String("docker://image/path/to/some/qmake"));
}
#endif
@@ -279,7 +288,7 @@ QVariantMap AddQtData::addQt(const QVariantMap &map) const
const QString qt = QString::fromLatin1(PREFIX) + QString::number(versionCount);
// Sanitize qmake path:
- QString saneQmake = QDir::cleanPath(m_qmake);
+ const QString saneQmake = cleanPath(m_qmake);
// insert data:
KeyValuePairList data;
diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp
index 7a81c3c7adf..d045a440d47 100644
--- a/src/tools/sdktool/operation.cpp
+++ b/src/tools/sdktool/operation.cpp
@@ -84,7 +84,7 @@ bool Operation::save(const QVariantMap &map, const QString &file) const
return false;
}
- QString dirName = QDir::cleanPath(path + "/..");
+ QString dirName = cleanPath(path + "/..");
QDir dir(dirName);
if (!dir.exists() && !dir.mkpath(QLatin1String("."))) {
std::cerr << "Error: Could not create directory " << qPrintable(dirName)
@@ -108,3 +108,12 @@ bool Operation::save(const QVariantMap &map, const QString &file) const
}
return true;
}
+
+QString cleanPath(const QString &orig)
+{
+ // QDir::cleanPath() destroys "//", one of which might be needed.
+ const int pos = orig.indexOf("://");
+ if (pos == -1)
+ return QDir::cleanPath(orig);
+ return orig.left(pos) + "://" + QDir::cleanPath(orig.mid(pos + 3));
+}
diff --git a/src/tools/sdktool/operation.h b/src/tools/sdktool/operation.h
index 886ed386675..438bf302b75 100644
--- a/src/tools/sdktool/operation.h
+++ b/src/tools/sdktool/operation.h
@@ -22,6 +22,8 @@ using KeyValuePairList = QList;
QVariant valueFromString(const QString &v);
+QString cleanPath(const QString &orig);
+
class Operation
{
public:
diff --git a/src/tools/sdktool/sdkpersistentsettings.cpp b/src/tools/sdktool/sdkpersistentsettings.cpp
index 7fda2d8d03c..b72fffa4c57 100644
--- a/src/tools/sdktool/sdkpersistentsettings.cpp
+++ b/src/tools/sdktool/sdkpersistentsettings.cpp
@@ -3,6 +3,8 @@
#include "sdkpersistentsettings.h"
+#include "operation.h" // for cleanPath()
+
#include
#include
#include
@@ -826,7 +828,7 @@ void SdkPersistentSettingsWriter::setContents(const QVariantMap &data)
bool SdkPersistentSettingsWriter::write(const QVariantMap &data, QString *errorString) const
{
- const QString parentDir = QDir::cleanPath(m_fileName + "/..");
+ const QString parentDir = cleanPath(m_fileName + "/..");
const QFileInfo fi(parentDir);
if (!(fi.exists() && fi.isDir() && fi.isWritable())) {
diff --git a/tests/auto/utils/filepath/tst_filepath.cpp b/tests/auto/utils/filepath/tst_filepath.cpp
index f9e10d5e207..6a269af7712 100644
--- a/tests/auto/utils/filepath/tst_filepath.cpp
+++ b/tests/auto/utils/filepath/tst_filepath.cpp
@@ -115,6 +115,8 @@ private slots:
void sort();
void sort_data();
+ void isRootPath();
+
private:
QTemporaryDir tempDir;
QString rootPath;
@@ -1308,6 +1310,14 @@ void tst_filepath::startsWithDriveLetter_data()
QTest::newRow("simple-win") << FilePath::fromString("c:/a") << true;
QTest::newRow("simple-linux") << FilePath::fromString("/c:/a") << false;
QTest::newRow("relative") << FilePath("a/b") << false;
+
+ QTest::newRow("remote-slash") << FilePath::fromString("docker://1234/") << false;
+ QTest::newRow("remote-single-letter") << FilePath::fromString("docker://1234/c") << false;
+ QTest::newRow("remote-drive") << FilePath::fromString("docker://1234/c:") << true;
+ QTest::newRow("remote-invalid-drive") << FilePath::fromString("docker://1234/c:a") << true;
+ QTest::newRow("remote-with-path") << FilePath::fromString("docker://1234/c:/a") << true;
+ QTest::newRow("remote-z") << FilePath::fromString("docker://1234/z:") << true;
+ QTest::newRow("remote-1") << FilePath::fromString("docker://1234/1:") << false;
}
void tst_filepath::startsWithDriveLetter()
@@ -1656,6 +1666,31 @@ void tst_filepath::sort()
QCOMPARE(sortedPaths, sorted);
}
+void tst_filepath::isRootPath()
+{
+ FilePath localRoot = FilePath::fromString(QDir::rootPath());
+ QVERIFY(localRoot.isRootPath());
+
+ FilePath localNonRoot = FilePath::fromString(QDir::rootPath() + "x");
+ QVERIFY(!localNonRoot.isRootPath());
+
+ if (HostOsInfo::isWindowsHost()) {
+ FilePath remoteWindowsRoot = FilePath::fromString("device://test/c:/");
+ QVERIFY(remoteWindowsRoot.isRootPath());
+
+ FilePath remoteWindowsRoot1 = FilePath::fromString("device://test/c:");
+ QVERIFY(remoteWindowsRoot1.isRootPath());
+
+ FilePath remoteWindowsNotRoot = FilePath::fromString("device://test/c:/x");
+ QVERIFY(!remoteWindowsNotRoot.isRootPath());
+ } else {
+ FilePath remoteRoot = FilePath::fromString("device://test/");
+ QVERIFY(remoteRoot.isRootPath());
+
+ FilePath remotePath = FilePath::fromString("device://test/x");
+ QVERIFY(!remotePath.isRootPath());
+ }
+}
void tst_filepath::sort_data()
{
QTest::addColumn("input");
diff --git a/tests/system/0001-Fix-build-on-macOS.patch b/tests/system/0001-Fix-build-on-macOS.patch
new file mode 100644
index 00000000000..124a6b7a9c6
--- /dev/null
+++ b/tests/system/0001-Fix-build-on-macOS.patch
@@ -0,0 +1,33 @@
+From e5aec585120ca65b92e642b50b1552f75df26b93 Mon Sep 17 00:00:00 2001
+From: Christian Stenger
+Date: Thu, 27 Jul 2023 08:49:30 +0200
+Subject: [PATCH] Fix build on macOS
+
+---
+ src/CMakeLists.txt | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index 7be6aad..0cad721 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -18,7 +18,6 @@ if(APPLE)
+ set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${speedcrunch_VERSION})
+ set(MACOSX_BUNDLE_VERSION ${speedcrunch_VERSION})
+ set(MACOSX_BUNDLE_LONG_VERSION_STRING Version ${speedcrunch_VERSION})
+- set(CMAKE_OSX_ARCHITECTURES ppc;i386)
+ else(APPLE)
+ set(PROGNAME speedcrunch)
+ endif(APPLE)
+@@ -71,7 +70,7 @@ if(APPLE)
+ set( speedcrunch_RESOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.app/Contents/Resources )
+ add_custom_command(TARGET ${PROGNAME} POST_BUILD
+ COMMAND mkdir ARGS -p ${speedcrunch_RESOURCE_DIR}
+- COMMAND cp ARGS -f resources/${MACOSX_BUNDLE_ICON_FILE} ${speedcrunch_RESOURCE_DIR})
++ COMMAND cp ARGS -f ${CMAKE_CURRENT_SOURCE_DIR}/resources/${MACOSX_BUNDLE_ICON_FILE} ${speedcrunch_RESOURCE_DIR})
+ endif(APPLE)
+
+ add_custom_target(confclean COMMAND rm -rf Makefile CMakeFiles/ CMakeCache.txt cmake_install.cmake DartTestfile.txt install_manifest.txt)
+--
+2.32.0 (Apple Git-132)
+
diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py
index 7176afc8e59..b878f9efef6 100644
--- a/tests/system/shared/debugger.py
+++ b/tests/system/shared/debugger.py
@@ -238,7 +238,7 @@ def __logDebugResult__():
def verifyBreakPoint(bpToVerify):
if isinstance(bpToVerify, dict):
- fileName = list(bpToVerify.keys())[0]
+ fileName = next(iter(bpToVerify.keys()))
editor = getEditorForFileSuffix(fileName)
if editor:
test.compare(waitForObject(":DebugModeWidget_QComboBox").toolTip, fileName,
@@ -247,7 +247,7 @@ def verifyBreakPoint(bpToVerify):
windowTitle = str(waitForObject(":Qt Creator_Core::Internal::MainWindow").windowTitle)
test.verify(windowTitle.startswith(os.path.basename(fileName) + " "),
"Verify that Creator's window title changed according to current file")
- return test.compare(line, list(bpToVerify.values())[0],
+ return test.compare(line, next(iter(bpToVerify.values())),
"Compare hit breakpoint to expected line number in %s" % fileName)
else:
test.fatal("Expected a dict for bpToVerify - got '%s'" % className(bpToVerify))
diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py
index d1e44102bcc..b39ef8060ee 100644
--- a/tests/system/shared/project.py
+++ b/tests/system/shared/project.py
@@ -248,11 +248,16 @@ def createProject_Qt_GUI(path, projectName, checks=True, addToVersionControl="")
type(editorWidget, "Myname")
result = re.search(pattern.replace("name", "Myname"), str(editorWidget.plainText))
+ failMsg = ("Step 5: Seems that not all instances of variable had been renamed "
+ "- Content of editor:\n%s" % editorWidget.plainText)
if result:
test.passes("Step 5: Verifying if: A value for a variable is inserted and all "
"instances of the variable within the snippet are renamed.")
+ elif JIRA.isBugStillOpen(29012):
+ test.xfail(failMsg)
else:
- test.fail("Step 5: Seems that not all instances of variable had been renamed "
- "- Content of editor:\n%s" % editorWidget.plainText)
+ test.fail(failMsg)
invokeMenuItem('File', 'Revert "main.cpp" to Saved')
clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton"))
invokeMenuItem("File", "Exit")
diff --git a/tests/system/suite_HELP/tst_HELP02/test.py b/tests/system/suite_HELP/tst_HELP02/test.py
index 8b6c32b7ded..9c5104087e0 100644
--- a/tests/system/suite_HELP/tst_HELP02/test.py
+++ b/tests/system/suite_HELP/tst_HELP02/test.py
@@ -44,7 +44,7 @@ def checkQtCreatorHelpVersion(expectedVersion):
helpContentWidget = waitForObject(':Qt Creator_QHelpContentWidget', 5000)
waitFor("any(map(rightStart, dumpItems(helpContentWidget.model())))", 10000)
items = dumpItems(helpContentWidget.model())
- test.compare(list(filter(rightStart, items))[0],
+ test.compare(next(iter(filter(rightStart, items))),
'Qt Creator Manual %s' % expectedVersion,
'Verifying whether manual uses expected version.')
except:
diff --git a/tests/system/suite_debugger/tst_cli_output_console/test.py b/tests/system/suite_debugger/tst_cli_output_console/test.py
index 9c7235cddb2..aed9089fed9 100644
--- a/tests/system/suite_debugger/tst_cli_output_console/test.py
+++ b/tests/system/suite_debugger/tst_cli_output_console/test.py
@@ -12,7 +12,11 @@ def main():
startQC()
if not startedWithoutPluginError():
return
- createProject_Qt_Console(tempDir(), project)
+ targets = []
+ if platform.system() in ('Microsoft', 'Windows'):
+ # Qt5.10 has constructs that do not work on Win because of limitation to older C++
+ targets = [Targets.DESKTOP_5_14_1_DEFAULT, Targets.DESKTOP_6_2_4]
+ createProject_Qt_Console(tempDir(), project, targets=targets)
mainEditor = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget")
replaceEditorContent(mainEditor, "")
diff --git a/tests/system/suite_general/tst_cmake_speedcrunch/test.py b/tests/system/suite_general/tst_cmake_speedcrunch/test.py
index 64d8d877f0d..4f75d43eb9d 100644
--- a/tests/system/suite_general/tst_cmake_speedcrunch/test.py
+++ b/tests/system/suite_general/tst_cmake_speedcrunch/test.py
@@ -9,7 +9,7 @@ def cmakeSupported():
versionLines = filter(lambda line: "cmake version " in line,
getOutputFromCmdline(["cmake", "--version"]).splitlines())
try:
- versionLine = list(versionLines)[0]
+ versionLine = next(iter(versionLines))
test.log("Using " + versionLine)
matcher = re.match("cmake version (\d+)\.(\d+)\.\d+", versionLine)
major = __builtin__.int(matcher.group(1))
@@ -32,6 +32,16 @@ def main():
if not SpeedCrunchPath:
test.fatal("Could not clone SpeedCrunch")
return
+ # patch CMakeLists.txt outside of QC
+ try:
+ patchFile = os.path.join(os.path.dirname(__file__),
+ "..", "..", "0001-Fix-build-on-macOS.patch")
+ subprocess.check_call(["git", "am", patchFile], cwd=SpeedCrunchPath)
+ test.log("Patched speedcrunch.")
+ except:
+ t, v = sys.exc_info()[:2]
+ test.warning("Patching speedcrunch failed.", "%s(%s)" % (str(t), str(v)))
+
startQC()
if not startedWithoutPluginError():
return
diff --git a/tests/system/suite_general/tst_cmake_speedcrunch/testdata/projecttree_speedcrunch.tsv b/tests/system/suite_general/tst_cmake_speedcrunch/testdata/projecttree_speedcrunch.tsv
index 2fd1d59bb2b..82a7ae6ac84 100644
--- a/tests/system/suite_general/tst_cmake_speedcrunch/testdata/projecttree_speedcrunch.tsv
+++ b/tests/system/suite_general/tst_cmake_speedcrunch/testdata/projecttree_speedcrunch.tsv
@@ -1,6 +1,5 @@
"text" "nestinglevel"
"CMakeLists.txt" "0"
-"speedcrunch" "0"
"Header Files" "1"
"genericdock.h" "2"
"Source Files" "1"
diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py
index 8579111b02c..d521f2092dd 100644
--- a/tests/system/suite_general/tst_create_proj_wizard/test.py
+++ b/tests/system/suite_general/tst_create_proj_wizard/test.py
@@ -49,8 +49,8 @@ def main():
availableProjectTypes.append({category:template})
safeClickButton("Cancel")
for current in availableProjectTypes:
- category = list(current.keys())[0]
- template = list(current.values())[0]
+ category = next(iter(current.keys()))
+ template = next(iter(current.values()))
with TestSection("Testing project template %s -> %s" % (category, template)):
displayedPlatforms = __createProject__(category, template)
if template.startswith("Qt Quick Application"):
diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py
index ce026e98d36..57d7ae02cb1 100644
--- a/tests/system/suite_general/tst_default_settings/test.py
+++ b/tests/system/suite_general/tst_default_settings/test.py
@@ -311,15 +311,15 @@ def __compareCompilers__(foundCompilers, expectedCompilers):
for currentExp in expectedCompilers:
if isString(currentExp):
continue
- key = list(currentExp.keys())[0]
+ key = next(iter(currentExp.keys()))
# the regex .*? is used for the different possible version strings of the WinSDK
# if it's present a regex will be validated otherwise simple string comparison
# same applies for [.0-9]+ which is used for minor/patch versions
isRegex = ".*?" in key or "[.0-9]+" in key
- if (((isRegex and re.match(key, list(currentFound.keys())[0], flags)))
+ if (((isRegex and re.match(key, next(iter(currentFound.keys())), flags)))
or currentFound.keys() == currentExp.keys()):
- if ((isWin and os.path.abspath(list(currentFound.values())[0].lower())
- == os.path.abspath(list(currentExp.values())[0].lower()))
+ if ((isWin and os.path.abspath(next(iter(currentFound.values())).lower())
+ == os.path.abspath(next(iter(currentExp.values())).lower()))
or currentFound.values() == currentExp.values()):
foundExp = True
break
@@ -359,24 +359,22 @@ def __lowerStrs__(iterable):
def __checkCreatedSettings__(settingsFolder):
waitForCleanShutdown()
qtProj = os.path.join(settingsFolder, "QtProject")
- folders = []
- files = [{os.path.join(qtProj, "QtCreator.db"):0},
- {os.path.join(qtProj, "QtCreator.ini"):30}]
- folders.append(os.path.join(qtProj, "qtcreator"))
- files.extend([{os.path.join(folders[0], "debuggers.xml"):0},
- {os.path.join(folders[0], "devices.xml"):0},
- {os.path.join(folders[0], "helpcollection.qhc"):0},
- {os.path.join(folders[0], "profiles.xml"):0},
- {os.path.join(folders[0], "qtversion.xml"):0},
- {os.path.join(folders[0], "toolchains.xml"):0}])
- folders.extend([os.path.join(folders[0], "generic-highlighter"),
- os.path.join(folders[0], "macros")])
+ creatorFolder = os.path.join(qtProj, "qtcreator")
+ folders = [creatorFolder,
+ os.path.join(creatorFolder, "generic-highlighter"),
+ os.path.join(creatorFolder, "macros")]
+ files = {os.path.join(qtProj, "QtCreator.db"):0,
+ os.path.join(qtProj, "QtCreator.ini"):30,
+ os.path.join(creatorFolder, "debuggers.xml"):0,
+ os.path.join(creatorFolder, "devices.xml"):0,
+ os.path.join(creatorFolder, "helpcollection.qhc"):0,
+ os.path.join(creatorFolder, "profiles.xml"):0,
+ os.path.join(creatorFolder, "qtversion.xml"):0,
+ os.path.join(creatorFolder, "toolchains.xml"):0}
for f in folders:
test.verify(os.path.isdir(f),
"Verifying whether folder '%s' has been created." % os.path.basename(f))
- for f in files:
- fName = list(f.keys())[0]
- fMinSize = list(f.values())[0]
+ for fName, fMinSize in files.items():
text = "created non-empty"
if fMinSize > 0:
text = "modified"
diff --git a/tests/system/suite_general/tst_opencreator_qbs/test.py b/tests/system/suite_general/tst_opencreator_qbs/test.py
index 6ff692d41cf..86c8f99e4da 100644
--- a/tests/system/suite_general/tst_opencreator_qbs/test.py
+++ b/tests/system/suite_general/tst_opencreator_qbs/test.py
@@ -8,7 +8,7 @@ def main():
if not neededFilePresent(pathCreator):
return
- startQC()
+ startQC(["-noload", "ClangCodeModel"])
if not startedWithoutPluginError():
return
openQbsProject(pathCreator)
@@ -24,7 +24,7 @@ def main():
else:
test.warning("Parsing project timed out")
compareProjectTree(rootNodeTemplate % "Qt Creator", "projecttree_creator.tsv")
- buildIssuesTexts = map(lambda i: str(i[0]), getBuildIssues())
+ buildIssuesTexts = map(lambda i: str(i[0]), getBuildIssues(False))
deprecationWarnings = "\n".join(set(filter(lambda s: "deprecated" in s, buildIssuesTexts)))
if deprecationWarnings:
test.warning("Creator claims that the .qbs file uses deprecated features.",
diff --git a/tests/system/suite_general/tst_openqt_creator/test.py b/tests/system/suite_general/tst_openqt_creator/test.py
index 257a32d8161..8bdb82e4e53 100644
--- a/tests/system/suite_general/tst_openqt_creator/test.py
+++ b/tests/system/suite_general/tst_openqt_creator/test.py
@@ -13,7 +13,7 @@ def main():
if not pathSpeedcrunch:
test.fatal("Could not clone SpeedCrunch")
return
- startQC()
+ startQC(["-noload", "ClangCodeModel"])
if not startedWithoutPluginError():
return
diff --git a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv
index e0e8060e7bd..662eb4fe255 100644
--- a/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv
+++ b/tests/system/suite_general/tst_openqt_creator/testdata/projecttree_creator.tsv
@@ -4166,7 +4166,6 @@
"Headers" "5"
"touchbar.h" "6"
"Sources" "5"
-"touchbar.cpp" "6"
"Headers" "4"
"optional" "6"
"optional.hpp" "7"
@@ -16895,21 +16894,6 @@
"qtc-askpass-main.cpp" "4"
"Other files" "3"
"qtc-askpass.qbs" "4"
-"qtcreatortool" "3"
-"qtcreatortool.pri" "4"
-"qtcreator" "4"
-"qtcreator.pri" "5"
-"qtcreator_ide_branding" "5"
-"qtcreator_ide_branding.pri" "6"
-"qtcreator_testvars" "5"
-"qtcreator_testvars.pri" "6"
-"Other files" "5"
-"CMakeLists.txt" "7"
-"rpath" "4"
-"rpath.pri" "5"
-"Sources" "3"
-"main.cpp" "4"
-"Other files" "3"
"qtpromaker" "2"
"qtpromaker.pro" "3"
"qtcreatortool" "3"
@@ -20837,7 +20821,6 @@
"Headers" "5"
"touchbar.h" "6"
"Sources" "5"
-"touchbar.cpp" "6"
"Headers" "4"
"optional" "6"
"optional.hpp" "7"
@@ -21758,7 +21741,6 @@
"Headers" "6"
"touchbar.h" "7"
"Sources" "6"
-"touchbar.cpp" "7"
"Headers" "5"
"optional" "7"
"optional.hpp" "8"
diff --git a/tests/system/suite_tools/tst_git_local/test.py b/tests/system/suite_tools/tst_git_local/test.py
index 9ce9a0b3164..aefdc07d9a1 100644
--- a/tests/system/suite_tools/tst_git_local/test.py
+++ b/tests/system/suite_tools/tst_git_local/test.py
@@ -86,12 +86,12 @@ def __clickCommit__(count):
show = str(description.plainText)
id = "Nobody "
time = "\w{3} \w{3} \d{1,2} \d{2}:\d{2}:\d{2} \d{4}.* seconds ago\)"
- expected = [{"commit %s" % commit:False},
- {"Author: %s, %s" % (id, time): True},
- {"Committer: %s, %s" % (id, time): True}]
+ expected = [["commit %s" % commit, False],
+ ["Author: %s, %s" % (id, time), True],
+ ["Committer: %s, %s" % (id, time), True]]
for line, exp in zip(show.splitlines(), expected):
- expLine = list(exp.keys())[0]
- isRegex = list(exp.values())[0]
+ expLine = exp[0]
+ isRegex = exp[1]
if isRegex:
test.verify(re.match(expLine, line), "Verifying commit header line '%s'" % line)
else: