Merge remote-tracking branch 'origin/master' into 4.15

Change-Id: Ia313b9a8bf82940e496b7456801faf552fe4b022
This commit is contained in:
Eike Ziller
2021-02-24 19:42:30 +01:00
37 changed files with 343 additions and 102 deletions

View File

@@ -33,9 +33,11 @@ Editing
### C++
* Added options for generation of getters and setters (QTCREATORBUG-1532)
* Added `Create Constructor` refactoring operation
* Added filtering of `Find Usages` based on access type (QTCREATORBUG-19373)
* Added `Create Getter and Setter Member Functions` refactoring action
(QTCREATORBUG-1532)
* Added `Generate Constructor` refactoring action
* Added filtering of `Find References to Symbol Under Cursor` based on access
type (QTCREATORBUG-19373)
* Added `Open in Editor` and `Open Type Hierarchy` to context menu on items in
type hierarchy
* Added highlighting of previous class when navigating in type hierarchy

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -51,6 +51,8 @@
\uicontrol {C++} > \uicontrol {Find References to Symbol Under Cursor} or
press \key {Ctrl+Shift+U}.
\image qtcreator-find-references-to-symbol-under-cursor.png "Search results for finding references to symbols"
\note You can also select \uicontrol Edit > \uicontrol {Find/Replace} >
\uicontrol {Advanced Find} > \uicontrol {C++ Symbols} to search for
classes, functions, enums, and declarations either from files listed as
@@ -100,6 +102,10 @@
\li To expand and collapse the list of all instances, click the
\inlineimage qtcreator-expand.png
(\uicontrol {Expand All}) button.
\li To filter the search results for the usage of symbols according to
access type, such as read, write, or declaration, click the
\inlineimage filtericon.png
(\uicontrol {Filter Tree}) button and select the access type.
\li To clear the search results, click the
\inlineimage clean_pane_small.png
(\uicontrol Clear) button.
@@ -184,7 +190,8 @@
\section1 Creating Functions
You can apply refactoring actions to implement member functions, insert
virtual functions of base classes, and greate getter and setter functions.
virtual functions of base classes, create getter and setter functions,
and generate constructors.
\section2 Implementing Member Functions
@@ -217,6 +224,16 @@
for member variables or only a getter or setter.
\image qtcreator-refactoring-getters-and-setters.png "Getters and Setters dialog"
\section2 Generating Constructors
You can apply the \uicontrol {Generate Constructor} refactoring action to
create a public, protected, or private constructor for a class. Select the
class members to initialize in the constructor. Drag and drop the parameters
to specify their order in the constructor.
\image qtcreator-refactoring-constructor.png "Constructor dialog"
\endif
\section1 Summary of Refactoring Actions
@@ -668,6 +685,10 @@
\li Creates either both getter and setter member functions for
member variables or only a getter or setter.
\li Member variable in class definition
\row
\li Generate Constructor
\li Creates a constructor for a class.
\li Class definition
\row
\li Move Function Definition
\li Moves a function definition to the implementation file, outside

View File

@@ -139,7 +139,10 @@ ScrollView {
bottomPadding: 0
expanded: importExpanded
expandOnClick: false
onToggleExpand: importExpanded = !importExpanded
onToggleExpand: {
if (categoryModel.rowCount() > 0)
importExpanded = !importExpanded
}
onShowContextMenu: {
importToRemove = importUsed ? "" : importUrl
contextMenu.popup()

View File

@@ -989,6 +989,21 @@ protected:
out("const ");
}
}
switch (ast->type) {
case PatternElement::Literal:
case PatternElement::Method:
case PatternElement::Binding:
break;
case PatternElement::Getter:
out("get ");
break;
case PatternElement::Setter:
out("set ");
break;
case PatternElement::SpreadElement:
out("...");
break;
}
out(ast->identifierToken);
if (ast->initializer) {
if (ast->isVariableDeclaration())
@@ -1312,6 +1327,8 @@ protected:
bool visit(ArgumentList *ast) override
{
for (ArgumentList *it = ast; it; it = it->next) {
if (it->isSpreadElement)
out("...");
accept(it->expression);
if (it->next) {
out(", ", it->commaToken);

View File

@@ -403,7 +403,7 @@ AndroidDeviceInfoList AvdManagerOutputParser::listVirtualDevices(const AndroidCo
avdList = parseAvdList(output);
} while (output.contains(avdManufacturerError));
for (const QString &avdPathStr : avdErrorPaths)
for (const QString &avdPathStr : qAsConst(avdErrorPaths))
AvdConfigEditManufacturerTag(avdPathStr, true);
return avdList;

View File

@@ -1494,7 +1494,7 @@ FilePath AndroidConfig::getJdkPath()
#endif // Q_OS_WIN
}
for (const QString &version : allVersions) {
for (const QString &version : qAsConst(allVersions)) {
settings->beginGroup(version);
jdkHome = FilePath::fromUserInput(settings->value("JavaHome").toString());
settings->endGroup();

View File

@@ -538,7 +538,7 @@ void AndroidRunnerWorker::asyncStartHelper()
forceStop();
asyncStartLogcat();
for (const QString &entry : m_beforeStartAdbCommands)
for (const QString &entry : qAsConst(m_beforeStartAdbCommands))
runAdb(entry.split(' ', Qt::SkipEmptyParts));
QStringList args({"shell", "am", "start"});
@@ -825,7 +825,7 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
m_debugServerProcess.reset();
// Run adb commands after application quit.
for (const QString &entry: m_afterFinishAdbCommands)
for (const QString &entry: qAsConst(m_afterFinishAdbCommands))
runAdb(entry.split(' ', Qt::SkipEmptyParts));
} else {
// In debugging cases this will be funneled to the engine to actually start

View File

@@ -566,7 +566,7 @@ void SdkManagerOutputParser::compilePackageAssociations()
deleteAlreadyInstalled(images);
// Associate the system images with sdk platforms.
for (AndroidSdkPackage *image : images) {
for (AndroidSdkPackage *image : qAsConst(images)) {
int imageApi = m_systemImages[image];
auto itr = std::find_if(m_packages.begin(), m_packages.end(),
[imageApi](const AndroidSdkPackage *p) {
@@ -1151,7 +1151,7 @@ void AndroidSdkManagerPrivate::parseCommonArguments(QFutureInterface<QString> &f
void AndroidSdkManagerPrivate::clearPackages()
{
for (AndroidSdkPackage *p : m_allPackages)
for (AndroidSdkPackage *p : qAsConst(m_allPackages))
delete p;
m_allPackages.clear();
}

View File

@@ -298,7 +298,7 @@ void AndroidSdkModel::selectMissingEssentials()
}
// Select SDK platform
for (const SdkPlatform *platform : m_sdkPlatforms) {
for (const SdkPlatform *platform : qAsConst(m_sdkPlatforms)) {
if (!platform->installedLocation().isEmpty()) {
pendingPkgs.removeOne(platform->sdkStylePath());
} else if (pendingPkgs.contains(platform->sdkStylePath()) &&

View File

@@ -154,7 +154,7 @@ SdkPlatform::SdkPlatform(QVersionNumber version, QString sdkStylePathStr, int ap
SdkPlatform::~SdkPlatform()
{
for (SystemImage *image : m_systemImages)
for (SystemImage *image : qAsConst(m_systemImages))
delete image;
m_systemImages.clear();
}

View File

@@ -177,7 +177,7 @@ void AvdDialog::updateDeviceDefinitionComboBox()
m_avdDialog.deviceDefinitionTypeComboBox->currentText());
m_avdDialog.deviceDefinitionComboBox->clear();
for (const DeviceDefinitionStruct &item : m_deviceDefinitionsList) {
for (const DeviceDefinitionStruct &item : qAsConst(m_deviceDefinitionsList)) {
if (item.deviceType == curDeviceType)
m_avdDialog.deviceDefinitionComboBox->addItem(item.name_id);
}
@@ -231,7 +231,7 @@ void AvdDialog::updateApiLevelComboBox()
});
m_avdDialog.targetApiComboBox->clear();
for (SystemImage *image : filteredList) {
for (SystemImage *image : qAsConst(filteredList)) {
QString imageString = "android-" % QString::number(image->apiLevel());
const QStringList imageSplits = image->sdkStylePath().split(';');
if (imageSplits.size() == 4)

View File

@@ -25,12 +25,21 @@
#include "javalanguageserver.h"
#include "androidconfigurations.h"
#include "androidconstants.h"
#include "androidmanager.h"
#include <languageclient/client.h>
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientutils.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/environment.h>
#include <utils/pathchooser.h>
#include <utils/temporarydirectory.h>
#include <utils/variablechooser.h>
#include <QGridLayout>
@@ -39,7 +48,6 @@
using namespace Utils;
constexpr char languageServerKey[] = "languageServer";
constexpr char workspaceKey[] = "workspace";
namespace Android {
namespace Internal {
@@ -67,7 +75,6 @@ JLSSettingsWidget::JLSSettingsWidget(const JLSSettings *settings, QWidget *paren
, m_name(new QLineEdit(settings->m_name, this))
, m_java(new PathChooser(this))
, m_ls(new PathChooser(this))
, m_workspace(new PathChooser(this))
{
int row = 0;
auto *mainLayout = new QGridLayout;
@@ -88,11 +95,6 @@ JLSSettingsWidget::JLSSettingsWidget(const JLSSettings *settings, QWidget *paren
m_ls->setPath(QDir::toNativeSeparators(settings->m_languageServer));
mainLayout->addWidget(m_ls, row, 1);
mainLayout->addWidget(new QLabel(tr("Workspace:")), ++row, 0);
m_workspace->setExpectedKind(Utils::PathChooser::Directory);
m_workspace->setPath(QDir::toNativeSeparators(settings->m_workspace));
mainLayout->addWidget(m_workspace, row, 1);
setLayout(mainLayout);
}
@@ -117,9 +119,6 @@ bool JLSSettings::applyFromSettingsWidget(QWidget *widget)
changed |= m_languageServer != jlswidget->languageServer();
m_languageServer = jlswidget->languageServer();
changed |= m_workspace != jlswidget->workspace();
m_workspace = jlswidget->workspace();
changed |= m_executable != jlswidget->java();
m_executable = jlswidget->java();
@@ -130,8 +129,7 @@ bool JLSSettings::applyFromSettingsWidget(QWidget *widget)
"-noverify "
"-Xmx1G "
"-jar \"%1\" "
"-configuration \"%2\" "
"-data \"%3\"";
"-configuration \"%2\"";
QFileInfo languageServerFileInfo(m_languageServer);
QDir configDir = languageServerFileInfo.absoluteDir();
@@ -145,7 +143,7 @@ bool JLSSettings::applyFromSettingsWidget(QWidget *widget)
configDir.cd("config_mac");
}
if (configDir.exists()) {
arguments = arguments.arg(m_languageServer, configDir.absolutePath(), m_workspace);
arguments = arguments.arg(m_languageServer, configDir.absolutePath());
changed |= m_arguments != arguments;
m_arguments = arguments;
}
@@ -159,14 +157,13 @@ QWidget *JLSSettings::createSettingsWidget(QWidget *parent) const
bool JLSSettings::isValid() const
{
return StdIOSettings::isValid() && !m_languageServer.isEmpty() && !m_workspace.isEmpty();
return StdIOSettings::isValid() && !m_languageServer.isEmpty();
}
QVariantMap JLSSettings::toMap() const
{
QVariantMap map = StdIOSettings::toMap();
map.insert(languageServerKey, m_languageServer);
map.insert(workspaceKey, m_workspace);
return map;
}
@@ -174,7 +171,6 @@ void JLSSettings::fromMap(const QVariantMap &map)
{
StdIOSettings::fromMap(map);
m_languageServer = map[languageServerKey].toString();
m_workspace = map[workspaceKey].toString();
}
LanguageClient::BaseSettings *JLSSettings::copy() const
@@ -182,12 +178,39 @@ LanguageClient::BaseSettings *JLSSettings::copy() const
return new JLSSettings(*this);
}
class JLSInterface : public LanguageClient::StdIOClientInterface
{
public:
JLSInterface() = default;
QString workspaceDir() const { return m_workspaceDir.path(); }
private:
TemporaryDirectory m_workspaceDir = TemporaryDirectory("QtCreator-jls-XXXXXX");
};
LanguageClient::BaseClientInterface *JLSSettings::createInterface() const
{
auto interface = new JLSInterface();
interface->setExecutable(m_executable);
QString arguments = this->arguments();
arguments += QString(" -data \"%1\"").arg(interface->workspaceDir());
interface->setArguments(arguments);
return interface;
}
class JLSClient : public LanguageClient::Client
{
public:
using Client::Client;
void executeCommand(const LanguageServerProtocol::Command &command) override;
void setCurrentProject(ProjectExplorer::Project *project) override;
void updateProjectFiles();
void updateTarget(ProjectExplorer::Target *target);
private:
ProjectExplorer::Target *m_currentTarget = nullptr;
};
void JLSClient::executeCommand(const LanguageServerProtocol::Command &command)
@@ -206,6 +229,127 @@ void JLSClient::executeCommand(const LanguageServerProtocol::Command &command)
}
}
void JLSClient::setCurrentProject(ProjectExplorer::Project *project)
{
Client::setCurrentProject(project);
QTC_ASSERT(project, return);
updateTarget(project->activeTarget());
updateProjectFiles();
connect(project, &ProjectExplorer::Project::activeTargetChanged,
this, &JLSClient::updateTarget);
}
static void generateProjectFile(const FilePath &projectDir,
const QString &qtSrc,
const QString &projectName)
{
const FilePath projectFilePath = projectDir.pathAppended(".project");
QFile projectFile(projectFilePath.toString());
if (projectFile.open(QFile::Truncate | QFile::WriteOnly)) {
QXmlStreamWriter writer(&projectFile);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeComment("Autogenerated by Qt Creator. "
"Changes to this file will not be taken into account.");
writer.writeStartElement("projectDescription");
writer.writeTextElement("name", projectName);
writer.writeStartElement("natures");
writer.writeTextElement("nature", "org.eclipse.jdt.core.javanature");
writer.writeEndElement(); // natures
writer.writeStartElement("linkedResources");
writer.writeStartElement("link");
writer.writeTextElement("name", "qtSrc");
writer.writeTextElement("type", "2");
writer.writeTextElement("location", qtSrc);
writer.writeEndElement(); // link
writer.writeEndElement(); // linkedResources
writer.writeEndElement(); // projectDescription
writer.writeEndDocument();
projectFile.close();
}
}
static void generateClassPathFile(const FilePath &projectDir,
const QString &sourceDir,
const QStringList &libs)
{
const FilePath classPathFilePath = projectDir.pathAppended(".classpath");
QFile classPathFile(classPathFilePath.toString());
if (classPathFile.open(QFile::Truncate | QFile::WriteOnly)) {
QXmlStreamWriter writer(&classPathFile);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeComment("Autogenerated by Qt Creator. "
"Changes to this file will not be taken into account.");
writer.writeStartElement("classpath");
writer.writeEmptyElement("classpathentry");
writer.writeAttribute("kind", "src");
writer.writeAttribute("path", sourceDir);
writer.writeEmptyElement("classpathentry");
writer.writeAttribute("kind", "src");
writer.writeAttribute("path", "qtSrc");
for (const QString &lib : libs) {
writer.writeEmptyElement("classpathentry");
writer.writeAttribute("kind", "lib");
writer.writeAttribute("path", lib);
}
writer.writeEndElement(); // classpath
writer.writeEndDocument();
classPathFile.close();
}
}
void JLSClient::updateProjectFiles()
{
using namespace ProjectExplorer;
if (!m_currentTarget)
return;
if (Target *target = m_currentTarget) {
Kit *kit = m_currentTarget->kit();
if (DeviceTypeKitAspect::deviceTypeId(kit) != Android::Constants::ANDROID_DEVICE_TYPE)
return;
if (ProjectNode *node = project()->findNodeForBuildKey(target->activeBuildKey())) {
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit);
if (!version)
return;
const QString qtSrc = version->prefix().toString() + "/src/android/java/src";
const FilePath &projectDir = project()->rootProjectDirectory();
if (!projectDir.exists())
return;
const FilePath packageSourceDir = FilePath::fromVariant(
node->data(Constants::AndroidPackageSourceDir));
FilePath sourceDir = packageSourceDir.pathAppended("src");
if (!sourceDir.exists())
return;
sourceDir = sourceDir.relativeChildPath(projectDir);
const FilePath &sdkLocation = AndroidConfigurations::currentConfig().sdkLocation();
const QString &targetSDK = AndroidManager::buildTargetSDK(m_currentTarget);
const QString androidJar = QString("%1/platforms/%2/android.jar")
.arg(sdkLocation.toString(), targetSDK);
QStringList libs(androidJar);
QDir libDir(packageSourceDir.pathAppended("libs").toString());
libs << Utils::transform(libDir.entryInfoList({"*.jar"}, QDir::Files),
&QFileInfo::absoluteFilePath);
generateProjectFile(projectDir, qtSrc, project()->displayName());
generateClassPathFile(projectDir, sourceDir.toString(), libs);
}
}
}
void JLSClient::updateTarget(ProjectExplorer::Target *target)
{
if (m_currentTarget) {
disconnect(m_currentTarget, &ProjectExplorer::Target::parsingFinished,
this, &JLSClient::updateProjectFiles);
}
m_currentTarget = target;
if (m_currentTarget) {
connect(m_currentTarget, &ProjectExplorer::Target::parsingFinished,
this, &JLSClient::updateProjectFiles);
}
updateProjectFiles();
}
LanguageClient::Client *JLSSettings::createClient(LanguageClient::BaseClientInterface *interface) const
{
return new JLSClient(interface);

View File

@@ -42,9 +42,9 @@ public:
void fromMap(const QVariantMap &map) final;
LanguageClient::BaseSettings *copy() const final;
LanguageClient::Client *createClient(LanguageClient::BaseClientInterface *interface) const final;
LanguageClient::BaseClientInterface *createInterface() const override;
QString m_languageServer;
QString m_workspace;
private:
JLSSettings(const JLSSettings &other) = default;

View File

@@ -128,7 +128,7 @@ void ClangToolsUnitTests::testProject()
QVERIFY(waitForFinishedTool.wait(m_timeout));
// Check for errors
const QString errorText = waitForFinishedTool.takeFirst().first().toString();
const QString errorText = waitForFinishedTool.takeFirst().constFirst().toString();
const bool finishedSuccessfully = errorText.isEmpty();
if (!finishedSuccessfully)
qWarning("Error: %s", qPrintable(errorText));

View File

@@ -245,7 +245,7 @@ static FilePath qmakeFromCMakeCache(const CMakeConfig &config)
if (!qmakeLocationTxt.open(QIODevice::ReadOnly)) {
return FilePath();
}
FilePath qmakeLocation = FilePath::fromUtf8(qmakeLocationTxt.readLine().data());
FilePath qmakeLocation = FilePath::fromUtf8(qmakeLocationTxt.readLine().constData());
qCDebug(cmInputLog) << "qmake location: " << qmakeLocation.toUserOutput();
return qmakeLocation;

View File

@@ -100,6 +100,13 @@ Client::Client(BaseClientInterface *clientInterface)
&Client::rehighlight);
}
QString Client::name() const
{
if (m_project && !m_project->displayName().isEmpty())
return tr("%1 for %2").arg(m_displayName, m_project->displayName());
return m_displayName;
}
static void updateEditorToolBar(QList<TextEditor::TextDocument *> documents)
{
for (TextEditor::TextDocument *document : documents) {
@@ -790,6 +797,15 @@ void Client::projectOpened(ProjectExplorer::Project *project)
void Client::projectClosed(ProjectExplorer::Project *project)
{
if (sendWorkspceFolderChanges()) {
WorkspaceFoldersChangeEvent event;
event.setRemoved({WorkSpaceFolder(DocumentUri::fromFilePath(project->projectDirectory()),
project->displayName())});
DidChangeWorkspaceFoldersParams params;
params.setEvent(event);
DidChangeWorkspaceFoldersNotification change(params);
sendContent(change);
}
if (project == m_project) {
if (m_state == Initialized) {
shutdown();
@@ -797,16 +813,8 @@ void Client::projectClosed(ProjectExplorer::Project *project)
m_state = Shutdown; // otherwise the manager would try to restart this server
emit finished();
}
m_project = nullptr;
}
if (!sendWorkspceFolderChanges())
return;
WorkspaceFoldersChangeEvent event;
event.setRemoved({WorkSpaceFolder(DocumentUri::fromFilePath(project->projectDirectory()),
project->displayName())});
DidChangeWorkspaceFoldersParams params;
params.setEvent(event);
DidChangeWorkspaceFoldersNotification change(params);
sendContent(change);
}
void Client::setSupportedLanguage(const LanguageFilter &filter)
@@ -1260,6 +1268,8 @@ void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)
bool Client::sendWorkspceFolderChanges() const
{
if (!reachable())
return false;
if (m_dynamicCapabilities.isRegistered(
DidChangeWorkspaceFoldersNotification::methodName).value_or(false)) {
return true;

View File

@@ -87,7 +87,7 @@ public:
// basic properties
Utils::Id id() const { return m_id; }
void setName(const QString &name) { m_displayName = name; }
QString name() const { return m_displayName; }
QString name() const;
void sendContent(const LanguageServerProtocol::IContent &content);
void cancelRequest(const LanguageServerProtocol::MessageId &id);
@@ -134,10 +134,10 @@ public:
bool documentUpdatePostponed(const Utils::FilePath &fileName) const;
// workspace control
void setCurrentProject(ProjectExplorer::Project *project);
virtual void setCurrentProject(ProjectExplorer::Project *project);
const ProjectExplorer::Project *project() const;
void projectOpened(ProjectExplorer::Project *project);
void projectClosed(ProjectExplorer::Project *project);
virtual void projectOpened(ProjectExplorer::Project *project);
virtual void projectClosed(ProjectExplorer::Project *project);
// commands
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,

View File

@@ -89,9 +89,7 @@ void BaseClientInterface::parseData(const QByteArray &data)
}
}
StdIOClientInterface::StdIOClientInterface(const QString &executable, const QString &arguments)
: m_executable(executable)
, m_arguments(arguments)
StdIOClientInterface::StdIOClientInterface()
{
connect(&m_process, &QProcess::readyReadStandardError,
this, &StdIOClientInterface::readError);
@@ -99,9 +97,6 @@ StdIOClientInterface::StdIOClientInterface(const QString &executable, const QStr
this, &StdIOClientInterface::readOutput);
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &StdIOClientInterface::onProcessFinished);
m_process.setArguments(Utils::QtcProcess::splitArgs(m_arguments));
m_process.setProgram(m_executable);
}
StdIOClientInterface::~StdIOClientInterface()
@@ -109,11 +104,6 @@ StdIOClientInterface::~StdIOClientInterface()
Utils::SynchronousProcess::stopProcess(m_process);
}
bool StdIOClientInterface::needsRestart(const StdIOSettings *settings) const
{
return m_executable != settings->m_executable || m_arguments != settings->arguments();
}
bool StdIOClientInterface::start()
{
m_process.start();
@@ -124,6 +114,16 @@ bool StdIOClientInterface::start()
return true;
}
void StdIOClientInterface::setExecutable(const QString &executable)
{
m_process.setProgram(executable);
}
void StdIOClientInterface::setArguments(const QString &arguments)
{
m_process.setArguments(Utils::QtcProcess::splitArgs(arguments));
}
void StdIOClientInterface::setWorkingDirectory(const QString &workingDirectory)
{
m_process.setWorkingDirectory(workingDirectory);

View File

@@ -25,6 +25,8 @@
#pragma once
#include "languageclient_global.h"
#include <languageserverprotocol/basemessage.h>
#include <QBuffer>
@@ -34,13 +36,13 @@ namespace LanguageClient {
class StdIOSettings;
class BaseClientInterface : public QObject
class LANGUAGECLIENT_EXPORT BaseClientInterface : public QObject
{
Q_OBJECT
public:
BaseClientInterface();
virtual ~BaseClientInterface();
~BaseClientInterface() override;
void sendMessage(const LanguageServerProtocol::BaseMessage &message);
virtual bool start() { return true; }
@@ -61,23 +63,23 @@ private:
LanguageServerProtocol::BaseMessage m_currentMessage;
};
class StdIOClientInterface : public BaseClientInterface
class LANGUAGECLIENT_EXPORT StdIOClientInterface : public BaseClientInterface
{
Q_OBJECT
public:
StdIOClientInterface(const QString &executable, const QString &arguments);
StdIOClientInterface();
~StdIOClientInterface() override;
StdIOClientInterface() = delete;
StdIOClientInterface(const StdIOClientInterface &) = delete;
StdIOClientInterface(StdIOClientInterface &&) = delete;
StdIOClientInterface &operator=(const StdIOClientInterface &) = delete;
StdIOClientInterface &operator=(StdIOClientInterface &&) = delete;
bool needsRestart(const StdIOSettings *settings) const;
bool start() override;
// These functions only have an effect if they are called before start
void setExecutable(const QString &executable);
void setArguments(const QString &arguments);
void setWorkingDirectory(const QString &workingDirectory);
protected:
@@ -88,9 +90,6 @@ private:
void readError();
void readOutput();
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
const QString m_executable;
const QString m_arguments;
};
} // namespace LanguageClient

View File

@@ -472,13 +472,17 @@ void LanguageClientManager::documentOpened(Core::IDocument *document)
continue;
// check whether we already have a client running for this project
if (Utils::findOrDefault(clients,
[project](const QPointer<Client> &client) {
return client->project() == project;
})) {
continue;
Client *clientForProject = Utils::findOrDefault(clients,
[project](Client *client) {
return client->project()
== project;
});
if (!clientForProject) {
clientForProject = startClient(setting, project);
clients << clientForProject;
}
clients << startClient(setting, project);
QTC_ASSERT(clientForProject, continue);
openDocumentWithClient(textDocument, clientForProject);
}
} else if (setting->m_startBehavior == BaseSettings::RequiresFile && clients.isEmpty()) {
clients << startClient(setting);

View File

@@ -722,7 +722,10 @@ Utils::CommandLine StdIOSettings::command() const
BaseClientInterface *StdIOSettings::createInterface() const
{
return new StdIOClientInterface(m_executable, arguments());
auto interface = new StdIOClientInterface;
interface->setExecutable(m_executable);
interface->setArguments(arguments());
return interface;
}
class JsonTreeItemDelegate : public QStyledItemDelegate

View File

@@ -62,7 +62,7 @@ void OutputParserTester::testParsing(const QString &lines,
{
const auto terminator = new TestTerminator(this);
if (!lineParsers().isEmpty())
terminator->setRedirectionDetector(lineParsers().last());
terminator->setRedirectionDetector(lineParsers().constLast());
addLineParser(terminator);
reset();
@@ -113,7 +113,7 @@ TestTerminator::TestTerminator(OutputParserTester *t) :
m_tester(t)
{
if (!t->lineParsers().isEmpty()) {
for (const Utils::FilePath &searchDir : t->lineParsers().first()->searchDirectories())
for (const Utils::FilePath &searchDir : t->lineParsers().constFirst()->searchDirectories())
addSearchDir(searchDir);
}
}

View File

@@ -96,6 +96,18 @@ QHash<int, QByteArray> ItemLibraryCategoriesModel::roleNames() const
return m_roleNames;
}
void ItemLibraryCategoriesModel::expandCategories(bool expand)
{
int i = 0;
for (const auto &category : std::as_const(m_categoryList)) {
if (category->categoryExpanded() != expand) {
category->setExpanded(expand);
emit dataChanged(index(i), index(i), {m_roleNames.key("categoryExpanded")});
}
++i;
}
}
void ItemLibraryCategoriesModel::addCategory(ItemLibraryCategory *category)
{
m_categoryList.append(category);

View File

@@ -48,6 +48,7 @@ public:
QHash<int, QByteArray> roleNames() const override;
void addCategory(ItemLibraryCategory *category);
void expandCategories(bool expand = true);
const QList<QPointer<ItemLibraryCategory>> &categorySections() const;

View File

@@ -78,6 +78,10 @@ bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *
hasVisibleItems = true;
}
// expand category if it has an item matching search criteria
if (hasVisibleItems && !categoryExpanded())
setExpanded(true);
return hasVisibleItems;
}

View File

@@ -80,25 +80,28 @@ QObject *ItemLibraryImport::categoryModel()
return &m_categoryModel;
}
void ItemLibraryImport::expandCategories(bool expand)
{
m_categoryModel.expandCategories(expand);
}
bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool *changed)
{
bool hasVisibleItems = false;
bool hasVisibleCategories = false;
*changed = false;
for (const auto &category : m_categoryModel.categorySections()) {
bool categoryChanged = false;
hasVisibleItems = category->updateItemVisibility(searchText, &categoryChanged);
bool hasVisibleItems = category->updateItemVisibility(searchText, &categoryChanged);
categoryChanged |= category->setVisible(hasVisibleItems);
*changed |= categoryChanged;
*changed |= hasVisibleItems;
if (hasVisibleItems)
hasVisibleCategories = true;
}
if (*changed)
m_categoryModel.resetModel();
return hasVisibleItems;
return hasVisibleCategories;
}
Import ItemLibraryImport::importEntry() const

View File

@@ -63,6 +63,7 @@ public:
void setImportUsed(bool importUsed);
void sortCategorySections();
void setImportExpanded(bool expanded = true);
void expandCategories(bool expand = true);
static QString userComponentsTitle();

View File

@@ -61,34 +61,28 @@ bool ItemLibraryModel::loadExpandedState(const QString &sectionName)
void ItemLibraryModel::expandAll()
{
bool changed = false;
int i = 0;
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
if (import->hasCategories() && !import->importExpanded()) {
changed = true;
if (!import->importExpanded()) {
import->setImportExpanded();
emit dataChanged(index(i), index(i), {m_roleNames.key("importExpanded")});
saveExpandedState(true, import->importUrl());
}
}
if (changed) {
beginResetModel();
endResetModel();
import->expandCategories(true);
++i;
}
}
void ItemLibraryModel::collapseAll()
{
bool changed = false;
int i = 0;
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
if (import->hasCategories() && import->importExpanded()) {
changed = true;
import->setImportExpanded(false);
emit dataChanged(index(i), index(i), {m_roleNames.key("importExpanded")});
saveExpandedState(false, import->importUrl());
}
}
if (changed) {
beginResetModel();
endResetModel();
++i;
}
}
@@ -329,9 +323,18 @@ void ItemLibraryModel::updateVisibility(bool *changed)
{
for (ItemLibraryImport *import : std::as_const(m_importList)) {
bool categoryChanged = false;
import->updateCategoryVisibility(m_searchText, &categoryChanged);
bool hasVisibleItems = import->updateCategoryVisibility(m_searchText, &categoryChanged);
*changed |= categoryChanged;
// expand import if it has an item matching search criteria
if (hasVisibleItems && !import->importExpanded())
import->setImportExpanded();
}
if (changed) {
beginResetModel();
endResetModel();
}
}

View File

@@ -275,6 +275,7 @@ void ItemLibraryWidget::handleAddImport(int index)
m_model->changeImports({import}, {});
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
m_stackedWidget->setCurrentIndex(0); // switch to the Components view after import is added
updateSearch();
}
void ItemLibraryWidget::delayedUpdateModel()

View File

@@ -134,7 +134,7 @@ public:
}
}
void storeIcon(Utils::SmallStringView name, Sqlite::TimeStamp newTimeStamp, const QIcon &icon)
void storeIcon(Utils::SmallStringView name, Sqlite::TimeStamp newTimeStamp, const QIcon &icon) override
{
try {
Sqlite::ImmediateTransaction transaction{database};

View File

@@ -337,7 +337,9 @@ void SubComponentManager::registerQmlFile(const QFileInfo &fileInfo, const QStri
ItemLibraryEntry itemLibraryEntry;
itemLibraryEntry.setType(componentName.toUtf8());
itemLibraryEntry.setName(baseComponentName);
#ifndef QMLDESIGNER_TEST
itemLibraryEntry.setCategory(ItemLibraryImport::userComponentsTitle());
#endif
itemLibraryEntry.setCustomComponentSource(fileInfo.absoluteFilePath());
if (!qualifier.isEmpty()) {
itemLibraryEntry.setRequiredImport(fixedQualifier);

View File

@@ -12,6 +12,17 @@ function foo(a, b) {
var foo = function (a, b) {}
function spread() {
iterableObj = [1, 2]
obj = {
"a": 42
}
foo(...iterableObj)
let arr = [...iterableObj, '4', 'five', 6]
foo(-1, ...args, 2, ...[3])
console.log(Math.max(...[1, 2, 3, 4]))
}
const func1 = x => x * 2
const func2 = x => {
return x * 7