Merge remote-tracking branch 'origin/15.0'

Conflicts:
	doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc
	src/plugins/projectexplorer/runcontrol.cpp
	src/plugins/qmljseditor/qmljseditorsettings.cpp

Change-Id: I113e3c8cd02e4bb6cbcd98a98436e46b96124f13
This commit is contained in:
Eike Ziller
2025-01-09 11:26:18 +01:00
47 changed files with 1588 additions and 351 deletions

View File

@@ -9,7 +9,7 @@ on:
env:
QT_VERSION: 6.7.2
MACOS_DEPLOYMENT_TARGET: 11.0
CLANG_VERSION: 19.1.0
CLANG_VERSION: 19.1.6
ELFUTILS_VERSION: 0.175
CMAKE_VERSION: 3.30.3
NINJA_VERSION: 1.10.2

View File

@@ -37,7 +37,7 @@ instructions:
variableValue: "RelWithDebInfo"
- type: EnvironmentVariable
variableName: LLVM_BASE_URL
variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_19.1.0-based
variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_19.1.6-based
- type: EnvironmentVariable
variableName: QTC_QT_MODULES
variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine"

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,162 @@
// Copyright (C) 2024 Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
/*!
\page creator-qtaiassistant.html
\previouspage creator-how-tos.html
\ingroup creator-how-to-edit
\title Use Qt AI Assistant
Qt AI Assistant is a coding assistant. When connected to a Large Language
Model (LLM), it auto-completes your code, gives expert coding advice,
suggests code fixes, as well as writes test cases and code documentation.
\image qtaiassistant-codecompletion.webp {Automatic Code Completion}
Qt AI Assistant is available for selected commercial Qt developer
license holders. For more information on licensing, select \uicontrol Compare
in \l{Qt pricing}.
\note The LLM itself is not in scope of the Qt AI Assistant. You need to
connect to a third-party LLM and agree to the terms and conditions, as well
as to the acceptable use policy of the LLM provider. By using Qt AI Assistant,
you agree to \l{Terms & Conditions - Qt Development Framework}.
Qt AI Assistant is currently experimental and powered by generative AI. Check
all suggestions to make sure that they are fit for use in your project.
\note Install and load the Qt AI Assistant extension to use it.
\section1 Connect to an LLM
You can connect to the following LLMs:
\list
\li Meta Code Llama 13B (running in a cloud deployment of your choice)
\li Meta Llama 3.1 70B (running in a cloud deployment of your choice)
\li Anthropic Claude 3.5 Sonnet (provided as subscription-based service
by Anthropic)
\li Meta Code Llama 7B through Ollama (running locally on your computer)
\endlist
To connect to an LLM:
\list 1
\li Go to \preferences > \uicontrol {AI Assistant} > \uicontrol General.
\image qtcreator-preferences-qtaiassistant-general.webp {AI Assistant General preferences}
\li Select an LLM for each configurable use case.
\li Go to \uicontrol Advanced.
\image qtcreator-preferences-qtaiassistant-advanced.webp {AI Assistant Advanced preferences}
\li Enter the API authentication token and server URL of each LLM.
For more information on where to get the access information, see the
third-party LLM provider documentation.
\endlist
\section1 Automatic code-completion
Qt AI Assistant can help you write code by suggesting what to write next.
It prompts the LLM to make one code suggestion when you stop typing.
To accept the entire suggestion, select the \key Tab key.
To accept parts of the suggestions, select \key {Alt+Right}.
To dismiss the suggestion, select \key Esc or navigate to another position in
the code editor.
To interact with Qt AI Assistant using the mouse, hover over the suggestion.
\image qtaiassistant-codecompletionbar.webp {Code completion tool bar when hovering over a suggestion}
When you hover over a suggestion, you can accept parts of the suggested code
snippet word-by-word or line-by-line.
To close the code completion bar, select the \key Esc key or move the cursor
to another position.
To turn auto-completion of code on or off globally for all projects, go to
\preferences > \uicontrol {AI Assistant}. Qt AI Assistant consumes a
significant number of tokens from the LLM. To cut costs, disable the
auto-completion feature when not needed, and use keyboard shortcuts for
code completion.
\section1 Complete code from the keyboard
To trigger code suggestions manually, select \key {Ctrl+'}.
\section1 Enter prompts and smart commands
In an inline prompt window in the text editor, you can prompt the assistant
to implement your requests in human language, ask questions, or execute
\e {smart commands}. To open the chat, select \key {Ctrl+Shift+A}.
Alternatively, to open the inline prompt window, you can select code
and then select \inlineimage icons/ai-assistant.png.
To close the inline prompt window, select \key Esc or
\inlineimage icons/close.png.
To go to Qt AI Assistant preferences from the inline prompt window, select
\inlineimage icons/settings.png.
\section2 Request suggestions using human language
To request suggestions using human language, enter your requests into the
input field. If you have highlighted code, the AI assistant adds it as
context to the prompt. Qt AI Assistant shows a suggestion that you can
copy to the clipboard by selecting \uicontrol Copy in the inline prompt
window.
\section2 Request test cases in Qt Test syntax
To write test cases with Qt AI Assistant:
\list 1
\li Highlight code in the code editor.
\li Open the inline prompt window.
\li Select the \uicontrol {/qtest} smart command.
\endlist
Qt AI Assistant generates a test case in \l{Qt Test} format that you can copy
and paste to your \l{Create Qt tests}{Qt test project}.
\section2 Request code documentation in Markdown format
To create code documentation:
\list 1
\li Highlight code in the code editor.
\li Open the inline prompt window.
\li Select the \uicontrol {/doc} smart command.
\endlist
Qt AI Assistant generates code documentation in a format that you can copy
and paste to your documentation file.
\section2 Request fixing of code
To request a fix to your code:
\list 1
\li Highlight code in the code editor.
\li Open the inline prompt window.
\li Select the \uicontrol {/fix} smart command.
\endlist
Qt AI Assistant writes a suggestion for a fix of your code.
\section2 Request explaining of code
To request an explanation of existing code:
\list 1
\li Highlight code in the code editor.
\li Open the inline prompt window.
\li Select the \uicontrol {/explain} smart command.
\endlist
Qt AI Assistant provides an explanation of the highlighted code.
\sa {Install extensions}, {Load extensions}
*/

View File

@@ -77,8 +77,9 @@
\image qtcreator-copilot.gif {Receiving suggestions from Copilot in the editor}
To manually request a suggestion at the current editor's cursor position,
enter \uicontrol {t} (\uicontrol {Request Copilot Suggestion}) in the
\l{Navigate with locator}{locator}.
enter \uicontrol {t}, followed by \key Space to show
\uicontrol {Request Copilot Suggestion} in the \l{Navigate with locator}
{locator}.
Hover the mouse over a suggestion to show a toolbar with
\inlineimage icons/prev.png

View File

@@ -5,6 +5,10 @@
\externalpage https://doc.qt.io/index.html
\title Qt Documentation
*/
/*!
\externalpage https://www.qt.io/terms-conditions/qt-dev-framework
\title Terms & Conditions - Qt Development Framework
*/
/*!
\externalpage https://www.lua.org/
\title Lua
@@ -277,3 +281,11 @@
\externalpage https://clang.llvm.org/docs/LibFormat.html
\title LibFormat: Documentation
*/
/*!
\externalpage https://git-scm.com/downloads
\title Git Downloads
*/
/*!
\externalpage https://www.gerritcodereview.com/
\title Gerrit Code Review
*/

View File

@@ -246,6 +246,34 @@
\generatelist creator-how-to-test
\section1 Use Git
\l{Git} is a fast decentralized version control system
that is available for Windows, Linux, and \macos. You can use the
\l {Gerrit Code Review} tool for projects that use Git.
\generatelist creator-how-to-git
\section2 Current file
\generatelist creator-how-to-git-current-file
\section2 Current project
\generatelist creator-how-to-git-current-project
\section2 Local repositories
\generatelist creator-how-to-git-local-repository
\section2 Commits
\generatelist creator-how-to-git-commits
\section2 Remote repositories
\generatelist creator-how-to-git-remote-repository
\section1 Use \QC
Use basic \QC features and preinstalled plugins. Install more plugins and

View File

@@ -95,6 +95,20 @@
\generatelist creator-how-to-get-help
\li Test
\generatelist creator-how-to-test
\li Use Git
\generatelist creator-how-to-git
\list
\li Current file
\generatelist creator-how-to-git-current-file
\li Current project
\generatelist creator-how-to-git-current-project
\li Local repositories
\generatelist creator-how-to-git-local-repository
\li Commits
\generatelist creator-how-to-git-commits
\li Remote repositories
\generatelist creator-how-to-git-remote-repository
\endlist
\li Use \QC
\generatelist creator-how-to-use
\li Use the UI

View File

@@ -86,6 +86,7 @@
\list
\li \l{Use \QC}
\li \l{Use the UI}
\li \l{Use Git}
\li \l{Design UIs}
\li \l{Create Models and Diagrams}
\li \l{Read Documentation}

View File

@@ -0,0 +1,30 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page creator-how-to-use-git-on-windows.html
\previouspage creator-how-tos.html
\ingroup creator-how-to-git
\title Use Git for Windows
If you configure Git for use with \c {git bash} only, and use SSH
authorization, Git looks for the SSH keys in the directory where the
\c HOME environment points to. The variable is always set by \c {git bash}.
However, the variable is typically not set in a Windows command prompt. When
you run Git from a Windows command prompt, it looks for the SSH keys in its
installation directory, and therefore, the authorization fails.
You can set the \c HOME environment variable from \QC. Go to \preferences >
\uicontrol {Version Control} > \uicontrol Git, and then select
\uicontrol {Set "HOME" environment variable}. \c HOME is
set to \c %HOMEDRIVE%%HOMEPATH% when the Git executable is run and
authorization works as it would with \c {git bash}.
\image qtcreator-preferences-vcs-git.webp {Git preferences}
\sa {Use Git}{How To: Use Git}, {Compare files},
{Set up version control systems}, {Version Control Systems}
*/

View File

@@ -6,6 +6,7 @@
\previouspage creator-how-tos.html
\ingroup creator-how-to-use
\ingroup creator-how-to-git
\title Set up version control systems
@@ -23,7 +24,7 @@
arise, you should be ready to use the system also from \QC.
For more information on using Git for Windows, see
\l {Using Git for Windows}.
\l {Use Git for Windows}.
\section1 General VCS preferences
@@ -82,5 +83,5 @@
To show file status, go to \preferences > \uicontrol {Version Control}
> \uicontrol General, and then select \uicontrol {Show VCS file status}.
\sa {Version Control Systems}
\sa {Use Git}{How To: Use Git}, {Version Control Systems}
*/

View File

@@ -20,16 +20,16 @@
Subversion is an open source version control system.
In addition to the standard version control system functions described in
\l {Use common VCS Functions}, you can select \uicontrol Tools >
\uicontrol Subversion > \uicontrol Describe to display commit log messages
for a revision.
\l {Use common VCS Functions}, you can go to \uicontrol Tools >
\uicontrol Subversion and select \uicontrol Describe to display commit log
messages for a revision.
You can use Git as a client for a Subversion server. For more information,
see \l{Using Git with Subversion}.
see \l{Use Git with Subversion}.
\section1 Subversion Preferences
To set Subversion preferences, select \preferences >
To set Subversion preferences, go to \preferences >
\uicontrol {Version Control} > \uicontrol Subversion:
\image qtcreator-preferences-vcs-subversion.webp {Subversion preferences}

View File

@@ -46,7 +46,7 @@
\li Enable the plugin to use it.
\row
\li \l{Git}
\li \l{http://git-scm.com/}
\li \l{https://git-scm.com/}
\li Git version 1.9.0, or later
Gerrit version 2.6, or later
@@ -71,7 +71,8 @@
\endtable
\sa {Create VCS repositories for new projects}, {Enable and disable plugins},
{Set up version control systems}, {Use common VCS functions}
{Use Git}{How To: Use Git}, {Set up version control systems},
{Use common VCS functions}
*/
/*!
@@ -80,23 +81,30 @@
\ingroup creator-how-to-projects-create
\ingroup creator-how-to-projects-configure
\ingroup creator-how-to-git
\title Create VCS repositories for new projects
\QC allows you to create repositories for version control systems that
support local repository creation, such as Git, Mercurial, or Bazaar.
When creating a new project by selecting \uicontrol File > \uicontrol{New File or
Project}, you can choose a version control system on the final wizard page.
You can create repositories for version control systems that
support local repository creation, such as Git, Mercurial, or Bazaar in
the following ways:
You can also select \uicontrol Tools and then select \uicontrol {Create Repository}
in the submenu for the version control system.
\list
\li To create a new project, go to \uicontrol File >
\uicontrol {New Project}, and select a version
control system on the last wizard page.
\li To place a project directory under version control, go to
\uicontrol Tools, and then select \uicontrol {Create Repository} in
the submenu for a version control system.
\li To import a project that is already under version control, go to
\uicontrol File > \uicontrol {New Project} >
\uicontrol {Project from Version Control} and select the version
control system that you use. Follow the instructions of the wizard
to import the project.
\endlist
To import a project that is under version control, choose \uicontrol File >
\uicontrol {New Project} > \uicontrol {Project from Version Control}
and select the version control system that you use. Follow the instructions
of the wizard to import the project.
\sa {Creating Projects}, {Use project wizards}, {Version Control Systems}
\sa {Use Git}{How To: Use Git}, {Use project wizards}, {Creating Projects},
{Git}, {Version Control Systems}
*/
/*!
@@ -104,6 +112,7 @@
\previouspage creator-how-tos.html
\ingroup creator-how-to-use
\ingroup creator-how-to-git
\title Use common VCS functions
@@ -136,15 +145,18 @@
All version control systems have menu options to \e{diff} the current
file or project: to compare it with the latest version stored in the
repository and to display the differences. In \QC, a diff is displayed in a
read-only editor. If the file is accessible, you can double-click on a
read-only editor.
\image qtcreator-git-diff-repository.webp {Git Diff Repository view}
\caption Git Diff Repository view
If the file is accessible, you can double-click on a
selected diff chunk and \QC opens an editor displaying the file, scrolled to
the line in question.
\image qtcreator-vcs-diff.png
With Git, Mercurial, and Subversion, the diff is displayed side-by-side in
a \l{Compare files}{diff editor} by default. To use the inline diff view
instead, select the \uicontrol {Switch to Text Diff Editor} (1) option from
instead, select the \uicontrol {Unified Diff Editor} option from
the toolbar. In the inline
diff view, you can use context menu commands to apply, revert, stage, and
unstage chunks or selected lines, as well as send chunks to a code pasting
@@ -160,7 +172,7 @@
To open annotation views, select \uicontrol {Annotate} or \uicontrol {Blame}.
They show the lines of the file and the identifier of the change the lines
originate from. Click the change identifier to see a detailed description of
originate from. Select the change identifier to see a detailed description of
the change.
To show the annotation of a previous version, right-click on the
@@ -204,5 +216,6 @@
You can select \uicontrol Delete to delete obsolete files from the repository.
\sa {Set up version control systems}, {Version Control Systems}
\sa {Use Git}{How To: Use Git}, {Set up version control systems},
{Version Control Systems}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -229,6 +229,8 @@
\list
\li \l{Finding the Qt runtime version}
\li \l{Using Git}
\generatelist studio-how-to-git-gs
\generatelist studio-how-to-git
\li \l{Use external tools}
\li \l{Accessing output, issue, and warning messages}
\li \l{\QDS on MCUs}

View File

@@ -582,18 +582,6 @@ void _ClosePseudoConsoleMembers(_In_ PseudoConsole* pPty)
// has yet to send before we hard kill it.
if (_HandleIsValid(pPty->hConPtyProcess))
{
// If the conhost is already dead, then that's fine. Presumably
// it's finished flushing it's output already.
DWORD dwExit = 0;
// If GetExitCodeProcess failed, it's likely conhost is already dead
// If so, skip waiting regardless of whatever error
// GetExitCodeProcess returned.
// We'll just go straight to killing conhost.
if (GetExitCodeProcess(pPty->hConPtyProcess, &dwExit) && dwExit == STILL_ACTIVE)
{
WaitForSingleObject(pPty->hConPtyProcess, INFINITE);
}
TerminateProcess(pPty->hConPtyProcess, 0);
CloseHandle(pPty->hConPtyProcess);
pPty->hConPtyProcess = nullptr;
@@ -754,7 +742,7 @@ public:
typedef HRESULT (*CreatePseudoConsolePtr)(
COORD size, // ConPty Dimensions
HANDLE hInput, // ConPty Input
HANDLE hOutput, // ConPty Output
HANDLE hOutput, // ConPty Output
DWORD dwFlags, // ConPty Flags
HPCON* phPC); // ConPty Reference
@@ -762,7 +750,7 @@ public:
typedef VOID (*ClosePseudoConsolePtr)(HPCON hPC);
static WindowsContext &instance()
static WindowsContext &instance()
{
static WindowsContext ctx;
return ctx;

View File

@@ -647,6 +647,11 @@ void TerminalSurface::sendFocus(bool hasFocus)
vterm_state_focus_out(vts);
}
bool TerminalSurface::isInAltScreen()
{
return d->m_altscreen;
}
void TerminalSurface::setWriteToPty(WriteToPty writeToPty)
{
d->m_writeToPty = writeToPty;

View File

@@ -105,6 +105,7 @@ public:
void mouseButton(Qt::MouseButton button, bool pressed, Qt::KeyboardModifiers modifiers);
void sendFocus(bool hasFocus);
bool isInAltScreen();
signals:
void invalidated(QRect grid);
void fullSizeChanged(QSize newSize);

View File

@@ -189,7 +189,8 @@ void TerminalView::setupSurface()
connect(d->m_surface.get(), &TerminalSurface::invalidated, this, [this](const QRect &rect) {
setSelection(std::nullopt);
updateViewportRect(gridToViewport(rect));
verticalScrollBar()->setValue(d->m_surface->fullSize().height());
if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
verticalScrollBar()->setValue(d->m_surface->fullSize().height());
});
connect(
d->m_surface.get(),
@@ -949,7 +950,33 @@ void TerminalView::keyPressEvent(QKeyEvent *event)
event->accept();
d->m_surface->sendKey(event);
if (d->m_surface->isInAltScreen()) {
d->m_surface->sendKey(event);
} else {
switch (event->key()) {
case Qt::Key_PageDown:
verticalScrollBar()->setValue(qBound(
0,
verticalScrollBar()->value() + d->m_surface->liveSize().height(),
verticalScrollBar()->maximum()));
break;
case Qt::Key_PageUp:
verticalScrollBar()->setValue(qBound(
0,
verticalScrollBar()->value() - d->m_surface->liveSize().height(),
verticalScrollBar()->maximum()));
break;
case Qt::Key_End:
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
break;
case Qt::Key_Home:
verticalScrollBar()->setValue(0);
break;
default:
d->m_surface->sendKey(event);
break;
}
}
}
void TerminalView::keyReleaseEvent(QKeyEvent *event)
@@ -977,9 +1004,10 @@ void TerminalView::applySizeChange()
if (d->m_surface->liveSize() == newLiveSize)
return;
resizePty(newLiveSize);
d->m_surface->resize(newLiveSize);
flushVTerm(true);
if (resizePty(newLiveSize)) {
d->m_surface->resize(newLiveSize);
flushVTerm(true);
}
}
void TerminalView::updateScrollBars()

View File

@@ -123,7 +123,12 @@ public:
return noHits;
}
virtual void resizePty(QSize newSize) { Q_UNUSED(newSize); }
virtual bool resizePty(QSize newSize)
{
Q_UNUSED(newSize);
return false;
}
virtual void setClipboard(const QString &text) { Q_UNUSED(text); }
virtual std::optional<Link> toLink(const QString &text)
{

View File

@@ -42,7 +42,7 @@ FileApiReader::FileApiReader()
QObject::connect(&m_watcher,
&FileSystemWatcher::directoryChanged,
this,
&FileApiReader::replyDirectoryHasChanged);
&FileApiReader::handleReplyDirectoryChange);
}
FileApiReader::~FileApiReader()
@@ -60,11 +60,12 @@ void FileApiReader::setParameters(const BuildDirParameters &p)
m_parameters = p;
qCDebug(cmakeFileApiMode) << "Work directory:" << m_parameters.buildDirectory.toUserOutput();
// Reset watcher:
m_watcher.clear();
FileApiParser::setupCMakeFileApi(m_parameters.buildDirectory);
const FilePath replyDirectory = FileApiParser::cmakeReplyDirectory(m_parameters.buildDirectory);
if (!m_watcher.watchesDirectory(replyDirectory))
m_watcher.addDirectory(replyDirectory.path(), FileSystemWatcher::WatchAllChanges);
resetData();
}
@@ -385,8 +386,7 @@ void FileApiReader::startCMakeState(const QStringList &configurationArguments)
qCDebug(cmakeFileApiMode) << ">>>>>> Running cmake with arguments:" << configurationArguments;
// Reset watcher:
m_watcher.removeFiles(m_watcher.filePaths());
m_watcher.removeDirectories(m_watcher.directoryPaths());
m_watcher.clear();
makeBackupConfiguration(true);
writeConfigurationIntoBuildDirectory(configurationArguments);
@@ -412,7 +412,7 @@ void FileApiReader::cmakeFinishedState(int exitCode)
m_lastCMakeExitCode != 0);
}
void FileApiReader::replyDirectoryHasChanged(const QString &directory) const
void FileApiReader::handleReplyDirectoryChange(const QString &directory)
{
if (m_isParsing)
return; // This has been triggered by ourselves, ignore.
@@ -424,8 +424,10 @@ void FileApiReader::replyDirectoryHasChanged(const QString &directory) const
QTC_CHECK(dir.isLocal());
QTC_ASSERT(dir.path() == directory, return);
if (m_lastReplyTimestamp.isValid() && reply.lastModified() > m_lastReplyTimestamp)
if (m_lastReplyTimestamp.isValid() && reply.lastModified() > m_lastReplyTimestamp) {
m_lastReplyTimestamp = reply.lastModified();
emit dirty();
}
}
} // CMakeProjectManager::Internal

View File

@@ -78,7 +78,7 @@ private:
void startCMakeState(const QStringList &configurationArguments);
void cmakeFinishedState(int exitCode);
void replyDirectoryHasChanged(const QString &directory) const;
void handleReplyDirectoryChange(const QString &directory);
void makeBackupConfiguration(bool store);
void writeConfigurationIntoBuildDirectory(const QStringList &configuration);

View File

@@ -48,6 +48,7 @@
#include <utils/theme/theme_p.h>
#include <QAuthenticator>
#include <QCheckBox>
#include <QDateTime>
#include <QDebug>
#include <QDialogButtonBox>
@@ -168,17 +169,27 @@ static void initTAndCAcceptDialog()
dialog.setWindowTitle(Tr::tr("Terms and Conditions"));
QDialogButtonBox buttonBox;
QCheckBox *acceptCheckBox;
QPushButton *acceptButton
= buttonBox.addButton(Tr::tr("Accept"), QDialogButtonBox::ButtonRole::YesRole);
QPushButton *decline
= buttonBox.addButton(Tr::tr("Decline"), QDialogButtonBox::ButtonRole::NoRole);
acceptButton->setAutoDefault(false);
acceptButton->setDefault(false);
acceptButton->setEnabled(false);
decline->setAutoDefault(true);
decline->setDefault(true);
QObject::connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
QObject::connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
const QLatin1String legal = QLatin1String(
"I confirm that I have reviewed and accept the terms and conditions\n"
"of this extension. I confirm that I have the authority and ability to\n"
"accept the terms and conditions of this extension for the customer.\n"
"I acknowledge that if the customer and the Qt Company already have a\n"
"valid agreement in place, that agreement shall apply, but these terms\n"
"shall govern the use of this extension.");
// clang-format off
Column {
Tr::tr("The plugin %1 requires you to accept the following terms and conditions:").arg(spec->name()), br,
@@ -187,11 +198,14 @@ static void initTAndCAcceptDialog()
readOnly(true),
}, br,
Row {
Tr::tr("Do you wish to accept?"), &buttonBox,
acceptCheckBox = new QCheckBox(legal), &buttonBox,
}
}.attachTo(&dialog);
// clang-format on
QObject::connect(
acceptCheckBox, &QCheckBox::toggled, acceptButton, &QPushButton::setEnabled);
return dialog.exec() == QDialog::Accepted;
});
}

View File

@@ -419,6 +419,14 @@ public:
{
setTitle(Tr::tr("Accept Terms and Conditions"));
const QLatin1String legal = QLatin1String(
"I confirm that I have reviewed and accept the terms and conditions "
"of this extension. I confirm that I have the authority and ability to "
"accept the terms and conditions of this extension for the customer. "
"I acknowledge that if the customer and the Qt Company already have a "
"valid agreement in place, that agreement shall apply, but these terms "
"shall govern the use of this extension.");
using namespace Layouting;
// clang-format off
Column {
@@ -427,7 +435,7 @@ public:
bindTo(&m_terms),
readOnly(true),
}, br,
m_accept = new QCheckBox(Tr::tr("I accept the terms and conditions.")),
m_accept = new QCheckBox(legal)
}.attachTo(this);
// clang-format on

View File

@@ -201,6 +201,20 @@ void setupProjectModule()
QTC_CHECK_EXPECTED(res);
});
});
// buildStateChanged
registerHook("projects.buildStateChanged", [](sol::main_function func, QObject *guard) {
QObject::connect(
BuildManager::instance(),
&BuildManager::buildStateChanged,
guard,
[func](ProjectExplorer::Project *pro) {
const bool isBuilding = BuildManager::isBuilding(pro);
expected_str<void> res = void_safe_call(func, pro, isBuilding);
QTC_CHECK_EXPECTED(res);
}
);
});
}
} // namespace Lua::Internal

View File

@@ -240,9 +240,21 @@ void setupTextEditorModule()
"to",
sol::property(&Range::end, &Range::end));
result.new_usertype<QTextCursor>(
auto textCursorType = result.new_usertype<QTextCursor>(
"TextCursor",
sol::no_constructor,
"create",
sol::overload(
[]() {
return QTextCursor();
},
[](QTextDocument *doc) {
return QTextCursor(doc);
},
[](const QTextCursor &other) {
return QTextCursor(other);
}
),
"position",
&QTextCursor::position,
"blockNumber",
@@ -279,7 +291,55 @@ void setupTextEditorModule()
return ret;
},
"insertText",
[](QTextCursor *textCursor, const QString &text) { textCursor->insertText(text); });
[](QTextCursor *textCursor, const QString &text) { textCursor->insertText(text); },
"movePosition",
sol::overload(
[](QTextCursor *cursor, QTextCursor::MoveOperation op) {
cursor->movePosition(op);
},
[](QTextCursor *cursor, QTextCursor::MoveOperation op, QTextCursor::MoveMode mode) {
cursor->movePosition(op, mode);
},
[](QTextCursor *cursor, QTextCursor::MoveOperation op, QTextCursor::MoveMode mode, int n) {
cursor->movePosition(op, mode, n);
}
));
textCursorType["MoveMode"] = lua.create_table_with(
"MoveAnchor", QTextCursor::MoveAnchor,
"KeepAnchor", QTextCursor::KeepAnchor
);
textCursorType["MoveOperation"] = lua.create_table_with(
"NoMove", QTextCursor::NoMove,
"Start", QTextCursor::Start,
"Up", QTextCursor::Up,
"StartOfLine", QTextCursor::StartOfLine,
"StartOfBlock", QTextCursor::StartOfBlock,
"StartOfWord", QTextCursor::StartOfWord,
"PreviousBlock", QTextCursor::PreviousBlock,
"PreviousCharacter",QTextCursor::PreviousCharacter,
"PreviousWord", QTextCursor::PreviousWord,
"Left", QTextCursor::Left,
"WordLeft", QTextCursor::WordLeft,
"End", QTextCursor::End,
"Down", QTextCursor::Down,
"EndOfLine", QTextCursor::EndOfLine,
"EndOfWord", QTextCursor::EndOfWord,
"EndOfBlock", QTextCursor::EndOfBlock,
"NextBlock", QTextCursor::NextBlock,
"NextCharacter", QTextCursor::NextCharacter,
"NextWord", QTextCursor::NextWord,
"Right", QTextCursor::Right,
"WordRight", QTextCursor::WordRight,
"NextCell", QTextCursor::NextCell,
"PreviousCell", QTextCursor::PreviousCell,
"NextRow", QTextCursor::NextRow,
"PreviousRow", QTextCursor::PreviousRow
);
using LayoutOrWidget = std::variant<Layouting::Layout *, Layouting::Widget *, QWidget *>;

View File

@@ -30,6 +30,32 @@ Utils::expected_str<void> connectHooks(
static Q_LOGGING_CATEGORY(logLuaEngine, "qtc.lua.engine", QtWarningMsg);
QString luaToString(lua_State *state, int index)
{
size_t l;
const char *s = luaL_tolstring(state, index, &l);
if (s == nullptr)
return {};
// Remove from stack what tolstring pushed onto it.
sol::stack::pop_n(state, 1);
return QString::fromUtf8(s, l);
}
template<typename T>
QString refToString(const T &ref)
{
if (ref.template is<QString>())
return ref.template as<QString>();
if (ref.template is<sol::table>())
return toJsonString(ref.template as<sol::table>());
auto pp = sol::stack::push_pop(ref);
return luaToString(ref.lua_state(), -1);
}
class LuaInterfaceImpl final : public QObject, public LuaInterface
{
public:
@@ -205,18 +231,38 @@ expected_str<void> connectHooks(
qCDebug(logLuaEngine) << "connectHooks called with path: " << path;
for (const auto &[k, v] : table) {
qCDebug(logLuaEngine) << "Processing key: " << k.as<QString>();
if (v.get_type() == sol::type::table) {
return connectHooks(
lua, v.as<sol::table>(), QStringList{path, k.as<QString>()}.join("."), guard);
} else if (v.get_type() == sol::type::function) {
QString hookName = QStringList{path, k.as<QString>()}.join(".");
qCDebug(logLuaEngine) << "Connecting function to hook: " << hookName;
auto it = d->m_hooks.find(hookName);
if (it == d->m_hooks.end())
return make_unexpected(Tr::tr("No hook with the name \"%1\" found.").arg(hookName));
else
it.value()(v.as<sol::function>(), guard);
if (k.get_type() != sol::type::string)
return make_unexpected(
Tr::tr("Non-string key encountered in Lua table at path \"%1\"").arg(path));
const auto keyName = k.as<QString>();
const auto currentPath = QStringList{path, keyName}.join(".");
qCDebug(logLuaEngine) << "Processing path:" << currentPath;
switch (v.get_type()) {
case sol::type::table: {
auto result = connectHooks(lua, v.as<sol::table>(), currentPath, guard);
if (!result)
return result;
break;
}
case sol::type::function: {
qCDebug(logLuaEngine) << "Connecting function to hook:" << currentPath;
auto it = d->m_hooks.find(currentPath);
if (it == d->m_hooks.end()) {
return make_unexpected(
Tr::tr("No hook with the name \"%1\" found.").arg(currentPath));
}
it.value()(v.as<sol::function>(), guard);
break;
}
default: {
return make_unexpected(Tr::tr("Unsupported value type \"%1\" at path \"%2\".")
.arg(static_cast<int>(v.get_type()))
.arg(currentPath));
}
}
}
@@ -316,8 +362,8 @@ expected_str<sol::protected_function> prepareSetup(
if (logLuaEngine().isDebugEnabled()) {
qCDebug(logLuaEngine) << "Script returned table with keys:";
for (const auto &[key, value] : *pluginTable) {
qCDebug(logLuaEngine) << "Key:" << key.as<QString>();
qCDebug(logLuaEngine) << "Value:" << value.as<QString>();
qCDebug(logLuaEngine) << "Key:" << refToString(key);
qCDebug(logLuaEngine) << "Value:" << refToString(value);
}
}

View File

@@ -59,6 +59,7 @@ EditorHooks = {}
---@field projectRemoved? function function(project: Project)
---@field aboutToRemoveProject? function function(project: Project)
---@field runActionsUpdated? function function() Called when Project.canRunStartupProject() might have changed.
---@field buildStateChanged? function function(project: Project, isBuilding: boolean)
---@class Hooks
---@field editors? EditorHooks

View File

@@ -18,6 +18,63 @@ local Range = {}
---@class TextCursor
local TextCursor = {}
---@enum TextCursor.MoveOperation
---Move operations for a TextCursor.
TextCursor.MoveOperation = {
NoMove = 0,
Start = 0,
Up = 0,
StartOfLine = 0,
StartOfBlock = 0,
StartOfWord = 0,
PreviousBlock = 0,
PreviousCharacter = 0,
PreviousWord = 0,
Left = 0,
WordLeft = 0,
End = 0,
Down = 0,
EndOfLine = 0,
EndOfWord = 0,
EndOfBlock = 0,
NextBlock = 0,
NextCharacter = 0,
NextWord = 0,
Right = 0,
WordRight = 0,
NextCell = 0,
PreviousCell = 0,
NextRow = 0,
PreviousRow = 0
}
---@enum TextCursor.MoveMode
---Specifies how the cursor moves (with or without anchoring the selection).
TextCursor.MoveMode = {
MoveAnchor = 0,
KeepAnchor = 0
}
---Creates a new `TextCursor` object.
---
---**Overload 1**: `TextCursor.create()`
--- No parameters. Creates a default-constructed cursor.
---
---**Overload 2**: `TextCursor.create(doc)`
--- - `doc`: A `QTextDocument*` (or usertype) from which to create the cursor.
---
---**Overload 3**: `TextCursor.create(other)`
--- - `other`: Another `TextCursor` to copy.
---
---@overload fun(): TextCursor
---@overload fun(doc: any): TextCursor
---@overload fun(other: TextCursor): TextCursor
---@return TextCursor
function TextCursor.create(...) end
---Returns the position of the cursor.
---@return integer position The position of the cursor.
function TextCursor:position() end
@@ -46,6 +103,27 @@ function TextCursor:selectionRange() end
---@param text string The text to insert.
function TextCursor:insertText(text) end
---Moves the cursor using a specified operation, and optionally a mode and/or repetition count.
---
---**Overload 1**: `cursor:movePosition(operation)`
--- - `operation`: A `TextCursor.MoveOperation`.
--- - Moves once, using the default mode `MoveAnchor`.
---
---**Overload 2**: `cursor:movePosition(operation, mode)`
--- - `operation`: A `TextCursor.MoveOperation`.
--- - `mode`: A `TextCursor.MoveMode` (e.g. `MoveAnchor` or `KeepAnchor`).
---
---**Overload 3**: `cursor:movePosition(operation, mode, n)`
--- - `operation`: A `TextCursor.MoveOperation`.
--- - `mode`: A `TextCursor.MoveMode`.
--- - `n`: Number of times to repeat the move.
---
---@overload fun(operation: TextCursor.MoveOperation)
---@overload fun(operation: TextCursor.MoveOperation, mode: TextCursor.MoveMode)
---@overload fun(operation: TextCursor.MoveOperation, mode: TextCursor.MoveMode, n: integer)
function TextCursor:movePosition(operation, mode, n) end
---@class MultiTextCursor
local MultiTextCursor = {}

View File

@@ -279,7 +279,9 @@ void JsonSummaryPage::updateProjectData(FolderNode *node)
m_wizard->setValue(QLatin1String(KEY_SELECTED_PROJECT), QVariant::fromValue(project));
m_wizard->setValue(QLatin1String(KEY_SELECTED_NODE), QVariant::fromValue(node));
m_wizard->setValue(QLatin1String(Constants::PROJECT_ISSUBPROJECT), node ? true : false);
m_wizard->setValue(Constants::PROJECT_ISSUBPROJECT, node ? true : false);
m_wizard->setValue(Constants::PREFERRED_PROJECT_NODE, QVariant::fromValue(node));
m_wizard->setValue(Constants::PREFERRED_PROJECT_NODE_PATH, node ? node->filePath().toString() : QString());
bool qtKeyWordsEnabled = true;
if (ProjectTree::hasNode(node)) {
const ProjectNode *projectNode = node->asProjectNode();

View File

@@ -1559,7 +1559,8 @@ void ProcessRunnerPrivate::start()
m_stopRequested = false;
QVariantHash extraData = q->runControl()->extraData();
extraData[TERMINAL_SHELL_NAME] = m_command.executable().fileName();
extraData[TERMINAL_SHELL_NAME]
= q->runControl()->target()->activeRunConfiguration()->displayName();
m_process.setCommand(cmdLine);
m_process.setEnvironment(env);

View File

@@ -35,7 +35,12 @@ public:
return m_fallbackStubCreator->startStubProcess(setup);
}
const Id id = Id::fromString(setup.m_commandLine.executable().toUserOutput());
const QString shellName
= setup.m_extraData
.value(TERMINAL_SHELL_NAME, setup.m_commandLine.executable().fileName())
.toString();
const Id id = Id::fromString(shellName);
TerminalWidget *terminal = m_terminalPane->stoppedTerminalWithId(id);
@@ -45,14 +50,10 @@ public:
if (!terminal) {
terminal = new TerminalWidget(nullptr, openParameters);
terminal->setShellName(
setup.m_extraData
.value(TERMINAL_SHELL_NAME, setup.m_commandLine.executable().fileName())
.toString());
terminal->setShellName(shellName);
m_terminalPane->addTerminal(terminal, "App");
} else {
terminal->setShellName(shellName);
terminal->restart(openParameters);
}

View File

@@ -42,7 +42,6 @@
#include <QPixmapCache>
#include <QRawFont>
#include <QRegularExpression>
#include <QScrollBar>
#include <QTextItem>
#include <QTextLayout>
#include <QToolTip>
@@ -346,10 +345,13 @@ qint64 TerminalWidget::writeToPty(const QByteArray &data)
return data.size();
}
void TerminalWidget::resizePty(QSize newSize)
bool TerminalWidget::resizePty(QSize newSize)
{
if (m_process && m_process->ptyData() && m_process->isRunning())
m_process->ptyData()->resize(newSize);
if (!m_process || !m_process->ptyData() || !m_process->isRunning())
return false;
m_process->ptyData()->resize(newSize);
return true;
}
void TerminalWidget::surfaceChanged()

View File

@@ -77,7 +77,7 @@ protected:
void contextMenuRequested(const QPoint &pos) override;
qint64 writeToPty(const QByteArray &data) override;
void resizePty(QSize newSize) override;
bool resizePty(QSize newSize) override;
void setClipboard(const QString &text) override;
std::optional<TerminalView::Link> toLink(const QString &text) override;