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

Change-Id: I3f2a6c553819e992da7e9f538dc44b95b482359e
This commit is contained in:
Eike Ziller
2020-10-02 10:47:07 +02:00
95 changed files with 1825 additions and 698 deletions

View File

@@ -144,6 +144,7 @@ void BoostTestOutputReader::handleMessageMatch(const QRegularExpressionMatch &ma
if (m_currentTest.isEmpty() || m_logLevel > LogLevel::UnitScope)
m_currentTest = caseFromContent(content);
m_result = ResultType::MessageFatal;
++m_summary[ResultType::MessageFatal];
m_description = content;
} else if (content.startsWith("last checkpoint:")) {
if (m_currentTest.isEmpty() || m_logLevel > LogLevel::UnitScope)
@@ -355,8 +356,9 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
sendCompleteInformation();
BoostTestResult *result = new BoostTestResult(id(), m_projectFile, QString());
int failed = match.captured(1).toInt();
int fatals = m_summary.value(ResultType::MessageFatal);
QString txt = tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3));
int passed = (m_testCaseCount != -1) ? m_testCaseCount - failed : -1;
int passed = qMax(0, m_testCaseCount - failed);
if (m_testCaseCount != -1)
txt.append(' ').append(tr("%1 tests passed.").arg(passed));
result->setDescription(txt);
@@ -364,7 +366,7 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
reportResult(TestResultPtr(result));
if (m_reportLevel == ReportLevel::Confirm) { // for the final summary
m_summary[ResultType::Pass] += passed;
m_summary[ResultType::Fail] += failed;
m_summary[ResultType::Fail] += failed - fatals;
}
m_testCaseCount = -1;
return;

View File

@@ -400,6 +400,7 @@ QSet<QString> QuickTestTreeItem::internalTargets() const
void QuickTestTreeItem::markForRemovalRecursively(const QString &filePath)
{
TestTreeItem::markForRemovalRecursively(filePath);
auto parser = dynamic_cast<QuickTestParser *>(framework()->testParser());
const QString proFile = parser->projectFileForMainCppFile(filePath);
if (!proFile.isEmpty()) {

View File

@@ -395,13 +395,10 @@ int TestResultModel::resultTypeCount(ResultType type) const
{
int result = 0;
for (const auto &resultsForId : m_testResultCount.values())
result += resultsForId.value(type, 0);
for (const auto &id : m_reportedSummary.keys()) {
if (int counted = m_testResultCount.value(id).value(type))
result -= counted;
result += m_reportedSummary[id].value(type);
// if we got a result count from the framework prefer that over our counted results
int reported = m_reportedSummary[id].value(type);
result += reported != 0 ? reported : m_testResultCount.value(id).value(type);
}
return result;
}

View File

@@ -218,6 +218,12 @@ QString BeautifierPlugin::msgFormatAtCursor()
return tr("&Format at Cursor");
}
QString BeautifierPlugin::msgFormatLines()
{
//: Menu entry
return tr("Format &Line(s)");
}
QString BeautifierPlugin::msgDisableFormattingSelectedText()
{
//: Menu entry

View File

@@ -41,6 +41,7 @@ public:
static QString msgFormatCurrentFile();
static QString msgFormatSelectedText();
static QString msgFormatAtCursor();
static QString msgFormatLines();
static QString msgDisableFormattingSelectedText();
static QString msgCommandPromptDialogTitle(const QString &command);
static void showError(const QString &error);

View File

@@ -65,6 +65,11 @@ ClangFormat::ClangFormat()
menu->addAction(cmd);
connect(m_formatFile, &QAction::triggered, this, &ClangFormat::formatFile);
m_formatLines = new QAction(BeautifierPlugin::msgFormatLines(), this);
cmd = Core::ActionManager::registerAction(m_formatLines, "ClangFormat.FormatLines");
menu->addAction(cmd);
connect(m_formatLines, &QAction::triggered, this, &ClangFormat::formatLines);
m_formatRange = new QAction(BeautifierPlugin::msgFormatAtCursor(), this);
cmd = Core::ActionManager::registerAction(m_formatRange, "ClangFormat.FormatAtCursor");
menu->addAction(cmd);
@@ -123,6 +128,31 @@ void ClangFormat::formatAtCursor()
}
}
void ClangFormat::formatLines()
{
const TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget();
if (!widget)
return;
const QTextCursor tc = widget->textCursor();
// Current line by default
int lineStart = tc.blockNumber() + 1;
int lineEnd = lineStart;
// Note that clang-format will extend the range to the next bigger
// syntactic construct if needed.
if (tc.hasSelection()) {
const QTextBlock start = tc.document()->findBlock(tc.selectionStart());
const QTextBlock end = tc.document()->findBlock(tc.selectionEnd());
lineStart = start.blockNumber() + 1;
lineEnd = end.blockNumber() + 1;
}
auto cmd = command();
cmd.addOption(QString("-lines=%1:%2").arg(QString::number(lineStart)).arg(QString::number(lineEnd)));
formatCurrentFile(cmd);
}
void ClangFormat::disableFormattingSelectedText()
{
TextEditorWidget *widget = TextEditorWidget::currentTextEditorWidget();

View File

@@ -48,10 +48,12 @@ public:
private:
void formatFile();
void formatAtCursor();
void formatLines();
void disableFormattingSelectedText();
TextEditor::Command command(int offset, int length) const;
QAction *m_formatFile = nullptr;
QAction *m_formatLines = nullptr;
QAction *m_formatRange = nullptr;
QAction *m_disableFormattingSelectedText = nullptr;
ClangFormatSettings m_settings;

View File

@@ -624,7 +624,7 @@ void Internal::CorePlugin::testOutputFormatter()
{
const QString input =
"B to be handled by B\r\n"
"not to be handled\n"
"not to be handled\n\n\n\n"
"A to be handled by A\n"
"continuation for A\r\n"
"B looks like B, but still continuation for A\r\n"
@@ -636,7 +636,7 @@ void Internal::CorePlugin::testOutputFormatter()
"B to be handled by B\n";
const QString output =
"handled by B\n"
"not to be handled\n"
"not to be handled\n\n\n\n"
"handled by A\n"
"handled by A\n"
"handled by A\n"

View File

@@ -357,7 +357,8 @@ void Project::setNeedsInitialExpansion(bool needsExpansion)
}
void Project::setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths,
const DocGenerator docGenerator)
const DocGenerator &docGenerator,
const DocUpdater &docUpdater)
{
QSet<Utils::FilePath> uniqueNewFiles = projectDocumentPaths;
uniqueNewFiles.remove(projectFilePath()); // Make sure to never add the main project file!
@@ -371,6 +372,10 @@ void Project::setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentP
Utils::erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<Core::IDocument> &d) {
return toRemove.contains(d->filePath());
});
if (docUpdater) {
for (const auto &doc : qAsConst(d->m_extraProjectDocuments))
docUpdater(doc.get());
}
for (const Utils::FilePath &p : toAdd) {
if (docGenerator) {
std::unique_ptr<Core::IDocument> doc = docGenerator(p);
@@ -779,6 +784,7 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
kit->makeReplacementKit();
kit->setup();
}, id);
QTC_ASSERT(k, return);
TaskHub::addTask(BuildSystemTask(Task::Warning, tr("Project \"%1\" was configured for "
"kit \"%2\" with id %3, which does not exist anymore. The new kit \"%4\" was "
"created in its place, in an attempt not to lose custom project settings.")

View File

@@ -165,8 +165,10 @@ public:
// Set project files that will be watched and by default trigger the same callback
// as the main project file.
using DocGenerator = std::function<std::unique_ptr<Core::IDocument>(const Utils::FilePath &)>;
using DocUpdater = std::function<void(Core::IDocument *)>;
void setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths,
const DocGenerator docGenerator = {});
const DocGenerator &docGenerator = {},
const DocUpdater &docUpdater = {});
void setDisplayName(const QString &name);
void setProjectLanguage(Utils::Id id, bool enabled);

View File

@@ -126,6 +126,8 @@ public:
return true;
}
void setPriFile(QmakePriFile *priFile) { m_priFile = priFile; }
private:
QmakePriFile *m_priFile;
};
@@ -301,15 +303,24 @@ void QmakeBuildSystem::updateDocuments()
projectDocuments.insert(n->filePath());
});
project()->setExtraProjectFiles(projectDocuments, [p = project()](const FilePath &fp)
-> std::unique_ptr<Core::IDocument> {
const auto priFileForPath = [p = project()](const FilePath &fp) -> QmakePriFile * {
const Node * const n = p->nodeForFilePath(fp, [](const Node *n) {
return dynamic_cast<const QmakePriFileNode *>(n); });
QTC_ASSERT(n, return std::make_unique<Core::IDocument>());
QmakePriFile * const priFile = static_cast<const QmakePriFileNode *>(n)->priFile();
QTC_ASSERT(n, return nullptr);
return static_cast<const QmakePriFileNode *>(n)->priFile();
};
const auto docGenerator = [&](const FilePath &fp)
-> std::unique_ptr<Core::IDocument> {
QmakePriFile * const priFile = priFileForPath(fp);
QTC_ASSERT(priFile, return std::make_unique<Core::IDocument>());
return std::make_unique<QmakePriFileDocument>(priFile, fp);
});
};
const auto docUpdater = [&](Core::IDocument *doc) {
QmakePriFile * const priFile = priFileForPath(doc->filePath());
QTC_ASSERT(priFile, return);
static_cast<QmakePriFileDocument *>(doc)->setPriFile(priFile);
};
project()->setExtraProjectFiles(projectDocuments, docGenerator, docUpdater);
}
void QmakeBuildSystem::updateCppCodeModel()

View File

@@ -195,5 +195,9 @@
<description><![CDATA[Building your first application for the NXP IMXRT1050 device.]]></description>
<tags>qtformcus,mcus,qt,video,NXP IMXRT1050-EVKB,2020</tags>
</tutorial>
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Creating dynamic UIs for a 'Qt for MCUs' application using Qt Design Studio and Photoshop" isVideo="true" videoUrl="https://youtu.be/USrLl6tRc00" videoLength="1:00:19">
<description><![CDATA[A step-by-step walkthrough showcasing how to create dynamic UIs using Qt Design Studio and Photoshop on MCUs.]]></description>
<tags>qtformcus,mcus,qt,video,2020</tags>
</tutorial>
</tutorials>
</instructionals>

View File

@@ -32,6 +32,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/settingsdatabase.h>
#include <coreplugin/shellcommand.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/infobar.h>
#include <utils/synchronousprocess.h>
@@ -159,18 +160,24 @@ void UpdateInfoPlugin::collectCheckForUpdatesOutput(const QString &contents)
d->m_collectedOutput += contents;
}
static QStringList availableUpdates(const QDomDocument &document)
struct Update
{
QString name;
QString version;
};
static QList<Update> availableUpdates(const QDomDocument &document)
{
if (document.isNull() || !document.firstChildElement().hasChildNodes())
return {};
QStringList result;
QList<Update> result;
const QDomNodeList updates = document.firstChildElement().elementsByTagName("update");
for (int i = 0; i < updates.size(); ++i) {
const QDomNode node = updates.item(i);
if (node.isElement()) {
const QDomElement element = node.toElement();
if (element.hasAttribute("name"))
result.append(element.attribute("name"));
result.append({element.attribute("name"), element.attribute("version")});
}
}
return result;
@@ -197,9 +204,14 @@ void UpdateInfoPlugin::checkForUpdatesFinished()
Core::ICore::infoBar()->removeInfo(InstallUpdates);
startUpdater();
});
const QStringList updates = availableUpdates(document);
const QList<Update> updates = availableUpdates(document);
info.setDetailsWidgetCreator([updates]() -> QWidget * {
const QString updateText = updates.join("</li><li>");
const QString updateText = Utils::transform(updates, [](const Update &u) {
return u.version.isEmpty()
? u.name
: tr("%1 (%2)", "Package name and version")
.arg(u.name, u.version);
}).join("</li><li>");
auto label = new QLabel;
label->setText("<qt><p>" + tr("Available updates:") + "<ul><li>" + updateText
+ "</li></ul></p></qt>");

View File

@@ -138,7 +138,6 @@ WebAssemblyToolChain::WebAssemblyToolChain() :
const CompilerConfiguration configuration = compilerConfiguration();
const QString command = configuration.llvmRoot.toString()
+ Utils::HostOsInfo::withExecutableSuffix("/clang");
setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
setCompilerCommand(Utils::FilePath::fromString(command));
setSupportedAbis({toolChainAbi()});
setTargetAbi(toolChainAbi());