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: