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

Change-Id: I4ea98cc1c14808afe44030a057f9ff289a57ccfe
This commit is contained in:
Eike Ziller
2020-10-06 10:05:47 +02:00
31 changed files with 760 additions and 163 deletions

View File

@@ -27,6 +27,7 @@ add_subdirectory(resourceeditor)
add_subdirectory(tasklist)
add_subdirectory(nim)
add_subdirectory(incredibuild)
add_subdirectory(conan)
# Level 4: (only depends on Level 3 and below)
add_subdirectory(clangpchmanager)

View File

@@ -57,36 +57,34 @@ namespace Internal {
* It is possible for the user to specify custom arguments.
*/
class AutogenStep : public AbstractProcessStep
class AutogenStep final : public AbstractProcessStep
{
Q_DECLARE_TR_FUNCTIONS(AutotoolsProjectManager::Internal::AutogenStep)
public:
AutogenStep(BuildStepList *bsl, Utils::Id id);
AutogenStep(BuildStepList *bsl, Id id);
private:
void doRun() override;
void doRun() final;
StringAspect *m_additionalArgumentsAspect = nullptr;
bool m_runAutogen = false;
};
AutogenStep::AutogenStep(BuildStepList *bsl, Utils::Id id) : AbstractProcessStep(bsl, id)
AutogenStep::AutogenStep(BuildStepList *bsl, Id id) : AbstractProcessStep(bsl, id)
{
m_additionalArgumentsAspect = addAspect<StringAspect>();
m_additionalArgumentsAspect->setSettingsKey(
"AutotoolsProjectManager.AutogenStep.AdditionalArguments");
m_additionalArgumentsAspect->setLabelText(tr("Arguments:"));
m_additionalArgumentsAspect->setDisplayStyle(StringAspect::LineEditDisplay);
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.AutogenStepArgs");
auto arguments = addAspect<StringAspect>();
arguments->setSettingsKey("AutotoolsProjectManager.AutogenStep.AdditionalArguments");
arguments->setLabelText(tr("Arguments:"));
arguments->setDisplayStyle(StringAspect::LineEditDisplay);
arguments->setHistoryCompleter("AutotoolsPM.History.AutogenStepArgs");
connect(m_additionalArgumentsAspect, &BaseAspect::changed, this, [this] {
connect(arguments, &BaseAspect::changed, this, [this] {
m_runAutogen = true;
});
setCommandLineProvider([this] {
setCommandLineProvider([arguments] {
return CommandLine(FilePath::fromString("./autogen.sh"),
m_additionalArgumentsAspect->value(),
arguments->value(),
CommandLine::Raw);
});

View File

@@ -55,38 +55,37 @@ namespace Internal {
* It is possible for the user to specify custom arguments.
*/
class AutoreconfStep : public AbstractProcessStep
class AutoreconfStep final : public AbstractProcessStep
{
Q_DECLARE_TR_FUNCTIONS(AutotoolsProjectManager::Internal::AutoreconfStep)
public:
AutoreconfStep(BuildStepList *bsl, Utils::Id id);
AutoreconfStep(BuildStepList *bsl, Id id);
void doRun() override;
private:
StringAspect *m_additionalArgumentsAspect = nullptr;
bool m_runAutoreconf = false;
};
AutoreconfStep::AutoreconfStep(BuildStepList *bsl, Utils::Id id)
AutoreconfStep::AutoreconfStep(BuildStepList *bsl, Id id)
: AbstractProcessStep(bsl, id)
{
m_additionalArgumentsAspect = addAspect<StringAspect>();
m_additionalArgumentsAspect->setSettingsKey("AutotoolsProjectManager.AutoreconfStep.AdditionalArguments");
m_additionalArgumentsAspect->setLabelText(tr("Arguments:"));
m_additionalArgumentsAspect->setValue("--force --install");
m_additionalArgumentsAspect->setDisplayStyle(StringAspect::LineEditDisplay);
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.AutoreconfStepArgs");
auto arguments = addAspect<StringAspect>();
arguments->setSettingsKey("AutotoolsProjectManager.AutoreconfStep.AdditionalArguments");
arguments->setLabelText(tr("Arguments:"));
arguments->setValue("--force --install");
arguments->setDisplayStyle(StringAspect::LineEditDisplay);
arguments->setHistoryCompleter("AutotoolsPM.History.AutoreconfStepArgs");
connect(m_additionalArgumentsAspect, &BaseAspect::changed, this, [this] {
connect(arguments, &BaseAspect::changed, this, [this] {
m_runAutoreconf = true;
});
setCommandLineProvider([this] {
return Utils::CommandLine(Utils::FilePath::fromString("autoreconf"),
m_additionalArgumentsAspect->value(),
Utils::CommandLine::Raw);
setCommandLineProvider([arguments] {
return CommandLine(FilePath::fromString("autoreconf"),
arguments->value(),
CommandLine::Raw);
});
setWorkingDirectoryProvider([this] { return project()->projectDirectory(); });
@@ -107,7 +106,7 @@ void AutoreconfStep::doRun()
m_runAutoreconf = true;
if (!m_runAutoreconf) {
emit addOutput(tr("Configuration unchanged, skipping autoreconf step."), BuildStep::OutputFormat::NormalMessage);
emit addOutput(tr("Configuration unchanged, skipping autoreconf step."), OutputFormat::NormalMessage);
emit finished(true);
return;
}

View File

@@ -74,43 +74,41 @@ static QString projectDirRelativeToBuildDir(BuildConfiguration *bc)
// * represented by an instance of the class MakeStepConfigWidget.
// */
class ConfigureStep : public ProjectExplorer::AbstractProcessStep
class ConfigureStep final : public AbstractProcessStep
{
Q_DECLARE_TR_FUNCTIONS(AutotoolsProjectManager::Internal::ConfigureStep)
public:
ConfigureStep(BuildStepList *bsl, Utils::Id id);
ConfigureStep(BuildStepList *bsl, Id id);
void setAdditionalArguments(const QString &list);
private:
void doRun() override;
void doRun() final;
StringAspect *m_additionalArgumentsAspect = nullptr;
bool m_runConfigure = false;
};
ConfigureStep::ConfigureStep(BuildStepList *bsl, Utils::Id id)
ConfigureStep::ConfigureStep(BuildStepList *bsl, Id id)
: AbstractProcessStep(bsl, id)
{
m_additionalArgumentsAspect = addAspect<StringAspect>();
m_additionalArgumentsAspect->setDisplayStyle(StringAspect::LineEditDisplay);
m_additionalArgumentsAspect->setSettingsKey(
"AutotoolsProjectManager.ConfigureStep.AdditionalArguments");
m_additionalArgumentsAspect->setLabelText(tr("Arguments:"));
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.ConfigureArgs");
auto arguments = addAspect<StringAspect>();
arguments->setDisplayStyle(StringAspect::LineEditDisplay);
arguments->setSettingsKey("AutotoolsProjectManager.ConfigureStep.AdditionalArguments");
arguments->setLabelText(tr("Arguments:"));
arguments->setHistoryCompleter("AutotoolsPM.History.ConfigureArgs");
connect(m_additionalArgumentsAspect, &BaseAspect::changed, this, [this] {
connect(arguments, &BaseAspect::changed, this, [this] {
m_runConfigure = true;
});
setWorkingDirectoryProvider([this] { return project()->projectDirectory(); });
setCommandLineProvider([this] {
setCommandLineProvider([this, arguments] {
BuildConfiguration *bc = buildConfiguration();
return CommandLine({FilePath::fromString(projectDirRelativeToBuildDir(bc) + "configure"),
m_additionalArgumentsAspect->value(),
arguments->value(),
CommandLine::Raw});
});
@@ -135,7 +133,7 @@ void ConfigureStep::doRun()
}
if (!m_runConfigure) {
emit addOutput(tr("Configuration unchanged, skipping configure step."), BuildStep::OutputFormat::NormalMessage);
emit addOutput(tr("Configuration unchanged, skipping configure step."), OutputFormat::NormalMessage);
emit finished(true);
return;
}

View File

@@ -0,0 +1,6 @@
add_qtc_plugin(Conan
PLUGIN_DEPENDS Core ProjectExplorer
SOURCES
conaninstallstep.cpp conaninstallstep.h
conanplugin.cpp conanplugin.h
)

View File

@@ -0,0 +1,20 @@
{
\"Name\" : \"Conan\",
\"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
\"Vendor\" : \"Jochen Seemann\",
\"Copyright\" : \"(C) 2018 Jochen Seemann, (C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
\"License\" : [ \"Commercial Usage\",
\"\",
\"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company.\",
\"\",
\"GNU General Public License Usage\",
\"\",
\"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\"
],
\"Category\" : \"Utilities\",
\"Experimental\" : true,
\"Description\" : \"Conan integration.\",
\"Url\" : \"http://www.qt.io\",
$$dependencyList
}

View File

@@ -0,0 +1,8 @@
include(../../qtcreatorplugin.pri)
SOURCES += \
conaninstallstep.cpp \
conanplugin.cpp
HEADERS += \
conaninstallstep.h \
conanplugin.h

View File

@@ -0,0 +1,19 @@
import qbs 1.0
QtcPlugin {
name: "Conan"
Depends { name: "Qt.widgets" }
Depends { name: "Utils" }
Depends { name: "Core" }
Depends { name: "ProjectExplorer" }
files: [
"conanplugin.h",
"conanplugin.cpp",
"conaninstallstep.h",
"conaninstallstep.cpp"
]
}

View File

@@ -0,0 +1,6 @@
QTC_PLUGIN_NAME = Conan
QTC_LIB_DEPENDS += \
utils
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer

View File

@@ -0,0 +1,131 @@
/****************************************************************************
**
** Copyright (C) 2018 Jochen Seemann
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "conaninstallstep.h"
#include <projectexplorer/abstractprocessstep.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/processparameters.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/task.h>
#include <projectexplorer/toolchain.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace ConanPackageManager {
namespace Internal {
// ConanInstallStep
class ConanInstallStep final : public AbstractProcessStep
{
Q_DECLARE_TR_FUNCTIONS(ConanPackageManager::Internal::ConanInstallStep)
public:
ConanInstallStep(BuildStepList *bsl, Id id);
private:
bool init() final;
void setupOutputFormatter(OutputFormatter *formatter) final;
};
ConanInstallStep::ConanInstallStep(BuildStepList *bsl, Id id)
: AbstractProcessStep(bsl, id)
{
setUseEnglishOutput();
setDisplayName(ConanInstallStep::tr("Conan install"));
auto conanFile = addAspect<StringAspect>();
conanFile->setSettingsKey("ConanPackageManager.InstallStep.ConanFile");
conanFile->setFilePath(project()->projectDirectory() / "conanfile.txt");
conanFile->setLabelText(tr("Conan file:"));
conanFile->setToolTip(tr("Enter location of conanfile.txt or conanfile.py"));
conanFile->setDisplayStyle(StringAspect::PathChooserDisplay);
conanFile->setExpectedKind(PathChooser::File);
auto additionalArguments = addAspect<StringAspect>();
additionalArguments->setSettingsKey("ConanPackageManager.InstallStep.AdditionalArguments");
additionalArguments->setLabelText(tr("Additional arguments:"));
additionalArguments->setDisplayStyle(StringAspect::LineEditDisplay);
setCommandLineProvider([this, conanFile, additionalArguments] {
BuildConfiguration::BuildType bt = buildConfiguration()->buildType();
const QString buildType = bt == BuildConfiguration::Release ? QString("Release")
: QString("Debug");
CommandLine cmd("conan");
cmd.addArgs({"install", "-s", "build_type=" + buildType, conanFile->value()});
cmd.addArgs(additionalArguments->value(), CommandLine::Raw);
return cmd;
});
setSummaryUpdater([this]() -> QString {
QList<ToolChain *> tcList = ToolChainKitAspect::toolChains(target()->kit());
if (tcList.isEmpty())
return "<b>" + ToolChainKitAspect::msgNoToolChainInTarget() + "</b>";
ProcessParameters param;
setupProcessParameters(&param);
return param.summary(displayName());
});
}
bool ConanInstallStep::init()
{
if (!AbstractProcessStep::init())
return false;
const QList<ToolChain *> tcList = ToolChainKitAspect::toolChains(target()->kit());
if (tcList.isEmpty()) {
emit addTask(Task::compilerMissingTask());
emitFaultyConfigurationMessage();
return false;
}
return true;
}
void ConanInstallStep::setupOutputFormatter(OutputFormatter *formatter)
{
formatter->addLineParser(new GnuMakeParser());
formatter->addLineParsers(kit()->createOutputParsers());
formatter->addSearchDir(processParameters()->effectiveWorkingDirectory());
AbstractProcessStep::setupOutputFormatter(formatter);
}
// ConanInstallStepFactory
ConanInstallStepFactory::ConanInstallStepFactory()
{
registerStep<ConanInstallStep>("ConanPackageManager.InstallStep");
setDisplayName(ConanInstallStep::tr("Run conan install"));
}
} // Internal
} // ConanPackageManager

View File

@@ -0,0 +1,40 @@
/****************************************************************************
**
** Copyright (C) 2018 Jochen Seemann
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/buildstep.h>
namespace ConanPackageManager {
namespace Internal {
class ConanInstallStepFactory final : public ProjectExplorer::BuildStepFactory
{
public:
ConanInstallStepFactory();
};
} // namespace Internal
} // namespace ConanPackageManager

View File

@@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2018 Jochen Seemann
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "conanplugin.h"
#include "conaninstallstep.h"
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/buildmanager.h>
namespace ConanPackageManager {
namespace Internal {
class ConanPluginRunData
{
public:
ConanInstallStepFactory installStepFactory;
};
ConanPlugin::~ConanPlugin()
{
delete m_runData;
}
void ConanPlugin::extensionsInitialized()
{ }
bool ConanPlugin::initialize(const QStringList &arguments, QString *errorString)
{
Q_UNUSED(arguments)
Q_UNUSED(errorString)
m_runData = new ConanPluginRunData;
return true;
}
} // namespace Internal
} // namespace ConanPackageManager

View File

@@ -0,0 +1,49 @@
/****************************************************************************
**
** Copyright (C) 2018 Jochen Seemann
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <extensionsystem/iplugin.h>
namespace ConanPackageManager {
namespace Internal {
class ConanPluginRunData;
class ConanPlugin final : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Conan.json")
~ConanPlugin() final;
void extensionsInitialized() final;
bool initialize(const QStringList &arguments, QString *errorString) final;
ConanPluginRunData *m_runData = nullptr;
};
} // namespace Internal
} // namespace ConanPackageManager

View File

@@ -89,104 +89,111 @@ void GdbMi::parseResultOrValue(const QChar *&from, const QChar *to)
}
}
// Reads one \ooo entity.
static bool parseOctalEscapedHelper(const QChar *&from, const QChar *to, QByteArray &buffer)
{
if (to - from < 4)
return false;
if (*from != '\\')
return false;
const char c1 = from[1].unicode();
const char c2 = from[2].unicode();
const char c3 = from[3].unicode();
if (!isdigit(c1) || !isdigit(c2) || !isdigit(c3))
return false;
buffer += char((c1 - '0') * 64 + (c2 - '0') * 8 + (c3 - '0'));
from += 4;
return true;
}
static bool parseHexEscapedHelper(const QChar *&from, const QChar *to, QByteArray &buffer)
{
if (to - from < 4)
return false;
if (from[0]!= '\\')
return false;
if (from[1] != 'x')
return false;
const char c1 = from[2].unicode();
const char c2 = from[3].unicode();
if (!isxdigit(c1) || !isxdigit(c2))
return false;
buffer += char(16 * fromhex(c1) + fromhex(c2));
from += 4;
return true;
}
static void parseSimpleEscape(const QChar *&from, const QChar *to, QString &result)
{
if (from == to) {
qDebug() << "MI Parse Error, unterminated backslash escape";
return;
}
QChar c = *from++;
switch (c.unicode()) {
case 'a': result += '\a'; break;
case 'b': result += '\b'; break;
case 'f': result += '\f'; break;
case 'n': result += '\n'; break;
case 'r': result += '\r'; break;
case 't': result += '\t'; break;
case 'v': result += '\v'; break;
case '"': result += '"'; break;
case '\'': result += '\''; break;
case '\\': result += '\\'; break;
default:
qDebug() << "MI Parse Error, unrecognized backslash escape";
}
}
// Reads subsequent \123 or \x12 entities and converts to Utf8,
// *or* one escaped char, *or* one unescaped char.
static void parseCharOrEscape(const QChar *&from, const QChar *to, QString &result)
{
QByteArray buffer;
while (parseOctalEscapedHelper(from, to, buffer))
;
while (parseHexEscapedHelper(from, to, buffer))
;
if (!buffer.isEmpty())
result.append(QString::fromUtf8(buffer));
else if (*from == '\\')
parseSimpleEscape(++from, to, result);
else
result += *from++;
}
QString GdbMi::parseCString(const QChar *&from, const QChar *to)
{
QString result;
if (to == from)
return QString();
//qDebug() << "parseCString: " << QString(from, to - from);
if (*from != '"') {
qDebug() << "MI Parse Error, double quote expected";
++from; // So we don't hang
return QString();
}
const QChar *ptr = from;
++ptr;
while (ptr < to) {
if (*ptr == '"') {
++ptr;
result = QString(from + 1, ptr - from - 2);
break;
}
if (*ptr == '\\') {
++ptr;
if (ptr == to) {
qDebug() << "MI Parse Error, unterminated backslash escape";
from = ptr; // So we don't hang
return QString();
}
}
++ptr;
}
from = ptr;
int idx = result.indexOf('\\');
if (idx >= 0) {
QChar *dst = result.data() + idx;
const QChar *src = dst + 1, *end = result.data() + result.length();
do {
QChar c = *src++;
switch (c.unicode()) {
case 'a': *dst++ = '\a'; break;
case 'b': *dst++ = '\b'; break;
case 'f': *dst++ = '\f'; break;
case 'n': *dst++ = '\n'; break;
case 'r': *dst++ = '\r'; break;
case 't': *dst++ = '\t'; break;
case 'v': *dst++ = '\v'; break;
case '"': *dst++ = '"'; break;
case '\\': *dst++ = '\\'; break;
case 'x': {
c = *src++;
int chars = 0;
uchar prod = 0;
while (true) {
uchar val = fromhex(c.unicode());
if (val == UCHAR_MAX)
break;
prod = prod * 16 + val;
if (++chars == 3 || src == end)
break;
c = *src++;
}
if (!chars) {
qDebug() << "MI Parse Error, unrecognized hex escape";
return QString();
}
*dst++ = prod;
break;
}
default:
{
int chars = 0;
uchar prod = 0;
forever {
if (c < '0' || c > '7') {
--src;
break;
}
prod = prod * 8 + c.unicode() - '0';
if (++chars == 3 || src == end)
break;
c = *src++;
}
if (!chars) {
qDebug() << "MI Parse Error, unrecognized backslash escape";
return QString();
}
*dst++ = prod;
}
}
while (src != end) {
QChar c = *src++;
if (c == '\\')
break;
*dst++ = c;
}
} while (src != end);
*dst = 0;
result.truncate(dst - result.data());
++from; // Skip initial quote.
QString result;
result.reserve(to - from);
while (from < to) {
if (*from == '"') {
++from;
return result;
}
parseCharOrEscape(from, to, result);
}
return result;
qDebug() << "MI Parse Error, unfinished string";
return QString();
}
void GdbMi::parseValue(const QChar *&from, const QChar *to)

View File

@@ -195,7 +195,7 @@ public:
const auto cppDocumentParser = BuiltinEditorDocumentParser::get(cppFile);
QVERIFY(cppDocumentParser);
const Document::Ptr cppDocument = cppDocumentParser->document();
QCOMPARE(cppDocument->editorRevision(), 2);
QVERIFY(cppDocument->editorRevision() >= 2);
QVERIFY(checkDiagsnosticMessages(cppDocument));
const auto hDocumentParser = BuiltinEditorDocumentParser::get(hFile);

View File

@@ -170,13 +170,9 @@ bool IosBuildStep::init()
if (!AbstractProcessStep::init())
return false;
BuildConfiguration *bc = buildConfiguration();
ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit());
if (!tc)
if (!tc) {
emit addTask(Task::compilerMissingTask());
if (!bc || !tc) {
emitFaultyConfigurationMessage();
return false;
}

View File

@@ -66,7 +66,8 @@ SUBDIRS = \
webassembly \
mcusupport \
marketplace \
incredibuild
incredibuild \
conan
qtHaveModule(serialport) {
SUBDIRS += serialterminal

View File

@@ -23,6 +23,7 @@ Project {
"cmakeprojectmanager/cmakeprojectmanager.qbs",
"mesonprojectmanager/mesonprojectmanager.qbs",
"compilationdatabaseprojectmanager/compilationdatabaseprojectmanager.qbs",
"conan/conan.qbs",
"coreplugin/coreplugin.qbs",
"coreplugin/images/logo/logo.qbs",
"cpaster/cpaster.qbs",

View File

@@ -55,18 +55,18 @@ const int PANEL_LEFT_MARGIN = 70;
// PanelsWidget
///
PanelsWidget::PanelsWidget(QWidget *parent) : QWidget(parent)
PanelsWidget::PanelsWidget(QWidget *parent)
: QWidget(parent), m_splitter(new Core::MiniSplitter(this))
{
const auto splitter = new Core::MiniSplitter(this);
m_root = new QWidget(nullptr);
m_root->setFocusPolicy(Qt::NoFocus);
m_root->setContentsMargins(0, 0, 40, 0);
splitter->addWidget(m_root);
splitter->addWidget(new QWidget);
splitter->setStretchFactor(1, 100); // Force root widget to its minimum size initially
m_splitter->addWidget(m_root);
m_splitter->addWidget(new QWidget);
m_splitter->setStretchFactor(1, 100); // Force root widget to its minimum size initially
const auto scroller = new QScrollArea(this);
scroller->setWidget(splitter);
scroller->setWidget(m_splitter);
scroller->setFrameStyle(QFrame::NoFrame);
scroller->setWidgetResizable(true);
scroller->setFocusPolicy(Qt::NoFocus);
@@ -153,4 +153,14 @@ void PanelsWidget::addPropertiesPanel(const QString &displayName, const QIcon &i
m_layout->addWidget(widget, widgetRow, 0, 1, 2);
}
QByteArray PanelsWidget::saveSplitterState() const
{
return m_splitter->saveState().toHex();
}
void PanelsWidget::loadSplitterState(const QByteArray &state)
{
m_splitter->restoreState(QByteArray::fromHex(state));
}
} // ProjectExplorer

View File

@@ -34,6 +34,8 @@ class QGridLayout;
class QIcon;
QT_END_NAMESPACE
namespace Core { class MiniSplitter; }
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT PanelsWidget : public QWidget
@@ -49,8 +51,12 @@ public:
void addPropertiesPanel(const QString &displayName, const QIcon &icon,
QWidget *widget);
QByteArray saveSplitterState() const;
void loadSplitterState(const QByteArray &state);
private:
QGridLayout *m_layout;
Core::MiniSplitter * const m_splitter;
QWidget *m_root;
};

View File

@@ -613,13 +613,32 @@ public:
QWidget *panel() const
{
if (!m_panel) {
m_panel = (m_subIndex == RunPage)
? new PanelsWidget(RunSettingsWidget::tr("Run Settings"),
QIcon(":/projectexplorer/images/RunSettings.png"),
new RunSettingsWidget(target()))
: new PanelsWidget(QCoreApplication::translate("BuildSettingsPanel", "Build Settings"),
QIcon(":/projectexplorer/images/BuildSettings.png"),
new BuildSettingsWidget(target()));
QString splitterStateKey = "PanelSplitterState:"
+ m_project->projectFilePath().toString() + ':';
if (m_subIndex == RunPage) {
splitterStateKey += "Run";
m_panel = new PanelsWidget(RunSettingsWidget::tr("Run Settings"),
QIcon(":/projectexplorer/images/RunSettings.png"),
new RunSettingsWidget(target()));
} else {
splitterStateKey += "Build";
m_panel = new PanelsWidget(QCoreApplication::translate("BuildSettingsPanel", "Build Settings"),
QIcon(":/projectexplorer/images/BuildSettings.png"),
new BuildSettingsWidget(target()));
}
const auto panel = qobject_cast<PanelsWidget *>(m_panel.data());
const auto loadSplitterValue = [panel, splitterStateKey] {
const QByteArray splitterState = SessionManager::value(splitterStateKey).toByteArray();
if (!splitterState.isEmpty())
panel->loadSplitterState(splitterState);
};
loadSplitterValue();
QObject::connect(SessionManager::instance(), &SessionManager::aboutToSaveSession,
panel, [panel, splitterStateKey] {
SessionManager::setValue(splitterStateKey, panel->saveSplitterState());
});
QObject::connect(SessionManager::instance(), &SessionManager::sessionLoaded,
panel, loadSplitterValue);
}
return m_panel;
}

View File

@@ -163,6 +163,8 @@ enum { NExtraSelectionKinds = 12 };
using TransformationMethod = QString(const QString &);
using ListTransformationMethod = void(QStringList &);
static constexpr char dropProperty[] = "dropProp";
class LineColumnLabel : public FixedSizeClickLabel
{
Q_OBJECT
@@ -714,7 +716,7 @@ public:
// block selection mode
bool m_inBlockSelectionMode = false;
QString copyBlockSelection();
void insertIntoBlockSelection(const QString &text = QString());
void insertIntoBlockSelection(const QString &text = QString(), const bool selectText = false);
void setCursorToColumn(QTextCursor &cursor, int column,
QTextCursor::MoveMode moveMode = QTextCursor::MoveAnchor);
void removeBlockSelection();
@@ -3802,7 +3804,7 @@ void TextEditorWidgetPrivate::setCursorToColumn(QTextCursor &cursor, int column,
cursor.block().text(), column), moveMode);
}
void TextEditorWidgetPrivate::insertIntoBlockSelection(const QString &text)
void TextEditorWidgetPrivate::insertIntoBlockSelection(const QString &text, const bool selectText)
{
// TODO: add autocompleter support
QTextCursor cursor = q->textCursor();
@@ -3828,6 +3830,7 @@ void TextEditorWidgetPrivate::insertIntoBlockSelection(const QString &text)
int positionBlock = m_blockSelection.positionBlock;
int anchorBlock = m_blockSelection.anchorBlock;
int column = m_blockSelection.positionColumn;
const int anchorColumn = m_blockSelection.anchorColumn;
const QTextBlock &firstBlock =
m_document->document()->findBlockByNumber(m_blockSelection.firstBlockNumber());
@@ -3880,7 +3883,10 @@ void TextEditorWidgetPrivate::insertIntoBlockSelection(const QString &text)
cursor.endEditBlock();
column += textLength;
m_blockSelection.fromPostition(positionBlock, column, anchorBlock, column);
m_blockSelection.fromPostition(positionBlock,
column,
anchorBlock,
selectText ? anchorColumn : column);
q->doSetTextCursor(m_blockSelection.selection(m_document.data()), true);
}
@@ -7722,8 +7728,9 @@ void TextEditorWidget::insertFromMimeData(const QMimeData *source)
if (d->m_codeAssistant.hasContext())
d->m_codeAssistant.destroyContext();
const bool selectInsertedText = source->property(dropProperty).toBool();
if (d->m_inBlockSelectionMode) {
d->insertIntoBlockSelection(text);
d->insertIntoBlockSelection(text, selectInsertedText);
return;
}
@@ -7738,7 +7745,16 @@ void TextEditorWidget::insertFromMimeData(const QMimeData *source)
QTextCursor cursor = textCursor();
if (!tps.m_autoIndent) {
cursor.beginEditBlock();
cursor.insertText(text);
if (selectInsertedText) {
const int anchor = cursor.position();
cursor.insertText(text);
const int pos = cursor.position();
cursor.endEditBlock();
cursor.setPosition(anchor);
cursor.setPosition(pos, QTextCursor::KeepAnchor);
} else {
cursor.insertText(text);
}
cursor.endEditBlock();
setTextCursor(cursor);
return;
@@ -7768,6 +7784,9 @@ void TextEditorWidget::insertFromMimeData(const QMimeData *source)
int cursorPosition = cursor.position();
cursor.insertText(text);
const QTextCursor endCursor = cursor;
QTextCursor startCursor = endCursor;
startCursor.setPosition(cursorPosition);
int reindentBlockEnd = cursor.blockNumber() - (hasFinalNewline?1:0);
@@ -7788,9 +7807,33 @@ void TextEditorWidget::insertFromMimeData(const QMimeData *source)
}
cursor.endEditBlock();
if (selectInsertedText) {
cursor.setPosition(startCursor.position());
cursor.setPosition(endCursor.position(), QTextCursor::KeepAnchor);
}
setTextCursor(cursor);
}
void TextEditorWidget::dropEvent(QDropEvent *e)
{
const QMimeData *mime = e->mimeData();
if (mime && (mime->hasText() || mime->hasHtml())) {
QMimeData *mimeOverwrite = duplicateMimeData(mime);
mimeOverwrite->setProperty(dropProperty, true);
auto dropOverwrite = new QDropEvent(e->pos(),
e->possibleActions(),
mimeOverwrite,
e->mouseButtons(),
e->keyboardModifiers());
QPlainTextEdit::dropEvent(dropOverwrite);
e->setAccepted(dropOverwrite->isAccepted());
delete dropOverwrite;
delete mimeOverwrite;
} else {
QPlainTextEdit::dropEvent(e);
}
}
QMimeData *TextEditorWidget::duplicateMimeData(const QMimeData *source)
{
Q_ASSERT(source);

View File

@@ -530,6 +530,7 @@ protected:
QMimeData *createMimeDataFromSelection() const override;
bool canInsertFromMimeData(const QMimeData *source) const override;
void insertFromMimeData(const QMimeData *source) override;
void dropEvent(QDropEvent *e) override;
virtual QString plainTextFromSelection(const QTextCursor &cursor) const;
static QString convertToPlainText(const QString &txt);