diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index 7fe40fd9554..2458857e830 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -15,6 +15,7 @@ General * Started work on supporting Lua based plugins (registering language servers, actions, preferences, and wizards) ([Documentation](https://doc-snapshots.qt.io/qtcreator-extending/lua-extensions.html)) +* Added a mode for managing extensions * Added `Clear` and `Save Contents` to context menus of all output views * Locator * Added the option to show results relative to project root @@ -38,6 +39,9 @@ Editing * Fixed that after hiding the editor in `Debug` mode, `Edit` mode always opened when opening documents, even if an external editor window was available ([QTCREATORBUG-30408](https://bugreports.qt.io/browse/QTCREATORBUG-30408)) +* Fixed that it wasn't possible to open a file in the text editor if it was + classified as a binary file format by the MIME database + ([QTCREATORBUG-31116](https://bugreports.qt.io/browse/QTCREATORBUG-31116)) ### C++ @@ -177,6 +181,12 @@ Projects * Fixed a crash when triggering `Follow Symbol` in a CMake file that does not belong to a project ([QTCREATORBUG-31077](https://bugreports.qt.io/browse/QTCREATORBUG-31077)) +* Fixed that multiple build configurations of the same type used the same + build directory + ([QTCREATORBUG-26066](https://bugreports.qt.io/browse/QTCREATORBUG-26066)) +* Fixed an issue with adding new files when file globs are used in the CMake + files + ([QTCREATORBUG-30445](https://bugreports.qt.io/browse/QTCREATORBUG-30445)) * Presets * Made CMake settings configurable ([QTCREATORBUG-25972](https://bugreports.qt.io/browse/QTCREATORBUG-25972), @@ -291,7 +301,8 @@ Platforms ### Remote Linux -* Added the option to use SSH port forwarding for debugging +* Added the `Use SSH port forwarding for debugging` option in `Preferences` > + `Devices` for a `Remote Linux Device` * Improved the performance of the generic deployment method * Fixed that the file size check that is performed before parsing C++ files could freeze Qt Creator until finished for remote projects @@ -343,8 +354,10 @@ Michael Weghorn Miikka Heikkinen Orgad Shaneh Pranta Dastider +Ralf Habacker Robert Löhning Sami Shalayel +Semih Yavuz Sergey Silin Shrief Gabr Teea Poldsam diff --git a/doc/qtcreator/images/qtcreator-preferences-devices-remote-linux.webp b/doc/qtcreator/images/qtcreator-preferences-devices-remote-linux.webp index 4b97b88b7a2..565d63ad6df 100644 Binary files a/doc/qtcreator/images/qtcreator-preferences-devices-remote-linux.webp and b/doc/qtcreator/images/qtcreator-preferences-devices-remote-linux.webp differ diff --git a/doc/qtcreator/src/debugger/creator-only/creator-debugger-setup.qdoc b/doc/qtcreator/src/debugger/creator-only/creator-debugger-setup.qdoc index c726d15e601..a6bc84a87b0 100644 --- a/doc/qtcreator/src/debugger/creator-only/creator-debugger-setup.qdoc +++ b/doc/qtcreator/src/debugger/creator-only/creator-debugger-setup.qdoc @@ -14,11 +14,11 @@ \ingroup creator-reference-debugger - \title Supported Native Debuggers + \title Supported Debuggers \brief Summary of supported debugger versions. - \QC supports native debuggers for debugging compiled code. + You can use \QC to debug compiled code. On most supported platforms, you can use the GNU Symbolic Debugger (GDB). On Microsoft Windows, when using the Microsoft toolchain, you need the Microsoft Console Debugger (CDB). On \macos and Linux, you can use the LLDB @@ -34,7 +34,7 @@ \header \li Platform \li Compiler - \li Native Debugger + \li Debugger \row \li Linux \li GCC, ICC @@ -57,9 +57,9 @@ \li Debugging Tools for Windows/CDB \endtable - The debugger plugin automatically selects a suitable native debugger for + \QC automatically selects a suitable debugger for each \l{Kits}{kit} from the ones found on the computer. The automatic - setup fails if the native debugger is not installed on the computer or + setup fails if the debugger is not installed on the computer or if \QC does not support the installed version. \section1 GDB Versions @@ -123,7 +123,7 @@ {Mac OS X Debugging Magic}. \section1 LLDB Versions - The LLDB native debugger has similar functionality to the GDB debugger. LLDB + The LLDB debugger has similar functionality to the GDB debugger. LLDB is the default debugger in Xcode on \macos for C++ on the desktop. LLDB is typically used with the Clang compiler (even though you can use it with GCC, too). diff --git a/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc b/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc index 25c127aa413..6880c27b5a2 100644 --- a/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc +++ b/doc/qtcreator/src/debugger/creator-only/creator-debugger.qdoc @@ -14,8 +14,7 @@ \title Debugging - The \QC debugger plugin acts as an interface between the \QC - core and external native debuggers that you can use to: + You can use debuggers to: \list \li Debug executable binary files - GNU Symbolic Debugger (GDB), @@ -28,7 +27,7 @@ \section1 Setting Up the Debugger - The debugger plugin automatically selects a suitable native debugger for + \QC automatically selects a suitable debugger for each \l{Kits}{kit} from the ones found on your system. You can select another kit. To specify the debugger and compiler to use for each kit, go to \preferences > \uicontrol Kits. @@ -36,7 +35,7 @@ \image qtcreator-kits.png {Kits preferences} You need to set up the debugger only if the automatic setup fails because - the native debugger is missing (for example, you must install the CDB + the debugger is missing (for example, you must install the CDB debugger on Windows yourself) or because \QC does not support the installed version. For example, when your system does not have GDB installed or the installed version is outdated, and you want to use a locally @@ -58,11 +57,11 @@ Optionally, you can set up the Microsoft Symbol Server if you need symbol information from Microsoft modules that is not found locally. - For more information, see \l{Supported Native Debuggers} and \l{CDB Paths}. + For more information, see \l{Supported Debuggers} and \l{CDB Paths}. \section1 Launching the Debugger - The debugger plugin can run the native debuggers in various operating modes + The debuggers run in various operating modes depending on where and how you start and run the debugged process. Some of the modes are only available for a particular operating system or platform: @@ -93,9 +92,8 @@ \section2 GDB Run Modes - The GDB native debugger used internally by the debugger plugin runs in - different modes to cope with the variety of supported platforms and - environments: + The GDB debugger runs in different modes to cope with the variety of + supported platforms and environments: \list \li \e{Plain mode} debugs locally started processes that do not need @@ -591,8 +589,24 @@ in GDB, see \l{https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html} {Debugging with GDB: Connecting to a Remote Target}. - \sa {Debug}{How To: Debug}, {GDB}, {Debugging}, - {Debuggers}, {Debugger}, {Kits} + \section1 Use SSH port forwarding + + To enable debugging on remote targets that cannot expose GDB server ports, + map the remote ports to local ports using SSH tunneling. \QC automatically + detects the local and remote ports. + + To turn on SSH port forwarding: + + \list 1 + \li Go to \preferences > \uicontrol Devices. + \image qtcreator-preferences-devices-remote-linux.webp {Remote Linux device preferences} + \li In \uicontrol Device, select \uicontrol {Remote Linux Device}. + \li Select \uicontrol {Use SSH port forwarding for debugging}. + \li Select \uicontrol OK. + \endlist + + \sa {Debug}{How To: Debug}, {Remote Linux}{How To: Develop for remote Linux}, + {GDB}, {Debugging}, {Debuggers}, {Debugger}, {Kits} */ /*! @@ -770,7 +784,7 @@ The log view acts as a console, so you can send the contents of the line under the text cursor in the log directly to the - native debugger. + debugger. \li \l{Troubleshooting Debugger} \l {Debugger Log} @@ -865,9 +879,9 @@ \title Examine complex values in Debug views - \QC displays the raw information from the native debuggers in a clear and + \QC displays the raw information from the debuggers in a clear and concise manner to simplify the debugging process without losing the power - of the native debuggers. + of the debuggers. \image qtcreator-locals.png {Locals view} @@ -1150,8 +1164,8 @@ \brief View information about the modules included in a debugged application. - The \uicontrol Modules view displays information that the debugger plugin - has about modules included in the application that is being debugged. + The \uicontrol Modules view displays information about modules included in + the application that is being debugged. A module is: @@ -1389,13 +1403,13 @@ \li Set \l{Debugger}{debugger preferences}. \endlist - \section1 Directly Interacting with Native Debuggers + \section1 Directly Interacting with Debuggers You can use the left pane of the \uicontrol {Debugger Log} view to directly - interact with the command line of the native debugger. + interact with the command line of the debugger. Press \key {Ctrl+Enter} to send the contents of the line under the - text cursor to the native debugger. Or, enter the command in the + text cursor to the debugger. Or, enter the command in the \uicontrol Command field. The right side pane of the \uicontrol {Debugger Log} view shows the command output. @@ -1464,7 +1478,7 @@ \brief Load, customize, and add debugging helpers. \QC uses Python scripts to translate raw memory contents and type information - data from native debugger backends (GDB, LLDB, and CDB are currently supported) + data from debugger backends (GDB, LLDB, and CDB are currently supported) into the form presented to the user in the \l {Local Variables and Function Parameters}{Locals} and \l {Evaluating Expressions}{Expressions} views. @@ -1520,7 +1534,7 @@ of Qt, or of your own library, at the same time. To add debugging helpers for custom types, add debugging helper - implementations to the startup file of the native debuggers (for example, + implementations to the startup file of the debuggers (for example, \c{~/.gdbinit} or \c{~/.lldbinit}) or specify them directly in the \uicontrol {Additional Startup Commands} in \preferences > \uicontrol Debugger > \uicontrol GDB. @@ -1733,7 +1747,7 @@ \endcode \li \c{putCallItem(self, name, rettype, value, func, *args)} - Uses the - native debugger backend to place the function call \c func returning + debugger backend to place the function call \c func returning \c rettype on the value specified by \a {value} and to output the resulting item. @@ -1880,7 +1894,7 @@ an integral or floating point type. Type objects, that is, instances of the \c{Dumper.Type} class, can be - created by native debugger backends, usually by evaluating Debug Information + created by debugger backends, usually by evaluating Debug Information built into or shipped alongside the debugged binary, or created on-the-fly by the debugging helper. @@ -2110,7 +2124,7 @@ \l {Run on many platforms}{build and run kit selector} picked a runnable target and you can run the application. - \li Make sure the debugger is \l{Supported Native Debuggers}{set up properly}. + \li Make sure the debugger is \l{Supported Debuggers}{set up properly}. \li In the \uicontrol Debug mode, go to \uicontrol View > \uicontrol Views > \uicontrol {Debugger Log} to open the diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc index baf079c08f3..d31fe7a97bd 100644 --- a/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc +++ b/doc/qtcreator/src/howto/creator-only/creator-how-tos.qdoc @@ -66,8 +66,7 @@ \section1 Debug - Use native debuggers to inspect the state of your application while - debugging. + Use debuggers to inspect the state of your application while it is running. \generatelist creator-how-to-debug diff --git a/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc b/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc index 8685f850ce4..a67a8fb7657 100644 --- a/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc +++ b/doc/qtcreator/src/howto/creator-only/qtcreator-faq.qdoc @@ -143,7 +143,7 @@ You must use Python version 2.6 or 2.7. - For more information, see \l{Supported Native Debuggers}. + For more information, see \l{Supported Debuggers}. \b {How do I generate a core file in \QC?} diff --git a/doc/qtcreator/src/linux-mobile/creator-projects-how-to-run-generic-linux.qdoc b/doc/qtcreator/src/linux-mobile/creator-projects-how-to-run-generic-linux.qdoc index 241b0ce2f34..aeb17305cf8 100644 --- a/doc/qtcreator/src/linux-mobile/creator-projects-how-to-run-generic-linux.qdoc +++ b/doc/qtcreator/src/linux-mobile/creator-projects-how-to-run-generic-linux.qdoc @@ -35,5 +35,6 @@ it is compatible with the GDB on the host. \sa {Remote Linux}{How To: Develop for remote Linux}, - {Run on many platforms}, {Compilers}, {Embedded Platforms}, {Kits} + {Debug remotely with GDB}, {Run on many platforms}, {Compilers}, + {Embedded Platforms}, {Kits} */ diff --git a/doc/qtcreator/src/linux-mobile/linuxdev.qdoc b/doc/qtcreator/src/linux-mobile/linuxdev.qdoc index e0ec120b85b..6691ca4b2c4 100644 --- a/doc/qtcreator/src/linux-mobile/linuxdev.qdoc +++ b/doc/qtcreator/src/linux-mobile/linuxdev.qdoc @@ -138,6 +138,6 @@ \include qtcreator-add-linux-device.qdocinc {add linux device} {Remote Linux Device} \sa {Remote Linux}{How To: Develop for remote Linux}, - {Developing for Remote Linux Devices}, + {Debug remotely with GDB}, {Developing for Remote Linux Devices}, {Remote Linux Deploy Configuration} */ diff --git a/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc b/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc index d7afb4ee549..1efaf8238d8 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-overview.qdoc @@ -266,10 +266,10 @@ to find the next one. \endlist - \QC integrates several native debuggers for inspecting the state of - your application while debugging. The debugger plugin automatically selects - a suitable native debugger for each kit from the ones it finds on the - computer. Edit the kits to override this choice. + \QC integrates several debuggers for inspecting the state of your + application. It automatically selects a suitable debugger for each + kit from the ones it finds on the computer. Edit the kits to override + this choice. If you install \QC with \QOI, the GNU Symbolic Debugger is installed automatically and you should be ready to start debugging after you create diff --git a/doc/qtcreator/src/overview/creator-only/creator-reference.qdoc b/doc/qtcreator/src/overview/creator-only/creator-reference.qdoc index 7415815ff02..6f2ed53a14e 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-reference.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-reference.qdoc @@ -21,7 +21,7 @@ \section1 Debuggers - Set up and use native debuggers to debug executable binary files, as well as + Set up and use debuggers to debug executable binary files, as well as QML, Java, and Python source code. \annotatedlist creator-reference-debugger diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-debuggers.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-debuggers.qdoc index a99de7c59ab..8720339ca6a 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-debuggers.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-debuggers.qdoc @@ -15,12 +15,11 @@ \title Add debuggers - The \QC debugger plugin acts as an interface between the \QC core and - external native debuggers such as the GNU Symbolic Debugger (GDB), + You can use debuggers, such as the GNU Symbolic Debugger (GDB), the Microsoft Console Debugger (CDB), a QML/JavaScript debugger, and the debugger of the low level virtual machine (LLVM) project, LLDB. - The debugger plugin automatically selects a suitable native debugger for + \QC automatically selects a suitable debugger for each \l{Kits}{kit} from the ones found on your system. To override this choice, select \preferences > \uicontrol Kits. @@ -75,6 +74,6 @@ The debugger disappears from the list when you select \uicontrol Apply. Until then, you can cancel the deletion by clicking \uicontrol Restore. - \sa {Debugging}, {Debuggers}, {Debugger}, {Supported Native Debuggers}, + \sa {Debugging}, {Debuggers}, {Debugger}, {Supported Debuggers}, {Troubleshooting Debugger} */ diff --git a/doc/qtcreator/src/python/creator-python-development.qdoc b/doc/qtcreator/src/python/creator-python-development.qdoc index ba8053c3d3d..10f054dcdab 100644 --- a/doc/qtcreator/src/python/creator-python-development.qdoc +++ b/doc/qtcreator/src/python/creator-python-development.qdoc @@ -26,7 +26,7 @@ \li \l{Run Python applications} \li \l{Python Run Settings} \li \l{PDB versions} - \li \l{Supported Native Debuggers} + \li \l{Supported Debuggers} \endlist For more information about developing with Qt for Python, including diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index 3f48e192b93..085fff92bdb 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -99,8 +99,8 @@ public: iter = iter->next; return *this; } - bool operator==(const ListIterator &other) { return iter == other.iter; } - bool operator!=(const ListIterator &other) { return iter != other.iter; } + bool operator==(const ListIterator &other) const { return iter == other.iter; } + bool operator!=(const ListIterator &other) const { return iter != other.iter; } }; ListIterator begin() { return {this}; } ListIterator end() { return {nullptr}; } diff --git a/src/libs/utils/multitextcursor.cpp b/src/libs/utils/multitextcursor.cpp index 0c2e5b07925..7e991d3cd31 100644 --- a/src/libs/utils/multitextcursor.cpp +++ b/src/libs/utils/multitextcursor.cpp @@ -330,13 +330,10 @@ static QTextLine currentTextLine(const QTextCursor &cursor) return layout->lineForTextPosition(relativePos); } -bool MultiTextCursor::multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey) +bool MultiTextCursor::multiCursorEvent( + QKeyEvent *e, QKeySequence::StandardKey matchKey, Qt::KeyboardModifiers filterModifiers) { - uint searchkey = (e->modifiers() | e->key()) - & ~(Qt::KeypadModifier - | Qt::GroupSwitchModifier - | Qt::AltModifier - | Qt::ShiftModifier); + uint searchkey = (e->modifiers() | e->key()) & ~(filterModifiers | Qt::AltModifier); const QList bindings = QKeySequence::keyBindings(matchKey); return bindings.contains(QKeySequence(searchkey)); @@ -348,42 +345,42 @@ bool MultiTextCursor::handleMoveKeyEvent(QKeyEvent *e, { if (e->modifiers() & Qt::AltModifier && !Utils::HostOsInfo::isMacHost()) { QTextCursor::MoveOperation op = QTextCursor::NoMove; - if (multiCursorAddEvent(e, QKeySequence::MoveToNextWord)) { + if (multiCursorEvent(e, QKeySequence::MoveToNextWord)) { op = QTextCursor::WordRight; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToPreviousWord)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToPreviousWord)) { op = QTextCursor::WordLeft; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToEndOfBlock)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToEndOfBlock)) { op = QTextCursor::EndOfBlock; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToStartOfBlock)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToStartOfBlock)) { op = QTextCursor::StartOfBlock; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToNextLine)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToNextLine, Qt::ShiftModifier)) { op = QTextCursor::Down; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToPreviousLine)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToPreviousLine, Qt::ShiftModifier)) { op = QTextCursor::Up; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToStartOfLine)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToStartOfLine)) { op = QTextCursor::StartOfLine; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToEndOfLine)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToEndOfLine)) { op = QTextCursor::EndOfLine; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToStartOfDocument)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToStartOfDocument)) { op = QTextCursor::Start; - } else if (multiCursorAddEvent(e, QKeySequence::MoveToEndOfDocument)) { + } else if (multiCursorEvent(e, QKeySequence::MoveToEndOfDocument)) { op = QTextCursor::End; - } else { - return false; } - const std::list cursors = m_cursorList; - for (QTextCursor cursor : cursors) { - if (camelCaseNavigationEnabled && op == QTextCursor::WordRight) - CamelCaseCursor::right(&cursor, edit, QTextCursor::MoveAnchor); - else if (camelCaseNavigationEnabled && op == QTextCursor::WordLeft) - CamelCaseCursor::left(&cursor, edit, QTextCursor::MoveAnchor); - else - cursor.movePosition(op, QTextCursor::MoveAnchor); + if (op != QTextCursor::NoMove) { + const std::list cursors = m_cursorList; + for (QTextCursor cursor : cursors) { + if (camelCaseNavigationEnabled && op == QTextCursor::WordRight) + CamelCaseCursor::right(&cursor, edit, QTextCursor::MoveAnchor); + else if (camelCaseNavigationEnabled && op == QTextCursor::WordLeft) + CamelCaseCursor::left(&cursor, edit, QTextCursor::MoveAnchor); + else + cursor.movePosition(op, QTextCursor::MoveAnchor); - addCursor(cursor); + addCursor(cursor); + } + return true; } - return true; } for (auto it = m_cursorList.begin(); it != m_cursorList.end(); ++it) { @@ -395,28 +392,28 @@ bool MultiTextCursor::handleMoveKeyEvent(QKeyEvent *e, op = QTextCursor::Right; } else if (e == QKeySequence::MoveToPreviousChar) { op = QTextCursor::Left; - } else if (e == QKeySequence::SelectNextChar) { + } else if (multiCursorEvent(e, QKeySequence::SelectNextChar)) { op = QTextCursor::Right; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectPreviousChar) { + } else if (multiCursorEvent(e, QKeySequence::SelectPreviousChar)) { op = QTextCursor::Left; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectNextWord) { + } else if (multiCursorEvent(e, QKeySequence::SelectNextWord)) { op = QTextCursor::WordRight; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectPreviousWord) { + } else if (multiCursorEvent(e, QKeySequence::SelectPreviousWord)) { op = QTextCursor::WordLeft; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectStartOfLine) { + } else if (multiCursorEvent(e, QKeySequence::SelectStartOfLine)) { op = QTextCursor::StartOfLine; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectEndOfLine) { + } else if (multiCursorEvent(e, QKeySequence::SelectEndOfLine)) { op = QTextCursor::EndOfLine; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectStartOfBlock) { + } else if (multiCursorEvent(e, QKeySequence::SelectStartOfBlock)) { op = QTextCursor::StartOfBlock; mode = QTextCursor::KeepAnchor; - } else if (e == QKeySequence::SelectEndOfBlock) { + } else if (multiCursorEvent(e, QKeySequence::SelectEndOfBlock)) { op = QTextCursor::EndOfBlock; mode = QTextCursor::KeepAnchor; } else if (e == QKeySequence::SelectStartOfDocument) { diff --git a/src/libs/utils/multitextcursor.h b/src/libs/utils/multitextcursor.h index dc554dd2276..c1099013095 100644 --- a/src/libs/utils/multitextcursor.h +++ b/src/libs/utils/multitextcursor.h @@ -108,7 +108,10 @@ public: const_iterator constBegin() const { return m_cursorMap.cbegin(); } const_iterator constEnd() const { return m_cursorMap.cend(); } - static bool multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey); + static bool multiCursorEvent( + QKeyEvent *e, + QKeySequence::StandardKey matchKey, + Qt::KeyboardModifiers additionalFilterModifier = {}); private: std::list m_cursorList; diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp index 3b5c6ccf916..c9453bb9084 100644 --- a/src/plugins/android/androidavdmanager.cpp +++ b/src/plugins/android/androidavdmanager.cpp @@ -20,10 +20,10 @@ namespace Android::Internal::AndroidAvdManager { static Q_LOGGING_CATEGORY(avdManagerLog, "qtc.android.avdManager", QtWarningMsg) -QString startAvd(const QString &name) +QString startAvd(const QString &name, const std::optional> &future) { if (!findAvd(name).isEmpty() || startAvdAsync(name)) - return waitForAvd(name); + return waitForAvd(name, future); return {}; } diff --git a/src/plugins/android/androidavdmanager.h b/src/plugins/android/androidavdmanager.h index 5a1f188038c..7f1b094bdd2 100644 --- a/src/plugins/android/androidavdmanager.h +++ b/src/plugins/android/androidavdmanager.h @@ -8,7 +8,7 @@ namespace Android::Internal::AndroidAvdManager { -QString startAvd(const QString &name); +QString startAvd(const QString &name, const std::optional> &future = {}); bool startAvdAsync(const QString &avdName); QString findAvd(const QString &avdName); QString waitForAvd(const QString &avdName, const std::optional> &future = {}); diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 4972c653c9d..2e24eae73a8 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -111,15 +111,14 @@ static void startAvd(const IDevice::Ptr &device, QWidget *parent) const AndroidDevice *androidDev = static_cast(device.get()); const QString name = androidDev->avdName(); qCDebug(androidDeviceLog, "Starting Android AVD id \"%s\".", qPrintable(name)); - auto future = Utils::asyncRun([name, device] { - const QString serialNumber = AndroidAvdManager::startAvd(name); + Utils::futureSynchronizer()->addFuture(Utils::asyncRun([name, device](QPromise &promise) { + const QString serialNumber = AndroidAvdManager::startAvd(name, promise.future()); // Mark the AVD as ReadyToUse once we know it's started if (!serialNumber.isEmpty()) { DeviceManager *const devMgr = DeviceManager::instance(); devMgr->setDeviceState(device->id(), IDevice::DeviceReadyToUse); } - }); - // TODO: use future! + })); } static void setEmulatorArguments(QWidget *parent) diff --git a/src/plugins/clangtools/diagnosticmark.cpp b/src/plugins/clangtools/diagnosticmark.cpp index 5ea0895b947..9eba17965f4 100644 --- a/src/plugins/clangtools/diagnosticmark.cpp +++ b/src/plugins/clangtools/diagnosticmark.cpp @@ -29,43 +29,15 @@ DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic, TextDocument *docum : TextMark(document, diagnostic.location.line, clangToolsCategory()) , m_diagnostic(diagnostic) { - setSettingsPage(Constants::SETTINGS_PAGE_ID); - - const bool isError = diagnostic.type == "error" || diagnostic.type == "fatal"; - setColor(isError ? Theme::CodeModel_Error_TextMarkColor : Theme::CodeModel_Warning_TextMarkColor); - setPriority(isError ? TextEditor::TextMark::HighPriority : TextEditor::TextMark::NormalPriority); - QIcon markIcon = diagnostic.icon(); - setIcon(markIcon.isNull() ? Icons::CODEMODEL_WARNING.icon() : markIcon); - setToolTip(createDiagnosticToolTipString(diagnostic, std::nullopt, true)); - setLineAnnotation(diagnostic.description); - setActionsProvider([diagnostic] { - // Copy to clipboard action - QList actions; - QAction *action = new QAction(); - action->setIcon(Icon::fromTheme("edit-copy")); - action->setToolTip(Tr::tr("Copy to Clipboard")); - QObject::connect(action, &QAction::triggered, [diagnostic] { - const QString text = createFullLocationString(diagnostic.location) - + ": " - + diagnostic.description; - setClipboardAndSelection(text); - }); - actions << action; - - // Disable diagnostic action - action = new QAction(); - action->setIcon(Icons::BROKEN.icon()); - action->setToolTip(Tr::tr("Disable Diagnostic")); - QObject::connect(action, &QAction::triggered, [diagnostic] { disableChecks({diagnostic}); }); - actions << action; - return actions; - }); + initialize(); } DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic) : TextMark(diagnostic.location.filePath, diagnostic.location.line, clangToolsCategory()) , m_diagnostic(diagnostic) -{} +{ + initialize(); +} void DiagnosticMark::disable() { @@ -89,6 +61,41 @@ Diagnostic DiagnosticMark::diagnostic() const return m_diagnostic; } +void DiagnosticMark::initialize() +{ + setSettingsPage(Constants::SETTINGS_PAGE_ID); + + const bool isError = m_diagnostic.type == "error" || m_diagnostic.type == "fatal"; + setColor(isError ? Theme::CodeModel_Error_TextMarkColor : Theme::CodeModel_Warning_TextMarkColor); + setPriority(isError ? TextEditor::TextMark::HighPriority : TextEditor::TextMark::NormalPriority); + QIcon markIcon = m_diagnostic.icon(); + setIcon(markIcon.isNull() ? Icons::CODEMODEL_WARNING.icon() : markIcon); + setToolTip(createDiagnosticToolTipString(m_diagnostic, std::nullopt, true)); + setLineAnnotation(m_diagnostic.description); + setActionsProvider([diagnostic = m_diagnostic] { + // Copy to clipboard action + QList actions; + QAction *action = new QAction(); + action->setIcon(Icon::fromTheme("edit-copy")); + action->setToolTip(Tr::tr("Copy to Clipboard")); + QObject::connect(action, &QAction::triggered, [diagnostic] { + const QString text = createFullLocationString(diagnostic.location) + + ": " + + diagnostic.description; + setClipboardAndSelection(text); + }); + actions << action; + + // Disable diagnostic action + action = new QAction(); + action->setIcon(Icons::BROKEN.icon()); + action->setToolTip(Tr::tr("Disable Diagnostic")); + QObject::connect(action, &QAction::triggered, [diagnostic] { disableChecks({diagnostic}); }); + actions << action; + return actions; + }); +} + } // namespace Internal } // namespace ClangTools diff --git a/src/plugins/clangtools/diagnosticmark.h b/src/plugins/clangtools/diagnosticmark.h index 6d566739d42..7d2999e66ec 100644 --- a/src/plugins/clangtools/diagnosticmark.h +++ b/src/plugins/clangtools/diagnosticmark.h @@ -25,6 +25,7 @@ public: std::optional toolType; private: + void initialize(); const Diagnostic m_diagnostic; bool m_enabled = true; }; diff --git a/src/plugins/coreplugin/images/mode_design_mask.png b/src/plugins/coreplugin/images/mode_design_mask.png index c2a82ef8914..2cd54a4c0c4 100644 Binary files a/src/plugins/coreplugin/images/mode_design_mask.png and b/src/plugins/coreplugin/images/mode_design_mask.png differ diff --git a/src/plugins/coreplugin/images/mode_design_mask@2x.png b/src/plugins/coreplugin/images/mode_design_mask@2x.png index 9a060d74983..a52d6274f0c 100644 Binary files a/src/plugins/coreplugin/images/mode_design_mask@2x.png and b/src/plugins/coreplugin/images/mode_design_mask@2x.png differ diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.cpp b/src/plugins/coreplugin/locator/locatorsettingspage.cpp index 4eeeb1a0ac3..dffe60501c4 100644 --- a/src/plugins/coreplugin/locator/locatorsettingspage.cpp +++ b/src/plugins/coreplugin/locator/locatorsettingspage.cpp @@ -214,21 +214,13 @@ void RichTextDelegate::paint(QPainter *painter, m_doc.setHtml(options.text); m_doc.setTextWidth(options.rect.width()); options.text = ""; - options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter); + options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget); painter->translate(options.rect.left(), options.rect.top()); QRect clip(0, 0, options.rect.width(), options.rect.height()); QAbstractTextDocumentLayout::PaintContext paintContext; paintContext.palette = options.palette; painter->setClipRect(clip); paintContext.clip = clip; - if (qobject_cast(options.widget)->selectionModel()->isSelected(index)) { - QAbstractTextDocumentLayout::Selection selection; - selection.cursor = QTextCursor(&m_doc); - selection.cursor.select(QTextCursor::Document); - selection.format.setBackground(options.palette.brush(QPalette::Highlight)); - selection.format.setForeground(options.palette.brush(QPalette::HighlightedText)); - paintContext.selections << selection; - } m_doc.documentLayout()->draw(painter, paintContext); painter->restore(); } diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index c8e6ed2b344..a9a70e60a67 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -349,9 +349,8 @@ void ModeManager::currentTabChanged(int index) if (!mode) return; - // FIXME: This hardcoded context update is required for the Debug and Edit modes, since - // they use the editor widget, which is already a context widget so the main window won't - // go further up the parent tree to find the mode context. + // Set the mode's context regardless of focus widget. + // Whenever a mode is active, it's Context is active. ICore::updateAdditionalContexts(d->m_addedContexts, mode->context()); d->m_addedContexts = mode->context(); diff --git a/src/plugins/cppcheck/cppcheckmanualrundialog.cpp b/src/plugins/cppcheck/cppcheckmanualrundialog.cpp index f5d5f687581..9ba540f50fd 100644 --- a/src/plugins/cppcheck/cppcheckmanualrundialog.cpp +++ b/src/plugins/cppcheck/cppcheckmanualrundialog.cpp @@ -19,10 +19,12 @@ namespace Cppcheck::Internal { -ManualRunDialog::ManualRunDialog(const ProjectExplorer::Project *project) +ManualRunDialog::ManualRunDialog(const ProjectExplorer::Project *project, + CppcheckSettings *settings) : m_model(new ProjectExplorer::SelectableFilesFromDirModel(this)) { QTC_ASSERT(project, return ); + QTC_ASSERT(settings, return); setWindowTitle(Tr::tr("Cppcheck Run Configuration")); @@ -52,9 +54,7 @@ ManualRunDialog::ManualRunDialog(const ProjectExplorer::Project *project) analyzeButton->setEnabled(m_model->hasCheckedFiles()); }); - m_manualRunSettings.readSettings(); - m_manualRunSettings.setAutoApply(true); - auto optionsWidget = m_manualRunSettings.layouter()().emerge(); + auto optionsWidget = settings->layouter()().emerge(); auto layout = new QVBoxLayout(this); layout->addWidget(optionsWidget); diff --git a/src/plugins/cppcheck/cppcheckmanualrundialog.h b/src/plugins/cppcheck/cppcheckmanualrundialog.h index fe5b920ee23..1f9c91e576a 100644 --- a/src/plugins/cppcheck/cppcheckmanualrundialog.h +++ b/src/plugins/cppcheck/cppcheckmanualrundialog.h @@ -3,8 +3,6 @@ #pragma once -#include "cppchecksettings.h" - #include namespace Utils { @@ -19,18 +17,18 @@ class SelectableFilesFromDirModel; namespace Cppcheck::Internal { +class CppcheckSettings; + class ManualRunDialog : public QDialog { public: - explicit ManualRunDialog(const ProjectExplorer::Project *project); + explicit ManualRunDialog(const ProjectExplorer::Project *project, CppcheckSettings *settings); Utils::FilePaths filePaths() const; QSize sizeHint() const override; - const CppcheckSettings &manualRunSettings() const { return m_manualRunSettings; } private: ProjectExplorer::SelectableFilesFromDirModel *m_model; - CppcheckSettings m_manualRunSettings; }; } // Cppcheck::Internal diff --git a/src/plugins/cppcheck/cppcheckplugin.cpp b/src/plugins/cppcheck/cppcheckplugin.cpp index 5bc99e54efb..341b25db029 100644 --- a/src/plugins/cppcheck/cppcheckplugin.cpp +++ b/src/plugins/cppcheck/cppcheckplugin.cpp @@ -40,6 +40,7 @@ class CppcheckPluginPrivate final : public QObject { public: explicit CppcheckPluginPrivate(); + ~CppcheckPluginPrivate(); CppcheckTextMarkManager marks; CppcheckTool tool{marks, Constants::CHECK_PROGRESS_ID}; @@ -49,9 +50,12 @@ public: Utils::Perspective perspective{Constants::PERSPECTIVE_ID, ::Cppcheck::Tr::tr("Cppcheck")}; Action *manualRunAction = nullptr; + QHash projectSettings; void startManualRun(); void updateManualRunAction(); + void saveProjectSettings(Project *project); + void loadProjectSettings(Project *project); }; CppcheckPluginPrivate::CppcheckPluginPrivate() @@ -104,6 +108,29 @@ CppcheckPluginPrivate::CppcheckPluginPrivate() action, &QAction::setEnabled); perspective.addToolBarAction(action); } + connect(ProjectManager::instance(), &ProjectManager::startupProjectChanged, + this, [this](Project *project) { + if (!project) + return; + CppcheckSettings *settings = projectSettings.value(project, nullptr); + if (!settings) { + settings = new CppcheckSettings; + settings->readSettings(); + settings->setAutoApply(true); + connect(project, &Project::aboutToSaveSettings, + this, [this, project]{ saveProjectSettings(project); }); + connect(project, &Project::settingsLoaded, + this, [this, project]{ loadProjectSettings(project); }); + projectSettings.insert(project, settings); + loadProjectSettings(project); + } + }); +} + +CppcheckPluginPrivate::~CppcheckPluginPrivate() +{ + qDeleteAll(projectSettings); + projectSettings.clear(); } void CppcheckPluginPrivate::startManualRun() @@ -112,7 +139,9 @@ void CppcheckPluginPrivate::startManualRun() if (!project) return; - ManualRunDialog dialog(project); + CppcheckSettings *settings = projectSettings.value(project, nullptr); + QTC_ASSERT(settings, return); + ManualRunDialog dialog(project, settings); if (dialog.exec() == ManualRunDialog::Rejected) return; @@ -123,7 +152,7 @@ void CppcheckPluginPrivate::startManualRun() return; manualRunTool.setProject(project); - manualRunTool.updateOptions(dialog.manualRunSettings()); + manualRunTool.updateOptions(*settings); manualRunTool.check(files); perspective.select(); } @@ -138,6 +167,30 @@ void CppcheckPluginPrivate::updateManualRunAction() manualRunAction->setEnabled(canRun); } +void CppcheckPluginPrivate::saveProjectSettings(Project *project) +{ + QTC_ASSERT(project, return); + CppcheckSettings *settings = projectSettings.value(project, nullptr); + QTC_ASSERT(settings, return); + + Store store; + settings->toMap(store); + project->setNamedSettings("CppcheckManual", Utils::variantFromStore(store)); +} + +void CppcheckPluginPrivate::loadProjectSettings(Project *project) +{ + QTC_ASSERT(project, return); + CppcheckSettings *settings = projectSettings.value(project, nullptr); + QTC_ASSERT(settings, return); + + const QVariant variant = project->namedSettings("CppcheckManual"); + if (!variant.isValid()) + return; + Store store = Utils::storeFromVariant(project->namedSettings("CppcheckManual")); + settings->fromMap(store); +} + class CppcheckPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT diff --git a/src/plugins/extensionmanager/CMakeLists.txt b/src/plugins/extensionmanager/CMakeLists.txt index 094c1eb7d91..56236df9fb7 100644 --- a/src/plugins/extensionmanager/CMakeLists.txt +++ b/src/plugins/extensionmanager/CMakeLists.txt @@ -5,6 +5,8 @@ add_qtc_plugin(ExtensionManager extensionmanagerconstants.h extensionmanagerplugin.cpp extensionmanagertr.h + extensionmanagersettings.cpp + extensionmanagersettings.h extensionmanagerwidget.cpp extensionmanagerwidget.h extensionsbrowser.cpp diff --git a/src/plugins/extensionmanager/extensionmanager.qbs b/src/plugins/extensionmanager/extensionmanager.qbs index 0d5fa5cb259..994d75f7366 100644 --- a/src/plugins/extensionmanager/extensionmanager.qbs +++ b/src/plugins/extensionmanager/extensionmanager.qbs @@ -13,6 +13,8 @@ QtcPlugin { "extensionmanagerconstants.h", "extensionmanagerplugin.cpp", "extensionmanagertr.h", + "extensionmanagersettings.cpp", + "extensionmanagersettings.h", "extensionmanagerwidget.cpp", "extensionmanagerwidget.h", "extensionsbrowser.cpp", diff --git a/src/plugins/extensionmanager/extensionmanagersettings.cpp b/src/plugins/extensionmanager/extensionmanagersettings.cpp new file mode 100644 index 00000000000..54f4920181c --- /dev/null +++ b/src/plugins/extensionmanager/extensionmanagersettings.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "extensionmanagersettings.h" +#include "extensionmanagertr.h" + +#include +#include + +#include + +namespace ExtensionManager::Internal { + +ExtensionManagerSettings &settings() +{ + static ExtensionManagerSettings theExtensionManagerSettings; + return theExtensionManagerSettings; +} + +ExtensionManagerSettings::ExtensionManagerSettings() +{ + setAutoApply(false); + setSettingsGroup("ExtensionManager"); + + externalRepoUrl.setDefaultValue("https://qc-extensions.qt.io"); + externalRepoUrl.setReadOnly(true); + + useExternalRepo.setSettingsKey("UseExternalRepo"); + useExternalRepo.setLabelText(Tr::tr("Use external repository")); + useExternalRepo.setToolTip(Tr::tr("Repository: %1").arg(externalRepoUrl())); + useExternalRepo.setDefaultValue(false); + + setLayouter([this] { + using namespace Layouting; + + return Column { + useExternalRepo, + st + }; + }); + + readSettings(); +} + +class ExtensionManagerSettingsPage : public Core::IOptionsPage +{ +public: + ExtensionManagerSettingsPage() + { + setId("ExtensionManager"); + setDisplayName(Tr::tr("Extensions")); + setCategory(Core::Constants::SETTINGS_CATEGORY_CORE); + setSettingsProvider([] { return &settings(); }); + } +}; + +const ExtensionManagerSettingsPage settingsPage; + +} // ExtensionManager::Internal diff --git a/src/plugins/extensionmanager/extensionmanagersettings.h b/src/plugins/extensionmanager/extensionmanagersettings.h new file mode 100644 index 00000000000..ed6b2f2aec4 --- /dev/null +++ b/src/plugins/extensionmanager/extensionmanagersettings.h @@ -0,0 +1,21 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace ExtensionManager::Internal { + +class ExtensionManagerSettings final : public Utils::AspectContainer +{ +public: + ExtensionManagerSettings(); + + Utils::StringAspect externalRepoUrl{this}; + Utils::BoolAspect useExternalRepo{this}; +}; + +ExtensionManagerSettings &settings(); + +} // ExtensionManager::Internal diff --git a/src/plugins/extensionmanager/extensionsbrowser.cpp b/src/plugins/extensionmanager/extensionsbrowser.cpp index da757c0bbfb..60d9be94df0 100644 --- a/src/plugins/extensionmanager/extensionsbrowser.cpp +++ b/src/plugins/extensionmanager/extensionsbrowser.cpp @@ -5,7 +5,7 @@ #include "extensionmanagertr.h" #include "extensionsmodel.h" -#include "utils/hostosinfo.h" +#include "extensionmanagersettings.h" #ifdef WITH_TESTS #include "extensionmanager_test.h" @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -399,14 +400,18 @@ void ExtensionsBrowser::fetchExtensions() // d->model->setExtensionsJson(testData("defaultpacks")); return; #endif // WITH_TESTS + if (!settings().useExternalRepo()) { + d->model->setExtensionsJson({}); + return; + } + using namespace Tasking; const auto onQuerySetup = [this](NetworkQuery &query) { - const QString host = "https://qc-extensions.qt.io"; const QString url = "%1/api/v1/search?request="; const QString requestTemplate = R"({"version":"%1","host_os":"%2","host_os_version":"%3","host_architecture":"%4","page_size":200})"; - const QString request = url.arg(host) + requestTemplate + const QString request = url.arg(settings().externalRepoUrl()) + requestTemplate .arg(QCoreApplication::applicationVersion()) .arg(osTypeToString(HostOsInfo::hostOs())) .arg(QSysInfo::productVersion()) @@ -444,6 +449,7 @@ QLabel *tfLabel(const TextFormat &tf, bool singleLine) label->setFixedHeight(tf.lineHeight()); label->setFont(tf.font()); label->setAlignment(Qt::Alignment(tf.drawTextFlags)); + label->setTextInteractionFlags(Qt::TextSelectableByMouse); QPalette pal = label->palette(); pal.setColor(QPalette::WindowText, tf.color()); diff --git a/src/plugins/languageclient/callandtypehierarchy.cpp b/src/plugins/languageclient/callandtypehierarchy.cpp index 8cfc3578c37..4b8f7117132 100644 --- a/src/plugins/languageclient/callandtypehierarchy.cpp +++ b/src/plugins/languageclient/callandtypehierarchy.cpp @@ -66,10 +66,14 @@ protected: return QVariant::fromValue( Link(m_client->serverUriToHostPath(m_item.uri()), start.line() + 1, start.character())); } - case AnnotationRole: + case AnnotationRole: { + QStringList result; if (const std::optional detail = m_item.detail()) - return *detail; - return {}; + result << *detail; + if (childCount() > 0) + result << QString("[%1]").arg(childCount()); + return result.isEmpty() ? QVariant() : QVariant(result.join(' ')); + } default: return TreeItem::data(column, role); } diff --git a/src/plugins/lua/meta/gui.lua b/src/plugins/lua/meta/gui.lua index 71f9f20cf65..ac3df927809 100644 --- a/src/plugins/lua/meta/gui.lua +++ b/src/plugins/lua/meta/gui.lua @@ -1,4 +1,4 @@ ----@meta Layout +---@meta Gui local gui = {} diff --git a/src/plugins/projectexplorer/devicesupport/filetransfer.h b/src/plugins/projectexplorer/devicesupport/filetransfer.h index 7ad6a5c5bc3..2d84351d55c 100644 --- a/src/plugins/projectexplorer/devicesupport/filetransfer.h +++ b/src/plugins/projectexplorer/devicesupport/filetransfer.h @@ -37,6 +37,7 @@ public: Utils::ProcessResultData resultData() const; static QString transferMethodName(FileTransferMethod method); + QString transferMethodName() const { return transferMethodName(transferMethod()); } signals: void progress(const QString &progressMessage); diff --git a/src/plugins/projectexplorer/images/build_hammer_mask.png b/src/plugins/projectexplorer/images/build_hammer_mask.png index c30f933962a..e75c3e15cff 100644 Binary files a/src/plugins/projectexplorer/images/build_hammer_mask.png and b/src/plugins/projectexplorer/images/build_hammer_mask.png differ diff --git a/src/plugins/projectexplorer/images/build_hammer_mask@2x.png b/src/plugins/projectexplorer/images/build_hammer_mask@2x.png index fc679b1d566..78beee25a8b 100644 Binary files a/src/plugins/projectexplorer/images/build_hammer_mask@2x.png and b/src/plugins/projectexplorer/images/build_hammer_mask@2x.png differ diff --git a/src/plugins/projectexplorer/images/mode_project_mask.png b/src/plugins/projectexplorer/images/mode_project_mask.png index 5799759f31f..00ad8d56ef3 100644 Binary files a/src/plugins/projectexplorer/images/mode_project_mask.png and b/src/plugins/projectexplorer/images/mode_project_mask.png differ diff --git a/src/plugins/projectexplorer/images/mode_project_mask@2x.png b/src/plugins/projectexplorer/images/mode_project_mask@2x.png index 79d0e7a5488..30a39506c44 100644 Binary files a/src/plugins/projectexplorer/images/mode_project_mask@2x.png and b/src/plugins/projectexplorer/images/mode_project_mask@2x.png differ diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp index 570dd8eda81..b127fa23a8b 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp @@ -572,14 +572,15 @@ static QStringList environmentTemplatesPaths() } static bool s_searchPathsInitialized = false; +Q_GLOBAL_STATIC(FilePath, s_installedWizardsPath, {Core::ICore::resourcePath(WIZARD_PATH)}) +Q_GLOBAL_STATIC(FilePaths, s_additionalWizardPaths) FilePaths &JsonWizardFactory::searchPaths() { static FilePaths m_searchPaths; if (!s_searchPathsInitialized) { s_searchPathsInitialized = true; - m_searchPaths = {Core::ICore::userResourcePath(WIZARD_PATH), - Core::ICore::resourcePath(WIZARD_PATH)}; + m_searchPaths = {Core::ICore::userResourcePath(WIZARD_PATH), *s_installedWizardsPath}; for (const QString &environmentTemplateDirName : environmentTemplatesPaths()) m_searchPaths << FilePath::fromString(environmentTemplateDirName); m_searchPaths << Utils::transform( @@ -598,6 +599,7 @@ FilePaths &JsonWizardFactory::searchPaths() } } } + m_searchPaths += *s_additionalWizardPaths; } return m_searchPaths; @@ -610,12 +612,16 @@ void JsonWizardFactory::resetSearchPaths() void JsonWizardFactory::addWizardPath(const FilePath &path) { - searchPaths().append(path); + s_additionalWizardPaths->append(path); } -void JsonWizardFactory::clearWizardPaths() +/*! + \internal +*/ +void JsonWizardFactory::setInstalledWizardsPath(const Utils::FilePath &path) { - searchPaths().clear(); + *s_installedWizardsPath = path; + resetSearchPaths(); } void JsonWizardFactory::setVerbose(int level) diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h index 490f58b99f3..5e7fba1f1de 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h @@ -27,7 +27,6 @@ class PROJECTEXPLORER_EXPORT JsonWizardFactory : public Core::IWizardFactory public: // Add search paths for wizard.json files. All subdirs are going to be checked. static void addWizardPath(const Utils::FilePath &path); - static void clearWizardPaths(); // actual interface of the wizard factory: class Generator { @@ -59,6 +58,9 @@ public: virtual std::pair screenSizeInfoFromPage(const QString &pageType) const; + // internal + static void setInstalledWizardsPath(const Utils::FilePath &path); + private: Utils::Wizard *runWizardImpl(const Utils::FilePath &path, QWidget *parent, Utils::Id platform, const QVariantMap &variables, bool showWizard = true) override; diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index 01c808275d3..bd73137b00d 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -161,14 +161,10 @@ void ExampleSetModel::recreateModel(const QtVersions &qtVersionsIn) // Sort by Qt version, example sets not associated to Qt last Utils::sort(items, [](QStandardItem *a, QStandardItem *b) { const QVersionNumber versionB = b->data(kVersionRole).value(); - if (versionB.isNull()) - return true; const QVersionNumber versionA = a->data(kVersionRole).value(); - if (versionA.isNull()) - return false; - if (versionA == versionB) - return a->data(Qt::DisplayRole).toString() < b->data(Qt::DisplayRole).toString(); - return versionA < versionB; + if (versionA != versionB) + return versionA < versionB; + return a->data(Qt::DisplayRole).toString() < b->data(Qt::DisplayRole).toString(); }); for (QStandardItem *item : std::as_const(items)) diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 0002e69f5f2..cba80697f08 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -176,12 +176,16 @@ GroupItem GenericDeployStep::transferTask(const Storage &storag const auto onError = [this](const FileTransfer &transfer) { const ProcessResultData result = transfer.resultData(); if (result.m_error == QProcess::FailedToStart) { - addErrorMessage(Tr::tr("rsync failed to start: %1").arg(result.m_errorString)); + addErrorMessage(Tr::tr("%1 failed to start: %2") + .arg(transfer.transferMethodName(), result.m_errorString)); } else if (result.m_exitStatus == QProcess::CrashExit) { - addErrorMessage(Tr::tr("rsync crashed.")); + addErrorMessage(Tr::tr("%1 crashed.").arg(transfer.transferMethodName())); } else if (result.m_exitCode != 0) { - addErrorMessage(Tr::tr("rsync failed with exit code %1.").arg(result.m_exitCode) - + "\n" + result.m_errorString); + addErrorMessage( + Tr::tr("%1 failed with exit code %2.") + .arg(transfer.transferMethodName()) + .arg(result.m_exitCode) + + "\n" + result.m_errorString); } }; return FileTransferTask(onSetup, onError, CallDoneIf::Error); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index be9cb716865..f2900a22158 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -27,11 +27,6 @@ using namespace Utils; namespace RemoteLinux { namespace Internal { -struct TransferStorage -{ - bool useGenericCopy = false; -}; - class GenericLinuxDeviceTesterPrivate { public: @@ -43,8 +38,7 @@ public: GroupItem echoTask(const QString &contents) const; GroupItem unameTask() const; GroupItem gathererTask() const; - GroupItem transferTask(FileTransferMethod method, - const Storage &storage) const; + GroupItem transferTask(FileTransferMethod method) const; GroupItem transferTasks() const; GroupItem commandTasks() const; @@ -192,8 +186,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const }; } -GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method, - const Storage &storage) const +GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method) const { const auto onSetup = [this, method](FileTransfer &transfer) { emit q->progressMessage(Tr::tr("Checking whether \"%1\" works...") @@ -201,7 +194,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho transfer.setTransferMethod(method); transfer.setTestDevice(m_device); }; - const auto onDone = [this, method, storage](const FileTransfer &transfer, DoneWith result) { + const auto onDone = [this, method](const FileTransfer &transfer, DoneWith result) { const QString methodName = FileTransfer::transferMethodName(method); if (result == DoneWith::Success) { emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName)); @@ -209,8 +202,6 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho m_device->setExtraData(Constants::SUPPORTS_RSYNC, true); else if (method == FileTransferMethod::Sftp) m_device->setExtraData(Constants::SUPPORTS_SFTP, true); - else - storage->useGenericCopy = true; return; } const ProcessResultData resultData = transfer.resultData(); @@ -251,13 +242,11 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const { - Storage storage; return Group { continueOnSuccess, - storage, - transferTask(FileTransferMethod::GenericCopy, storage), - transferTask(FileTransferMethod::Sftp, storage), - transferTask(FileTransferMethod::Rsync, storage), + transferTask(FileTransferMethod::GenericCopy), + transferTask(FileTransferMethod::Sftp), + transferTask(FileTransferMethod::Rsync), onGroupDone([this] { emit q->errorMessage(Tr::tr("Deployment to this device will not work out of the box.") + "\n"); diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 6cb94efb35b..a2094a0d423 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -609,8 +609,7 @@ void StudioWelcomePlugin::extensionsInitialized() // Enable QDS new project dialog and QDS wizards if (Core::ICore::isQtDesignStudio()) { - ProjectExplorer::JsonWizardFactory::clearWizardPaths(); - ProjectExplorer::JsonWizardFactory::addWizardPath( + ProjectExplorer::JsonWizardFactory::setInstalledWizardsPath( Core::ICore::resourcePath("qmldesigner/studio_templates")); Core::ICore::setNewDialogFactory([](QWidget *parent) { return new QdsNewDialog(parent); }); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 5bd5667a4b7..f1acff134b6 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -3087,15 +3087,21 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) if (ro || !isPrintableText(eventText)) { QTextCursor::MoveOperation blockSelectionOperation = QTextCursor::NoMove; - if (e->modifiers() == (Qt::AltModifier | Qt::ShiftModifier) && !Utils::HostOsInfo::isMacHost()) { - if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToNextLine)) + if (e->modifiers() == (Qt::AltModifier | Qt::ShiftModifier) + && !Utils::HostOsInfo::isMacHost()) { + if (MultiTextCursor::multiCursorEvent( + e, QKeySequence::MoveToNextLine, Qt::ShiftModifier)) { blockSelectionOperation = QTextCursor::Down; - else if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToPreviousLine)) + } else if (MultiTextCursor::multiCursorEvent( + e, QKeySequence::MoveToPreviousLine, Qt::ShiftModifier)) { blockSelectionOperation = QTextCursor::Up; - else if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToNextChar)) + } else if (MultiTextCursor::multiCursorEvent( + e, QKeySequence::MoveToNextChar, Qt::ShiftModifier)) { blockSelectionOperation = QTextCursor::NextCharacter; - else if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToPreviousChar)) + } else if (MultiTextCursor::multiCursorEvent( + e, QKeySequence::MoveToPreviousChar, Qt::ShiftModifier)) { blockSelectionOperation = QTextCursor::PreviousCharacter; + } } if (blockSelectionOperation != QTextCursor::NoMove) { @@ -7431,6 +7437,25 @@ void TextEditorWidgetPrivate::handleBackspaceKey() QTC_ASSERT(!q->multiTextCursor().hasSelection(), return); MultiTextCursor cursor = m_cursors; cursor.beginEditBlock(); + + const TabSettings tabSettings = m_document->tabSettings(); + const TypingSettings &typingSettings = m_document->typingSettings(); + + auto behavior = typingSettings.m_smartBackspaceBehavior; + if (cursor.hasMultipleCursors()) { + if (behavior == TypingSettings::BackspaceFollowsPreviousIndents) { + behavior = TypingSettings::BackspaceNeverIndents; + } else if (behavior == TypingSettings::BackspaceUnindents) { + for (QTextCursor &c : cursor) { + if (c.positionInBlock() == 0 + || c.positionInBlock() > TabSettings::firstNonSpace(c.block().text())) { + behavior = TypingSettings::BackspaceNeverIndents; + break; + } + } + } + } + for (QTextCursor &c : cursor) { const int pos = c.position(); if (!pos) @@ -7443,9 +7468,6 @@ void TextEditorWidgetPrivate::handleBackspaceKey() cursorWithinSnippet = snippetCheckCursor(snippetCursor); } - const TabSettings tabSettings = m_document->tabSettings(); - const TypingSettings &typingSettings = m_document->typingSettings(); - if (typingSettings.m_autoIndent && !m_autoCompleteHighlightPos.isEmpty() && (m_autoCompleteHighlightPos.last() == c) && m_removeAutoCompletedText && m_autoCompleter->autoBackspace(c)) { @@ -7453,12 +7475,12 @@ void TextEditorWidgetPrivate::handleBackspaceKey() } bool handled = false; - if (typingSettings.m_smartBackspaceBehavior == TypingSettings::BackspaceNeverIndents) { + if (behavior == TypingSettings::BackspaceNeverIndents) { if (cursorWithinSnippet) c.beginEditBlock(); c.deletePreviousChar(); handled = true; - } else if (typingSettings.m_smartBackspaceBehavior + } else if (behavior == TypingSettings::BackspaceFollowsPreviousIndents) { QTextBlock currentBlock = c.block(); int positionInBlock = pos - currentBlock.position(); @@ -7493,7 +7515,7 @@ void TextEditorWidgetPrivate::handleBackspaceKey() } } } - } else if (typingSettings.m_smartBackspaceBehavior == TypingSettings::BackspaceUnindents) { + } else if (behavior == TypingSettings::BackspaceUnindents) { if (c.positionInBlock() == 0 || c.positionInBlock() > TabSettings::firstNonSpace(c.block().text())) { if (cursorWithinSnippet) diff --git a/src/plugins/welcome/images/mode_welcome_mask.png b/src/plugins/welcome/images/mode_welcome_mask.png index f15a361e45d..bd53ad1ae29 100644 Binary files a/src/plugins/welcome/images/mode_welcome_mask.png and b/src/plugins/welcome/images/mode_welcome_mask.png differ diff --git a/src/plugins/welcome/images/mode_welcome_mask@2x.png b/src/plugins/welcome/images/mode_welcome_mask@2x.png index 63b8b88ed83..09810189365 100644 Binary files a/src/plugins/welcome/images/mode_welcome_mask@2x.png and b/src/plugins/welcome/images/mode_welcome_mask@2x.png differ diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index d58e1b596ef..a51819744a0 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -8727,17 +8727,10 @@ width="100%" height="100%" style="stroke-width:0.88039" /> - - - - + + + + + - - - + + + + - - - - - - + + + + + + - - - - +