Merge remote-tracking branch 'origin/14.0'

Change-Id: Id00d72a8707d122b72d89ed0ecf03ad5ed8230d2
This commit is contained in:
Eike Ziller
2024-07-11 12:10:59 +02:00
44 changed files with 386 additions and 339 deletions

View File

@@ -1,3 +1,3 @@
// Copyright (C) 2023 The Qt Company Ltd. // Copyright (C) %{CurrentDate:yyyy} The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

View File

@@ -15,6 +15,8 @@
<div class="indexboxcont indexboxbar"> <div class="indexboxcont indexboxbar">
<ul> <ul>
<li><a href="creator-overview.html">Overview</a></li> <li><a href="creator-overview.html">Overview</a></li>
<li><a href="creator-quick-tour.html">User Interface</a></li>
<li><a href="creator-configuring.html">Configuring Qt Creator</a></li>
<li><a href="creator-project-creating.html">Creating Projects</a></li> <li><a href="creator-project-creating.html">Creating Projects</a></li>
<li><a href="creator-configuring-projects.html">Configuring Projects</a></li> <li><a href="creator-configuring-projects.html">Configuring Projects</a></li>
<li><a href="creator-debugging.html">Debugging</a></li> <li><a href="creator-debugging.html">Debugging</a></li>

View File

@@ -9,7 +9,7 @@
/*! /*!
\page creator-how-to-use-heob.html \page creator-how-to-use-heob.html
\previouspage creator-clang-tools.html \previouspage creator-how-tos.html
\ingroup creator-how-to-analyze \ingroup creator-how-to-analyze

View File

@@ -19,20 +19,6 @@
\annotatedlist creator-reference-analyzer \annotatedlist creator-reference-analyzer
\section1 Debuggers
Set up and use debuggers to debug executable binary files, as well as
QML, Java, and Python source code.
\annotatedlist creator-reference-debugger
\section2 Debugger Views
Inspect the state of your application while debugging in the
\uicontrol Debug mode.
\annotatedlist creator-reference-debugger-views
\section1 Build Systems \section1 Build Systems
When you create projects, you can choose the build system to use for When you create projects, you can choose the build system to use for
@@ -50,6 +36,20 @@
\annotatedlist creator-reference-build-configurations \annotatedlist creator-reference-build-configurations
\section1 Debuggers
Set up and use debuggers to debug executable binary files, as well as
QML, Java, and Python source code.
\annotatedlist creator-reference-debugger
\section2 Debugger Views
Inspect the state of your application while debugging in the
\uicontrol Debug mode.
\annotatedlist creator-reference-debugger-views
\section1 Devices \section1 Devices
Connect devices to the computer to run, debug, and analyze applications Connect devices to the computer to run, debug, and analyze applications
@@ -114,6 +114,8 @@
\section2 Debugger \section2 Debugger
Preferences for debugging.
\annotatedlist creator-reference-preferences-debugger \annotatedlist creator-reference-preferences-debugger
\section2 Kits \section2 Kits

View File

@@ -46,6 +46,6 @@ QtcProduct {
Export { Export {
Depends { name: "cpp" } Depends { name: "cpp" }
Depends { name: "ExtensionSystem" } Depends { name: "ExtensionSystem" }
cpp.includePaths: ".." cpp.includePaths: exportingProduct.sourceDirectory + "/.."
} }
} }

View File

@@ -24,6 +24,7 @@
"qbs.Probes", "qbs.Probes",
"qbs.Process", "qbs.Process",
"qbs.PropertyList", "qbs.PropertyList",
"qbs.ProviderUtils",
"qbs.TemporaryDir", "qbs.TemporaryDir",
"qbs.TextFile", "qbs.TextFile",
"qbs.UnixUtils", "qbs.UnixUtils",

View File

@@ -19,7 +19,6 @@ Module {
exports: [ "qbs/Depends 1.0" ] exports: [ "qbs/Depends 1.0" ]
prototype: "QQuickItem" prototype: "QQuickItem"
Property { name: "condition"; type: "bool" } Property { name: "condition"; type: "bool" }
Property { name: "enableFallback"; type: "bool" }
Property { name: "limitToSubProject"; type: "bool" } Property { name: "limitToSubProject"; type: "bool" }
Property { name: "multiplexConfigurationIds"; type: "string"; isList: true } Property { name: "multiplexConfigurationIds"; type: "string"; isList: true }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
@@ -93,6 +92,8 @@ Module {
name: "ModuleProvider" name: "ModuleProvider"
exports: [ "qbs/ModuleProvider 1.0" ] exports: [ "qbs/ModuleProvider 1.0" ]
prototype: "QQuickItem" prototype: "QQuickItem"
Property { name: "isEager"; type: "bool" }
Property { name: "moduleName"; type: "string" }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "outputBaseDir"; type: "string" } Property { name: "outputBaseDir"; type: "string" }
Property { name: "relativeSearchPaths"; type: "string"; isList: true } Property { name: "relativeSearchPaths"; type: "string"; isList: true }

View File

@@ -22,5 +22,16 @@ int main(int argc, char *argv[])
} }
@endif @endif
// Set up code that uses the Qt event loop here.
// Call a.quit() or a.exit() to quit the application.
// A not very useful example would be including
// #include <QTimer>
// near the top of the file and calling
// QTimer::singleShot(5000, &a, &QCoreApplication::quit);
// which quits the application after 5 seconds.
// If you do not need a running Qt event loop, remove the call
// to a.exec() or use the Non-Qt Plain C++ Application template.
return a.exec(); return a.exec();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,6 @@ QtcLibrary {
Export { Export {
Depends { name: "cpp" } Depends { name: "cpp" }
cpp.includePaths: "include" cpp.includePaths: exportingProduct.sourceDirectory + "/include"
} }
} }

View File

@@ -396,8 +396,8 @@ QtcLibrary {
Export { Export {
cpp.includePaths: [ cpp.includePaths: [
".", exportingProduct.sourceDirectory,
"./qtserialization/inc" exportingProduct.sourceDirectory + "/qtserialization/inc"
] ]
} }
} }

View File

@@ -14,7 +14,7 @@ QtcLibrary {
Export { Export {
Depends { name: "cpp" } Depends { name: "cpp" }
cpp.includePaths: ".." cpp.includePaths: exportingProduct.sourceDirectory + "/.."
} }
} }

View File

@@ -26,7 +26,10 @@ QtcLibrary {
Export { Export {
Depends { name: "cpp" } Depends { name: "cpp" }
cpp.includePaths: ["..", "../.."] cpp.includePaths: [
exportingProduct.sourceDirectory + "/..",
exportingProduct.sourceDirectory + "/../.."
]
} }
} }

View File

@@ -53,7 +53,7 @@ inline Utils::expected_str<OsType> osTypeFromString(const QString &string)
inline Utils::expected_str<OsArch> osArchFromString(const QString &architecture) inline Utils::expected_str<OsArch> osArchFromString(const QString &architecture)
{ {
if (architecture == QLatin1String("x86_64")) if (architecture == QLatin1String("x86_64") || architecture == QLatin1String("amd64"))
return OsArchAMD64; return OsArchAMD64;
if (architecture == QLatin1String("x86")) if (architecture == QLatin1String("x86"))
return OsArchX86; return OsArchX86;

View File

@@ -474,6 +474,6 @@ QtcLibrary {
Export { Export {
Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] } Depends { name: "Qt"; submodules: ["concurrent", "widgets" ] }
Depends { name: "Tasking" } Depends { name: "Tasking" }
cpp.includePaths: "mimetypes2" cpp.includePaths: exportingProduct.sourceDirectory + "/mimetypes2"
} }
} }

View File

@@ -37,7 +37,7 @@ static void updateCMakePathsFromQMake(QStringList &initialCMakeArguments)
return; return;
// ~Qt/6.x/platform/bin/qmake -> ~Qt/6.x/platform // ~Qt/6.x/platform/bin/qmake -> ~Qt/6.x/platform
const QByteArray qmakePrefixPath = qmakeFilePath.parentDir().parentDir().toString().toUtf8(); const QByteArray qmakePrefixPath = qmakeFilePath.parentDir().parentDir().path().toUtf8();
const QByteArrayList cmakePathsVariables = {"CMAKE_PREFIX_PATH", "CMAKE_FIND_ROOT_PATH"}; const QByteArrayList cmakePathsVariables = {"CMAKE_PREFIX_PATH", "CMAKE_FIND_ROOT_PATH"};
for (const QByteArray &var : cmakePathsVariables) { for (const QByteArray &var : cmakePathsVariables) {

View File

@@ -399,12 +399,10 @@ static SnippetAndLocation generateSnippetAndLocationForSources(
static expected_str<bool> insertSnippetSilently(const FilePath &cmakeFile, static expected_str<bool> insertSnippetSilently(const FilePath &cmakeFile,
const SnippetAndLocation &snippetLocation) const SnippetAndLocation &snippetLocation)
{ {
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>( BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::openEditorAt(
Core::EditorManager::openEditorAt({cmakeFile, {cmakeFile, int(snippetLocation.line), int(snippetLocation.column)},
int(snippetLocation.line),
int(snippetLocation.column)},
Constants::CMAKE_EDITOR_ID, Constants::CMAKE_EDITOR_ID,
Core::EditorManager::DoNotMakeVisible)); Core::EditorManager::DoNotMakeVisible | Core::EditorManager::DoNotChangeCurrentEditor));
if (!editor) { if (!editor) {
return make_unexpected("BaseTextEditor cannot be obtained for " + cmakeFile.toUserOutput() return make_unexpected("BaseTextEditor cannot be obtained for " + cmakeFile.toUserOutput()
+ ":" + QString::number(snippetLocation.line) + ":" + ":" + QString::number(snippetLocation.line) + ":"
@@ -864,12 +862,13 @@ RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
} }
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>( BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(
Core::EditorManager::openEditorAt({filePos.value().cmakeFile, Core::EditorManager::openEditorAt(
{filePos.value().cmakeFile,
static_cast<int>(filePos.value().argumentPosition.Line), static_cast<int>(filePos.value().argumentPosition.Line),
static_cast<int>(filePos.value().argumentPosition.Column static_cast<int>(filePos.value().argumentPosition.Column - 1)},
- 1)},
Constants::CMAKE_EDITOR_ID, Constants::CMAKE_EDITOR_ID,
Core::EditorManager::DoNotMakeVisible)); Core::EditorManager::DoNotMakeVisible
| Core::EditorManager::DoNotChangeCurrentEditor));
if (!editor) { if (!editor) {
badFiles << file; badFiles << file;
@@ -976,7 +975,8 @@ bool CMakeBuildSystem::renameFile(Node *context,
static_cast<int>(fileToRename->argumentPosition.Line), static_cast<int>(fileToRename->argumentPosition.Line),
static_cast<int>(fileToRename->argumentPosition.Column - 1)}, static_cast<int>(fileToRename->argumentPosition.Column - 1)},
Constants::CMAKE_EDITOR_ID, Constants::CMAKE_EDITOR_ID,
Core::EditorManager::DoNotMakeVisible)); Core::EditorManager::DoNotMakeVisible
| Core::EditorManager::DoNotChangeCurrentEditor));
if (!editor) { if (!editor) {
qCCritical(cmakeBuildSystemLog).noquote() qCCritical(cmakeBuildSystemLog).noquote()
<< "BaseTextEditor cannot be obtained for" << fileToRename->cmakeFile.path() << "BaseTextEditor cannot be obtained for" << fileToRename->cmakeFile.path()

View File

@@ -16,6 +16,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/icon.h> #include <utils/icon.h>
#include <utils/fsengine/fileiconprovider.h>
#include <utils/mimeconstants.h> #include <utils/mimeconstants.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
@@ -627,7 +628,7 @@ static FolderNode *createSourceGroupNode(const QString &sourceGroupName,
if (!existingNode) { if (!existingNode) {
auto node = createCMakeVFolder(sourceDirectory, Node::DefaultFolderPriority + 5, p); auto node = createCMakeVFolder(sourceDirectory, Node::DefaultFolderPriority + 5, p);
node->setListInProject(false); node->setListInProject(false);
node->setIcon([] { return Icon::fromTheme("edit-copy"); }); node->setIcon([] { return FileIconProvider::icon(QFileIconProvider::Folder); });
existingNode = node.get(); existingNode = node.get();

View File

@@ -20,11 +20,14 @@
#include <QFocusEvent> #include <QFocusEvent>
#include <QHeaderView> #include <QHeaderView>
#include <QVBoxLayout> #include <QLoggingCategory>
#include <QScrollBar> #include <QScrollBar>
#include <QVBoxLayout>
using namespace Utils; using namespace Utils;
Q_LOGGING_CATEGORY(openEditorsLog, "qtc.core.openeditorswindow", QtWarningMsg);
namespace Core::Internal { namespace Core::Internal {
class OpenEditorsItem : public TreeItem class OpenEditorsItem : public TreeItem
@@ -196,6 +199,7 @@ bool OpenEditorsWindow::eventFilter(QObject *obj, QEvent *e)
} else if (e->type() == QEvent::KeyRelease) { } else if (e->type() == QEvent::KeyRelease) {
auto ke = static_cast<QKeyEvent*>(e); auto ke = static_cast<QKeyEvent*>(e);
qCDebug(openEditorsLog()) << ke;
if (ke->modifiers() == 0 if (ke->modifiers() == 0
/*HACK this is to overcome some event inconsistencies between platforms*/ /*HACK this is to overcome some event inconsistencies between platforms*/
|| (ke->modifiers() == Qt::AltModifier || (ke->modifiers() == Qt::AltModifier

View File

@@ -193,9 +193,13 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
menu.exec(d->m_editorList->mapToGlobal(p)); menu.exec(d->m_editorList->mapToGlobal(p));
}); });
connect(d->m_dragHandleMenu, &QMenu::aboutToShow, this, [this] { connect(d->m_dragHandleMenu, &QMenu::aboutToShow, this, [this] {
d->m_dragHandleMenu->clear();
fillListContextMenu(d->m_dragHandleMenu); fillListContextMenu(d->m_dragHandleMenu);
}); });
connect(d->m_dragHandleMenu, &QMenu::aboutToHide, this, [this] {
// Remove actions from context menu, to avoid any shortcuts set on them
// for the display in the menu interfering with global actions
d->m_dragHandleMenu->clear();
});
connect(d->m_lockButton, &QAbstractButton::clicked, this, &EditorToolBar::makeEditorWritable); connect(d->m_lockButton, &QAbstractButton::clicked, this, &EditorToolBar::makeEditorWritable);
connect(d->m_closeEditorButton, &QAbstractButton::clicked, connect(d->m_closeEditorButton, &QAbstractButton::clicked,
this, &EditorToolBar::closeEditor, Qt::QueuedConnection); this, &EditorToolBar::closeEditor, Qt::QueuedConnection);

View File

@@ -160,15 +160,6 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
setProperty(StyleHelper::C_TOP_BORDER, true); setProperty(StyleHelper::C_TOP_BORDER, true);
setSingleRow(false); setSingleRow(false);
QWidget::setTabOrder(m_findEdit, m_replaceEdit);
QWidget::setTabOrder(m_replaceEdit, m_findPreviousButton);
QWidget::setTabOrder(m_findPreviousButton, m_findNextButton);
QWidget::setTabOrder(m_findNextButton, m_replaceButton);
QWidget::setTabOrder(m_replaceButton, m_replaceNextButton);
QWidget::setTabOrder(m_replaceNextButton, m_replaceAllButton);
QWidget::setTabOrder(m_replaceAllButton, m_advancedButton);
QWidget::setTabOrder(m_advancedButton, m_close);
connect(m_findEdit, &Utils::FancyLineEdit::editingFinished, connect(m_findEdit, &Utils::FancyLineEdit::editingFinished,
this, &FindToolBar::invokeResetIncrementalSearch); this, &FindToolBar::invokeResetIncrementalSearch);
connect(m_findEdit, &Utils::FancyLineEdit::textChanged, connect(m_findEdit, &Utils::FancyLineEdit::textChanged,
@@ -447,6 +438,17 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
connect(&m_findStepTimer, &QTimer::timeout, this, &FindToolBar::invokeFindStep); connect(&m_findStepTimer, &QTimer::timeout, this, &FindToolBar::invokeFindStep);
setLightColoredIcon(isLightColored()); setLightColoredIcon(isLightColored());
QWidget::setTabOrder(m_findEdit->button(FancyLineEdit::Left), m_findEdit);
QWidget::setTabOrder(m_findEdit, m_replaceEdit);
QWidget::setTabOrder(m_replaceEdit, m_findPreviousButton);
QWidget::setTabOrder(m_findPreviousButton, m_findNextButton);
QWidget::setTabOrder(m_findNextButton, m_selectAllButton);
QWidget::setTabOrder(m_selectAllButton, m_replaceButton);
QWidget::setTabOrder(m_replaceButton, m_replaceNextButton);
QWidget::setTabOrder(m_replaceNextButton, m_replaceAllButton);
QWidget::setTabOrder(m_replaceAllButton, m_advancedButton);
QWidget::setTabOrder(m_advancedButton, m_close);
} }
FindToolBar::~FindToolBar() = default; FindToolBar::~FindToolBar() = default;
@@ -1024,23 +1026,6 @@ void FindToolBar::selectAll()
} }
} }
bool FindToolBar::focusNextPrevChild(bool next)
{
QAbstractButton *optionsButton = m_findEdit->button(Utils::FancyLineEdit::Left);
// close tab order
if (next && m_advancedButton->hasFocus())
optionsButton->setFocus(Qt::TabFocusReason);
else if (next && optionsButton->hasFocus())
m_findEdit->setFocus(Qt::TabFocusReason);
else if (!next && optionsButton->hasFocus())
m_advancedButton->setFocus(Qt::TabFocusReason);
else if (!next && m_findEdit->hasFocus())
optionsButton->setFocus(Qt::TabFocusReason);
else
return Utils::StyledBar::focusNextPrevChild(next);
return true;
}
void FindToolBar::resizeEvent(QResizeEvent *event) void FindToolBar::resizeEvent(QResizeEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)

View File

@@ -64,7 +64,6 @@ public slots:
void setBackward(bool backward); void setBackward(bool backward);
protected: protected:
bool focusNextPrevChild(bool next) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
private: private:

View File

@@ -488,7 +488,7 @@ void DoxygenTest::runTest(const QByteArray &original,
// testDocument.m_editorWidget->unfoldAll(); // testDocument.m_editorWidget->unfoldAll();
testDocument.m_editor->setCursorPosition(testDocument.m_cursorPosition); testDocument.m_editor->setCursorPosition(testDocument.m_cursorPosition);
TestCase::waitForRehighlightedSemanticDocument(testDocument.m_editorWidget); QVERIFY(TestCase::waitForRehighlightedSemanticDocument(testDocument.m_editorWidget));
// Send 'ENTER' key press // Send 'ENTER' key press
QKeyEvent event(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); QKeyEvent event(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);

View File

@@ -295,10 +295,18 @@ bool TestCase::waitForProcessedEditorDocument(const FilePath &filePath, int time
return waitForProcessedEditorDocument_internal(editorDocument, timeOutInMs); return waitForProcessedEditorDocument_internal(editorDocument, timeOutInMs);
} }
CPlusPlus::Document::Ptr TestCase::waitForRehighlightedSemanticDocument(CppEditorWidget *editorWidget) CPlusPlus::Document::Ptr TestCase::waitForRehighlightedSemanticDocument(
CppEditorWidget *editorWidget, int timeoutInMs)
{ {
while (!editorWidget->isSemanticInfoValid()) QElapsedTimer timer;
timer.start();
while (!editorWidget->isSemanticInfoValid()) {
if (timer.elapsed() >= timeoutInMs)
return {};
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QThread::msleep(20);
}
return editorWidget->semanticInfo().doc; return editorWidget->semanticInfo().doc;
} }

View File

@@ -140,7 +140,7 @@ public:
const Utils::FilePath &filePath, int timeOutInMs = 5000); const Utils::FilePath &filePath, int timeOutInMs = 5000);
static CPlusPlus::Document::Ptr waitForRehighlightedSemanticDocument( static CPlusPlus::Document::Ptr waitForRehighlightedSemanticDocument(
CppEditorWidget *editorWidget); CppEditorWidget *editorWidget, int timeoutInMs = defaultTimeOutInMs);
enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ }; enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ };
static bool waitUntilProjectIsFullyOpened(ProjectExplorer::Project *project, static bool waitUntilProjectIsFullyOpened(ProjectExplorer::Project *project,

View File

@@ -77,7 +77,7 @@ UseSelectionsTestCase::UseSelectionsTestCase(CppTestDocument &testFile,
closeEditorAtEndOfTestCase(testFile.m_editor); closeEditorAtEndOfTestCase(testFile.m_editor);
testFile.m_editor->setCursorPosition(testFile.m_cursorPosition); testFile.m_editor->setCursorPosition(testFile.m_cursorPosition);
waitForRehighlightedSemanticDocument(m_editorWidget); QVERIFY(waitForRehighlightedSemanticDocument(m_editorWidget));
bool hasTimedOut; bool hasTimedOut;
const SelectionList selections = waitForUseSelections(&hasTimedOut); const SelectionList selections = waitForUseSelections(&hasTimedOut);

View File

@@ -164,7 +164,7 @@ TestActionsTestCase::TestActionsTestCase(const Actions &tokenActions, const Acti
QVERIFY(CppModelManager::workingCopy().get(filePath)); QVERIFY(CppModelManager::workingCopy().get(filePath));
// Rehighlight // Rehighlight
waitForRehighlightedSemanticDocument(editorWidget); QVERIFY(waitForRehighlightedSemanticDocument(editorWidget));
// Run all file actions // Run all file actions
executeActionsOnEditorWidget(editorWidget, fileActions); executeActionsOnEditorWidget(editorWidget, fileActions);

View File

@@ -310,7 +310,7 @@ F2TestCase::F2TestCase(CppEditorAction action,
// Rehighlight // Rehighlight
if (!useClangd) if (!useClangd)
waitForRehighlightedSemanticDocument(testFile->m_editorWidget); QVERIFY(waitForRehighlightedSemanticDocument(testFile->m_editorWidget));
} }
// Activate editor of initial test file // Activate editor of initial test file

View File

@@ -104,7 +104,7 @@ BaseQuickFixTestCase::BaseQuickFixTestCase(const QList<TestDocumentPtr> &testDoc
} }
// Rehighlight // Rehighlight
waitForRehighlightedSemanticDocument(document->m_editorWidget); QVERIFY(waitForRehighlightedSemanticDocument(document->m_editorWidget));
} }
// Enforce the default cpp code style, so we are independent of config file settings. // Enforce the default cpp code style, so we are independent of config file settings.

View File

@@ -299,6 +299,12 @@ public:
bool reset(); bool reset();
void setState(Client::State state)
{
m_state = state;
emit q->stateChanged(state);
}
Client::State m_state = Client::Uninitialized; Client::State m_state = Client::Uninitialized;
QHash<LanguageServerProtocol::MessageId, QHash<LanguageServerProtocol::MessageId,
LanguageServerProtocol::ResponseHandler::Callback> m_responseHandlers; LanguageServerProtocol::ResponseHandler::Callback> m_responseHandlers;
@@ -569,7 +575,7 @@ void Client::initialize()
// directly send content now otherwise the state check of sendContent would fail // directly send content now otherwise the state check of sendContent would fail
d->sendMessageNow(initRequest); d->sendMessageNow(initRequest);
d->m_state = InitializeRequested; d->setState(InitializeRequested);
} }
void Client::shutdown() void Client::shutdown()
@@ -581,7 +587,7 @@ void Client::shutdown()
d->shutDownCallback(shutdownResponse); d->shutDownCallback(shutdownResponse);
}); });
sendMessage(shutdown); sendMessage(shutdown);
d->m_state = ShutdownRequested; d->setState(ShutdownRequested);
d->m_shutdownTimer.start(); d->m_shutdownTimer.start();
} }
@@ -1526,7 +1532,7 @@ void Client::projectClosed(ProjectExplorer::Project *project)
if (d->m_state == Initialized) { if (d->m_state == Initialized) {
LanguageClientManager::shutdownClient(this); LanguageClientManager::shutdownClient(this);
} else { } else {
d->m_state = Shutdown; // otherwise the manager would try to restart this server d->setState(Shutdown); // otherwise the manager would try to restart this server
emit finished(); emit finished();
} }
d->m_project = nullptr; d->m_project = nullptr;
@@ -1696,7 +1702,7 @@ bool ClientPrivate::reset()
} }
m_restartCountResetTimer.start(); m_restartCountResetTimer.start();
--m_restartsLeft; --m_restartsLeft;
m_state = Client::Uninitialized; setState(Client::Uninitialized);
m_responseHandlers.clear(); m_responseHandlers.clear();
m_clientInterface->resetBuffer(); m_clientInterface->resetBuffer();
updateOpenedEditorToolBars(); updateOpenedEditorToolBars();
@@ -1723,7 +1729,7 @@ bool ClientPrivate::reset()
void Client::setError(const QString &message) void Client::setError(const QString &message)
{ {
log(message); log(message);
d->m_state = d->m_state < Initialized ? FailedToInitialize : Error; d->setState(d->m_state < Initialized ? FailedToInitialize : Error);
} }
ProgressManager *Client::progressManager() ProgressManager *Client::progressManager()
@@ -2152,7 +2158,7 @@ void ClientPrivate::initializeCallback(const InitializeRequest::Response &initRe
QMessageBox::Retry | QMessageBox::Cancel, QMessageBox::Retry | QMessageBox::Cancel,
QMessageBox::Retry); QMessageBox::Retry);
if (result == QMessageBox::Retry) { if (result == QMessageBox::Retry) {
m_state = Client::Uninitialized; setState(Client::Uninitialized);
q->initialize(); q->initialize();
return; return;
} }
@@ -2204,7 +2210,7 @@ void ClientPrivate::initializeCallback(const InitializeRequest::Response &initRe
m_tokenSupport.setLegend(tokenProvider.legend()); m_tokenSupport.setLegend(tokenProvider.legend());
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized"; qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
m_state = Client::Initialized; setState(Client::Initialized);
q->sendMessage(InitializeNotification(InitializedParams())); q->sendMessage(InitializeNotification(InitializedParams()));
q->updateConfiguration(m_configuration); q->updateConfiguration(m_configuration);
@@ -2227,7 +2233,7 @@ void ClientPrivate::shutDownCallback(const ShutdownRequest::Response &shutdownRe
// directly send content now otherwise the state check of sendContent would fail // directly send content now otherwise the state check of sendContent would fail
sendMessageNow(ExitNotification()); sendMessageNow(ExitNotification());
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown"; qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " shutdown";
m_state = Client::Shutdown; setState(Client::Shutdown);
m_shutdownTimer.start(); m_shutdownTimer.start();
} }

View File

@@ -215,6 +215,7 @@ signals:
void documentUpdated(TextEditor::TextDocument *document); void documentUpdated(TextEditor::TextDocument *document);
void workDone(const LanguageServerProtocol::ProgressToken &token); void workDone(const LanguageServerProtocol::ProgressToken &token);
void shadowDocumentSwitched(const Utils::FilePath &filePath); void shadowDocumentSwitched(const Utils::FilePath &filePath);
void stateChanged(State state);
void finished(); void finished();
protected: protected:

View File

@@ -275,13 +275,14 @@ LanguageClientManager *LanguageClientManager::instance()
return managerInstance; return managerInstance;
} }
QList<Client *> LanguageClientManager::clientsSupportingDocument(const TextEditor::TextDocument *doc) QList<Client *> LanguageClientManager::clientsSupportingDocument(
const TextEditor::TextDocument *doc, bool onlyReachable)
{ {
QTC_ASSERT(managerInstance, return {}); QTC_ASSERT(managerInstance, return {});
QTC_ASSERT(doc, return {};); QTC_ASSERT(doc, return {};);
return Utils::filtered(managerInstance->reachableClients(), [doc](Client *client) { return Utils::filtered(
return client->isSupportedDocument(doc); onlyReachable ? managerInstance->reachableClients() : managerInstance->m_clients,
}); [doc](Client *client) { return client->isSupportedDocument(doc); });
} }
void LanguageClientManager::applySettings() void LanguageClientManager::applySettings()

View File

@@ -48,7 +48,8 @@ public:
static LanguageClientManager *instance(); static LanguageClientManager *instance();
static QList<Client *> clientsSupportingDocument(const TextEditor::TextDocument *doc); static QList<Client *> clientsSupportingDocument(
const TextEditor::TextDocument *doc, bool onlyReachable = true);
static void applySettings(); static void applySettings();
static QList<BaseSettings *> currentSettings(); static QList<BaseSettings *> currentSettings();

View File

@@ -253,7 +253,7 @@ void updateEditorToolBar(Core::IEditor *editor)
auto menu = new QMenu; auto menu = new QMenu;
auto clientsGroup = new QActionGroup(menu); auto clientsGroup = new QActionGroup(menu);
clientsGroup->setExclusive(true); clientsGroup->setExclusive(true);
for (auto client : LanguageClientManager::clientsSupportingDocument(document)) { for (auto client : LanguageClientManager::clientsSupportingDocument(document, false)) {
auto action = clientsGroup->addAction(client->name()); auto action = clientsGroup->addAction(client->name());
auto reopen = [action, client = QPointer(client), document] { auto reopen = [action, client = QPointer(client), document] {
if (!client) if (!client)
@@ -263,6 +263,10 @@ void updateEditorToolBar(Core::IEditor *editor)
}; };
action->setCheckable(true); action->setCheckable(true);
action->setChecked(client == LanguageClientManager::clientForDocument(document)); action->setChecked(client == LanguageClientManager::clientForDocument(document));
action->setEnabled(client->reachable());
QObject::connect(client, &Client::stateChanged, action, [action, client] {
action->setEnabled(client->reachable());
});
QObject::connect(action, &QAction::triggered, reopen); QObject::connect(action, &QAction::triggered, reopen);
} }
menu->addActions(clientsGroup->actions()); menu->addActions(clientsGroup->actions());

View File

@@ -62,6 +62,7 @@ QtcPlugin {
"perfprofiler.qrc", "perfprofiler.qrc",
] ]
Qt.core.resourceFileBaseName: "PerfProfilerQml" // avoid conflicting qrc file
Group { Group {
name: "Qml Files" name: "Qml Files"
Qt.core.resourcePrefix: "qt/qml/QtCreator/PerfProfiler/" Qt.core.resourcePrefix: "qt/qml/QtCreator/PerfProfiler/"

View File

@@ -400,6 +400,11 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
&& thisWorkingDirectory == tab.runControl->workingDirectory() && thisWorkingDirectory == tab.runControl->workingDirectory()
&& thisEnvironment == tab.runControl->environment(); && thisEnvironment == tab.runControl->environment();
}); });
const auto updateOutputFileName = [this](int index, RunControl *rc) {
qobject_cast<OutputWindow *>(m_tabWidget->widget(index))
//: file name suggested for saving application output, %1 = run configuration display name
->setOutputFileNameHint(Tr::tr("application-output-%1.txt").arg(rc->displayName()));
};
if (tab != m_runControlTabs.end()) { if (tab != m_runControlTabs.end()) {
// Reuse this tab // Reuse this tab
if (tab->runControl) if (tab->runControl)
@@ -415,6 +420,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
const int tabIndex = m_tabWidget->indexOf(tab->window); const int tabIndex = m_tabWidget->indexOf(tab->window);
QTC_ASSERT(tabIndex != -1, return); QTC_ASSERT(tabIndex != -1, return);
m_tabWidget->setTabText(tabIndex, rc->displayName()); m_tabWidget->setTabText(tabIndex, rc->displayName());
updateOutputFileName(tabIndex, rc);
tab->window->scrollToBottom(); tab->window->scrollToBottom();
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Reusing tab" qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Reusing tab"
@@ -430,8 +436,6 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
ow->setWindowIcon(Icons::WINDOW.icon()); ow->setWindowIcon(Icons::WINDOW.icon());
ow->setWordWrapEnabled(m_settings.wrapOutput); ow->setWordWrapEnabled(m_settings.wrapOutput);
ow->setMaxCharCount(m_settings.maxCharCount); ow->setMaxCharCount(m_settings.maxCharCount);
//: file name suggested for saving application output, %1 = run configuration display name
ow->setOutputFileNameHint(Tr::tr("application-output-%1.txt").arg(rc->displayName()));
auto updateFontSettings = [ow] { auto updateFontSettings = [ow] {
ow->setBaseFont(TextEditor::TextEditorSettings::fontSettings().font()); ow->setBaseFont(TextEditor::TextEditorSettings::fontSettings().font());
@@ -457,6 +461,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
m_runControlTabs.push_back(RunControlTab(rc, ow)); m_runControlTabs.push_back(RunControlTab(rc, ow));
m_tabWidget->addTab(ow, rc->displayName()); m_tabWidget->addTab(ow, rc->displayName());
updateOutputFileName(m_tabWidget->count() - 1, rc);
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Adding tab for" << rc; qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Adding tab for" << rc;
updateCloseActions(); updateCloseActions();
setFilteringEnabled(m_tabWidget->count() > 0); setFilteringEnabled(m_tabWidget->count() > 0);

View File

@@ -237,6 +237,7 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
buttonLayout->addWidget(d->m_toggleButton); buttonLayout->addWidget(d->m_toggleButton);
connect(d->m_toggleButton, &QPushButton::clicked, this, [this] { connect(d->m_toggleButton, &QPushButton::clicked, this, [this] {
d->m_model->toggleVariable(d->m_environmentView->currentIndex()); d->m_model->toggleVariable(d->m_environmentView->currentIndex());
d->m_editor.setEnvironmentItems(d->m_model->userChanges());
updateButtons(); updateButtons();
}); });

View File

@@ -1337,7 +1337,7 @@ static FilePaths dirsToCreate(const FilesToTransfer &files)
static QByteArray transferCommand(bool link) static QByteArray transferCommand(bool link)
{ {
return link ? "ln -s" : "put"; return link ? "ln -s" : "put -R";
} }
class SshTransferInterface : public FileTransferInterface class SshTransferInterface : public FileTransferInterface
@@ -1558,7 +1558,7 @@ private:
const auto batchIt = m_batches.begin(); const auto batchIt = m_batches.begin();
for (auto filesIt = batchIt->cbegin(); filesIt != batchIt->cend(); ++filesIt) { for (auto filesIt = batchIt->cbegin(); filesIt != batchIt->cend(); ++filesIt) {
const FileToTransfer fixedFile = fixLocalFileOnWindows(*filesIt, options); const FileToTransfer fixedFile = fixLocalFileOnWindows(*filesIt, options);
options << fixedLocalPath(fixedFile.m_source); options << fixedFile.m_source.path();
} }
options << fixedRemotePath(batchIt.key(), userAtHost()); options << fixedRemotePath(batchIt.key(), userAtHost());
m_batches.erase(batchIt); m_batches.erase(batchIt);
@@ -1588,11 +1588,6 @@ private:
return fixedFile; return fixedFile;
} }
QString fixedLocalPath(const FilePath &file) const
{
return file.isDir() && file.path().back() != '/' ? file.path() + '/' : file.path();
}
QString fixedRemotePath(const FilePath &file, const QString &remoteHost) const QString fixedRemotePath(const FilePath &file, const QString &remoteHost) const
{ {
return remoteHost + ':' + file.path(); return remoteHost + ':' + file.path();

View File

@@ -4142,6 +4142,7 @@ void TextEditorWidgetPrivate::registerActions()
.contextAction(); .contextAction();
m_visualizeWhitespaceAction = ActionBuilder(this, VISUALIZE_WHITESPACE) m_visualizeWhitespaceAction = ActionBuilder(this, VISUALIZE_WHITESPACE)
.setContext(m_editorContext) .setContext(m_editorContext)
.setCheckable(true)
.addOnToggled( .addOnToggled(
this, this,
[this](bool checked) { [this](bool checked) {
@@ -4157,6 +4158,7 @@ void TextEditorWidgetPrivate::registerActions()
.contextAction(); .contextAction();
m_textWrappingAction = ActionBuilder(this, TEXT_WRAPPING) m_textWrappingAction = ActionBuilder(this, TEXT_WRAPPING)
.setContext(m_editorContext) .setContext(m_editorContext)
.setCheckable(true)
.addOnToggled( .addOnToggled(
this, this,
[this](bool checked) { [this](bool checked) {

View File

@@ -453,7 +453,8 @@ void TextEditorPlugin::createEditorCommands()
TextActionBuilder(this, VISUALIZE_WHITESPACE) TextActionBuilder(this, VISUALIZE_WHITESPACE)
.setText(Tr::tr("&Visualize Whitespace")) .setText(Tr::tr("&Visualize Whitespace"))
.setDefaultKeySequence(Tr::tr("Meta+E, Meta+V"), Tr::tr("Ctrl+E, Ctrl+V")) .setDefaultKeySequence(Tr::tr("Meta+E, Meta+V"), Tr::tr("Ctrl+E, Ctrl+V"))
.addToContainer(M_EDIT_ADVANCED, G_EDIT_FORMAT); .addToContainer(M_EDIT_ADVANCED, G_EDIT_FORMAT)
.setCheckable(true);
TextActionBuilder(this, CLEAN_WHITESPACE) TextActionBuilder(this, CLEAN_WHITESPACE)
.setText(Tr::tr("Clean Whitespace")) .setText(Tr::tr("Clean Whitespace"))
.addToContainer(M_EDIT_ADVANCED, G_EDIT_FORMAT); .addToContainer(M_EDIT_ADVANCED, G_EDIT_FORMAT);

View File

@@ -37,7 +37,7 @@ def getQtCreatorVersionFromFile():
def checkQtCreatorHelpVersion(expectedVersion): def checkQtCreatorHelpVersion(expectedVersion):
def rightStart(x): def rightStart(x):
return x.startswith('Qt Creator Manual') return x.startswith('Qt Creator Documentation')
switchViewTo(ViewConstants.HELP) switchViewTo(ViewConstants.HELP)
try: try:
@@ -45,7 +45,7 @@ def checkQtCreatorHelpVersion(expectedVersion):
waitFor("any(map(rightStart, dumpItems(helpContentWidget.model())))", 10000) waitFor("any(map(rightStart, dumpItems(helpContentWidget.model())))", 10000)
items = dumpItems(helpContentWidget.model()) items = dumpItems(helpContentWidget.model())
test.compare(next(iter(filter(rightStart, items))), test.compare(next(iter(filter(rightStart, items))),
'Qt Creator Manual %s' % expectedVersion, 'Qt Creator Documentation %s' % expectedVersion,
'Verifying whether manual uses expected version.') 'Verifying whether manual uses expected version.')
except: except:
t, v = sys.exc_info()[:2] t, v = sys.exc_info()[:2]

View File

@@ -17,7 +17,7 @@ def invokeContextMenuItemOnBookmarkFolder(view, item, menuItem):
"window=':Add Bookmark_BookmarkDialog'}", menuItem)) "window=':Add Bookmark_BookmarkDialog'}", menuItem))
def textForQtVersion(text): def textForQtVersion(text):
suffix = "Qt Creator Manual" suffix = "Qt Creator Documentation"
if text != suffix: if text != suffix:
text += " | " + suffix text += " | " + suffix
return text return text
@@ -28,15 +28,14 @@ def main():
return return
# goto help mode and click on topic # goto help mode and click on topic
switchViewTo(ViewConstants.HELP) switchViewTo(ViewConstants.HELP)
manualQModelIndex = getQModelIndexStr("text?='Qt Creator Manual *'", manualQModelIndex = getQModelIndexStr("text?='Qt Creator Documentation *'",
":Qt Creator_QHelpContentWidget") ":Qt Creator_QHelpContentWidget")
manualQMIObj = waitForObject(manualQModelIndex) manualQMIObj = waitForObject(manualQModelIndex)
doubleClick(manualQMIObj, 5, 5, 0, Qt.LeftButton) doubleClick(manualQMIObj, 5, 5, 0, Qt.LeftButton)
if not waitFor("not manualQMIObj.collapsed", 2000): if not waitFor("not manualQMIObj.collapsed", 2000):
test.warning("It takes more than two seconds to expand the help content tree.") test.warning("It takes more than two seconds to expand the help content tree.")
devQModelIndex = getQModelIndexStr("text='Developing with Qt Creator'", manualQModelIndex)
doubleClick(devQModelIndex) gettingStartedQModelIndex = getQModelIndexStr("text='Getting Started'", manualQModelIndex)
gettingStartedQModelIndex = getQModelIndexStr("text='Getting Started'", devQModelIndex)
doubleClick(gettingStartedQModelIndex) doubleClick(gettingStartedQModelIndex)
pageTitle = "Configuring Qt Creator" pageTitle = "Configuring Qt Creator"
mouseClick(waitForObject(getQModelIndexStr("text='%s'" % pageTitle, mouseClick(waitForObject(getQModelIndexStr("text='%s'" % pageTitle,
@@ -80,7 +79,7 @@ def main():
configQModelIndex = getQModelIndexStr("text?='%s'" % textForQtVersion("%s*" % pageTitle), configQModelIndex = getQModelIndexStr("text?='%s'" % textForQtVersion("%s*" % pageTitle),
folder2QModelIndex) folder2QModelIndex)
newFolderQModelIndex = getQModelIndexStr("text='New Folder'", sampleQModelIndex) newFolderQModelIndex = getQModelIndexStr("text='New Folder'", sampleQModelIndex)
manualQModelIndex = getQModelIndexStr("text='%s'" % textForQtVersion("Qt Creator Manual"), manualQModelIndex = getQModelIndexStr("text='%s'" % textForQtVersion("Qt Creator Documentation"),
newFolderQModelIndex) newFolderQModelIndex)
test.verify(checkIfObjectExists(sampleQModelIndex, verboseOnFail = True) and test.verify(checkIfObjectExists(sampleQModelIndex, verboseOnFail = True) and
checkIfObjectExists(folder1QModelIndex, verboseOnFail = True) and checkIfObjectExists(folder1QModelIndex, verboseOnFail = True) and
@@ -99,7 +98,7 @@ def main():
type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Right>") type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Right>")
type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Down>") type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Down>")
type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Return>") type(waitForObject(":Qt Creator_Bookmarks_TreeView"), "<Return>")
test.verify(textForQtVersion("Qt Creator Manual") in getHelpTitle(), test.verify(textForQtVersion("Qt Creator Documentation") in getHelpTitle(),
"Verifying if second bookmark is opened") "Verifying if second bookmark is opened")
# delete previously created directory # delete previously created directory
clickButton(waitForObject(":Qt Creator.Add Bookmark_QToolButton")) clickButton(waitForObject(":Qt Creator.Add Bookmark_QToolButton"))

View File

@@ -75,7 +75,7 @@ def main():
wsButton = getWelcomeScreenSideBarButton(getStarted) wsButton = getWelcomeScreenSideBarButton(getStarted)
if test.verify(object.exists(wsButton), if test.verify(object.exists(wsButton),
"Verifying: Qt Creator displays Welcome Page with '%s' button." % getStarted): "Verifying: Qt Creator displays Welcome Page with '%s' button." % getStarted):
if clickItemVerifyHelpCombo(wsButton, "Getting Started | Qt Creator Manual", if clickItemVerifyHelpCombo(wsButton, "Getting Started \| Qt Creator Documentation",
"Verifying: Help with Creator Documentation is being opened."): "Verifying: Help with Creator Documentation is being opened."):
textUrls = {'Online Community':'https://forum.qt.io', textUrls = {'Online Community':'https://forum.qt.io',
@@ -92,7 +92,7 @@ def main():
wsButton = getWelcomeScreenSideBarButton(getStarted) wsButton = getWelcomeScreenSideBarButton(getStarted)
if object.exists(wsButton): if object.exists(wsButton):
mouseClick(wsButton) mouseClick(wsButton)
qcManualQModelIndexStr = getQModelIndexStr("text~='Qt Creator Manual [0-9.]+'", qcManualQModelIndexStr = getQModelIndexStr("text~='Qt Creator Documentation [0-9.]+'",
":Qt Creator_QHelpContentWidget") ":Qt Creator_QHelpContentWidget")
if str(waitForObject(":Qt Creator_HelpSelector_QComboBox").currentText) == "(Untitled)": if str(waitForObject(":Qt Creator_HelpSelector_QComboBox").currentText) == "(Untitled)":
mouseClick(qcManualQModelIndexStr) mouseClick(qcManualQModelIndexStr)