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

@@ -37,7 +37,7 @@ static void updateCMakePathsFromQMake(QStringList &initialCMakeArguments)
return;
// ~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"};
for (const QByteArray &var : cmakePathsVariables) {

View File

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

View File

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

View File

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

View File

@@ -193,9 +193,13 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
menu.exec(d->m_editorList->mapToGlobal(p));
});
connect(d->m_dragHandleMenu, &QMenu::aboutToShow, this, [this] {
d->m_dragHandleMenu->clear();
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_closeEditorButton, &QAbstractButton::clicked,
this, &EditorToolBar::closeEditor, Qt::QueuedConnection);

View File

@@ -160,15 +160,6 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
setProperty(StyleHelper::C_TOP_BORDER, true);
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,
this, &FindToolBar::invokeResetIncrementalSearch);
connect(m_findEdit, &Utils::FancyLineEdit::textChanged,
@@ -447,6 +438,17 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
connect(&m_findStepTimer, &QTimer::timeout, this, &FindToolBar::invokeFindStep);
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;
@@ -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)
{
Q_UNUSED(event)

View File

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

View File

@@ -488,7 +488,7 @@ void DoxygenTest::runTest(const QByteArray &original,
// testDocument.m_editorWidget->unfoldAll();
testDocument.m_editor->setCursorPosition(testDocument.m_cursorPosition);
TestCase::waitForRehighlightedSemanticDocument(testDocument.m_editorWidget);
QVERIFY(TestCase::waitForRehighlightedSemanticDocument(testDocument.m_editorWidget));
// Send 'ENTER' key press
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);
}
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();
QThread::msleep(20);
}
return editorWidget->semanticInfo().doc;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -275,13 +275,14 @@ LanguageClientManager *LanguageClientManager::instance()
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(doc, return {};);
return Utils::filtered(managerInstance->reachableClients(), [doc](Client *client) {
return client->isSupportedDocument(doc);
});
return Utils::filtered(
onlyReachable ? managerInstance->reachableClients() : managerInstance->m_clients,
[doc](Client *client) { return client->isSupportedDocument(doc); });
}
void LanguageClientManager::applySettings()

View File

@@ -48,7 +48,8 @@ public:
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 QList<BaseSettings *> currentSettings();

View File

@@ -253,7 +253,7 @@ void updateEditorToolBar(Core::IEditor *editor)
auto menu = new QMenu;
auto clientsGroup = new QActionGroup(menu);
clientsGroup->setExclusive(true);
for (auto client : LanguageClientManager::clientsSupportingDocument(document)) {
for (auto client : LanguageClientManager::clientsSupportingDocument(document, false)) {
auto action = clientsGroup->addAction(client->name());
auto reopen = [action, client = QPointer(client), document] {
if (!client)
@@ -263,6 +263,10 @@ void updateEditorToolBar(Core::IEditor *editor)
};
action->setCheckable(true);
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);
}
menu->addActions(clientsGroup->actions());

View File

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

View File

@@ -400,6 +400,11 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
&& thisWorkingDirectory == tab.runControl->workingDirectory()
&& 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()) {
// Reuse this tab
if (tab->runControl)
@@ -415,6 +420,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
const int tabIndex = m_tabWidget->indexOf(tab->window);
QTC_ASSERT(tabIndex != -1, return);
m_tabWidget->setTabText(tabIndex, rc->displayName());
updateOutputFileName(tabIndex, rc);
tab->window->scrollToBottom();
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Reusing tab"
@@ -430,8 +436,6 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
ow->setWindowIcon(Icons::WINDOW.icon());
ow->setWordWrapEnabled(m_settings.wrapOutput);
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] {
ow->setBaseFont(TextEditor::TextEditorSettings::fontSettings().font());
@@ -457,6 +461,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
m_runControlTabs.push_back(RunControlTab(rc, ow));
m_tabWidget->addTab(ow, rc->displayName());
updateOutputFileName(m_tabWidget->count() - 1, rc);
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Adding tab for" << rc;
updateCloseActions();
setFilteringEnabled(m_tabWidget->count() > 0);

View File

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

View File

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

View File

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

View File

@@ -453,7 +453,8 @@ void TextEditorPlugin::createEditorCommands()
TextActionBuilder(this, VISUALIZE_WHITESPACE)
.setText(Tr::tr("&Visualize Whitespace"))
.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)
.setText(Tr::tr("Clean Whitespace"))
.addToContainer(M_EDIT_ADVANCED, G_EDIT_FORMAT);