From 15b308c62152214f4acd4061d837ff48ac083112 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 13 Feb 2024 12:31:03 +0100 Subject: [PATCH 01/12] Update change log for 13.0.0 beta and add JIRA links Change-Id: I949f60c547058592d92b0d1a7475ae1b85867304 Reviewed-by: Leena Miettinen --- dist/changelog/changes-13.0.0.md | 97 +++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/dist/changelog/changes-13.0.0.md b/dist/changelog/changes-13.0.0.md index bd3fc5e3d51..793e47e97f2 100644 --- a/dist/changelog/changes-13.0.0.md +++ b/dist/changelog/changes-13.0.0.md @@ -34,18 +34,18 @@ General dock area * Added the option to show file paths relative to the active project to the search results view - (QTCREATORBUG-29462) + ([QTCREATORBUG-29462](https://bugreports.qt.io/browse/QTCREATORBUG-29462)) * Added a `Current` button for selecting the directory of the current document for searching in `Files in File System` * Added `Copy to Clipboard` to the `About Qt Creator` dialog - (QTCREATORBUG-29886) + ([QTCREATORBUG-29886](https://bugreports.qt.io/browse/QTCREATORBUG-29886)) Editing ------- * Made syntax highlighting asynchronous * Fixed that `Shift+Tab` did not always unindent - (QTCREATORBUG-29742) + ([QTCREATORBUG-29742](https://bugreports.qt.io/browse/QTCREATORBUG-29742)) * Fixed that `Surround text selection with brackets` did nothing for `<` * Fixed following links without a file name in documents without a file name @@ -53,34 +53,39 @@ Editing * Added the `Move Definition Here` refactoring action that moves an existing function definition to its declaration - (QTCREATORBUG-9515) + ([QTCREATORBUG-9515](https://bugreports.qt.io/browse/QTCREATORBUG-9515)) +* Added the `Enclose in QByteArrayLiteral` refactoring action + ([QTCREATORBUG-12995](https://bugreports.qt.io/browse/QTCREATORBUG-12995)) * Enabled the completion inside comments and strings by falling back to the built-in code model - (QTCREATORBUG-20828) + ([QTCREATORBUG-20828](https://bugreports.qt.io/browse/QTCREATORBUG-20828)) * Improved the position of headers inserted by refactoring operations - (QTCREATORBUG-21826) + ([QTCREATORBUG-21826](https://bugreports.qt.io/browse/QTCREATORBUG-21826)) * Improved the coding style settings by separating Clang Format and other coding style settings, and using a plain text editor for custom Clang Format settings * Fixed that the class wizards used the class name for the include guard instead of the file name - (QTCREATORBUG-30140) + ([QTCREATORBUG-30140](https://bugreports.qt.io/browse/QTCREATORBUG-30140)) * Fixed that renaming classes did not change the include directive for the renamed header in the source file - (QTCREATORBUG-30154) + ([QTCREATORBUG-30154](https://bugreports.qt.io/browse/QTCREATORBUG-30154)) * Fixed issues with refactoring template functions - (QTCREATORBUG-29408) + ([QTCREATORBUG-29408](https://bugreports.qt.io/browse/QTCREATORBUG-29408)) +* Fixed the `Add Definition` refactoring action for member functions of a + template class in a namespace + ([QTCREATORBUG-22076](https://bugreports.qt.io/browse/QTCREATORBUG-22076)) * Clangd * Fixed that `Follow Symbol Under Cursor` only worked for exact matches - (QTCREATORBUG-29814) + ([QTCREATORBUG-29814](https://bugreports.qt.io/browse/QTCREATORBUG-29814)) ### QML * Added navigation from QML components to the C++ code in the project - (QTCREATORBUG-28086) + ([QTCREATORBUG-28086](https://bugreports.qt.io/browse/QTCREATORBUG-28086)) * Added a button for launching the QML Preview on the current document to the editor tool bar * Added color previews when hovering Qt color functions - (QTCREATORBUG-29966) + ([QTCREATORBUG-29966](https://bugreports.qt.io/browse/QTCREATORBUG-29966)) ### Python @@ -95,7 +100,7 @@ Editing ### Widget Designer * Fixed the indentation of the code that is inserted by `Go to slot` - (QTCREATORBUG-11730) + ([QTCREATORBUG-11730](https://bugreports.qt.io/browse/QTCREATORBUG-11730)) ### Compiler Explorer @@ -108,6 +113,10 @@ Editing endings) to the tool bar * Added support for following links to the text editor +### Binary Files + +* Fixed issues with large addresses + Projects -------- @@ -115,41 +124,62 @@ Projects was configured for kits that have vanished, as a replacement for the automatic creation of "Replacement" kits * Added the status of devices to the device lists - (QTCREATORBUG-20941) + ([QTCREATORBUG-20941](https://bugreports.qt.io/browse/QTCREATORBUG-20941)) * Added the `Preferences > Build & Run > General > Application environment` option for globally modifying the environment for all run configurations - (QTCREATORBUG-29530) + ([QTCREATORBUG-29530](https://bugreports.qt.io/browse/QTCREATORBUG-29530)) * Added a file wizard for Qt translation (`.ts`) files - (QTCREATORBUG-29775) + ([QTCREATORBUG-29775](https://bugreports.qt.io/browse/QTCREATORBUG-29775)) * Increased the maximum width of the target selector - (QTCREATORBUG-30038) + ([QTCREATORBUG-30038](https://bugreports.qt.io/browse/QTCREATORBUG-30038)) * Fixed that the `Left` cursor key did not always collapse the current item - (QTBUG-118515) + ([QTBUG-118515](https://bugreports.qt.io/browse/QTBUG-118515)) * Fixed inconsistent folder hierarchies in the project tree - (QTCREATORBUG-29923) + ([QTCREATORBUG-29923](https://bugreports.qt.io/browse/QTCREATORBUG-29923)) ### CMake * Added support for custom output parsers for the configuration of projects - (QTCREATORBUG-29992) + ([QTCREATORBUG-29992](https://bugreports.qt.io/browse/QTCREATORBUG-29992)) * Made cache variables available even if project configuration failed +* CMake Presets + * Fixed `Reload CMake Presets` if the project was not configured yet + ([QTCREATORBUG-30238](https://bugreports.qt.io/browse/QTCREATORBUG-30238)) + * Fixed that kits were accumulating on the project setup page + ([QTCREATORBUG-29535](https://bugreports.qt.io/browse/QTCREATORBUG-29535)) + * Fixed that `binaryDir` was not handled for all presets + ([QTCREATORBUG-30236](https://bugreports.qt.io/browse/QTCREATORBUG-30236)) + * Fixed a freeze with nested presets + ([QTCREATORBUG-30288](https://bugreports.qt.io/browse/QTCREATORBUG-30288)) +* Conan + * Fixed that backslashes were wrongly used for paths on Windows + ([QTCREATORBUG-30326](https://bugreports.qt.io/browse/QTCREATORBUG-30326)) + +### Qbs + +* Added support for code completion with the Qbs language server + (QBS-395) ### Python * Added `Generate Kit` to the Python interpreter preferences for generating a Python kit with this interpreter * Added the target setup page when loading unconfigured Python projects +* Added a `requirements.txt` file to the application wizard * Fixed that the same Python interpreter could be auto-detected multiple times under different names Debugging --------- +* Added a `dr` locator filter for debugging a project + ### C++ +* Added a pretty printer for `std::tuple` * Fixed that breakpoints were not hit while the message dialog about missing debug information was shown - (QTCREATORBUG-30168) + ([QTCREATORBUG-30168](https://bugreports.qt.io/browse/QTCREATORBUG-30168)) ### Debug Adapter Protocol @@ -161,7 +191,7 @@ Analyzer ### Clang * Added `Edit Checks as Strings` for Clazy - (QTCREATORBUG-24846) + ([QTCREATORBUG-24846](https://bugreports.qt.io/browse/QTCREATORBUG-24846)) ### Axivion @@ -171,16 +201,19 @@ Terminal -------- * Added `Select All` to the context menu - (QTCREATORBUG-29922) + ([QTCREATORBUG-29922](https://bugreports.qt.io/browse/QTCREATORBUG-29922)) * Fixed the startup performance on Windows - (QTCREATORBUG-29840) + ([QTCREATORBUG-29840](https://bugreports.qt.io/browse/QTCREATORBUG-29840)) * Fixed the integration of the `fish` shell * Fixed that `Ctrl+W` closed the terminal even when shortcuts were blocked - (QTCREATORBUG-30070) + ([QTCREATORBUG-30070](https://bugreports.qt.io/browse/QTCREATORBUG-30070)) +* Fixed issues with Windows Powershell Version Control Systems ----------------------- +* Added support for remote version control operations + ### Git * Added the upstream status for untracked branches to `Branches` view @@ -195,22 +228,27 @@ Test Integration Platforms --------- +### Windows + +* Fixed Clang compiler ABI detection for WOA64 + ([QTCREATORBUG-30060](https://bugreports.qt.io/browse/QTCREATORBUG-30060)) + ### Android * Add support for target-based android-build directories (??? is that ready? Qt 6.8+ ???) - (QTBUG-117443) + ([QTBUG-117443](https://bugreports.qt.io/browse/QTBUG-117443)) ### iOS * Fixed the detection of iOS 17 devices * Fixed deployment and running applications for iOS 17 devices (application output, debugging, and profiling are not supported) - (QTCREATORBUG-29682) + ([QTCREATORBUG-29682](https://bugreports.qt.io/browse/QTCREATORBUG-29682)) ### Remote Linux * Fixed that debugging unnecessarily downloaded files from the remote system - (QTCREATORBUG-29614) + ([QTCREATORBUG-29614](https://bugreports.qt.io/browse/QTCREATORBUG-29614)) Credits for these changes go to: -------------------------------- @@ -238,6 +276,7 @@ Esa Törmänen Fabian Kosmale Friedemann Kleint Henning Gruendl +Ilya Kulakov Jaroslaw Kobus Johanna Vanhatapio Karim Abdelrahman @@ -249,6 +288,7 @@ Marcus Tillmanns Mathias Hasselmann Mats Honkamaa Mehdi Salem +Michael Weghorn Miikka Heikkinen Mitch Curtis Olivier De Cannière @@ -257,6 +297,7 @@ Pranta Dastider Robert Löhning Sami Shalayel Samuel Jose Raposo Vieira Mira +Samuel Mira Serg Kryvonos Shrief Gabr Sivert Krøvel From 5937f1b78e96c85c2c7bad4cfb24a4c73e6d519f Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 13 Feb 2024 11:22:11 +0100 Subject: [PATCH 02/12] Update qbs submodule to HEAD of 2.3 branch Change-Id: Ideb5c401beb5f512e47ab3e6f7c32fe6e7edda1e Reviewed-by: Reviewed-by: Christian Stenger --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index a04135ed738..a30e54c2e7f 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit a04135ed738d5d65669441fad1593713c3ca2a89 +Subproject commit a30e54c2e7fb7d9735a364497914a5df452dd1ad From f905ad1aa648c4b1c31fcfb2a77dfe241ec2eb1f Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 13 Feb 2024 10:22:33 +0100 Subject: [PATCH 03/12] Terminal: Fix handling stub timeout Change-Id: Idaf18ac404d878382d5912793a667200bd7fe6f9 Reviewed-by: Reviewed-by: hjk --- src/libs/utils/terminalinterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/utils/terminalinterface.cpp b/src/libs/utils/terminalinterface.cpp index de3f57145cc..0d5a3be0203 100644 --- a/src/libs/utils/terminalinterface.cpp +++ b/src/libs/utils/terminalinterface.cpp @@ -420,6 +420,7 @@ void TerminalInterface::start() connect(d->stubConnectTimeoutTimer.get(), &QTimer::timeout, this, [this] { killInferiorProcess(); killStubProcess(); + emitFinished(-1, QProcess::ExitStatus::CrashExit); }); d->stubConnectTimeoutTimer->setSingleShot(true); d->stubConnectTimeoutTimer->start(10000); From 4cd5bdc4f6a7ab1578854fb7b0dc3b68c4e5da85 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 13 Feb 2024 09:17:34 +0100 Subject: [PATCH 04/12] LinuxDevice: Show warning if terminal open fails Change-Id: Ifb7a628e7d3f253d834cf8e6503db087def64e0f Reviewed-by: hjk --- src/plugins/remotelinux/linuxdevice.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 80b33c215f5..b166b702d34 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1007,7 +1007,7 @@ LinuxDevice::LinuxDevice() setOpenTerminal([this](const Environment &env, const FilePath &workingDir) -> expected_str { - Process proc; + Process *proc = new Process; // If we will not set any environment variables, we can leave out the shell executable // as the "ssh ..." call will automatically launch the default shell if there are @@ -1015,11 +1015,19 @@ LinuxDevice::LinuxDevice() // specify the shell executable. const QString shell = env.hasChanges() ? env.value_or("SHELL", "/bin/sh") : QString(); - proc.setCommand({filePath(shell), {}}); - proc.setTerminalMode(TerminalMode::Detached); - proc.setEnvironment(env); - proc.setWorkingDirectory(workingDir); - proc.start(); + proc->setCommand({filePath(shell), {}}); + proc->setTerminalMode(TerminalMode::Run); + proc->setEnvironment(env); + proc->setWorkingDirectory(workingDir); + proc->start(); + + QObject::connect(proc, &Process::done, proc, [proc](){ + if (proc->exitCode() != 0){ + qCWarning(linuxDeviceLog) << proc->exitMessage(); + Core::MessageManager::writeFlashing(proc->exitMessage()); + } + proc->deleteLater(); + }); return {}; }); From e7670dd9dbc69273f67b1c49b063a2762e9b8f9c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 11 Feb 2024 17:10:08 +0100 Subject: [PATCH 05/12] Axivion: Simplify string constructions Change-Id: I6dfefbcba47486a16f793c46c281c7f0fb2e888d Reviewed-by: Christian Stenger Reviewed-by: Qt CI Bot --- src/plugins/axivion/axivionplugin.cpp | 49 +++++++++++---------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp index 8d2b869963f..cd8fca0a0c5 100644 --- a/src/plugins/axivion/axivionplugin.cpp +++ b/src/plugins/axivion/axivionplugin.cpp @@ -266,8 +266,8 @@ static QUrl urlForProject(const QString &projectName) } static constexpr int httpStatusCodeOk = 200; -static const QLatin1String jsonContentType{ "application/json" }; -static const QLatin1String htmlContentType{ "text/html" }; +constexpr char s_htmlContentType[] = "text/html"; +constexpr char s_jsonContentType[] = "application/json"; static Group fetchHtmlRecipe(const QUrl &url, const std::function &handler) { @@ -284,15 +284,11 @@ static Group fetchHtmlRecipe(const QUrl &url, const std::functioncredentials); - const QByteArray ua = QByteArrayLiteral("Axivion") - + QCoreApplication::applicationName().toUtf8() - + QByteArrayLiteral("Plugin/") - + QCoreApplication::applicationVersion().toUtf8(); - request.setRawHeader(QByteArrayLiteral("X-Axivion-User-Agent"), ua); + request.setRawHeader("Accept", s_htmlContentType); + request.setRawHeader("Authorization", storage->credentials); + const QByteArray ua = "Axivion" + QCoreApplication::applicationName().toUtf8() + + "Plugin/" + QCoreApplication::applicationVersion().toUtf8(); + request.setRawHeader("X-Axivion-User-Agent", ua); query.setRequest(request); query.setNetworkAccessManager(&dd->m_networkAccessManager); }; @@ -307,11 +303,10 @@ static Group fetchHtmlRecipe(const QUrl &url, const std::functionreadAll()); return DoneResult::Success; } - return DoneResult::Error; }; @@ -340,22 +335,19 @@ static Group fetchDataRecipe(const QUrl &url, storage->credentials = QByteArrayLiteral("AxToken ") + settings().server.token.toUtf8(); }; - const auto onQuerySetup = [storage, url](NetworkQuery &query) { + const auto onNetworkQuerySetup = [storage, url](NetworkQuery &query) { QNetworkRequest request(url); - request.setRawHeader(QByteArrayLiteral("Accept"), - QByteArray(jsonContentType.data(), jsonContentType.size())); - request.setRawHeader(QByteArrayLiteral("Authorization"), - storage->credentials); - const QByteArray ua = QByteArrayLiteral("Axivion") - + QCoreApplication::applicationName().toUtf8() - + QByteArrayLiteral("Plugin/") - + QCoreApplication::applicationVersion().toUtf8(); - request.setRawHeader(QByteArrayLiteral("X-Axivion-User-Agent"), ua); + request.setRawHeader("Accept", s_jsonContentType); + request.setRawHeader("Authorization", storage->credentials); + const QByteArray ua = "Axivion" + QCoreApplication::applicationName().toUtf8() + + "Plugin/" + QCoreApplication::applicationVersion().toUtf8(); + request.setRawHeader("X-Axivion-User-Agent", ua); query.setRequest(request); query.setNetworkAccessManager(&dd->m_networkAccessManager); + return SetupResult::Continue; }; - const auto onQueryDone = [storage, url](const NetworkQuery &query, DoneWith doneWith) { + const auto onNetworkQueryDone = [storage, url](const NetworkQuery &query, DoneWith doneWith) { QNetworkReply *reply = query.reply(); const QNetworkReply::NetworkError error = reply->error(); const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -366,13 +358,13 @@ static Group fetchDataRecipe(const QUrl &url, .trimmed() .toLower(); if (doneWith == DoneWith::Success && statusCode == httpStatusCodeOk - && contentType == jsonContentType) { + && contentType == s_jsonContentType) { storage->serializableData = reply->readAll(); return DoneResult::Success; } const auto getError = [&]() -> Error { - if (contentType == jsonContentType) { + if (contentType == s_jsonContentType) { try { return DashboardError(reply->url(), statusCode, reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), @@ -389,8 +381,7 @@ static Group fetchDataRecipe(const QUrl &url, return NetworkError(reply->url(), error, reply->errorString()); }; - MessageManager::writeFlashing( - QStringLiteral("Axivion: %1").arg(getError().message())); + MessageManager::writeFlashing(QStringLiteral("Axivion: %1").arg(getError().message())); return DoneResult::Error; }; @@ -411,7 +402,7 @@ static Group fetchDataRecipe(const QUrl &url, const Group recipe { storage, Sync(onCredentialSetup), - NetworkQueryTask(onQuerySetup, onQueryDone), + NetworkQueryTask(onNetworkQuerySetup, onNetworkQueryDone), AsyncTask(onDeserializeSetup, onDeserializeDone) }; From 5d8cf8ce09a8b47dd40cb1c43fe7980dc939b5e0 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 13 Feb 2024 14:21:42 +0100 Subject: [PATCH 06/12] Doc: Describe setting environment variables for run configurations ...in Preferences > Build & Run > General > Application environment > Change. Task-number: QTCREATORBUG-30209 Change-Id: Idd58652b25ef6cfebf7bfda1a237f4c661b4c3b6 Reviewed-by: Christian Kandeler --- ...creator-projects-settings-environment.qdoc | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc index 6a883e8666d..3f200320fc1 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-environment.qdoc @@ -87,7 +87,25 @@ To run in a clean system environment, select \uicontrol {Clean Environment}. - \section2 Run on devices + \section2 Set the environment for all run configurations + + To set environment variables for running and debugging applications, so + that they don't affect \QC itself, set environment variables for run + configurations of all projects: + + \list 1 + \li Go to \preferences > \uicontrol {Build & Run} > \uicontrol General. + \li Select \uicontrol Change in \uicontrol {Application environment}. + \li Set environment variables in \uicontrol {Edit Environment}. + \image qtcreator-edit-environment.webp {Edit Environment dialog} + \endlist + + For example, set \c QT_FORCE_STDERR_LOGGING=1 to see application output + in \l {Application Output} instead of a journal or system log. + + Or, set \c QT_MESSAGE_PATTERN to add information to debugging messages. + + \section2 Use device environment When running on a mobile device connected to the development host, \QC fetches information about the \uicontrol {Device Environment} from the device. From 322dcd2c456dffeac1bf24496af77030776893f7 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 13 Feb 2024 17:00:04 +0100 Subject: [PATCH 07/12] CppEditor: Re-add function decl/def switch handler Was accidentally removed in 3771eb196b066314d427d7343cb1d4c6e2c5d6a4. Fixes: QTCREATORBUG-30363 Change-Id: Ifef1266b144d2eb5b7b69ff3e721f781b4455e96 Reviewed-by: hjk --- src/plugins/cppeditor/cppeditorplugin.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index b68c739f82e..c9185e372c1 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -323,6 +323,10 @@ void CppEditorPlugin::addPerSymbolActions() switchDeclDef.setTouchBarText(Tr::tr("Decl/Def", "text on macOS touch bar")); switchDeclDef.addToContainers(menus, Constants::G_SYMBOL); switchDeclDef.addToContainer(Core::Constants::TOUCH_BAR, Core::Constants::G_TOUCHBAR_NAVIGATION); + switchDeclDef.addOnTriggered(this, [] { + if (CppEditorWidget *editorWidget = currentCppEditorWidget()) + editorWidget->switchDeclarationDefinition(/*inNextSplit*/ false); + }); ActionBuilder openDeclDefSplit(this, Constants::OPEN_DECLARATION_DEFINITION_IN_NEXT_SPLIT); openDeclDefSplit.setText(Tr::tr("Open Function Declaration/Definition in Next Split")); From fc9863c768f17454c1cde2fd0395a70eb59342ad Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 13 Feb 2024 17:45:38 +0100 Subject: [PATCH 08/12] NetworkQuery: Support more operations Make it possible to PUT, POST and DELETE. Add setWriteData() method, to be used with PUT and POST. Change-Id: I99da38b60120b7efdab391db9b4d638f17d555df Reviewed-by: hjk --- src/libs/solutions/tasking/networkquery.cpp | 15 ++++++++++++++- src/libs/solutions/tasking/networkquery.h | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/libs/solutions/tasking/networkquery.cpp b/src/libs/solutions/tasking/networkquery.cpp index b02bb9cea1c..335f79afd94 100644 --- a/src/libs/solutions/tasking/networkquery.cpp +++ b/src/libs/solutions/tasking/networkquery.cpp @@ -19,7 +19,20 @@ void NetworkQuery::start() emit done(DoneResult::Error); return; } - m_reply.reset(m_manager->get(m_request)); + switch (m_operation) { + case NetworkOperation::Get: + m_reply.reset(m_manager->get(m_request)); + break; + case NetworkOperation::Put: + m_reply.reset(m_manager->put(m_request, m_writeData)); + break; + case NetworkOperation::Post: + m_reply.reset(m_manager->post(m_request, m_writeData)); + break; + case NetworkOperation::Delete: + m_reply.reset(m_manager->deleteResource(m_request)); + break; + } connect(m_reply.get(), &QNetworkReply::finished, this, [this] { disconnect(m_reply.get(), &QNetworkReply::finished, this, nullptr); emit done(toDoneResult(m_reply->error() == QNetworkReply::NoError)); diff --git a/src/libs/solutions/tasking/networkquery.h b/src/libs/solutions/tasking/networkquery.h index bf08bd1e7b5..dd099dc7a88 100644 --- a/src/libs/solutions/tasking/networkquery.h +++ b/src/libs/solutions/tasking/networkquery.h @@ -22,6 +22,8 @@ namespace Tasking { // is independent on Qt::Network. // Possibly, it could be placed inside Qt::Network library, as a wrapper around QNetworkReply. +enum class NetworkOperation { Get, Put, Post, Delete }; + class TASKING_EXPORT NetworkQuery final : public QObject { Q_OBJECT @@ -29,6 +31,8 @@ class TASKING_EXPORT NetworkQuery final : public QObject public: ~NetworkQuery(); void setRequest(const QNetworkRequest &request) { m_request = request; } + void setOperation(NetworkOperation operation) { m_operation = operation; } + void setWriteData(const QByteArray &data) { m_writeData = data; } void setNetworkAccessManager(QNetworkAccessManager *manager) { m_manager = manager; } QNetworkReply *reply() const { return m_reply.get(); } void start(); @@ -39,6 +43,8 @@ signals: private: QNetworkRequest m_request; + NetworkOperation m_operation = NetworkOperation::Get; + QByteArray m_writeData; // Used by Put and Post QNetworkAccessManager *m_manager = nullptr; std::unique_ptr m_reply; }; From 02d930b210686b6e33e197cce3d4cdd092073afa Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 13 Feb 2024 13:46:49 +0100 Subject: [PATCH 09/12] Debugger: Improve display of elided string data This was not adding the length before. The problem that the size is suddenly off by a factor of two for QString as elision counts bytes is still present. Change-Id: Ibcb595dc2d9aaa73b3feec955b4d14613307797f Reviewed-by: David Schulz --- src/plugins/debugger/watchhandler.cpp | 40 ++++++++++++--------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index eef0ba5a3ba..651c86bf2d6 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -818,14 +818,24 @@ static QString formattedValue(const WatchItem *item) return reformatInteger(integer, format, item->size, false); } - if (item->elided) { - QString v = item->value; - v.chop(1); - QString len = item->elided > 0 ? QString::number(item->elided) : "unknown length"; - return quoteUnprintable(v) + "\"... (" + len + ')'; + const int maxLength = settings().displayStringLimit(); + QString v = quoteUnprintable(item->value); + + if (v.endsWith('"')) { + if (item->elided) { + v.chop(1); + v.append("...\""); + } + int len = item->elided ? item->elided : item->value.length() - 2; + v += QString(" (%1)").arg(len > 0 ? QString::number(len) : "unknown length"); + return v; } - return quoteUnprintable(item->value); + if (v.size() > maxLength) { + v.truncate(maxLength); + v += QLatin1String("..."); + } + return v; } // Get a pointer address from pointer values reported by the debugger. @@ -886,18 +896,6 @@ QVariant WatchItem::editValue() const return QVariant(quoteUnprintable(stringValue)); } -// Truncate value for item view, maintaining quotes. -static QString truncateValue(QString v) -{ - enum { maxLength = 512 }; - if (v.size() < maxLength) - return v; - const bool isQuoted = v.endsWith('"'); // check for 'char* "Hallo"' - v.truncate(maxLength); - v += QLatin1String(isQuoted ? "...\"" : "..."); - return v; -} - static QString displayName(const WatchItem *item) { QString result; @@ -939,13 +937,9 @@ static QString displayName(const WatchItem *item) return result; } - void WatchItem::updateValueCache() const { - QString formatted = truncateValue(formattedValue(this)); - if (formatted.endsWith('"')) - formatted.append(QString(" (%1)").arg(this->value.length() - 2)); - valueCache = formatted; + valueCache = formattedValue(this); valueCache = watchModel(this)->removeNamespaces(valueCache); if (valueCache.isEmpty() && this->address) valueCache += QString::fromLatin1("@0x" + QByteArray::number(this->address, 16)); From a26aff7afd17b1f7ddda917ad07e1c1a9292ec9d Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 13 Feb 2024 14:58:56 +0100 Subject: [PATCH 10/12] Debugger: Report full sizes instead of the elide setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More direct communication of the meaning. Use 'length' when talking about things like string lengths, and 'size' for sizes in bytes. Task-number:  QTCREATORBUG-30065 Change-Id: Ifed84a5dab4ed890973c1abf4d427655eb50a61a Reviewed-by: David Schulz --- share/qtcreator/debugger/creatortypes.py | 4 +- share/qtcreator/debugger/dumper.py | 179 +++++++++++------------ share/qtcreator/debugger/qttypes.py | 169 +++++++++++---------- src/plugins/debugger/watchdata.cpp | 8 +- src/plugins/debugger/watchdata.h | 2 +- src/plugins/debugger/watchhandler.cpp | 10 +- 6 files changed, 184 insertions(+), 188 deletions(-) diff --git a/share/qtcreator/debugger/creatortypes.py b/share/qtcreator/debugger/creatortypes.py index 24c16ce0094..ba5b53450b0 100644 --- a/share/qtcreator/debugger/creatortypes.py +++ b/share/qtcreator/debugger/creatortypes.py @@ -204,7 +204,7 @@ def qdump__CPlusPlus__Internal__Value(d, value): def qdump__Utils__FilePath(d, value): data, path_len, scheme_len, host_len = d.split("{@QString}IHH", value) - elided, enc = d.encodeStringHelper(data, d.displayStringLimit) + length, enc = d.encodeStringHelper(data, d.displayStringLimit) # enc is concatenated path + scheme + host if scheme_len: scheme_pos = path_len * 4 @@ -221,7 +221,7 @@ def qdump__Utils__FilePath(d, value): val += path_enc else: val = enc - d.putValue(val, "utf16", elided=elided) + d.putValue(val, "utf16", length=length) d.putPlainChildren(value) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 1fd42848d4e..ad25ad2dbeb 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -44,15 +44,15 @@ class ReportItem(): subsequent better guesses during a putItem() run. """ - def __init__(self, value=None, encoding=None, priority=-100, elided=None): + def __init__(self, value=None, encoding=None, priority=-100, length=None): self.value = value self.priority = priority self.encoding = encoding - self.elided = elided + self.length = length def __str__(self): - return 'Item(value: %s, encoding: %s, priority: %s, elided: %s)' \ - % (self.value, self.encoding, self.priority, self.elided) + return 'Item(value: %s, encoding: %s, priority: %s, length: %s)' \ + % (self.value, self.encoding, self.priority, self.length) class Timer(): @@ -349,8 +349,8 @@ class DumperBase(): else: if self.currentValue.encoding is not None: self.put('valueencoded="%s",' % self.currentValue.encoding) - if self.currentValue.elided: - self.put('valueelided="%s",' % self.currentValue.elided) + if self.currentValue.length: + self.put('valuelen="%s",' % self.currentValue.length) self.put('value="%s",' % self.currentValue.value) except: pass @@ -376,7 +376,7 @@ class DumperBase(): b = bytes(bytearray.fromhex(value)) value = codecs.decode(b, 'utf-16') self.put('"%s"' % value) - if self.currentValue.elided: + if self.currentValue.length: self.put('...') if self.currentType.value: @@ -545,40 +545,40 @@ class DumperBase(): # assume no Qt 3 support by default return False - # Clamps size to limit. - def computeLimit(self, size, limit): + # Clamps length to limit. + def computeLimit(self, length, limit=0): if limit == 0: limit = self.displayStringLimit - if limit is None or size <= limit: - return 0, size - return size, limit + if limit is None or length <= limit: + return length + return limit def vectorData(self, value): if self.qtVersion() >= 0x060000: - data, size, alloc = self.qArrayData(value) + data, length, alloc = self.qArrayData(value) elif self.qtVersion() >= 0x050000: vector_data_ptr = self.extractPointer(value) if self.ptrSize() == 4: - (ref, size, alloc, offset) = self.split('IIIp', vector_data_ptr) + (ref, length, alloc, offset) = self.split('IIIp', vector_data_ptr) else: - (ref, size, alloc, pad, offset) = self.split('IIIIp', vector_data_ptr) + (ref, length, alloc, pad, offset) = self.split('IIIIp', vector_data_ptr) alloc = alloc & 0x7ffffff data = vector_data_ptr + offset else: vector_data_ptr = self.extractPointer(value) - (ref, alloc, size) = self.split('III', vector_data_ptr) + (ref, alloc, length) = self.split('III', vector_data_ptr) data = vector_data_ptr + 16 - self.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) - return data, size + self.check(0 <= length and length <= alloc and alloc <= 1000 * 1000 * 1000) + return data, length def qArrayData(self, value): if self.qtVersion() >= 0x60000: - dd, data, size = self.split('ppp', value) + dd, data, length = self.split('ppp', value) if dd: _, _, alloc = self.split('iip', dd) else: # fromRawData - alloc = size - return data, size, alloc + alloc = length + return data, length, alloc return self.qArrayDataHelper(self.extractPointer(value)) def qArrayDataHelper(self, array_data_ptr): @@ -586,10 +586,10 @@ class DumperBase(): if self.qtVersion() >= 0x050000: # QTypedArray: # - QtPrivate::RefCount ref - # - int size + # - int length # - uint alloc : 31, capacityReserved : 1 # - qptrdiff offset - (ref, size, alloc, offset) = self.split('IIpp', array_data_ptr) + (ref, length, alloc, offset) = self.split('IIpp', array_data_ptr) alloc = alloc & 0x7ffffff data = array_data_ptr + offset if self.ptrSize() == 4: @@ -599,43 +599,42 @@ class DumperBase(): elif self.qtVersion() >= 0x040000: # Data: # - QBasicAtomicInt ref; - # - int alloc, size; + # - int alloc, length; # - [padding] # - char *data; if self.ptrSize() == 4: - (ref, alloc, size, data) = self.split('IIIp', array_data_ptr) + (ref, alloc, length, data) = self.split('IIIp', array_data_ptr) else: - (ref, alloc, size, pad, data) = self.split('IIIIp', array_data_ptr) + (ref, alloc, length, pad, data) = self.split('IIIIp', array_data_ptr) else: # Data: # - QShared count; # - QChar *unicode # - char *ascii # - uint len: 30 - (dummy, dummy, dummy, size) = self.split('IIIp', array_data_ptr) - size = self.extractInt(array_data_ptr + 3 * self.ptrSize()) & 0x3ffffff - alloc = size # pretend. + (dummy, dummy, dummy, length) = self.split('IIIp', array_data_ptr) + length = self.extractInt(array_data_ptr + 3 * self.ptrSize()) & 0x3ffffff + alloc = length # pretend. data = self.extractPointer(array_data_ptr + self.ptrSize()) - return data, size, alloc + return data, length, alloc def encodeStringHelper(self, value, limit): - data, size, alloc = self.qArrayData(value) + data, length, alloc = self.qArrayData(value) if alloc != 0: - self.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) - elided, shown = self.computeLimit(2 * size, 2 * limit) - return elided, self.readMemory(data, shown) + self.check(0 <= length and length <= alloc and alloc <= 100 * 1000 * 1000) + shown = self.computeLimit(2 * length, 2 * limit) + return length, self.readMemory(data, shown) def encodeByteArrayHelper(self, value, limit): - data, size, alloc = self.qArrayData(value) + data, length, alloc = self.qArrayData(value) if alloc != 0: - self.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) - elided, shown = self.computeLimit(size, limit) - return elided, self.readMemory(data, shown) + self.check(0 <= length and length <= alloc and alloc <= 100 * 1000 * 1000) + shown = self.computeLimit(length, limit) + return length, self.readMemory(data, shown) - def putCharArrayValue(self, data, size, charSize, + def putCharArrayValue(self, data, length, charSize, displayFormat=DisplayFormat.Automatic): - bytelen = size * charSize - elided, shown = self.computeLimit(bytelen, self.displayStringLimit) + shown = self.computeLimit(length, self.displayStringLimit) mem = self.readMemory(data, shown) if charSize == 1: if displayFormat in (DisplayFormat.Latin1String, DisplayFormat.SeparateLatin1String): @@ -650,13 +649,13 @@ class DumperBase(): encodingType = 'ucs4' #childType = 'int' - self.putValue(mem, encodingType, elided=elided) + self.putValue(mem, encodingType, length=length) if displayFormat in ( DisplayFormat.SeparateLatin1String, DisplayFormat.SeparateUtf8String, DisplayFormat.Separate): - elided, shown = self.computeLimit(bytelen, 100000) + shown = self.computeLimit(length, 100000) self.putDisplay(encodingType + ':separate', self.readMemory(data, shown)) def putCharArrayHelper(self, data, size, charType, @@ -676,15 +675,15 @@ class DumperBase(): return self.hexencode(bytes(self.readRawMemory(addr, size))) def encodeByteArray(self, value, limit=0): - elided, data = self.encodeByteArrayHelper(value, limit) + _, data = self.encodeByteArrayHelper(value, limit) return data def putByteArrayValue(self, value): - elided, data = self.encodeByteArrayHelper(value, self.displayStringLimit) - self.putValue(data, 'latin1', elided=elided) + length, data = self.encodeByteArrayHelper(value, self.displayStringLimit) + self.putValue(data, 'latin1', length=length) def encodeString(self, value, limit=0): - elided, data = self.encodeStringHelper(value, limit) + _, data = self.encodeStringHelper(value, limit) return data def encodedUtf16ToUtf8(self, s): @@ -730,8 +729,8 @@ class DumperBase(): return inner def putStringValue(self, value): - elided, data = self.encodeStringHelper(value, self.displayStringLimit) - self.putValue(data, 'utf16', elided=elided) + length, data = self.encodeStringHelper(value, self.displayStringLimit) + self.putValue(data, 'utf16', length=length) def putPtrItem(self, name, value): with SubItem(self, name): @@ -900,12 +899,12 @@ class DumperBase(): if not self.isInt(thing): raise RuntimeError('Expected an integral value, got %s' % type(thing)) - def readToFirstZero(self, base, tsize, maximum): + def readToFirstZero(self, base, typesize, maximum): self.checkIntType(base) - self.checkIntType(tsize) + self.checkIntType(typesize) self.checkIntType(maximum) - code = self.packCode + (None, 'b', 'H', None, 'I')[tsize] + code = self.packCode + (None, 'b', 'H', None, 'I')[typesize] #blob = self.readRawMemory(base, 1) blob = bytes() while maximum > 1: @@ -916,8 +915,8 @@ class DumperBase(): maximum = int(maximum / 2) self.warn('REDUCING READING MAXIMUM TO %s' % maximum) - #DumperBase.warn('BASE: 0x%x TSIZE: %s MAX: %s' % (base, tsize, maximum)) - for i in range(0, maximum, tsize): + #DumperBase.warn('BASE: 0x%x TSIZE: %s MAX: %s' % (base, typesize, maximum)) + for i in range(0, maximum, typesize): t = struct.unpack_from(code, blob, i)[0] if t == 0: return 0, i, self.hexencode(blob[:i]) @@ -925,9 +924,9 @@ class DumperBase(): # Real end is unknown. return -1, maximum, self.hexencode(blob[:maximum]) - def encodeCArray(self, p, tsize, limit): - elided, shown, blob = self.readToFirstZero(p, tsize, limit) - return elided, blob + def encodeCArray(self, p, typesize, limit): + length, shown, blob = self.readToFirstZero(p, typesize, limit) + return length, blob def putItemCount(self, count, maximum=1000000000): # This needs to override the default value, so don't use 'put' directly. @@ -1043,12 +1042,12 @@ class DumperBase(): self.currentType.value = typish.name self.currentType.priority = priority - def putValue(self, value, encoding=None, priority=0, elided=None): + def putValue(self, value, encoding=None, priority=0, length=None): # Higher priority values override lower ones. - # elided = 0 indicates all data is available in value, + # length = None indicates all data is available in value, # otherwise it's the true length. if priority >= self.currentValue.priority: - self.currentValue = ReportItem(value, encoding, priority, elided) + self.currentValue = ReportItem(value, encoding, priority, length) def putSpecialValue(self, encoding, value='', children=None): self.putValue(value, encoding) @@ -1226,13 +1225,13 @@ class DumperBase(): return False - def putSimpleCharArray(self, base, size=None): - if size is None: - elided, shown, data = self.readToFirstZero(base, 1, self.displayStringLimit) + def putSimpleCharArray(self, base, length=None): + if length is None: + length, shown, data = self.readToFirstZero(base, 1, self.displayStringLimit) else: - elided, shown = self.computeLimit(int(size), self.displayStringLimit) + shown = self.computeLimit(length) data = self.readMemory(base, shown) - self.putValue(data, 'latin1', elided=elided) + self.putValue(data, 'latin1', length=length) def putDisplay(self, editFormat, value): self.putField('editformat', editFormat) @@ -1248,8 +1247,8 @@ class DumperBase(): if targetType.name in ('char', 'signed char', 'unsigned char', 'uint8_t', 'CHAR'): # Use UTF-8 as default for char *. self.putType(typeName) - (elided, shown, data) = self.readToFirstZero(ptr, 1, limit) - self.putValue(data, 'utf8', elided=elided) + (length, shown, data) = self.readToFirstZero(ptr, 1, limit) + self.putValue(data, 'utf8', length=length) if self.isExpanded(): self.putArrayData(ptr, shown, innerType) return True @@ -1257,55 +1256,55 @@ class DumperBase(): if targetType.name in ('wchar_t', 'WCHAR'): self.putType(typeName) charSize = self.lookupType('wchar_t').size() - (elided, data) = self.encodeCArray(ptr, charSize, limit) + (length, data) = self.encodeCArray(ptr, charSize, limit) if charSize == 2: - self.putValue(data, 'utf16', elided=elided) + self.putValue(data, 'utf16', length=length) else: - self.putValue(data, 'ucs4', elided=elided) + self.putValue(data, 'ucs4', length=length) return True if displayFormat == DisplayFormat.Latin1String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 1, limit) - self.putValue(data, 'latin1', elided=elided) + (length, data) = self.encodeCArray(ptr, 1, limit) + self.putValue(data, 'latin1', length=length) return True if displayFormat == DisplayFormat.SeparateLatin1String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 1, limit) - self.putValue(data, 'latin1', elided=elided) + (length, data) = self.encodeCArray(ptr, 1, limit) + self.putValue(data, 'latin1', length=length) self.putDisplay('latin1:separate', data) return True if displayFormat == DisplayFormat.Utf8String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 1, limit) - self.putValue(data, 'utf8', elided=elided) + (length, data) = self.encodeCArray(ptr, 1, limit) + self.putValue(data, 'utf8', length=length) return True if displayFormat == DisplayFormat.SeparateUtf8String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 1, limit) - self.putValue(data, 'utf8', elided=elided) + (length, data) = self.encodeCArray(ptr, 1, limit) + self.putValue(data, 'utf8', length=length) self.putDisplay('utf8:separate', data) return True if displayFormat == DisplayFormat.Local8BitString: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 1, limit) - self.putValue(data, 'local8bit', elided=elided) + (length, data) = self.encodeCArray(ptr, 1, limit) + self.putValue(data, 'local8bit', length=length) return True if displayFormat == DisplayFormat.Utf16String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 2, limit) - self.putValue(data, 'utf16', elided=elided) + (length, data) = self.encodeCArray(ptr, 2, limit) + self.putValue(data, 'utf16', length=length) return True if displayFormat == DisplayFormat.Ucs4String: self.putType(typeName) - (elided, data) = self.encodeCArray(ptr, 4, limit) - self.putValue(data, 'ucs4', elided=elided) + (length, data) = self.encodeCArray(ptr, 4, limit) + self.putValue(data, 'ucs4', length=length) return True return False @@ -2577,17 +2576,17 @@ class DumperBase(): def extractQStringFromQDataStream(self, buf, offset): """ Read a QString from the stream """ - size = struct.unpack_from('!I', buf, offset)[0] + length = struct.unpack_from('!I', buf, offset)[0] offset += 4 - string = buf[offset:offset + size].decode('utf-16be') - return (string, offset + size) + string = buf[offset:offset + length].decode('utf-16be') + return (string, offset + length) def extractQByteArrayFromQDataStream(self, buf, offset): """ Read a QByteArray from the stream """ - size = struct.unpack_from('!I', buf, offset)[0] + length = struct.unpack_from('!I', buf, offset)[0] offset += 4 - string = buf[offset:offset + size].decode('latin1') - return (string, offset + size) + string = buf[offset:offset + length].decode('latin1') + return (string, offset + length) def extractIntFromQDataStream(self, buf, offset): """ Read an int from the stream """ diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index b08f60a9bb3..06e7d473254 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -28,46 +28,46 @@ def qform__QByteArray(): def qedit__QByteArray(d, value, data): d.call('void', value, 'resize', str(len(data))) - (base, size, alloc) = d.stringData(value) + (base, length, alloc) = d.stringData(value) d.setValues(base, 'char', [ord(c) for c in data]) def qdump__QByteArray(d, value): if d.qtVersion() >= 0x60000: - dd, data, size = value.split('ppi') + dd, data, length = value.split('ppi') if dd: _, _, alloc = d.split('iii', dd) else: # fromRawData - alloc = size + alloc = length else: - data, size, alloc = d.qArrayData(value) + data, length, alloc = d.qArrayData(value) - d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000)) - if size > 0: + d.check(alloc == 0 or (0 <= length and length <= alloc and alloc <= 100000000)) + if length > 0: d.putExpandable() - elided, shown = d.computeLimit(size, d.displayStringLimit) + shown = d.computeLimit(length, d.displayStringLimit) p = d.readMemory(data, shown) displayFormat = d.currentItemFormat() if displayFormat == DisplayFormat.Automatic or displayFormat == DisplayFormat.Latin1String: - d.putValue(p, 'latin1', elided=elided) + d.putValue(p, 'latin1', length=length) elif displayFormat == DisplayFormat.SeparateLatin1String: - d.putValue(p, 'latin1', elided=elided) + d.putValue(p, 'latin1', length=length) d.putDisplay('latin1:separate', d.encodeByteArray(value, limit=100000)) elif displayFormat == DisplayFormat.Utf8String: - d.putValue(p, 'utf8', elided=elided) + d.putValue(p, 'utf8', length=length) elif displayFormat == DisplayFormat.SeparateUtf8String: - d.putValue(p, 'utf8', elided=elided) + d.putValue(p, 'utf8', length=length) d.putDisplay('utf8:separate', d.encodeByteArray(value, limit=100000)) if d.isExpanded(): - d.putArrayData(data, size, d.charType()) + d.putArrayData(data, length, d.charType()) #def qdump__QArrayData(d, value): -# data, size, alloc = d.qArrayDataHelper(value.address()) -# d.check(alloc == 0 or (0 <= size and size <= alloc and alloc <= 100000000)) -# d.putValue(d.readMemory(data, size), 'latin1') +# data, length, alloc = d.qArrayDataHelper(value.address()) +# d.check(alloc == 0 or (0 <= length and length <= alloc and alloc <= 100000000)) +# d.putValue(d.readMemory(data, length), 'latin1') # d.putPlainChildren(value) @@ -81,10 +81,10 @@ def qdump__QBitArray(d, value): else: data, basize, _ = d.qArrayData(value['d']) unused = d.extractByte(data) if data else 0 - size = basize * 8 - unused - d.putItemCount(size) + length = basize * 8 - unused + d.putItemCount(length) if d.isExpanded(): - with Children(d, size, maxNumChild=10000): + with Children(d, length, maxNumChild=10000): for i in d.childRange(): q = data + 1 + int(i / 8) with SubItem(d, i): @@ -1621,17 +1621,17 @@ def qdumpHelper_QSet45(d, value): ptrSize = d.ptrSize() dptr = d.extractPointer(value) - (fakeNext, buckets, ref, size, nodeSize, userNumBits, numBits, numBuckets) = \ + (fakeNext, buckets, ref, length, nodeSize, userNumBits, numBits, numBuckets) = \ d.split('ppiiihhi', dptr) - d.check(0 <= size and size <= 100 * 1000 * 1000) + d.check(0 <= length and length <= 100 * 1000 * 1000) d.check(-1 <= ref and ref < 100000) - d.putItemCount(size) + d.putItemCount(length) if d.isExpanded(): keyType = value.type[0] isShort = d.qtVersion() < 0x050000 and keyType.name == 'int' - with Children(d, size, childType=keyType): + with Children(d, length, childType=keyType): node = hashDataFirstNode() for i in d.childRange(): if isShort: @@ -1714,15 +1714,15 @@ def qdump__QStack(d, value): def qdump__QPolygonF(d, value): - data, size = d.vectorData(value) - d.putItemCount(size) - d.putPlotData(data, size, d.createType('@QPointF')) + data, length = d.vectorData(value) + d.putItemCount(length) + d.putPlotData(data, length, d.createType('@QPointF')) def qdump__QPolygon(d, value): - data, size = d.vectorData(value) - d.putItemCount(size) - d.putPlotData(data, size, d.createType('@QPoint')) + data, length = d.vectorData(value) + d.putItemCount(length) + d.putPlotData(data, length, d.createType('@QPoint')) def qdump__QGraphicsPolygonItem(d, value): @@ -1741,14 +1741,14 @@ def qdump__QGraphicsPolygonItem(d, value): offset = 328 if d.isMsvcTarget() else 320 else: offset = 308 - data, size = d.vectorData(dptr + offset) - d.putItemCount(size) - d.putPlotData(data, size, d.createType('@QPointF')) + data, length = d.vectorData(dptr + offset) + d.putItemCount(length) + d.putPlotData(data, length, d.createType('@QPointF')) def qedit__QString(d, value, data): d.call('void', value, 'resize', str(len(data))) - (base, size, alloc) = d.stringData(value) + (base, length, alloc) = d.stringData(value) d.setValues(base, 'short', [ord(c) for c in data]) @@ -1758,14 +1758,14 @@ def qform__QString(): def qdump__QString(d, value): d.putStringValue(value) - data, size, _ = d.stringData(value) + data, length, _ = d.stringData(value) displayFormat = d.currentItemFormat() if displayFormat == DisplayFormat.Separate: d.putDisplay('utf16:separate', d.encodeString(value, limit=100000)) - if (size > 0): + if (length > 0): d.putExpandable() if d.isExpanded(): - d.putArrayData(data, size, d.createType('@QChar')) + d.putArrayData(data, length, d.createType('@QChar')) def qdump__QSettingsKey(d, value): @@ -1774,8 +1774,8 @@ def qdump__QSettingsKey(d, value): def qdump__QStaticStringData(d, value): - size = value.type[0] - (ref, size, alloc, pad, offset, data) = value.split('iii@p%ss' % (2 * size)) + length = value.type[0] + (ref, length, alloc, pad, offset, data) = value.split('iii@p%ss' % (2 * length)) d.putValue(d.hexencode(data), 'utf16') d.putPlainChildren(value) @@ -1788,28 +1788,28 @@ def qdump__QTypedArrayData(d, value): def qdump__QStringData(d, value): - (ref, size, alloc, pad, offset) = value.split('III@p') - elided, shown = d.computeLimit(size, d.displayStringLimit) + (ref, length, alloc, pad, offset) = value.split('III@p') + shown = d.computeLimit(length, d.displayStringLimit) data = d.readMemory(value.address() + offset, shown * 2) - d.putValue(data, 'utf16', elided=elided) + d.putValue(data, 'utf16', length=length) d.putPlainChildren(value) def qdump__QAnyStringView(d, value): - data, size = value.split('pp') + data, length = value.split('pp') bits = d.ptrSize() * 8 - 2 - tag = size >> bits - size = size & (2**bits - 1) - elided, shown = d.computeLimit(size, d.displayStringLimit) + tag = length >> bits + length = length & (2**bits - 1) + shown = d.computeLimit(length, d.displayStringLimit) if tag == 0: mem = d.readMemory(data, shown) - d.putValue(mem, 'utf8', elided=elided) + d.putValue(mem, 'utf8', length=length) elif tag == 1: mem = d.readMemory(data, shown) - d.putValue(mem, 'latin1', elided=elided) + d.putValue(mem, 'latin1', length=length) elif tag == 2: mem = d.readMemory(data, shown * 2) - d.putValue(mem, 'utf16', elided=elided) + d.putValue(mem, 'utf16', length=length) else: d.putSpecialValue('empty') d.putPlainChildren(value) @@ -1825,16 +1825,15 @@ def qdump__QStringView(d, value): if idata == 0: d.putValue('(null)') return - size = value['m_size'] - isize = size.integer() - elided, shown = d.computeLimit(isize, d.displayStringLimit) + length = value['m_size'].integer() + shown = d.computeLimit(length, d.displayStringLimit) mem = d.readMemory(idata, shown * 2) - d.putValue(mem, 'utf16', elided=elided) + d.putValue(mem, 'utf16', length=length) if d.currentItemFormat() == DisplayFormat.Separate: d.putDisplay('utf16:separate', mem) d.putExpandable() if d.isExpanded(): - d.putArrayData(idata, isize, d.createType('char16_t')) + d.putArrayData(idata, length, d.createType('char16_t')) def qdump__QHashedString(d, value): @@ -1848,12 +1847,12 @@ def qdump__QQmlRefCount(d, value): def qdump__QStringRef(d, value): - (stringptr, pos, size) = value.split('pii') + (stringptr, pos, length) = value.split('pii') if stringptr == 0: d.putValue('(null)') return data, ssize, alloc = d.stringData(d.createValue(stringptr, '@QString')) - d.putValue(d.readMemory(data + 2 * pos, 2 * size), 'utf16') + d.putValue(d.readMemory(data + 2 * pos, 2 * length), 'utf16') d.putPlainChildren(value) @@ -1937,7 +1936,7 @@ def qdump__QUrl(d, value): userNameEnc = d.encodeString(userName) hostEnc = d.encodeString(host) - elided, pathEnc = d.encodeStringHelper(path, d.displayStringLimit) + length, pathEnc = d.encodeStringHelper(path, d.displayStringLimit) url = d.encodeString(scheme) url += '3a002f002f00' # '://' if len(userNameEnc): @@ -1946,7 +1945,7 @@ def qdump__QUrl(d, value): if port >= 0: url += '3a00' + ''.join(['%02x00' % ord(c) for c in str(port)]) url += pathEnc - d.putValue(url, 'utf16', elided=elided) + d.putValue(url, 'utf16', length=length) displayFormat = d.currentItemFormat() if displayFormat == DisplayFormat.Separate: @@ -2162,7 +2161,7 @@ def qdumpHelper__QVariant6(d, value): qdumpHelper_QVariant_0(d, value) return - revision, alignment, size, flags, variantType, metaObjectPtr, name = \ + revision, alignment, length, flags, variantType, metaObjectPtr, name = \ d.split('HHIIIpp', metaTypeInterface) # Well-known simple type. @@ -2241,7 +2240,7 @@ def qdumpHelper__QVariant45(d, value): base1 = d.extractPointer(value) #DumperBase.warn('BASE 1: %s %s' % (base1, innert)) base = d.extractPointer(base1) - #DumperBase.warn('SIZE 1: %s' % size) + #DumperBase.warn('SIZE 1: %s' % length) val = d.createValue(base, innerType) else: #DumperBase.warn('DIRECT ITEM 1: %s' % innerType) @@ -2268,7 +2267,7 @@ def qdumpHelper__QVariant45(d, value): d.putSpecialValue('notcallable') return None ptr = p.pointer() - (elided, blob) = d.encodeCArray(ptr, 1, 100) + (_, blob) = d.encodeCArray(ptr, 1, 100) innerType = d.hexdecode(blob) # Prefer namespaced version. @@ -2303,34 +2302,34 @@ def qform__QVector(): def qdump__QVector(d, value): if d.qtVersion() >= 0x060000: - data, size = d.listData(value) - d.putItemCount(size) - d.putPlotData(data, size, d.createType(value.type.ltarget[0])) + data, length = d.listData(value) + d.putItemCount(length) + d.putPlotData(data, length, d.createType(value.type.ltarget[0])) # g++ 9.3 does not add the template parameter list to the debug info. # Fake it for the common case: if value.type.name == d.qtNamespace() + "QVector": d.putBetterType(value.type.name + '<' + value.type.ltarget[0].name + '>') else: - data, size = d.vectorData(value) - d.putItemCount(size) - d.putPlotData(data, size, d.createType(value.type[0])) + data, length = d.vectorData(value) + d.putItemCount(length) + d.putPlotData(data, length, d.createType(value.type[0])) if False: def qdump__QObjectConnectionList(d, value): - data, size = d.vectorData(value) - d.putItemCount(size) - d.putPlotData(data, size, d.createType('@QObjectPrivate::ConnectionList')) + data, length = d.vectorData(value) + d.putItemCount(length) + d.putPlotData(data, length, d.createType('@QObjectPrivate::ConnectionList')) def qdump__QVarLengthArray(d, value): if d.qtVersion() >= 0x060000: - cap, size, data = value.split('QQp') + cap, length, data = value.split('QQp') else: - cap, size, data = value.split('iip') - d.check(0 <= size) - d.putItemCount(size) - d.putPlotData(data, size, value.type[0]) + cap, length, data = value.split('iip') + d.check(0 <= length) + d.putItemCount(length) + d.putPlotData(data, length, value.type[0]) def qdump__QSharedPointer(d, value): @@ -2401,20 +2400,20 @@ def qdump__QXmlAttributes(d, value): def qdump__QXmlStreamStringRef(d, value): s = value['m_string'] - (data, size, alloc) = d.stringData(s) + (data, length, alloc) = d.stringData(s) data += 2 * int(value['m_position']) - size = int(value['m_size']) - s = d.readMemory(data, 2 * size) + length = int(value['m_size']) + s = d.readMemory(data, 2 * length) d.putValue(s, 'utf16') d.putPlainChildren(value) def qdump__QXmlStreamAttribute(d, value): s = value['m_name']['m_string'] - (data, size, alloc) = d.stringData(s) + (data, length, alloc) = d.stringData(s) data += 2 * int(value['m_name']['m_position']) - size = int(value['m_name']['m_size']) - s = d.readMemory(data, 2 * size) + length = int(value['m_name']['m_size']) + s = d.readMemory(data, 2 * length) d.putValue(s, 'utf16') d.putPlainChildren(value) @@ -2505,8 +2504,8 @@ def qdump__QV4__ExecutionContext(d, value): def qdump__QQmlSourceLocation(d, value): (sourceFile, line, col) = value.split('pHH') - (data, size, alloc) = d.stringData(value) - d.putValue(d.readMemory(data, 2 * size), 'utf16') + (data, length, alloc) = d.stringData(value) + d.putValue(d.readMemory(data, 2 * length), 'utf16') d.putField('valuesuffix', ':%s:%s' % (line, col)) d.putPlainChildren(value) @@ -3345,9 +3344,7 @@ def qdump__QJsonValue(d, value): return if t == 3: d.putType('QJsonValue (String)') - string = value.split('{@QString}')[0] - elided, base = d.encodeString(string, d.displayStringLimit) - d.putValue(base, 'utf16', elided=elided) + d.putStringValue(value.split('{@QString}')[0]) return if t == 4: d.putType('QJsonValue (Array)') @@ -3472,9 +3469,9 @@ def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes): bytedata_len = d.extractInt(bytedata) bytedata_data = bytedata + 4 # sizeof(QtCbor::ByteData) header part - elided, shown = d.computeLimit(bytedata_len, d.displayStringLimit) + shown = d.computeLimit(bytedata_len, d.displayStringLimit) res = d.readMemory(bytedata_data, shown) - d.putValue(res, enc, elided=elided) + d.putValue(res, enc, length=bytedata_len) def qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, idx, bytedata, is_cbor): diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 8d0af0e4d31..120ce756122 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -151,8 +151,8 @@ QString WatchItem::toString() const if (!value.isEmpty()) str << "value=\"" << value << doubleQuoteComma; - if (elided) - str << "valueelided=\"" << elided << doubleQuoteComma; + if (valuelen) + str << "valuelen=\"" << valuelen << doubleQuoteComma; if (!editvalue.isEmpty()) str << "editvalue=\"<...>\","; @@ -300,9 +300,9 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort) if (mi.isValid()) id = mi.toInt(); - mi = input["valueelided"]; + mi = input["valuelen"]; if (mi.isValid()) - elided = mi.toInt(); + valuelen = mi.toInt(); mi = input["bitpos"]; if (mi.isValid()) diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index bb2e458bcd3..672ded5e7c6 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -72,7 +72,7 @@ public: uint bitsize = 0; // Size in case of bit fields uint autoDerefCount = 0; // number of levels of automatic dereferencing that has taken place (for pointer types) uint variablesReference = 0;// reference to the variable in the variables request DAP related - int elided = 0; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise + int valuelen = 0; // -1 if cut on unknown size, full size otherwise int arrayIndex = -1; // -1 if not an array member uchar sortGroup = 0; // 0 - ordinary member, 1 - vptr, 2 - base class bool wantsChildren = false; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 651c86bf2d6..841dc4d0156 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -822,12 +822,12 @@ static QString formattedValue(const WatchItem *item) QString v = quoteUnprintable(item->value); if (v.endsWith('"')) { - if (item->elided) { + if (item->valuelen > maxLength) { v.chop(1); v.append("...\""); } - int len = item->elided ? item->elided : item->value.length() - 2; - v += QString(" (%1)").arg(len > 0 ? QString::number(len) : "unknown length"); + if (item->valuelen > 0) + v += QString(" (%1)").arg(item->valuelen); return v; } @@ -1297,7 +1297,7 @@ Qt::ItemFlags WatchModel::flags(const QModelIndex &idx) const // FIXME: Forcing types is not implemented yet. //if (idx.column() == 2) // return editable; // Watcher types can be set by force. - if (column == ValueColumn && item->valueEditable && !item->elided) + if (column == ValueColumn && item->valueEditable && item->valuelen >= 0) return editable; // Watcher values are sometimes editable. } } else if (item->isLocal()) { @@ -1305,7 +1305,7 @@ Qt::ItemFlags WatchModel::flags(const QModelIndex &idx) const return notEditable; if (isRunning && !m_engine->hasCapability(AddWatcherWhileRunningCapability)) return notEditable; - if (column == ValueColumn && item->valueEditable && !item->elided) + if (column == ValueColumn && item->valueEditable && item->valuelen >= 0) return editable; // Locals values are sometimes editable. if (column == ValueColumn && item->arrayIndex >= 0) return editable; From 7b57ae31f6338fdb3faa7403a1a1f4c7e0f22caa Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 13 Feb 2024 15:04:20 +0100 Subject: [PATCH 11/12] Avoid automatic creation of performance data related .json files Amends 1a84ae038df0757f44d890ad3d5b2e055d5dda7e which enabled building the Nanotrace library by default. The part that is used for startup performance logging is only enabled at runtime with the `-trace` command line argument, but some logging using the "hr" variant was automatically created. Disable that part at compile time by default. Fixes: QTCREATORBUG-30331 Change-Id: I8add207c760bfe2dde52534f55feb7b637ccb600 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller Reviewed-by: --- src/libs/nanotrace/CMakeLists.txt | 7 ++++++- src/libs/nanotrace/nanotracehr.h | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libs/nanotrace/CMakeLists.txt b/src/libs/nanotrace/CMakeLists.txt index f2fa830e2d3..8652a817985 100644 --- a/src/libs/nanotrace/CMakeLists.txt +++ b/src/libs/nanotrace/CMakeLists.txt @@ -3,7 +3,6 @@ add_qtc_library(Nanotrace SOURCES nanotraceglobals.h nanotrace.cpp nanotrace.h - nanotracehr.cpp nanotracehr.h PUBLIC_DEPENDS Qt::Core Qt::Gui PROPERTIES CXX_VISIBILITY_PRESET default @@ -16,3 +15,9 @@ extend_qtc_library(Nanotrace CONDITION DESIGN_STUDIO_USE_NANOTRACE PUBLIC_DEFINES NANOTRACE_DESIGNSTUDIO_ENABLED ) + +option(NANOTRACEHR_ENABLED "Enables collecting high resolution performance data" OFF) +extend_qtc_library(Nanotrace + SOURCES + nanotracehr.cpp nanotracehr.h +) diff --git a/src/libs/nanotrace/nanotracehr.h b/src/libs/nanotrace/nanotracehr.h index d49e12a87a0..74b1381b064 100644 --- a/src/libs/nanotrace/nanotracehr.h +++ b/src/libs/nanotrace/nanotracehr.h @@ -34,7 +34,7 @@ enum class Tracing { IsDisabled, IsEnabled }; constexpr Tracing tracingStatus() { -#ifdef NANOTRACE_ENABLED +#ifdef NANOTRACEHR_ENABLED return Tracing::IsEnabled; #else return Tracing::IsDisabled; @@ -1569,7 +1569,7 @@ template Tracer(typename Category::ArgumentType name, Category &category, Arguments &&...) -> Tracer; -#ifdef NANOTRACE_ENABLED +#ifdef NANOTRACEHR_ENABLED class GlobalTracer { public: From 321b2454771f29e8d1ef085b637564a01acdb042 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 6 Feb 2024 16:58:52 +0100 Subject: [PATCH 12/12] Doc: Describe Help > About Qt Creator > Copy and Close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the instructions for contacting Qt from the front page to a how-to topic. Task-number: QTCREATORBUG-30209 Change-Id: I4f4083927ad54bdca555e1825f817f494e30e860 Reviewed-by: André Hartmann Reviewed-by: hjk --- .../creator-how-to-contact-qt.qdoc | 49 +++++++++++++++++++ doc/qtcreator/src/qtcreator.qdoc | 17 +------ 2 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 doc/qtcreator/src/howto/creator-only/creator-how-to-contact-qt.qdoc diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-to-contact-qt.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-to-contact-qt.qdoc new file mode 100644 index 00000000000..93b8844f240 --- /dev/null +++ b/doc/qtcreator/src/howto/creator-only/creator-how-to-contact-qt.qdoc @@ -0,0 +1,49 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page creator-how-to-contact-qt.html + \previouspage creator-how-tos.html + + \ingroup creator-how-to-use + + \title Contact Qt + + To report bugs and tell us what you think about \QC and Qt, + go to \uicontrol Help. + + \section1 Report bugs and suggest improvements + + To report bugs and add suggestions for improvement to the + \l{https://bugreports.qt.io/}{Qt Project Bug Tracker}, + go to \uicontrol Help > \uicontrol {Report Bug}. + + To copy information about your \QC version that you can paste to the bug + report, go to \uicontrol Help > \uicontrol {About \QC} and select + \uicontrol {Copy and Close}. + + To copy detailed information about your system that you can paste to the bug + report, go to \uicontrol Help > \uicontrol {System Information} and select + \uicontrol {Copy to Clipboard}. + + To get commercial Qt support, go to \uicontrol Help > + \uicontrol {Commercial Qt Support} and create a service request. + To check your licenses and services, go to \uicontrol Help > + \uicontrol {Qt Account}. + + \section1 Give feedback + + To rate \QC and send us feedback, go to \uicontrol Help > + \uicontrol {Give Feedback}. + + Or, give feedback from your Qt account. + + \section1 Join discussions + + To join the \l{https://lists.qt-project.org/listinfo/qt-creator} + {\QC mailing list} or \l{https://web.libera.chat/#qt-creator} + {#qt-creator} channel on Libera.Chat IRC, go to \uicontrol Help > + \uicontrol Contact. + + \sa {Pasting and Fetching Code Snippets}, {Technical Support} +*/ diff --git a/doc/qtcreator/src/qtcreator.qdoc b/doc/qtcreator/src/qtcreator.qdoc index 840ef3805bc..7c2d8ce775e 100644 --- a/doc/qtcreator/src/qtcreator.qdoc +++ b/doc/qtcreator/src/qtcreator.qdoc @@ -86,6 +86,7 @@ \endlist \li \b {\l{Reference}} \list + \li \l {Acknowledgements} \li \l {Build Systems} \li \l {Command-Line Options} \li \l {Custom Wizards} @@ -94,21 +95,5 @@ \li \l {Supported Platforms} \li \l {Reference}{See More...} \endlist - \row - \li {4,1} \b {Contact Us} - \list - \li To report bugs and suggestions to the - \l{https://bugreports.qt.io/}{Qt Project Bug Tracker}, - select \uicontrol Help > \uicontrol {Report Bug}. - \li To copy and paste detailed information about your - system to the bug report, select \uicontrol Help > - \uicontrol {System Information}. - \li To join the \l{https://lists.qt-project.org/listinfo/qt-creator} - {\QC mailing list} or \l{https://web.libera.chat/#qt-creator} - {#qt-creator} channel on Libera.Chat IRC, select - \uicontrol Help > \uicontrol Contact. - \li For credits and a list of third-party libraries, see - \l {Acknowledgements}. - \endlist \endtable */