forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/9.0' into qds/dev" into qds/dev
This commit is contained in:
@@ -488,7 +488,7 @@ void AndroidDeployQtStep::gatherFilesToPull()
|
||||
|
||||
void AndroidDeployQtStep::doRun()
|
||||
{
|
||||
runInThread([this] { return runImpl(); });
|
||||
m_synchronizer.addFuture(runInThread([this] { return runImpl(); }));
|
||||
}
|
||||
|
||||
void AndroidDeployQtStep::runCommand(const CommandLine &command)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <utils/commandline.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/futuresynchronizer.h>
|
||||
|
||||
namespace Utils { class QtcProcess; }
|
||||
|
||||
@@ -91,6 +92,8 @@ private:
|
||||
Utils::FilePath m_workingDirectory;
|
||||
Utils::Environment m_environment;
|
||||
AndroidDeviceInfo m_deviceInfo;
|
||||
|
||||
Utils::FutureSynchronizer m_synchronizer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ void AndroidDeviceManager::setupWifiForDevice(const IDevice::Ptr &device, QWidge
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, parent, [adbSelector, &parent]() {
|
||||
QTimer::singleShot(2000, parent, [adbSelector, parent]() {
|
||||
// Get device IP address
|
||||
QStringList args = adbSelector;
|
||||
args.append({"shell", "ip", "route"});
|
||||
|
||||
@@ -18,6 +18,9 @@ namespace CatchXml {
|
||||
const char TestCaseElement[] = "TestCase";
|
||||
const char SectionElement[] = "Section";
|
||||
const char ExceptionElement[] = "Exception";
|
||||
const char InfoElement[] = "Info";
|
||||
const char WarningElement[] = "Warning";
|
||||
const char FailureElement[] = "Failure";
|
||||
const char ExpressionElement[] = "Expression";
|
||||
const char ExpandedElement[] = "Expanded";
|
||||
const char BenchmarkResults[] = "BenchmarkResults";
|
||||
@@ -102,6 +105,13 @@ void CatchOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
|
||||
m_currentResult = m_shouldFail ? ResultType::UnexpectedPass : ResultType::Pass;
|
||||
else
|
||||
m_currentResult = m_mayFail || m_shouldFail ? ResultType::ExpectedFail : ResultType::Fail;
|
||||
} else if (m_currentTagName == CatchXml::WarningElement) {
|
||||
m_currentResult = ResultType::MessageWarn;
|
||||
} else if (m_currentTagName == CatchXml::InfoElement) {
|
||||
m_currentResult = ResultType::MessageInfo;
|
||||
} else if (m_currentTagName == CatchXml::FailureElement) {
|
||||
m_currentResult = ResultType::Fail;
|
||||
recordTestInformation(m_xmlReader.attributes());
|
||||
} else if (m_currentTagName == CatchXml::BenchmarkResults) {
|
||||
recordBenchmarkInformation(m_xmlReader.attributes());
|
||||
m_currentResult = ResultType::Benchmark;
|
||||
@@ -121,7 +131,10 @@ void CatchOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
|
||||
const auto text = m_xmlReader.text();
|
||||
if (m_currentTagName == CatchXml::ExpandedElement) {
|
||||
m_currentExpression.append(text);
|
||||
} else if (m_currentTagName == CatchXml::ExceptionElement) {
|
||||
} else if (m_currentTagName == CatchXml::ExceptionElement
|
||||
|| m_currentTagName == CatchXml::InfoElement
|
||||
|| m_currentTagName == CatchXml::WarningElement
|
||||
|| m_currentTagName == CatchXml::FailureElement) {
|
||||
m_currentExpression.append('\n').append(text.trimmed());
|
||||
}
|
||||
break;
|
||||
@@ -138,10 +151,15 @@ void CatchOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
|
||||
} else if (currentTag == QLatin1String(CatchXml::GroupElement)) {
|
||||
testOutputNodeFinished(GroupNode);
|
||||
} else if (currentTag == QLatin1String(CatchXml::ExpressionElement)
|
||||
|| currentTag == QLatin1String(CatchXml::FailureElement)
|
||||
|| currentTag == QLatin1String(CatchXml::BenchmarkResults)) {
|
||||
sendResult(m_currentResult);
|
||||
m_currentExpression.clear();
|
||||
m_testCaseInfo.pop();
|
||||
} else if (currentTag == QLatin1String(CatchXml::WarningElement)
|
||||
|| currentTag == QLatin1String(CatchXml::InfoElement)) {
|
||||
sendResult(m_currentResult);
|
||||
m_currentExpression.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -255,6 +273,8 @@ void CatchOutputReader::sendResult(const ResultType result)
|
||||
.arg(catchResult->description()));
|
||||
} else if (result == ResultType::Benchmark || result == ResultType::MessageFatal) {
|
||||
catchResult->setDescription(m_currentExpression);
|
||||
} else if (result == ResultType::MessageWarn || result == ResultType::MessageInfo) {
|
||||
catchResult->setDescription(m_currentExpression.trimmed());
|
||||
}
|
||||
|
||||
reportResult(catchResult);
|
||||
|
||||
@@ -417,6 +417,7 @@ IAssistProposal *CustomAssistProcessor::perform(const AssistInterface *interface
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete interface;
|
||||
GenericProposalModelPtr model(new GenericProposalModel);
|
||||
model->loadContent(completions);
|
||||
const auto proposal = new GenericProposal(m_position, model);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <languageclient/languageclientsymbolsupport.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
#include <languageserverprotocol/jsonrpcmessages.h>
|
||||
#include <texteditor/codeassist/assistinterface.h>
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
#include <texteditor/codeassist/iassistprovider.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
@@ -41,8 +42,9 @@ public:
|
||||
void resetData(bool resetFollowSymbolData);
|
||||
|
||||
private:
|
||||
IAssistProposal *perform(const AssistInterface *) override
|
||||
IAssistProposal *perform(const AssistInterface *interface) override
|
||||
{
|
||||
delete interface;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,9 +164,15 @@ void doSemanticHighlighting(
|
||||
const Position endPos = startPos.withOffset(token.length, &doc);
|
||||
return Range(startPos, endPos);
|
||||
};
|
||||
const auto isOutputParameter = [&ast, &tokenRange](const ExpandedSemanticToken &token) {
|
||||
const int clangdMajorVersion = clangdVersion.majorVersion();
|
||||
const auto isOutputParameter = [&ast, &tokenRange, clangdMajorVersion]
|
||||
(const ExpandedSemanticToken &token) {
|
||||
if (token.modifiers.contains(QLatin1String("usedAsMutableReference")))
|
||||
return true;
|
||||
if (token.modifiers.contains(QLatin1String("usedAsMutablePointer")))
|
||||
return true;
|
||||
if (clangdMajorVersion >= 16)
|
||||
return false;
|
||||
if (token.type != "variable" && token.type != "property" && token.type != "parameter")
|
||||
return false;
|
||||
const Range range = tokenRange(token);
|
||||
@@ -260,7 +266,7 @@ void doSemanticHighlighting(
|
||||
};
|
||||
|
||||
const std::function<HighlightingResult(const ExpandedSemanticToken &)> toResult
|
||||
= [&ast, &isOutputParameter, &tokenRange, ver = clangdVersion.majorVersion()]
|
||||
= [&ast, &isOutputParameter, &tokenRange, clangdMajorVersion]
|
||||
(const ExpandedSemanticToken &token) {
|
||||
TextStyles styles;
|
||||
if (token.type == "variable") {
|
||||
@@ -277,7 +283,7 @@ void doSemanticHighlighting(
|
||||
? C_VIRTUAL_METHOD : C_FUNCTION;
|
||||
if (token.modifiers.contains("definition")) {
|
||||
styles.mixinStyles.push_back(C_FUNCTION_DEFINITION);
|
||||
} else if (ver < 16 && ast.isValid()) {
|
||||
} else if (clangdMajorVersion < 16 && ast.isValid()) {
|
||||
const ClangdAstPath path = getAstPath(ast, tokenRange(token));
|
||||
if (path.length() > 1) {
|
||||
const ClangdAstNode declNode = path.at(path.length() - 2);
|
||||
@@ -291,7 +297,7 @@ void doSemanticHighlighting(
|
||||
styles.mainStyle = C_TYPE;
|
||||
if (token.modifiers.contains("constructorOrDestructor")) {
|
||||
styles.mainStyle = C_FUNCTION;
|
||||
} else if (ver < 16 && ast.isValid()) {
|
||||
} else if (clangdMajorVersion < 16 && ast.isValid()) {
|
||||
const ClangdAstPath path = getAstPath(ast, tokenRange(token));
|
||||
if (!path.isEmpty()) {
|
||||
if (path.last().kind() == "CXXConstructor") {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMetaObject>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include <optional>
|
||||
@@ -68,6 +69,7 @@ ClangdSwitchDeclDef::ClangdSwitchDeclDef(ClangdClient *client, TextDocument *doc
|
||||
[this](const DocumentUri &uri, const DocumentSymbolsResult &symbols) {
|
||||
if (uri != d->uri)
|
||||
return;
|
||||
d->client->documentSymbolCache()->disconnect(this);
|
||||
d->docSymbols = symbols;
|
||||
if (d->ast)
|
||||
d->handleDeclDefSwitchReplies();
|
||||
@@ -108,7 +110,7 @@ void ClangdSwitchDeclDef::emitDone()
|
||||
return;
|
||||
|
||||
d->done = true;
|
||||
emit done();
|
||||
QMetaObject::invokeMethod(this, &ClangdSwitchDeclDef::done, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
std::optional<ClangdAstNode> ClangdSwitchDeclDef::Private::getFunctionNode() const
|
||||
|
||||
@@ -1012,12 +1012,6 @@ void ClangdTestHighlighting::test_data()
|
||||
<< QList<int>{C_LOCAL} << 0;
|
||||
QTest::newRow("const pointer argument") << 491 << 26 << 491 << 27
|
||||
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const reference via member function call as output argument (object)")
|
||||
<< 580 << 29 << 580 << 30
|
||||
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const reference via member function call as output argument (function)")
|
||||
<< 580 << 31 << 580 << 37
|
||||
<< QList<int>{C_FUNCTION, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("value argument") << 501 << 57 << 501 << 58
|
||||
<< QList<int>{C_LOCAL} << 0;
|
||||
QTest::newRow("non-const ref argument as second arg") << 501 << 61 << 501 << 62
|
||||
@@ -1026,8 +1020,6 @@ void ClangdTestHighlighting::test_data()
|
||||
<< QList<int>{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const pointer argument expression") << 513 << 30 << 513 << 31
|
||||
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const ref argument from qualified member (object)") << 525 << 31 << 525 << 39
|
||||
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const ref argument from qualified member (member)") << 525 << 40 << 525 << 46
|
||||
<< QList<int>{C_FIELD, C_OUTPUT_ARGUMENT} << 0;
|
||||
QTest::newRow("non-const ref argument to constructor") << 540 << 47 << 540 << 55
|
||||
@@ -1394,14 +1386,6 @@ void ClangdTestHighlighting::test()
|
||||
actualStyles << s;
|
||||
}
|
||||
|
||||
QEXPECT_FAIL("non-const reference via member function call as output argument (object)",
|
||||
"See below", Continue);
|
||||
QEXPECT_FAIL("non-const reference via member function call as output argument (function)",
|
||||
"Without punctuation and comment tokens from clangd, it's not possible "
|
||||
"to highlight entire expressions. But do we really want this? What about nested "
|
||||
"calls where the inner arguments are const?",
|
||||
Continue);
|
||||
|
||||
QCOMPARE(actualStyles, expectedStyles);
|
||||
QCOMPARE(result.kind, expectedKind);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,11 @@ void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style,
|
||||
|
||||
// This is a separate pass, don't do it unless it's the full formatting.
|
||||
style.FixNamespaceComments = false;
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
style.AlignTrailingComments = {clang::format::FormatStyle::TCAS_Never, 0};
|
||||
#else
|
||||
style.AlignTrailingComments = false;
|
||||
#endif
|
||||
|
||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
||||
return;
|
||||
|
||||
@@ -49,7 +49,11 @@ clang::format::FormatStyle qtcStyle()
|
||||
#else
|
||||
style.AlignOperands = true;
|
||||
#endif
|
||||
#if LLVM_VERSION_MAJOR >= 16
|
||||
style.AlignTrailingComments = {FormatStyle::TCAS_Always, 0};
|
||||
#else
|
||||
style.AlignTrailingComments = true;
|
||||
#endif
|
||||
style.AllowAllParametersOfDeclarationOnNextLine = true;
|
||||
#if LLVM_VERSION_MAJOR >= 10
|
||||
style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
|
||||
|
||||
@@ -88,6 +88,7 @@ const char DEVELOPMENT_TEAM_FLAG[] = "Ios:DevelopmentTeam:Flag";
|
||||
const char PROVISIONING_PROFILE_FLAG[] = "Ios:ProvisioningProfile:Flag";
|
||||
const char CMAKE_OSX_ARCHITECTURES_FLAG[] = "CMAKE_OSX_ARCHITECTURES:DefaultFlag";
|
||||
const char QT_QML_DEBUG_FLAG[] = "Qt:QML_DEBUG_FLAG";
|
||||
const char QT_QML_DEBUG_PARAM[] = "-DQT_QML_DEBUG";
|
||||
const char CMAKE_QT6_TOOLCHAIN_FILE_ARG[]
|
||||
= "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=%{Qt:QT_INSTALL_PREFIX}/lib/cmake/Qt6/qt.toolchain.cmake";
|
||||
const char CMAKE_BUILD_TYPE[] = "CMake.Build.Type";
|
||||
@@ -876,7 +877,7 @@ CMakeConfig CMakeBuildSettingsWidget::getQmlDebugCxxFlags()
|
||||
"CMAKE_CXX_FLAGS_RELWITHDEBINFO",
|
||||
"CMAKE_CXX_FLAGS_INIT"};
|
||||
const QByteArrayList cxxFlags{"CMAKE_CXX_FLAGS_INIT", "CMAKE_CXX_FLAGS"};
|
||||
const QByteArray qmlDebug("-DQT_QML_DEBUG");
|
||||
const QByteArray qmlDebug(QT_QML_DEBUG_PARAM);
|
||||
|
||||
CMakeConfig changedConfig;
|
||||
|
||||
@@ -1446,8 +1447,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
||||
[this] {
|
||||
if (aspect<QtSupport::QmlDebuggingAspect>()->value()
|
||||
== TriState::Enabled) {
|
||||
return QLatin1String(
|
||||
"-DQT_QML_DEBUG");
|
||||
return QLatin1String(QT_QML_DEBUG_PARAM);
|
||||
}
|
||||
return QLatin1String();
|
||||
});
|
||||
@@ -1665,7 +1665,7 @@ bool CMakeBuildConfiguration::hasQmlDebugging(const CMakeConfig &config)
|
||||
// such that in doubt we leave the QML Debugging setting at "Leave at default"
|
||||
const QString cxxFlagsInit = config.stringValueOf("CMAKE_CXX_FLAGS_INIT");
|
||||
const QString cxxFlags = config.stringValueOf("CMAKE_CXX_FLAGS");
|
||||
return cxxFlagsInit.contains("-DQT_QML_DEBUG") && cxxFlags.contains("-DQT_QML_DEBUG");
|
||||
return cxxFlagsInit.contains(QT_QML_DEBUG_PARAM) && cxxFlags.contains(QT_QML_DEBUG_PARAM);
|
||||
}
|
||||
|
||||
void CMakeBuildConfiguration::buildTarget(const QString &buildTarget)
|
||||
|
||||
@@ -1186,8 +1186,8 @@ void CMakeBuildSystem::updateQmlJSCodeModel(const QStringList &extraHeaderPaths,
|
||||
return;
|
||||
|
||||
Project *p = project();
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager
|
||||
->defaultProjectInfoForProject(p);
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(p, p->files(Project::HiddenRccFolders));
|
||||
|
||||
projectInfo.importPaths.clear();
|
||||
|
||||
|
||||
@@ -739,7 +739,8 @@ bool EditorManagerPrivate::skipOpeningBigTextFile(const FilePath &filePath)
|
||||
if (!filePath.exists())
|
||||
return false;
|
||||
|
||||
const MimeType mimeType = Utils::mimeTypeForFile(filePath);
|
||||
const MimeType mimeType = Utils::mimeTypeForFile(filePath,
|
||||
MimeMatchMode::MatchDefaultAndRemote);
|
||||
if (!mimeType.inherits("text/plain"))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -166,7 +166,8 @@ const EditorTypeList EditorType::defaultEditorTypes(const MimeType &mimeType)
|
||||
const EditorTypeList EditorType::preferredEditorTypes(const FilePath &filePath)
|
||||
{
|
||||
// default factories by mime type
|
||||
const Utils::MimeType mimeType = Utils::mimeTypeForFile(filePath);
|
||||
const Utils::MimeType mimeType = Utils::mimeTypeForFile(filePath,
|
||||
MimeMatchMode::MatchDefaultAndRemote);
|
||||
EditorTypeList factories = defaultEditorTypes(mimeType);
|
||||
// user preferred factory to front
|
||||
EditorType *userPreferred = Internal::userPreferredEditorTypes().value(mimeType);
|
||||
|
||||
@@ -175,7 +175,9 @@ QList<IWizardFactory*> IWizardFactory::allWizardFactories()
|
||||
QHash<Id, IWizardFactory *> sanityCheck;
|
||||
for (const FactoryCreator &fc : std::as_const(s_factoryCreators)) {
|
||||
IWizardFactory *newFactory = fc();
|
||||
QTC_ASSERT(newFactory, continue);
|
||||
// skip factories referencing wizard page generators provided by plugins not loaded
|
||||
if (!newFactory)
|
||||
continue;
|
||||
IWizardFactory *existingFactory = sanityCheck.value(newFactory->id());
|
||||
|
||||
QTC_ASSERT(existingFactory != newFactory, continue);
|
||||
|
||||
@@ -949,7 +949,8 @@ void MainWindow::openFile()
|
||||
static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fileFactories,
|
||||
const FilePath &filePath)
|
||||
{
|
||||
const QString typeName = Utils::mimeTypeForFile(filePath).name();
|
||||
const QString typeName = Utils::mimeTypeForFile(filePath, MimeMatchMode::MatchDefaultAndRemote)
|
||||
.name();
|
||||
return Utils::findOrDefault(fileFactories, [typeName](IDocumentFactory *f) {
|
||||
return f->mimeTypes().contains(typeName);
|
||||
});
|
||||
|
||||
@@ -112,7 +112,7 @@ void GdbMi::parseResultOrValue(DebuggerOutputParser &parser)
|
||||
}
|
||||
|
||||
// Reads one \ooo entity.
|
||||
static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QByteArray &buffer)
|
||||
static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QString &buffer)
|
||||
{
|
||||
if (parser.remainingChars() < 4)
|
||||
return false;
|
||||
@@ -130,7 +130,7 @@ static bool parseOctalEscapedHelper(DebuggerOutputParser &parser, QByteArray &bu
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QByteArray &buffer)
|
||||
static bool parseHexEscapedHelper(DebuggerOutputParser &parser, QString &buffer)
|
||||
{
|
||||
if (parser.remainingChars() < 4)
|
||||
return false;
|
||||
@@ -178,15 +178,16 @@ static void parseSimpleEscape(DebuggerOutputParser &parser, QString &result)
|
||||
// *or* one escaped char, *or* one unescaped char.
|
||||
static void parseCharOrEscape(DebuggerOutputParser &parser, QString &result)
|
||||
{
|
||||
QByteArray buffer;
|
||||
while (parseOctalEscapedHelper(parser, buffer))
|
||||
const int oldSize = result.size();
|
||||
while (parseOctalEscapedHelper(parser, result))
|
||||
;
|
||||
while (parseHexEscapedHelper(parser, buffer))
|
||||
while (parseHexEscapedHelper(parser, result))
|
||||
;
|
||||
|
||||
if (!buffer.isEmpty()) {
|
||||
result.append(QString::fromUtf8(buffer));
|
||||
} else if (parser.isCurrent('\\')) {
|
||||
if (result.size() != oldSize)
|
||||
return;
|
||||
|
||||
if (parser.isCurrent('\\')) {
|
||||
parser.advance();
|
||||
parseSimpleEscape(parser, result);
|
||||
} else {
|
||||
@@ -254,7 +255,6 @@ void GdbMi::parseTuple_helper(DebuggerOutputParser &parser)
|
||||
{
|
||||
parser.skipCommas();
|
||||
//qDebug() << "parseTuple_helper: " << parser.buffer();
|
||||
QString buf = parser.buffer();
|
||||
m_type = Tuple;
|
||||
while (!parser.isAtEnd()) {
|
||||
if (parser.isCurrent('}')) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
#include <QToolTip>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWheelEvent>
|
||||
|
||||
@@ -100,6 +101,11 @@ LiteHtmlHelpViewer::LiteHtmlHelpViewer(QWidget *parent)
|
||||
&QLiteHtmlWidget::contextMenuRequested,
|
||||
this,
|
||||
&LiteHtmlHelpViewer::showContextMenu);
|
||||
connect(m_viewer, &QLiteHtmlWidget::linkHighlighted, this, [this](const QUrl &url) {
|
||||
m_highlightedLink = url;
|
||||
if (!url.isValid())
|
||||
QToolTip::hideText();
|
||||
});
|
||||
auto layout = new QVBoxLayout;
|
||||
setLayout(layout);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -284,6 +290,12 @@ bool LiteHtmlHelpViewer::eventFilter(QObject *src, QEvent *e)
|
||||
goForward(1);
|
||||
return true;
|
||||
}
|
||||
} else if (e->type() == QEvent::ToolTip) {
|
||||
auto he = static_cast<QHelpEvent *>(e);
|
||||
if (m_highlightedLink.isValid())
|
||||
QToolTip::showText(he->globalPos(),
|
||||
m_highlightedLink.toDisplayString(),
|
||||
m_viewer->viewport());
|
||||
}
|
||||
return HelpViewer::eventFilter(src, e);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "helpviewer.h"
|
||||
#include "openpagesmanager.h"
|
||||
|
||||
#include <qlitehtmlwidget.h>
|
||||
|
||||
#include <QTextBrowser>
|
||||
#include <QUrl>
|
||||
|
||||
#include <optional>
|
||||
|
||||
@@ -68,6 +68,7 @@ private:
|
||||
QLiteHtmlWidget *m_viewer;
|
||||
std::vector<HistoryItem> m_backItems;
|
||||
std::vector<HistoryItem> m_forwardItems;
|
||||
QUrl m_highlightedLink;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -293,7 +293,8 @@ LanguageClientCompletionAssistProcessor::~LanguageClientCompletionAssistProcesso
|
||||
|
||||
QTextDocument *LanguageClientCompletionAssistProcessor::document() const
|
||||
{
|
||||
return m_document;
|
||||
QTC_ASSERT(m_assistInterface, return nullptr);
|
||||
return m_assistInterface->textDocument();
|
||||
}
|
||||
|
||||
QList<AssistProposalItemInterface *> LanguageClientCompletionAssistProcessor::generateCompletionItems(
|
||||
@@ -315,6 +316,7 @@ static QString assistReasonString(AssistReason reason)
|
||||
|
||||
IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistInterface *interface)
|
||||
{
|
||||
m_assistInterface.reset(interface);
|
||||
QTC_ASSERT(m_client, return nullptr);
|
||||
m_pos = interface->position();
|
||||
m_basePos = m_pos;
|
||||
@@ -366,7 +368,6 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn
|
||||
m_client->sendMessage(completionRequest);
|
||||
m_client->addAssistProcessor(this);
|
||||
m_currentRequest = completionRequest.id();
|
||||
m_document = interface->textDocument();
|
||||
m_filePath = interface->filePath();
|
||||
qCDebug(LOGLSPCOMPLETION) << QTime::currentTime()
|
||||
<< " : request completions at " << m_pos
|
||||
@@ -425,7 +426,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
|
||||
model->loadContent(proposalItems);
|
||||
LanguageClientCompletionProposal *proposal = new LanguageClientCompletionProposal(m_basePos,
|
||||
model);
|
||||
proposal->m_document = m_document;
|
||||
proposal->m_document = m_assistInterface->textDocument();
|
||||
proposal->m_pos = m_pos;
|
||||
proposal->setSupportsPrefix(false);
|
||||
setAsyncProposalAvailable(proposal);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
@@ -74,7 +75,7 @@ protected:
|
||||
private:
|
||||
void handleCompletionResponse(const LanguageServerProtocol::CompletionRequest::Response &response);
|
||||
|
||||
QPointer<QTextDocument> m_document;
|
||||
QScopedPointer<const TextEditor::AssistInterface> m_assistInterface;
|
||||
Utils::FilePath m_filePath;
|
||||
QPointer<Client> m_client;
|
||||
std::optional<LanguageServerProtocol::MessageId> m_currentRequest;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace LanguageServerProtocol;
|
||||
|
||||
@@ -66,6 +68,7 @@ FunctionHintProcessor::FunctionHintProcessor(Client *client)
|
||||
|
||||
IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface)
|
||||
{
|
||||
const QScopedPointer<const AssistInterface> deleter(interface);
|
||||
QTC_ASSERT(m_client, return nullptr);
|
||||
m_pos = interface->position();
|
||||
QTextCursor cursor(interface->textDocument());
|
||||
|
||||
@@ -196,12 +196,22 @@ public:
|
||||
EnvironmentItems changes;
|
||||
QStringList pathAdditions; // clazy:exclude=inefficient-qlist-soft
|
||||
|
||||
// The Desktop version depends on the Qt shared libs in Qul_DIR/bin.
|
||||
// If CMake's fileApi is avaialble, we can rely on the "Add library search path to PATH"
|
||||
// feature of the run configuration. Otherwise, we just prepend the path, here.
|
||||
if (mcuTarget->toolChainPackage()->isDesktopToolchain()
|
||||
&& !CMakeProjectManager::CMakeToolManager::defaultCMakeTool()->hasFileApi())
|
||||
pathAdditions.append((qtForMCUsSdkPackage->path() / "bin").toUserOutput());
|
||||
// The Desktop version depends on the Qt shared libs.
|
||||
// As CMake's fileApi is available, we can rely on the "Add library search path to PATH"
|
||||
// feature of the run configuration.
|
||||
//
|
||||
// Since MinGW support is added from Qul 2.3.0,
|
||||
// the Qt shared libs for Windows desktop platform have been moved
|
||||
// from Qul_DIR/bin to Qul_DIR/lib/(msvc|gnu)
|
||||
// and the QPA plugin has been moved to the same location.
|
||||
// So Windows host requires to add the path in this case.
|
||||
if (mcuTarget->toolChainPackage()->isDesktopToolchain() && HostOsInfo::isWindowsHost()
|
||||
&& !McuSupportOptions::isLegacyVersion(mcuTarget->qulVersion())) {
|
||||
const FilePath libPath = (qtForMCUsSdkPackage->path() / "lib"
|
||||
/ mcuTarget->desktopCompilerId());
|
||||
pathAdditions.append(libPath.toUserOutput());
|
||||
changes.append({"QT_QPA_PLATFORM_PLUGIN_PATH", libPath.toUserOutput()});
|
||||
}
|
||||
|
||||
auto processPackage = [&pathAdditions](const McuPackagePtr &package) {
|
||||
if (package->isAddToSystemPath())
|
||||
@@ -261,6 +271,12 @@ public:
|
||||
true);
|
||||
}
|
||||
|
||||
if (!McuSupportOptions::isLegacyVersion(mcuTarget->qulVersion())
|
||||
&& HostOsInfo::isWindowsHost()) {
|
||||
// From 2.3.0, QUL_COMPILER_NAME needs to be set on Windows
|
||||
// to select proper cmake files depending on the toolchain for Windows.
|
||||
configMap.insert("QUL_COMPILER_NAME", mcuTarget->desktopCompilerId().toLatin1());
|
||||
}
|
||||
} else {
|
||||
const FilePath cMakeToolchainFile = mcuTarget->toolChainFilePackage()->path();
|
||||
|
||||
@@ -287,7 +303,7 @@ public:
|
||||
false);
|
||||
}
|
||||
|
||||
configMap.insert("QUL_PLATFORM", mcuTarget->platform().name.toUtf8());
|
||||
configMap.insert("QUL_PLATFORM", mcuTarget->platform().name.toLower().toUtf8());
|
||||
|
||||
if (mcuTarget->colorDepth() != McuTarget::UnspecifiedColorDepth)
|
||||
configMap.insert("QUL_COLOR_DEPTH", QString::number(mcuTarget->colorDepth()).toLatin1());
|
||||
@@ -593,6 +609,11 @@ void updatePathsInExistingKits(const SettingsHandler::Ptr &settingsHandler)
|
||||
for (const auto &target : std::as_const(repo.mcuTargets)) {
|
||||
if (target->isValid()) {
|
||||
for (auto *kit : kitsWithMismatchedDependencies(target.get())) {
|
||||
if (kitQulVersion(kit) != target->qulVersion()) {
|
||||
//Do not update kits made for other Qt for MCUs SDK versions
|
||||
continue;
|
||||
}
|
||||
|
||||
auto changes = cMakeConfigToMap(CMakeConfigurationKitAspect::configuration(kit));
|
||||
|
||||
const auto updateForPackage = [&changes](const McuPackagePtr &package) {
|
||||
|
||||
@@ -30,23 +30,45 @@ using namespace Utils;
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
static const Utils::FilePath expandWildcards(const Utils::FilePath& path)
|
||||
// Utils::FileFilter do not support globbing with "*" placed in the middle of the path,
|
||||
// since it is required for paths such as "Microsoft Visual Studio/2019/*/VC/Tools/MSVC/*/bin/Hostx64/x64"
|
||||
// The filter is applied for each time a wildcard character is found in a path component.
|
||||
// Returns a pair of the longest path if multiple ones exists and the number of components that were not found.
|
||||
static const std::pair<Utils::FilePath, int> expandWildcards(
|
||||
const FilePath path, const QList<QStringView> patternComponents)
|
||||
{
|
||||
if (!path.fileName().contains("*") && !path.fileName().contains("?"))
|
||||
return path;
|
||||
// Only absolute paths are currently supported
|
||||
// Call FilePath::cleanPath on the path before calling this function
|
||||
if (!path.exists() || path.isRelativePath())
|
||||
return {path, patternComponents.size()};
|
||||
|
||||
const FilePath p = path.parentDir();
|
||||
// All components are found
|
||||
if (patternComponents.empty())
|
||||
return {path, patternComponents.size()};
|
||||
|
||||
auto entries = p.dirEntries(
|
||||
Utils::FileFilter({path.fileName()}, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
|
||||
const QString currentComponent = patternComponents.front().toString();
|
||||
FilePath currentPath = path / currentComponent;
|
||||
|
||||
if (entries.isEmpty())
|
||||
return path;
|
||||
if (!currentComponent.contains("*") && !currentComponent.contains("?") && currentPath.exists())
|
||||
return expandWildcards(path / currentComponent,
|
||||
{patternComponents.constBegin() + 1, patternComponents.constEnd()});
|
||||
|
||||
auto entries = path.dirEntries(
|
||||
Utils::FileFilter({currentComponent}, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
|
||||
|
||||
std::pair<FilePath, int> retPair = {path, patternComponents.size()};
|
||||
|
||||
// Return the last match (can correspond to the latest version)
|
||||
sort(entries, [](const FilePath &a, const FilePath &b) { return a.fileName() < b.fileName(); });
|
||||
for (const auto &entry : entries) {
|
||||
auto [entry_path, remaining_components] = expandWildcards(entry,
|
||||
{patternComponents.constBegin()
|
||||
+ 1,
|
||||
patternComponents.constEnd()});
|
||||
if (remaining_components <= retPair.second)
|
||||
retPair = {entry_path, remaining_components};
|
||||
}
|
||||
|
||||
return entries.last();
|
||||
return retPair;
|
||||
}
|
||||
|
||||
Macros *McuSdkRepository::globalMacros()
|
||||
@@ -60,7 +82,32 @@ void McuSdkRepository::expandVariablesAndWildcards()
|
||||
for (const auto &target : std::as_const(mcuTargets)) {
|
||||
auto macroExpander = getMacroExpander(*target);
|
||||
for (const auto &package : target->packages()) {
|
||||
package->setPath(expandWildcards(macroExpander->expand(package->path())));
|
||||
// Expand variables
|
||||
const auto path = macroExpander->expand(package->path());
|
||||
|
||||
//expand wildcards
|
||||
// Ignore expanding if no wildcards are found
|
||||
if (!path.path().contains("*") && !path.path().contains("?")) {
|
||||
package->setPath(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList pathComponents = path.cleanPath().path().split("/");
|
||||
|
||||
// Path components example on linux: {"", "home", "username"}
|
||||
// Path components example on windows: {"C:", "Users", "username"}
|
||||
// 2 for empty_split_entry(linux)|root(windows) + at least one component
|
||||
if (pathComponents.size() < 2) {
|
||||
package->setPath(path);
|
||||
continue;
|
||||
}
|
||||
// drop empty_split_entry(linux)|root(windows)
|
||||
pathComponents.pop_front();
|
||||
|
||||
package->setPath(
|
||||
expandWildcards(FilePath::fromString(QDir::rootPath()),
|
||||
{pathComponents.constBegin(), pathComponents.constEnd()})
|
||||
.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,15 +362,15 @@ McuPackagePtr createStm32CubeProgrammerPackage(const SettingsHandler::Ptr &setti
|
||||
FilePath defaultPath;
|
||||
const QString cubePath = "STMicroelectronics/STM32Cube/STM32CubeProgrammer";
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
defaultPath = findInProgramFiles(cubePath) / "bin";
|
||||
defaultPath = findInProgramFiles(cubePath);
|
||||
else
|
||||
defaultPath = FileUtils::homePath() / cubePath / "bin";
|
||||
defaultPath = FileUtils::homePath() / cubePath;
|
||||
if (!defaultPath.exists())
|
||||
FilePath defaultPath = {};
|
||||
|
||||
const FilePath detectionPath = FilePath::fromUserInput(
|
||||
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "STM32_Programmer_CLI.exe"
|
||||
: "STM32_Programmer.sh"));
|
||||
QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "bin/STM32_Programmer_CLI.exe"
|
||||
: "bin/STM32_Programmer.sh"));
|
||||
|
||||
return McuPackagePtr{
|
||||
new McuPackage(settingsHandler,
|
||||
|
||||
@@ -61,6 +61,26 @@ bool McuTarget::isValid() const
|
||||
});
|
||||
}
|
||||
|
||||
QString McuTarget::desktopCompilerId() const
|
||||
{
|
||||
// MinGW shares CMake configuration with GCC
|
||||
// and it is distinguished from MSVC by CMake compiler ID.
|
||||
// This provides the compiler ID to set up a different Qul configuration
|
||||
// for MSVC and MinGW.
|
||||
if (m_toolChainPackage) {
|
||||
switch (m_toolChainPackage->toolchainType()) {
|
||||
case McuToolChainPackage::ToolChainType::MSVC:
|
||||
return QLatin1String("msvc");
|
||||
case McuToolChainPackage::ToolChainType::GCC:
|
||||
case McuToolChainPackage::ToolChainType::MinGW:
|
||||
return QLatin1String("gnu");
|
||||
default:
|
||||
return QLatin1String("unsupported");
|
||||
}
|
||||
}
|
||||
return QLatin1String("invalid");
|
||||
}
|
||||
|
||||
void McuTarget::printPackageProblems() const
|
||||
{
|
||||
for (auto package : packages()) {
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
OS os() const;
|
||||
int colorDepth() const;
|
||||
bool isValid() const;
|
||||
QString desktopCompilerId() const;
|
||||
void printPackageProblems() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto iar_stm32f469i_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto iar_stm32f769i_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -20,12 +20,12 @@ constexpr auto iar_stm32h750b_discovery_baremetal_json = R"(
|
||||
"type": "path",
|
||||
"setting": "Stm32CubeProgrammer",
|
||||
"defaultValue": {
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"
|
||||
"windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/",
|
||||
"linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/"
|
||||
},
|
||||
"detectionPath": {
|
||||
"windows": "STM32_Programmer_CLI.exe",
|
||||
"linux": "STM32_Programmer.sh"
|
||||
"windows": "bin/STM32_Programmer_CLI.exe",
|
||||
"linux": "bin/STM32_Programmer.sh"
|
||||
},
|
||||
"optional": false,
|
||||
"addToSystemPath": true
|
||||
|
||||
@@ -141,10 +141,10 @@ const QString xpressoIdeDetectionPath{
|
||||
|
||||
const char stmCubeProgrammerSetting[]{"Stm32CubeProgrammer"};
|
||||
const char stmCubeProgrammerLabel[]{"STM32CubeProgrammer"};
|
||||
const QString stmCubeProgrammerPath{QString{defaultToolPath} + "/bin"};
|
||||
const QString stmCubeProgrammerPath{defaultToolPath};
|
||||
const QString stmCubeProgrammerDetectionPath{HostOsInfo::isWindowsHost()
|
||||
? QString("STM32_Programmer_CLI.exe")
|
||||
: QString("STM32_Programmer.sh")};
|
||||
? QString("bin/STM32_Programmer_CLI.exe")
|
||||
: QString("bin/STM32_Programmer.sh")};
|
||||
|
||||
const char renesasProgrammerSetting[]{"RenesasFlashProgrammer"};
|
||||
const char renesasProgrammerCmakeVar[]{"RENESAS_FLASH_PROGRAMMER_PATH"};
|
||||
@@ -1703,31 +1703,43 @@ void McuSupportTest::test_addToSystemPathFlag()
|
||||
void McuSupportTest::test_processWildcards_data()
|
||||
{
|
||||
QTest::addColumn<QString>("package_label");
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<bool>("isFile");
|
||||
QTest::addColumn<QString>("expected_path");
|
||||
QTest::addColumn<QStringList>("paths");
|
||||
|
||||
QTest::newRow("\"*\" at the end") << "FAKE_WILDCARD_TEST_1"
|
||||
<< "folder-123" << false;
|
||||
QTest::newRow("\"*\" in the middle") << "FAKE_WILDCARD_TEST_2"
|
||||
<< "file-123.exe" << true;
|
||||
QTest::newRow("\"*\" at the start") << "FAKE_WILDCARD_TEST_3"
|
||||
<< "123-file.exe" << true;
|
||||
QTest::newRow("wildcard_at_the_end") << "FAKE_WILDCARD_TEST_1" << "folder-123" << QStringList {"folder-123/" };
|
||||
QTest::newRow("wildcard_in_th_middle") << "FAKE_WILDCARD_TEST_2" << "file-123.exe" << QStringList {"file-123.exe"};
|
||||
QTest::newRow("wildcard_at_the_end") << "FAKE_WILDCARD_TEST_3" << "123-file.exe" << QStringList( "123-file.exe");
|
||||
QTest::newRow("multi_wildcards")
|
||||
<< "FAKE_WILDCARD_TEST_MULTI"
|
||||
<< "2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64"
|
||||
<< QStringList{
|
||||
"2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/",
|
||||
"2019/Alpha/Beta/Gamma/",
|
||||
"2019/Community/VC/Tools/MSVC/",
|
||||
"2019/Community/VC/Tools/MSVC/14.29.30133/bin/",
|
||||
"2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/",
|
||||
"2019/Enterprise/VC/Tools/MSVC/",
|
||||
};
|
||||
}
|
||||
|
||||
void McuSupportTest::test_processWildcards()
|
||||
{
|
||||
QFETCH(QString, package_label);
|
||||
QFETCH(QString, path);
|
||||
QFETCH(bool, isFile);
|
||||
QFETCH(QString, expected_path);
|
||||
QFETCH(QStringList, paths);
|
||||
|
||||
QVERIFY(createFakePath(testing_output_dir / "wildcards" / path, isFile));
|
||||
for (const auto &path : paths)
|
||||
QVERIFY(createFakePath(testing_output_dir / "wildcards" / path, !path.endsWith("/")));
|
||||
|
||||
auto [targets, packages] = createTestingKitTargetsAndPackages(wildcards_test_kit);
|
||||
auto testWildcardsPackage = findOrDefault(packages, [&](const McuPackagePtr &pkg) {
|
||||
return (pkg->label() == package_label);
|
||||
});
|
||||
QVERIFY(testWildcardsPackage != nullptr);
|
||||
QCOMPARE(testWildcardsPackage->path().toString(), FilePath(testing_output_dir / "wildcards" / path).toString());
|
||||
QVERIFY(paths.size() > 0);
|
||||
// FilePaths with "/" at the end and without it evaluate to different paths.
|
||||
QCOMPARE(testWildcardsPackage->path(),
|
||||
FilePath(testing_output_dir / "wildcards" / expected_path));
|
||||
}
|
||||
|
||||
void McuSupportTest::test_nonemptyVersionDetector()
|
||||
|
||||
@@ -34,6 +34,13 @@ constexpr auto wildcards_test_kit = R"(
|
||||
"defaultValue": "%{MCU_TESTING_FOLDER}/wildcards/*-file.exe",
|
||||
"envVar": "",
|
||||
"type": "path"
|
||||
},
|
||||
{
|
||||
"label": "FAKE_WILDCARD_TEST_MULTI",
|
||||
"description": "Assert '*' is replaced by possible values",
|
||||
"defaultValue": "%{MCU_TESTING_FOLDER}/wildcards/2019/*/VC/Tools/MSVC/*/bin/Hostx64/x64",
|
||||
"envVar": "",
|
||||
"type": "path"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -61,6 +61,8 @@ void ToolKitAspectWidget::removeTool(const MesonTools::Tool_t &tool)
|
||||
|
||||
void ToolKitAspectWidget::setCurrentToolIndex(int index)
|
||||
{
|
||||
if (m_toolsComboBox->count() == 0)
|
||||
return;
|
||||
const Utils::Id id = Utils::Id::fromSetting(m_toolsComboBox->itemData(index));
|
||||
if (m_type == ToolType::Meson)
|
||||
MesonToolKitAspect::setMesonTool(m_kit, id);
|
||||
|
||||
@@ -295,7 +295,7 @@ QVariant BuildStep::data(Id id) const
|
||||
immutable steps are run. The default implementation returns \c false.
|
||||
*/
|
||||
|
||||
void BuildStep::runInThread(const std::function<bool()> &syncImpl)
|
||||
QFuture<bool> BuildStep::runInThread(const std::function<bool()> &syncImpl)
|
||||
{
|
||||
m_runInGuiThread = false;
|
||||
m_cancelFlag = false;
|
||||
@@ -304,7 +304,9 @@ void BuildStep::runInThread(const std::function<bool()> &syncImpl)
|
||||
emit finished(watcher->result());
|
||||
watcher->deleteLater();
|
||||
});
|
||||
watcher->setFuture(Utils::runAsync(syncImpl));
|
||||
auto future = Utils::runAsync(syncImpl);
|
||||
watcher->setFuture(future);
|
||||
return future;
|
||||
}
|
||||
|
||||
std::function<bool ()> BuildStep::cancelChecker() const
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QFuture>
|
||||
#include <QWidget>
|
||||
|
||||
#include <atomic>
|
||||
@@ -117,7 +118,7 @@ signals:
|
||||
protected:
|
||||
virtual QWidget *createConfigWidget();
|
||||
|
||||
void runInThread(const std::function<bool()> &syncImpl);
|
||||
QFuture<bool> runInThread(const std::function<bool()> &syncImpl);
|
||||
|
||||
std::function<bool()> cancelChecker() const;
|
||||
bool isCanceled() const;
|
||||
|
||||
@@ -423,7 +423,7 @@ QString JsonWizard::evaluate(const QVariant &v) const
|
||||
void JsonWizard::openFiles(const JsonWizard::GeneratorFiles &files)
|
||||
{
|
||||
QString errorMessage;
|
||||
bool openedSomething = false;
|
||||
bool openedSomething = stringValue("DoNotOpenFile") == "true";
|
||||
for (const JsonWizard::GeneratorFile &f : files) {
|
||||
const Core::GeneratedFile &file = f.file;
|
||||
if (!file.filePath().exists()) {
|
||||
|
||||
@@ -109,6 +109,10 @@ const Project::NodeMatcher Project::GeneratedFiles = [](const Node *node) {
|
||||
return isListedFileNode(node) && node->isGenerated();
|
||||
};
|
||||
|
||||
const Project::NodeMatcher Project::HiddenRccFolders = [](const Node *node) {
|
||||
return node->isFolderNodeType() && node->filePath().fileName() == ".rcc";
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// ProjectDocument:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
static const NodeMatcher AllFiles;
|
||||
static const NodeMatcher SourceFiles;
|
||||
static const NodeMatcher GeneratedFiles;
|
||||
static const NodeMatcher HiddenRccFolders;
|
||||
|
||||
Utils::FilePaths files(const NodeMatcher &matcher) const;
|
||||
bool isKnownFile(const Utils::FilePath &filename) const;
|
||||
|
||||
@@ -250,7 +250,8 @@ void PythonBuildSystem::triggerParsing()
|
||||
|
||||
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
if (modelManager) {
|
||||
auto projectInfo = modelManager->defaultProjectInfoForProject(project());
|
||||
const auto hiddenRccFolders = project()->files(Project::HiddenRccFolders);
|
||||
auto projectInfo = modelManager->defaultProjectInfoForProject(project(), hiddenRccFolders);
|
||||
|
||||
for (const QString &importPath : std::as_const(m_qmlImportPaths)) {
|
||||
const FilePath filePath = FilePath::fromString(importPath);
|
||||
|
||||
@@ -1052,8 +1052,9 @@ void QbsBuildSystem::updateQmlJsCodeModel()
|
||||
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
if (!modelManager)
|
||||
return;
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
|
||||
modelManager->defaultProjectInfoForProject(project());
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(project(),
|
||||
project()->files(Project::HiddenRccFolders));
|
||||
|
||||
const QJsonObject projectData = session()->projectData();
|
||||
if (projectData.isEmpty())
|
||||
@@ -1068,7 +1069,7 @@ void QbsBuildSystem::updateQmlJsCodeModel()
|
||||
});
|
||||
|
||||
project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID,
|
||||
!projectInfo.sourceFiles.isEmpty());
|
||||
!projectInfo.sourceFiles.isEmpty());
|
||||
modelManager->updateProjectInfo(projectInfo, project());
|
||||
}
|
||||
|
||||
|
||||
@@ -410,8 +410,9 @@ void QmakeBuildSystem::updateQmlJSCodeModel()
|
||||
if (!modelManager)
|
||||
return;
|
||||
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
|
||||
modelManager->defaultProjectInfoForProject(project());
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(project(),
|
||||
project()->files(Project::HiddenRccFolders));
|
||||
|
||||
const QList<QmakeProFile *> proFiles = rootProFile()->allProFiles();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <theme.h>
|
||||
#include <utils/hdrimage.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <modelnodeoperations.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
@@ -64,6 +65,13 @@ bool AssetsLibraryModel::loadExpandedState(const QString &assetPath)
|
||||
return m_expandedStateHash.value(assetPath, true);
|
||||
}
|
||||
|
||||
bool AssetsLibraryModel::isEffectQmlExist(const QString &effectName)
|
||||
{
|
||||
Utils::FilePath effectsResDir = ModelNodeOperations::getEffectsDirectory();
|
||||
Utils::FilePath qmlPath = effectsResDir.resolvePath(effectName + "/" + effectName + ".qml");
|
||||
return qmlPath.exists();
|
||||
}
|
||||
|
||||
AssetsLibraryModel::DirExpandState AssetsLibraryModel::getAllExpandedState() const
|
||||
{
|
||||
const auto keys = m_expandedStateHash.keys();
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
static void saveExpandedState(bool expanded, const QString &assetPath);
|
||||
static bool loadExpandedState(const QString &assetPath);
|
||||
|
||||
static bool isEffectQmlExist(const QString &effectName);
|
||||
|
||||
enum class DirExpandState {
|
||||
SomeExpanded,
|
||||
AllExpanded,
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <utils/utilsicons.h>
|
||||
#include "utils/environment.h"
|
||||
#include "utils/filepath.h"
|
||||
#include "utils/qtcprocess.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -50,9 +49,6 @@
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static QString propertyEditorResourcesPath()
|
||||
@@ -242,44 +238,7 @@ QSet<QString> AssetsLibraryWidget::supportedAssetSuffixes(bool complex)
|
||||
|
||||
void AssetsLibraryWidget::openEffectMaker(const QString &filePath)
|
||||
{
|
||||
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
|
||||
if (!target) {
|
||||
qWarning() << __FUNCTION__ << "No project open";
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::FilePath projectPath = target->project()->projectDirectory();
|
||||
QString effectName = QFileInfo(filePath).baseName();
|
||||
QString effectResDir = "asset_imports/Effects/" + effectName;
|
||||
Utils::FilePath effectResPath = projectPath.resolvePath(effectResDir);
|
||||
if (!effectResPath.exists())
|
||||
QDir(projectPath.toString()).mkpath(effectResDir);
|
||||
|
||||
const QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||
if (baseQtVersion) {
|
||||
auto effectMakerPath = baseQtVersion->binPath().pathAppended("QQEffectMaker").withExecutableSuffix();
|
||||
if (!effectMakerPath.exists()) {
|
||||
qWarning() << __FUNCTION__ << "Cannot find EffectMaker app";
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::FilePath effectPath = Utils::FilePath::fromString(filePath);
|
||||
QString effectContents = QString::fromUtf8(effectPath.fileContents().value_or(QByteArray()));
|
||||
QStringList arguments;
|
||||
arguments << filePath;
|
||||
if (effectContents.isEmpty())
|
||||
arguments << "--create";
|
||||
arguments << "--exportpath" << effectResPath.toString();
|
||||
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (env.osType() == Utils::OsTypeMac)
|
||||
env.appendOrSet("QSG_RHI_BACKEND", "metal");
|
||||
|
||||
m_qqemProcess.reset(new Utils::QtcProcess);
|
||||
m_qqemProcess->setEnvironment(env);
|
||||
m_qqemProcess->setCommand({ effectMakerPath, arguments });
|
||||
m_qqemProcess->start();
|
||||
}
|
||||
ModelNodeOperations::openEffectMaker(filePath);
|
||||
}
|
||||
|
||||
void AssetsLibraryWidget::setModel(Model *model)
|
||||
|
||||
@@ -22,7 +22,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class FileSystemWatcher;
|
||||
class QtcProcess;
|
||||
}
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -96,8 +95,6 @@ private:
|
||||
bool m_updateRetry = false;
|
||||
QString m_filterText;
|
||||
QPoint m_dragStartPoint;
|
||||
|
||||
std::unique_ptr<Utils::QtcProcess> m_qqemProcess;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -47,11 +47,15 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include "projectexplorer/session.h"
|
||||
#include "projectexplorer/target.h"
|
||||
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include "utils/qtcprocess.h"
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <QComboBox>
|
||||
@@ -1621,6 +1625,51 @@ void updateImported3DAsset(const SelectionContext &selectionContext)
|
||||
}
|
||||
}
|
||||
|
||||
void openEffectMaker(const QString &filePath)
|
||||
{
|
||||
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
|
||||
if (!target) {
|
||||
qWarning() << __FUNCTION__ << "No project open";
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::FilePath projectPath = target->project()->projectDirectory();
|
||||
QString effectName = QFileInfo(filePath).baseName();
|
||||
QString effectResDir = "asset_imports/Effects/" + effectName;
|
||||
Utils::FilePath effectResPath = projectPath.resolvePath(effectResDir);
|
||||
if (!effectResPath.exists())
|
||||
QDir(projectPath.toString()).mkpath(effectResDir);
|
||||
|
||||
const QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||
if (baseQtVersion) {
|
||||
auto effectMakerPath = baseQtVersion->binPath().pathAppended("QQEffectMaker").withExecutableSuffix();
|
||||
if (!effectMakerPath.exists()) {
|
||||
qWarning() << __FUNCTION__ << "Cannot find EffectMaker app";
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::FilePath effectPath = Utils::FilePath::fromString(filePath);
|
||||
QStringList arguments;
|
||||
arguments << filePath;
|
||||
if (effectPath.fileContents())
|
||||
arguments << "--create";
|
||||
arguments << "--exportpath" << effectResPath.toString();
|
||||
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (env.osType() == Utils::OsTypeMac)
|
||||
env.appendOrSet("QSG_RHI_BACKEND", "metal");
|
||||
|
||||
Utils::QtcProcess *qqemProcess = new Utils::QtcProcess();
|
||||
qqemProcess->setEnvironment(env);
|
||||
qqemProcess->setCommand({ effectMakerPath, arguments });
|
||||
qqemProcess->start();
|
||||
|
||||
QObject::connect(qqemProcess, &Utils::QtcProcess::done, [qqemProcess]() {
|
||||
qqemProcess->deleteLater();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Utils::FilePath getEffectsDirectory()
|
||||
{
|
||||
QString defaultDir = "asset_imports/Effects";
|
||||
|
||||
@@ -79,10 +79,11 @@ void openSignalDialog(const SelectionContext &selectionContext);
|
||||
void updateImported3DAsset(const SelectionContext &selectionContext);
|
||||
|
||||
QMLDESIGNERCORE_EXPORT Utils::FilePath getEffectsDirectory();
|
||||
void openEffectMaker(const QString &filePath);
|
||||
|
||||
// ModelNodePreviewImageOperations
|
||||
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
||||
QVariant previewImageDataForImageNode(const ModelNode &modelNode);
|
||||
|
||||
} // namespace ModelNodeOperationso
|
||||
} // namespace ModelNodeOperations
|
||||
} //QmlDesigner
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
#include "formeditorscene.h"
|
||||
#include "formeditorview.h"
|
||||
#include "assetslibrarywidget.h"
|
||||
#include "assetslibrarymodel.h"
|
||||
#include <metainfo.h>
|
||||
#include <modelnodeoperations.h>
|
||||
#include <nodehints.h>
|
||||
#include <rewritingexception.h>
|
||||
#include "qmldesignerconstants.h"
|
||||
@@ -19,6 +21,7 @@
|
||||
#include <QMimeData>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <QMessageBox>
|
||||
|
||||
static Q_LOGGING_CATEGORY(dragToolInfo, "qtc.qmldesigner.formeditor", QtWarningMsg);
|
||||
|
||||
@@ -242,9 +245,31 @@ void DragTool::dropEvent(const QList<QGraphicsItem *> &itemList, QGraphicsSceneD
|
||||
if (targetContainerFormEditorItem) {
|
||||
QmlItemNode parentQmlItemNode = targetContainerFormEditorItem->qmlItemNode();
|
||||
QString effectName = QFileInfo(effectPath).baseName();
|
||||
QmlItemNode effectNode = QmlItemNode::createQmlItemNodeForEffect(view(), parentQmlItemNode, effectName);
|
||||
|
||||
view()->setSelectedModelNodes({effectNode});
|
||||
if (!AssetsLibraryModel::isEffectQmlExist(effectName)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Effect " + effectName + " is empty");
|
||||
msgBox.setInformativeText("Do you want to edit " + effectName + "?");
|
||||
msgBox.setStandardButtons(QMessageBox::No |QMessageBox::Yes);
|
||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
int ret = msgBox.exec();
|
||||
switch (ret) {
|
||||
case QMessageBox::Yes:
|
||||
ModelNodeOperations::openEffectMaker(effectPath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
QmlItemNode effectNode = QmlItemNode::
|
||||
createQmlItemNodeForEffect(view(), parentQmlItemNode, effectName);
|
||||
|
||||
view()->setSelectedModelNodes({parentQmlItemNode});
|
||||
view()->resetPuppet();
|
||||
|
||||
commitTransaction();
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <model.h>
|
||||
#include <abstractview.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <QUrl>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QFileInfo>
|
||||
@@ -151,12 +153,22 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
|
||||
return newQmlItemNode;
|
||||
}
|
||||
|
||||
static bool useLayerEffect()
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
const QString layerEffectEntry = "QML/Designer/UseLayerEffect";
|
||||
|
||||
return settings->value(layerEffectEntry, true).toBool();
|
||||
}
|
||||
|
||||
QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view,
|
||||
const QmlItemNode &parentNode,
|
||||
const QString &effectName)
|
||||
{
|
||||
QmlItemNode newQmlItemNode;
|
||||
|
||||
const bool layerEffect = useLayerEffect();
|
||||
|
||||
QmlDesigner::Import import = Import::createLibraryImport("Effects." + effectName, "1.0");
|
||||
try {
|
||||
if (!view->model()->hasImport(import, true, true))
|
||||
@@ -167,11 +179,17 @@ QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view,
|
||||
|
||||
TypeName type(effectName.toUtf8());
|
||||
newQmlItemNode = QmlItemNode(view->createModelNode(type, 1, 0));
|
||||
NodeAbstractProperty parentProperty = parentNode.defaultNodeAbstractProperty();
|
||||
NodeAbstractProperty parentProperty = layerEffect
|
||||
? parentNode.nodeAbstractProperty("layer.effect")
|
||||
: parentNode.defaultNodeAbstractProperty();
|
||||
parentProperty.reparentHere(newQmlItemNode);
|
||||
|
||||
newQmlItemNode.modelNode().bindingProperty("source").setExpression("parent");
|
||||
newQmlItemNode.modelNode().bindingProperty("anchors.fill").setExpression("parent");
|
||||
if (!layerEffect) {
|
||||
newQmlItemNode.modelNode().bindingProperty("source").setExpression("parent");
|
||||
newQmlItemNode.modelNode().bindingProperty("anchors.fill").setExpression("parent");
|
||||
} else {
|
||||
parentNode.modelNode().variantProperty("layer.enabled").setValue(true);
|
||||
}
|
||||
|
||||
QTC_ASSERT(newQmlItemNode.isValid(), return QmlItemNode());
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmldesignerplugin.h"
|
||||
#include "coreplugin/iwizardfactory.h"
|
||||
#include "designmodecontext.h"
|
||||
#include "designmodewidget.h"
|
||||
#include "dynamiclicensecheck.h"
|
||||
@@ -41,8 +42,10 @@
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/designmode.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/featureprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/iwizardfactory.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@@ -54,19 +57,19 @@
|
||||
#include <sqlitelibraryinitializer.h>
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QTimer>
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <qplugin.h>
|
||||
#include <QDebug>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
#include <QApplication>
|
||||
#include <qplugin.h>
|
||||
|
||||
#include "nanotrace/nanotrace.h"
|
||||
#include <modelnodecontextmenu_helper.h>
|
||||
@@ -79,6 +82,17 @@ namespace QmlDesigner {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class EnterpriseFeatureProvider : public Core::IFeatureProvider
|
||||
{
|
||||
public:
|
||||
QSet<Utils::Id> availableFeatures(Utils::Id id) const override
|
||||
{
|
||||
return {"QmlDesigner.Wizards.Enterprise"};
|
||||
}
|
||||
QSet<Utils::Id> availablePlatforms() const override { return {}; }
|
||||
QString displayNameForPlatform(Utils::Id id) const override { return {}; }
|
||||
};
|
||||
|
||||
QString normalizeIdentifier(const QString &string)
|
||||
{
|
||||
if (string.isEmpty())
|
||||
@@ -232,6 +246,8 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
||||
//TODO Move registering those types out of the property editor, since they are used also in the states editor
|
||||
Quick2PropertyEditorView::registerQmlTypes();
|
||||
|
||||
if (QmlDesigner::checkLicense() == QmlDesigner::FoundLicense::enterprise)
|
||||
Core::IWizardFactory::registerFeatureProvider(new EnterpriseFeatureProvider);
|
||||
Exception::setWarnAboutException(!QmlDesignerPlugin::instance()
|
||||
->settings()
|
||||
.value(DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT)
|
||||
|
||||
@@ -20,22 +20,23 @@
|
||||
#include <qmljstools/qmljstoolssettings.h>
|
||||
#include <qmljstools/qmljscodestylepreferences.h>
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
#include <texteditor/formattexteditor.h>
|
||||
#include <texteditor/snippets/snippetprovider.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <texteditor/tabsettings.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/json.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QTextDocument>
|
||||
#include <QMenu>
|
||||
@@ -260,24 +261,14 @@ void QmlJSEditorPluginPrivate::reformatFile()
|
||||
tabSettings.m_tabSize,
|
||||
QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->currentCodeStyleSettings().lineLength);
|
||||
|
||||
// QTextDocument::setPlainText cannot be used, as it would reset undo/redo history
|
||||
const auto setNewText = [this, &newText]() {
|
||||
auto ed = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor());
|
||||
if (ed) {
|
||||
TextEditor::updateEditorText(ed->editorWidget(), newText);
|
||||
} else {
|
||||
QTextCursor tc(m_currentDocument->document());
|
||||
tc.movePosition(QTextCursor::Start);
|
||||
tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
tc.insertText(newText);
|
||||
};
|
||||
|
||||
IEditor *ed = EditorManager::currentEditor();
|
||||
if (ed) {
|
||||
QByteArray state = ed->saveState();
|
||||
int line = ed->currentLine();
|
||||
int column = ed->currentColumn();
|
||||
setNewText();
|
||||
ed->gotoLine(line, column - 1);
|
||||
ed->restoreState(state);
|
||||
} else {
|
||||
setNewText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,36 @@ static void setupProjectInfoQmlBundles(ModelManagerInterface::ProjectInfo &proje
|
||||
}
|
||||
}
|
||||
|
||||
static void findAllQrcFiles(const FilePath &filePath, FilePaths &out)
|
||||
{
|
||||
filePath.iterateDirectory(
|
||||
[&out](const FilePath &path) {
|
||||
out.append(path.canonicalPath());
|
||||
return true;
|
||||
},
|
||||
{{"*.qrc"}, QDir::Files});
|
||||
}
|
||||
|
||||
static FilePaths findGeneratedQrcFiles(const ModelManagerInterface::ProjectInfo &pInfo,
|
||||
const FilePaths &hiddenRccFolders)
|
||||
{
|
||||
FilePaths result;
|
||||
// Search in Application Directories for directories named ".rcc"
|
||||
// and add all .qrc files in there to the resource file list.
|
||||
for (const Utils::FilePath &path : pInfo.applicationDirectories) {
|
||||
Utils::FilePath generatedQrcDir = path.pathAppended(".rcc");
|
||||
findAllQrcFiles(generatedQrcDir, result);
|
||||
}
|
||||
|
||||
for (const Utils::FilePath &hiddenRccFolder : hiddenRccFolders) {
|
||||
findAllQrcFiles(hiddenRccFolder, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
|
||||
Project *project) const
|
||||
Project *project, const FilePaths &hiddenRccFolders) const
|
||||
{
|
||||
ModelManagerInterface::ProjectInfo projectInfo;
|
||||
projectInfo.project = project;
|
||||
@@ -187,6 +215,7 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
|
||||
}
|
||||
|
||||
setupProjectInfoQmlBundles(projectInfo);
|
||||
projectInfo.generatedQrcFiles = findGeneratedQrcFiles(projectInfo, hiddenRccFolders);
|
||||
return projectInfo;
|
||||
}
|
||||
|
||||
@@ -298,7 +327,7 @@ void ModelManager::updateDefaultProjectInfo()
|
||||
Project *currentProject = SessionManager::startupProject();
|
||||
setDefaultProject(containsProject(currentProject)
|
||||
? projectInfo(currentProject)
|
||||
: defaultProjectInfoForProject(currentProject),
|
||||
: defaultProjectInfoForProject(currentProject, {}),
|
||||
currentProject);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ protected:
|
||||
WorkingCopy workingCopyInternal() const override;
|
||||
void addTaskInternal(const QFuture<void> &result, const QString &msg,
|
||||
const char *taskId) const override;
|
||||
ProjectInfo defaultProjectInfoForProject(ProjectExplorer::Project *project) const override;
|
||||
ProjectInfo defaultProjectInfoForProject(
|
||||
ProjectExplorer::Project *project, const Utils::FilePaths &hiddenRccFolders) const override;
|
||||
private:
|
||||
void updateDefaultProjectInfo();
|
||||
void loadDefaultQmlTypeDescriptions();
|
||||
|
||||
@@ -311,8 +311,9 @@ void QmlBuildSystem::refresh(RefreshOptions options)
|
||||
if (!modelManager)
|
||||
return;
|
||||
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
|
||||
modelManager->defaultProjectInfoForProject(project());
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(project(),
|
||||
project()->files(Project::HiddenRccFolders));
|
||||
const QStringList searchPaths = makeAbsolute(canonicalProjectDir(), customImportPaths());
|
||||
for (const QString &searchPath : searchPaths)
|
||||
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/futuresynchronizer.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@@ -80,6 +82,8 @@ private:
|
||||
BoolAspect *m_ignoreMissingFilesAspect = nullptr;
|
||||
bool m_packagingNeeded = false;
|
||||
QList<DeployableFile> m_files;
|
||||
|
||||
FutureSynchronizer m_synchronizer;
|
||||
};
|
||||
|
||||
TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl, Id id)
|
||||
@@ -126,7 +130,7 @@ bool TarPackageCreationStep::init()
|
||||
|
||||
void TarPackageCreationStep::doRun()
|
||||
{
|
||||
runInThread([this] { return runImpl(); });
|
||||
m_synchronizer.addFuture(runInThread([this] { return runImpl(); }));
|
||||
}
|
||||
|
||||
bool TarPackageCreationStep::fromMap(const QVariantMap &map)
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
virtual ~IAssistProcessor();
|
||||
|
||||
virtual IAssistProposal *immediateProposal(const AssistInterface *) { return nullptr; }
|
||||
virtual IAssistProposal *perform(const AssistInterface *interface) = 0;
|
||||
virtual IAssistProposal *perform(const AssistInterface *interface) = 0; // takes ownership
|
||||
|
||||
void setAsyncProposalAvailable(IAssistProposal *proposal);
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ static FormatTask format(FormatTask task)
|
||||
* actually changed parts are updated while preserving the cursor position, the folded
|
||||
* blocks, and the scroll bar position.
|
||||
*/
|
||||
static void updateEditorText(QPlainTextEdit *editor, const QString &text)
|
||||
void updateEditorText(QPlainTextEdit *editor, const QString &text)
|
||||
{
|
||||
const QString editorText = editor->toPlainText();
|
||||
if (editorText == text)
|
||||
|
||||
@@ -44,5 +44,6 @@ TEXTEDITOR_EXPORT void formatEditor(TextEditorWidget *editor, const TextEditor::
|
||||
int startPos = -1, int endPos = 0);
|
||||
TEXTEDITOR_EXPORT void formatEditorAsync(TextEditorWidget *editor, const TextEditor::Command &command,
|
||||
int startPos = -1, int endPos = 0);
|
||||
TEXTEDITOR_EXPORT void updateEditorText(QPlainTextEdit *editor, const QString &text);
|
||||
|
||||
} // namespace TextEditor
|
||||
|
||||
@@ -732,7 +732,7 @@ Core::IDocument::OpenResult TextDocument::open(QString *errorString,
|
||||
emit aboutToOpen(filePath, realFilePath);
|
||||
OpenResult success = openImpl(errorString, filePath, realFilePath, /*reload =*/ false);
|
||||
if (success == OpenResult::Success) {
|
||||
setMimeType(Utils::mimeTypeForFile(filePath).name());
|
||||
setMimeType(Utils::mimeTypeForFile(filePath, MimeMatchMode::MatchDefaultAndRemote).name());
|
||||
emit openFinishedSuccessfully();
|
||||
}
|
||||
return success;
|
||||
|
||||
@@ -3343,7 +3343,9 @@ void TextEditorWidgetPrivate::updateFileLineEndingVisible()
|
||||
|
||||
void TextEditorWidgetPrivate::reconfigure()
|
||||
{
|
||||
m_document->setMimeType(Utils::mimeTypeForFile(m_document->filePath()).name());
|
||||
m_document->setMimeType(
|
||||
Utils::mimeTypeForFile(m_document->filePath(),
|
||||
MimeMatchMode::MatchDefaultAndRemote).name());
|
||||
q->configureGenericHighlighter();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user