Merge "Merge remote-tracking branch 'origin/14.0' into qds/dev" into qds/dev

This commit is contained in:
The Qt Project
2024-07-23 14:08:09 +00:00
138 changed files with 3748 additions and 1646 deletions

View File

@@ -601,12 +601,21 @@ void installQASIPackage(Target *target, const FilePath &packagePath)
}
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << "install" << "-r " << packagePath.path();
arguments << "install" << "-r" << packagePath.path();
QString error;
Process *process = startAdbProcess(arguments, &error);
if (process) {
// TODO: Potential leak when the process is still running on Creator shutdown.
QObject::connect(process, &Process::done, process, &QObject::deleteLater);
process->setParent(target);
QObject::connect(process, &Process::done, target, [process] {
if (process->result() == ProcessResult::FinishedWithSuccess) {
MessageManager::writeSilently(
Tr::tr("Android package installation finished with success."));
} else {
MessageManager::writeDisrupting(Tr::tr("Android package installation failed.")
+ '\n' + process->cleanedStdErr());
}
process->deleteLater();
});
} else {
MessageManager::writeDisrupting(
Tr::tr("Android package installation failed.\n%1").arg(error));

View File

@@ -54,23 +54,24 @@ AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName)
const int apiLevel = AndroidManager::deviceApiLevel(m_target);
qCDebug(androidRunnerLog) << "Device API:" << apiLevel;
m_worker.reset(new AndroidRunnerWorker(this, m_packageName));
m_worker = new AndroidRunnerWorker(this, m_packageName);
m_worker->setIntentName(intent);
m_worker->setIsPreNougat(apiLevel <= 23);
m_worker->moveToThread(&m_thread);
QObject::connect(&m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
connect(this, &AndroidRunner::asyncStart, m_worker.data(), &AndroidRunnerWorker::asyncStart);
connect(this, &AndroidRunner::asyncStop, m_worker.data(), &AndroidRunnerWorker::asyncStop);
connect(this, &AndroidRunner::asyncStart, m_worker, &AndroidRunnerWorker::asyncStart);
connect(this, &AndroidRunner::asyncStop, m_worker, &AndroidRunnerWorker::asyncStop);
connect(this, &AndroidRunner::androidDeviceInfoChanged,
m_worker.data(), &AndroidRunnerWorker::setAndroidDeviceInfo);
connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessStarted,
m_worker, &AndroidRunnerWorker::setAndroidDeviceInfo);
connect(m_worker, &AndroidRunnerWorker::remoteProcessStarted,
this, &AndroidRunner::handleRemoteProcessStarted);
connect(m_worker.data(), &AndroidRunnerWorker::remoteProcessFinished,
connect(m_worker, &AndroidRunnerWorker::remoteProcessFinished,
this, &AndroidRunner::handleRemoteProcessFinished);
connect(m_worker.data(), &AndroidRunnerWorker::remoteOutput,
this, &AndroidRunner::remoteOutput);
connect(m_worker.data(), &AndroidRunnerWorker::remoteErrorOutput,
connect(m_worker, &AndroidRunnerWorker::remoteOutput, this, &AndroidRunner::remoteOutput);
connect(m_worker, &AndroidRunnerWorker::remoteErrorOutput,
this, &AndroidRunner::remoteErrorOutput);
connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,

View File

@@ -56,7 +56,7 @@ private:
QString m_launchedAVDName;
QThread m_thread;
QTimer m_checkAVDTimer;
QScopedPointer<AndroidRunnerWorker> m_worker;
AndroidRunnerWorker *m_worker = nullptr;
QPointer<ProjectExplorer::Target> m_target;
Utils::Port m_debugServerPort;
QUrl m_qmlServer;

View File

@@ -171,24 +171,26 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
m_extraAppParams = runControl->commandLine().arguments();
if (const Store sd = runControl->settingsData(Constants::ANDROID_AM_START_ARGS);
!sd.values().isEmpty()) {
!sd.isEmpty()) {
QTC_CHECK(sd.first().typeId() == QMetaType::QString);
const QString startArgs = sd.first().toString();
m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix);
}
if (const Store sd = runControl->settingsData(Constants::ANDROID_PRESTARTSHELLCMDLIST);
!sd.values().isEmpty()) {
QTC_CHECK(sd.first().typeId() == QMetaType::QString);
const QStringList commands = sd.first().toString().split('\n', Qt::SkipEmptyParts);
!sd.isEmpty()) {
const QVariant &first = sd.first();
QTC_CHECK(first.typeId() == QMetaType::QStringList);
const QStringList commands = first.toStringList();
for (const QString &shellCmd : commands)
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
}
if (const Store sd = runControl->settingsData(Constants::ANDROID_POSTFINISHSHELLCMDLIST);
!sd.values().isEmpty()) {
QTC_CHECK(sd.first().typeId() == QMetaType::QString);
const QStringList commands = sd.first().toString().split('\n', Qt::SkipEmptyParts);
!sd.isEmpty()) {
const QVariant &first = sd.first();
QTC_CHECK(first.typeId() == QMetaType::QStringList);
const QStringList commands = first.toStringList();
for (const QString &shellCmd : commands)
m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
}
@@ -203,6 +205,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit());
m_useAppParamsForQmlDebugger = version->qtVersion() >= QVersionNumber(5, 12);
m_pidRunner.setParent(this); // Move m_pidRunner object together with *this into a separate thread.
}
AndroidRunnerWorker::~AndroidRunnerWorker()

View File

@@ -259,7 +259,7 @@ void handleInactiveRegions(LanguageClient::Client *client, const JsonRpcMessage
const QList<Range> inactiveRegions = params->inactiveRegions();
QList<BlockRange> ifdefedOutBlocks;
for (const Range &r : inactiveRegions) {
const int startPos = r.start().toPositionInDocument(doc->document());
const int startPos = Position(r.start().line(), 0).toPositionInDocument(doc->document());
const int endPos = r.end().toPositionInDocument(doc->document()) + 1;
ifdefedOutBlocks.emplaceBack(startPos, endPos);
}

View File

@@ -37,3 +37,8 @@ extend_qtc_plugin(ClangFormat
DEFINES
TESTDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/data"
)
extend_qtc_plugin(ClangFormat
CONDITION TARGET LLVM
DEPENDS LLVM
)

View File

@@ -177,10 +177,11 @@ void ClangToolsPlugin::registerAnalyzeActions()
widget->toolBar()->addWidget(button);
const auto toolsMenu = new QMenu(widget);
button->setMenu(toolsMenu);
for (const auto &toolInfo : {std::make_pair(ClangTidyTool::instance(),
Constants::RUN_CLANGTIDY_ON_CURRENT_FILE),
std::make_pair(ClazyTool::instance(),
Constants::RUN_CLAZY_ON_CURRENT_FILE)}) {
for (const auto &toolInfo :
{std::pair<ClangTool *, Utils::Id>(
ClangTidyTool::instance(), Constants::RUN_CLANGTIDY_ON_CURRENT_FILE),
std::pair<ClangTool *, Utils::Id>(
ClazyTool::instance(), Constants::RUN_CLAZY_ON_CURRENT_FILE)}) {
ClangTool * const tool = toolInfo.first;
Command * const cmd = ActionManager::command(toolInfo.second);
QAction *const action = toolsMenu->addAction(tool->name(), [editor, tool] {

View File

@@ -226,7 +226,8 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Id id) :
useStaging.setSettingsKey(USE_STAGING_KEY);
useStaging.setLabel(Tr::tr("Stage for installation"), BoolAspect::LabelPlacement::AtCheckBox);
useStaging.setDefaultValue(supportsStageForInstallation(kit()));
useStaging.setDefaultValue(supportsStageForInstallation(kit()) && !isCleanStep());
useStaging.setEnabled(!isCleanStep());
stagingDir.setSettingsKey(STAGING_DIR_KEY);
stagingDir.setLabelText(Tr::tr("Staging directory:"));
@@ -522,6 +523,11 @@ void CMakeBuildStep::setBuildPreset(const QString &preset)
QWidget *CMakeBuildStep::createConfigWidget()
{
auto updateDetails = [this] {
const bool haveCleanTarget = m_buildTargets.contains(cleanTarget());
useStaging.setEnabled(!haveCleanTarget);
if (useStaging() && haveCleanTarget)
useStaging.setValue(false);
ProcessParameters param;
setupProcessParameters(&param);
param.setCommandLine(cmakeCommand());

View File

@@ -1239,6 +1239,7 @@ void CMakeBuildSystem::clearCMakeCache()
path.removeRecursively();
emit configurationCleared();
emitParsingFinished(false);
}
void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)

View File

@@ -46,6 +46,19 @@ namespace CMakeProjectManager::Internal {
static Q_LOGGING_CATEGORY(cmInputLog, "qtc.cmake.import", QtWarningMsg);
class ToolchainDescriptionEx
{
public:
Utils::FilePath compilerPath;
Utils::Id language;
QString originalTargetTriple;
operator ProjectExplorer::ToolchainDescription() const
{
return ProjectExplorer::ToolchainDescription{compilerPath, language};
}
};
struct DirectoryData
{
// Project Stuff:
@@ -64,7 +77,7 @@ struct DirectoryData
QString toolset;
FilePath sysroot;
QtProjectImporter::QtVersionData qt;
QVector<ToolchainDescription> toolchains;
QVector<ToolchainDescriptionEx> toolchains;
QVariant debugger;
};
@@ -321,12 +334,30 @@ static CMakeConfig configurationFromPresetProbe(
const PresetsDetails::ConfigurePreset &configurePreset)
{
const FilePath cmakeListTxt = importPath / Constants::CMAKE_LISTS_TXT;
cmakeListTxt.writeFileContents(QByteArray("cmake_minimum_required(VERSION 3.15)\n"
"\n"
"project(preset-probe)\n"
"set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE FILEPATH \"\" FORCE)\n"
"set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACHE FILEPATH \"\" FORCE)\n"
"\n"));
cmakeListTxt.writeFileContents(QByteArray(R"(
cmake_minimum_required(VERSION 3.15)
project(preset-probe)
foreach (file_path_value
CMAKE_C_COMPILER CMAKE_CXX_COMPILER CMAKE_SYSROOT QT_HOST_PATH CMAKE_MAKE_PROGRAM)
if (${file_path_value})
set(${file_path_value} "${${file_path_value}}" CACHE FILEPATH "" FORCE)
endif()
endforeach()
foreach (path_value CMAKE_PREFIX_PATH CMAKE_FIND_ROOT_PATH)
if (${path_value})
set(${path_value} "${${path_value}}" CACHE PATH "" FORCE)
endif()
endforeach()
foreach (string_value CMAKE_C_COMPILER_TARGET CMAKE_CXX_COMPILER_TARGET)
if (${string_value})
set(${string_value} "${${string_value}}" CACHE STRING "" FORCE)
endif()
endforeach()
)"));
Process cmake;
cmake.setDisableUnixTerminal();
@@ -574,9 +605,9 @@ static QMakeAndCMakePrefixPath qtInfoFromCMakeCache(const CMakeConfig &config,
return {qmakeLocation, resultedPrefixPath};
}
static QVector<ToolchainDescription> extractToolchainsFromCache(const CMakeConfig &config)
static QVector<ToolchainDescriptionEx> extractToolchainsFromCache(const CMakeConfig &config)
{
QVector<ToolchainDescription> result;
QVector<ToolchainDescriptionEx> result;
bool haveCCxxCompiler = false;
for (const CMakeConfigItem &i : config) {
if (!i.key.startsWith("CMAKE_") || !i.key.endsWith("_COMPILER"))
@@ -593,7 +624,10 @@ static QVector<ToolchainDescription> extractToolchainsFromCache(const CMakeConfi
}
else
languageId = Id::fromName(language);
result.append({FilePath::fromUtf8(i.value), languageId});
result.append(
{FilePath::fromUtf8(i.value),
languageId,
config.stringValueOf("CMAKE_" + language + "_COMPILER_TARGET")});
}
if (!haveCCxxCompiler) {
@@ -612,10 +646,14 @@ static QVector<ToolchainDescription> extractToolchainsFromCache(const CMakeConfi
const FilePath linker = config.filePathValueOf("CMAKE_LINKER");
if (!linker.isEmpty()) {
const FilePath compilerPath = linker.parentDir();
result.append({compilerPath.pathAppended(cCompilerName),
ProjectExplorer::Constants::C_LANGUAGE_ID});
result.append({compilerPath.pathAppended(cxxCompilerName),
ProjectExplorer::Constants::CXX_LANGUAGE_ID});
result.append(
{compilerPath.pathAppended(cCompilerName),
ProjectExplorer::Constants::C_LANGUAGE_ID,
{}});
result.append(
{compilerPath.pathAppended(cxxCompilerName),
ProjectExplorer::Constants::CXX_LANGUAGE_ID,
{}});
}
}
}
@@ -1052,7 +1090,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
const bool compilersMatch = [k, data] {
const QList<Id> allLanguages = ToolchainManager::allLanguages();
for (const ToolchainDescription &tcd : data->toolchains) {
for (const ToolchainDescriptionEx &tcd : data->toolchains) {
if (!Utils::contains(allLanguages,
[&tcd](const Id &language) { return language == tcd.language; }))
continue;
@@ -1065,7 +1103,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
}();
const bool noCompilers = [k, data] {
const QList<Id> allLanguages = ToolchainManager::allLanguages();
for (const ToolchainDescription &tcd : data->toolchains) {
for (const ToolchainDescriptionEx &tcd : data->toolchains) {
if (!Utils::contains(allLanguages,
[&tcd](const Id &language) { return language == tcd.language; }))
continue;
@@ -1117,7 +1155,7 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
SysRootKitAspect::setSysRoot(k, data->sysroot);
for (const ToolchainDescription &cmtcd : data->toolchains) {
for (const ToolchainDescriptionEx &cmtcd : data->toolchains) {
const ToolchainData tcd = findOrCreateToolchains(cmtcd);
QTC_ASSERT(!tcd.tcs.isEmpty(), continue);
@@ -1126,7 +1164,15 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
addTemporaryData(ToolchainKitAspect::id(), tc->id(), k);
}
ToolchainKitAspect::setToolchain(k, tcd.tcs.at(0));
Toolchain* toolchain = tcd.tcs.at(0);
if (!cmtcd.originalTargetTriple.isEmpty())
toolchain->setExplicitCodeModelTargetTriple(cmtcd.originalTargetTriple);
// Mark CMake presets toolchains as manual
if (!data->cmakePresetDisplayname.isEmpty() && tcd.areTemporary)
toolchain->setDetection(Toolchain::ManualDetection);
ToolchainKitAspect::setToolchain(k, toolchain);
}
if (!data->cmakePresetDisplayname.isEmpty()) {
@@ -1335,7 +1381,7 @@ void CMakeProjectImporterTest::testCMakeProjectImporterToolchain()
config.append(CMakeConfigItem(key.toUtf8(), value.toUtf8()));
}
const QVector<ToolchainDescription> tcs = extractToolchainsFromCache(config);
const QVector<ToolchainDescriptionEx> tcs = extractToolchainsFromCache(config);
QCOMPARE(tcs.count(), expectedLanguages.count());
for (int i = 0; i < tcs.count(); ++i) {
QCOMPARE(tcs.at(i).language, expectedLanguages.at(i));

View File

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

View File

@@ -852,7 +852,7 @@ QList<IContext *> ICore::currentContextObjects()
Returns the widget of the top level IContext of the current context, or \c
nullptr if there is none.
\sa currentContextObject()
\sa currentContextObjects()
*/
QWidget *ICore::currentContextWidget()
{
@@ -2311,7 +2311,7 @@ QList<IContext *> ICore::contextObjects(QWidget *widget)
\sa removeContextObject()
\sa updateAdditionalContexts()
\sa currentContextObject()
\sa currentContextObjects()
\sa {The Action Manager and Commands}
*/
@@ -2330,7 +2330,7 @@ void ICore::addContextObject(IContext *context)
\sa addContextObject()
\sa updateAdditionalContexts()
\sa currentContextObject()
\sa currentContextObjects()
*/
void ICore::removeContextObject(IContext *context)

View File

@@ -10,9 +10,11 @@
#include "editormanager/editormanager.h"
#include "find/basetextfind.h"
#include "icore.h"
#include "messagemanager.h"
#include <aggregation/aggregate.h>
#include <utils/fileutils.h>
#include <utils/outputformatter.h>
#include <utils/qtcassert.h>
@@ -294,7 +296,16 @@ void OutputWindow::contextMenuEvent(QContextMenuEvent *event)
menu->addSeparator();
QAction *saveAction = menu->addAction(Tr::tr("Save Contents..."));
connect(saveAction, &QAction::triggered, this, [this] {
QFileDialog::saveFileContent(toPlainText().toUtf8(), d->outputFileNameHint);
const FilePath file = FileUtils::getSaveFilePath(
ICore::dialogParent(), {}, FileUtils::homePath() / d->outputFileNameHint);
if (!file.isEmpty()) {
QString error;
Utils::TextFileFormat format;
format.codec = EditorManager::defaultTextCodec();
format.lineTerminationMode = EditorManager::defaultLineEnding();
if (!format.writeFile(file, toPlainText(), &error))
MessageManager::writeDisrupting(error);
}
});
saveAction->setEnabled(!document()->isEmpty());

View File

@@ -146,6 +146,7 @@ void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *cust
}
Environment env = customEnv ? *customEnv : m_command.deviceEnvironment();
DebuggerItem::addAndroidLldbPythonEnv(m_command, env);
// QNX gdb unconditionally checks whether the QNX_TARGET env variable is
// set and bails otherwise, even when it is not used by the specific

View File

@@ -575,9 +575,11 @@ void DebuggerRunTool::start()
connect(engine, &DebuggerEngine::attachToCoreRequested, this, [this](const QString &coreFile) {
auto rc = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
rc->copyDataFromRunControl(runControl());
rc->resetDataForAttachToCore();
auto name = QString(Tr::tr("%1 - Snapshot %2").arg(runControl()->displayName()).arg(++d->snapshotCounter));
auto debugger = new DebuggerRunTool(rc);
debugger->setStartMode(AttachToCore);
debugger->setCloseMode(DetachAtClose);
debugger->setRunControlName(name);
debugger->setCoreFilePath(FilePath::fromString(coreFile), true);
debugger->startRunControl();

View File

@@ -647,6 +647,7 @@ public:
void positionShow(const TextEditorWidget *editorWidget);
void updateTooltip(DebuggerEngine *engine);
void updateTooltip2(DebuggerEngine *engine);
void setState(DebuggerTooltipState newState);
void destroy();
@@ -782,6 +783,11 @@ DebuggerToolTipHolder::DebuggerToolTipHolder(const DebuggerToolTipContext &conte
// after normal WatchModel update.
void DebuggerToolTipHolder::updateTooltip(DebuggerEngine *engine)
{
QTimer::singleShot(0, [this, engine] { updateTooltip2(engine); });
}
void DebuggerToolTipHolder::updateTooltip2(DebuggerEngine *engine)
{
widget->setEngine(engine);

View File

@@ -279,6 +279,8 @@ public:
}
});
connect(ExtensionSystem::PluginManager::instance(),
&ExtensionSystem::PluginManager::pluginsChanged, this, &PluginStatusWidget::update);
connect(m_restartButton, &QAbstractButton::clicked,
ICore::instance(), &ICore::restart, Qt::QueuedConnection);
@@ -423,6 +425,7 @@ ExtensionManagerWidget::ExtensionManagerWidget()
m_linksTitle = sectionTitle(h6CapitalTF, Tr::tr("More information"));
m_links = tfLabel(contentTF, false);
m_links->setOpenExternalLinks(true);
m_links->setTextInteractionFlags(Qt::TextBrowserInteraction);
m_imageTitle = sectionTitle(h6CapitalTF, {});
m_image = new QLabel;
m_imageMovie.setDevice(&m_imageDataBuffer);

View File

@@ -25,4 +25,17 @@ QtcPlugin {
"haskelltokenizer.cpp", "haskelltokenizer.h",
"stackbuildstep.cpp", "stackbuildstep.h"
]
Qt.core.resourceFileBaseName: "HaskellWizards" // avoid conflicting qrc file
Group {
name: "Wizard files"
Qt.core.resourceSourceBase: sourceDirectory
Qt.core.resourcePrefix: "haskell/"
fileTags: "qt.core.resource_data"
prefix: "share/wizards/"
files: [
"module/file.hs",
"module/wizard.json",
]
}
}

View File

@@ -992,12 +992,12 @@ IosToolTaskAdapter::IosToolTaskAdapter() {}
void IosToolTaskAdapter::start()
{
task()->m_iosToolHandler = new IosToolHandler(Internal::IosDeviceType(task()->m_deviceType));
connect(task()->m_iosToolHandler, &IosToolHandler::finished, this, [this] {
task()->m_iosToolHandler->deleteLater();
task()->m_iosToolHandler.reset(new IosToolHandler(Internal::IosDeviceType(task()->m_deviceType)));
connect(task()->m_iosToolHandler.get(), &IosToolHandler::finished, this, [this] {
task()->m_iosToolHandler.release()->deleteLater();
emit done(Tasking::DoneResult::Success);
});
task()->m_startHandler(task()->m_iosToolHandler);
task()->m_startHandler(task()->m_iosToolHandler.get());
}
} // namespace Ios

View File

@@ -82,7 +82,7 @@ public:
private:
friend class IosToolTaskAdapter;
IosToolHandler *m_iosToolHandler = nullptr;
std::unique_ptr<IosToolHandler> m_iosToolHandler;
StartHandler m_startHandler;
Internal::IosDeviceType m_deviceType = Internal::IosDeviceType::IosDevice;
};

View File

@@ -9,6 +9,11 @@ QtcPlugin {
Depends { name: "lua546" }
Depends { name: "sol2" }
Properties {
condition: qbs.toolchain.contains("mingw")
cpp.optimization: "fast"
}
files: [
// "generateqtbindings.cpp", // use this if you need to generate some code
"lua_global.h",

View File

@@ -399,6 +399,11 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
&& thisWorkingDirectory == tab.runControl->workingDirectory()
&& thisEnvironment == tab.runControl->environment();
});
const auto updateOutputFileName = [this](int index, RunControl *rc) {
qobject_cast<OutputWindow *>(m_tabWidget->widget(index))
//: file name suggested for saving application output, %1 = run configuration display name
->setOutputFileNameHint(Tr::tr("application-output-%1.txt").arg(rc->displayName()));
};
if (tab != m_runControlTabs.end()) {
// Reuse this tab
if (tab->runControl)
@@ -414,6 +419,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
const int tabIndex = m_tabWidget->indexOf(tab->window);
QTC_ASSERT(tabIndex != -1, return);
m_tabWidget->setTabText(tabIndex, rc->displayName());
updateOutputFileName(tabIndex, rc);
tab->window->scrollToBottom();
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Reusing tab"
@@ -429,8 +435,6 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
ow->setWindowIcon(Icons::WINDOW.icon());
ow->setWordWrapEnabled(m_settings.wrapOutput);
ow->setMaxCharCount(m_settings.maxCharCount);
//: file name suggested for saving application output, %1 = run configuration display name
ow->setOutputFileNameHint(Tr::tr("application-output-%1.txt").arg(rc->displayName()));
auto updateFontSettings = [ow] {
ow->setBaseFont(TextEditor::TextEditorSettings::fontSettings().font());
@@ -456,6 +460,7 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
m_runControlTabs.push_back(RunControlTab(rc, ow));
m_tabWidget->addTab(ow, rc->displayName());
updateOutputFileName(m_tabWidget->count() - 1, rc);
qCDebug(appOutputLog) << "AppOutputPane::createNewOutputWindow: Adding tab for" << rc;
updateCloseActions();
setFilteringEnabled(m_tabWidget->count() > 0);

View File

@@ -85,7 +85,7 @@ static QString translatedOrUntranslatedText(QVariantMap &map, const QString &key
{
if (key.size() >= 1) {
const QString trKey = "tr" + key.at(0).toUpper() + key.mid(1); // "text" -> "trText"
const QString trValue = JsonWizardFactory::localizedString(consumeValue(map, trKey).toString());
const QString trValue = JsonWizardFactory::localizedString(consumeValue(map, trKey));
if (!trValue.isEmpty())
return trValue;
}
@@ -188,9 +188,10 @@ JsonFieldPage::Field *JsonFieldPage::Field::parse(const QVariant &input, QString
*errorMessage = Tr::tr("Field \"%1\" has unsupported type \"%2\".").arg(name).arg(type);
return nullptr;
}
data->setTexts(name,
JsonWizardFactory::localizedString(consumeValue(tmp, DISPLAY_NAME_KEY).toString()),
JsonWizardFactory::localizedString(consumeValue(tmp, TOOLTIP_KEY).toString()));
data->setTexts(
name,
JsonWizardFactory::localizedString(consumeValue(tmp, DISPLAY_NAME_KEY)),
JsonWizardFactory::localizedString(consumeValue(tmp, TOOLTIP_KEY)));
data->setVisibleExpression(consumeValue(tmp, VISIBLE_KEY, true));
data->setEnabledExpression(consumeValue(tmp, ENABLED_KEY, true));
@@ -837,6 +838,7 @@ void PathChooserField::setup(JsonFieldPage *page, const QString &name)
QTC_ASSERT(w, return);
page->registerFieldWithName(name, w, "path", SIGNAL(textChanged(QString)));
QObject::connect(w, &PathChooser::textChanged, page, &WizardPage::completeChanged);
QObject::connect(w, &PathChooser::validChanged, page, &WizardPage::completeChanged);
}
bool PathChooserField::validate(MacroExpander *expander, QString *message)
@@ -973,7 +975,7 @@ std::unique_ptr<QStandardItem> createStandardItemFromListItem(const QVariant &it
auto standardItem = std::make_unique<QStandardItem>();
if (item.typeId() == QMetaType::QVariantMap) {
QVariantMap tmp = item.toMap();
const QString key = JsonWizardFactory::localizedString(consumeValue(tmp, "trKey", QString()).toString());
const QString key = JsonWizardFactory::localizedString(consumeValue(tmp, "trKey"));
const QVariant value = consumeValue(tmp, "value", key);
if (key.isNull() || key.isEmpty()) {
@@ -984,7 +986,7 @@ std::unique_ptr<QStandardItem> createStandardItemFromListItem(const QVariant &it
standardItem->setData(value, ListField::ValueRole);
standardItem->setData(consumeValue(tmp, "condition", true), ListField::ConditionRole);
standardItem->setData(consumeValue(tmp, "icon"), ListField::IconStringRole);
standardItem->setToolTip(JsonWizardFactory::localizedString(consumeValue(tmp, "trToolTip", QString()).toString()));
standardItem->setToolTip(JsonWizardFactory::localizedString(consumeValue(tmp, "trToolTip")));
warnAboutUnsupportedKeys(tmp, QString(), "List");
} else {
const QString keyvalue = item.toString();

View File

@@ -763,10 +763,9 @@ QString JsonWizardFactory::localizedString(const QVariant &value)
return {};
if (value.typeId() == QMetaType::QVariantMap) {
QVariantMap tmp = value.toMap();
const QString locale = languageSetting().toLower();
QStringList locales;
locales << locale << QLatin1String("en") << QLatin1String("C") << tmp.keys();
for (const QString &locale : std::as_const(locales)) {
const QString currentLocale = languageSetting().toLower();
const QStringList locales{currentLocale, "en", "C"};
for (const QString &locale : locales) {
QString result = tmp.value(locale, QString()).toString();
if (!result.isEmpty())
return result;

View File

@@ -364,6 +364,12 @@ void RunControl::copyDataFromRunControl(RunControl *runControl)
d->copyData(runControl->d.get());
}
void RunControl::resetDataForAttachToCore()
{
d->m_workers.clear();
d->state = RunControlState::Initialized;
}
void RunControl::copyDataFromRunConfiguration(RunConfiguration *runConfig)
{
QTC_ASSERT(runConfig, return);

View File

@@ -150,6 +150,7 @@ public:
void copyDataFromRunConfiguration(RunConfiguration *runConfig);
void copyDataFromRunControl(RunControl *runControl);
void resetDataForAttachToCore();
void setAutoDeleteOnStop(bool autoDelete);

View File

@@ -48,10 +48,7 @@ const char TEXTEDITOR_CONTEXT_ID[] = "QmlDesigner.TextEditorContext";
TextEditorView::TextEditorView(ExternalDependenciesInterface &externalDependencies)
: AbstractView{externalDependencies}
, m_widget(new TextEditorWidget(this))
, m_textEditorContext(new Internal::TextEditorContext(m_widget))
{
Core::ICore::addContextObject(m_textEditorContext);
Core::Context context(TEXTEDITOR_CONTEXT_ID);
/*
@@ -87,7 +84,11 @@ void TextEditorView::modelAttached(Model *model)
// Set the context of the text editor, but we add another special context to override shortcuts.
Core::Context context = textEditor->context();
context.prepend(TEXTEDITOR_CONTEXT_ID);
m_textEditorContext = new Internal::TextEditorContext(m_widget);
m_textEditorContext->setWidget(textEditor->widget()); // toplevel focus widget of the editor
m_textEditorContext->setContext(context);
Core::ICore::addContextObject(m_textEditorContext);
m_widget->setTextEditor(std::move(textEditor));
}

View File

@@ -85,7 +85,7 @@ public:
private:
QPointer<TextEditorWidget> m_widget;
Internal::TextEditorContext *m_textEditorContext;
Internal::TextEditorContext *m_textEditorContext = nullptr;
bool m_errorState = false;
};

View File

@@ -85,16 +85,16 @@ void NavigatorContext::contextHelp(const HelpCallback &callback) const
qobject_cast<NavigatorWidget *>(m_widget)->contextHelp(callback);
}
TextEditorContext::TextEditorContext(QWidget *widget)
: IContext(widget)
TextEditorContext::TextEditorContext(TextEditorWidget *parent)
: IContext(parent)
, m_parent(parent)
{
setWidget(widget);
setContext(Core::Context(Constants::C_QMLTEXTEDITOR, Constants::C_QT_QUICK_TOOLS_MENU));
}
void TextEditorContext::contextHelp(const HelpCallback &callback) const
{
qobject_cast<TextEditorWidget *>(m_widget)->contextHelp(callback);
m_parent->contextHelp(callback);
}
} // namespace QmlDesigner::Internal

View File

@@ -6,6 +6,9 @@
#include <coreplugin/icontext.h>
namespace QmlDesigner {
class TextEditorWidget;
namespace Internal {
/**
@@ -70,8 +73,11 @@ class TextEditorContext : public Core::IContext
Q_OBJECT
public:
TextEditorContext(QWidget *widget);
TextEditorContext(TextEditorWidget *parent);
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
private:
TextEditorWidget *m_parent = nullptr;
};
} // namespace Internal
} // namespace QmlDesigner

View File

@@ -45,7 +45,7 @@ const char CUSTOM_COMMAND[] = "QmlJSEditor.useCustomFormatCommand";
const char CUSTOM_ANALYZER[] = "QmlJSEditor.useCustomAnalyzer";
const char DISABLED_MESSAGES[] = "QmlJSEditor.disabledMessages";
const char DISABLED_MESSAGES_NONQUICKUI[] = "QmlJSEditor.disabledMessagesNonQuickUI";
const char DEFAULT_CUSTOM_FORMAT_COMMAND[] = "%{CurrentDocument:Project:QT_HOST_BINS}/qmlformat";
const char DEFAULT_CUSTOM_FORMAT_COMMAND[] = "%{CurrentDocument:Project:QT_HOST_BINS}/qmlformat%{HostOs:ExecutableSuffix}";
using namespace QmlJSEditor::Internal;
using namespace Utils;

View File

@@ -481,6 +481,10 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare
&QmllsSettingsManager::settingsChanged,
this,
&Internal::QmlJSEditorDocumentPrivate::settingsChanged);
connect(modelManager,
&ModelManagerInterface::projectInfoUpdated,
this,
&Internal::QmlJSEditorDocumentPrivate::settingsChanged);
// semantic info
m_semanticInfoUpdater = new SemanticInfoUpdater();
@@ -751,7 +755,7 @@ static Utils::FilePath qmllsForFile(const Utils::FilePath &file,
&& QVersionNumber::fromString(pInfo.qtVersionString) < settings.mininumQmllsVersion) {
return {};
}
return pInfo.qmllsPath;
return pInfo.qmllsPath.exists() ? pInfo.qmllsPath : Utils::FilePath();
}
void QmlJSEditorDocumentPrivate::settingsChanged()
@@ -766,7 +770,7 @@ void QmlJSEditorDocumentPrivate::settingsChanged()
auto lspClientManager = LanguageClient::LanguageClientManager::instance();
if (newQmlls.isEmpty()) {
qCDebug(qmllsLog) << "disabling qmlls for" << q->filePath();
if (LanguageClient::Client *client = lspClientManager->clientForDocument(q)) {
if (lspClientManager->clientForDocument(q)) {
qCDebug(qmllsLog) << "deactivating " << q->filePath() << "in qmlls" << newQmlls;
lspClientManager->openDocumentWithClient(q, nullptr);
} else

View File

@@ -49,7 +49,7 @@ QString uniqueProjectName(const QString &path)
/***********************/
QdsNewDialog::QdsNewDialog(QWidget *parent)
: m_dialog{new QQuickWidget(parent)}
: m_dialog{Utils::makeUniqueObjectPtr<QQuickWidget>(parent)}
, m_categoryModel{new PresetCategoryModel(&m_presetData, this)}
, m_presetModel{new PresetModel(&m_presetData, this)}
, m_screenSizeModel{new ScreenSizeModel(this)}
@@ -57,7 +57,7 @@ QdsNewDialog::QdsNewDialog(QWidget *parent)
, m_recentsStore{"RecentPresets.json", StorePolicy::UniqueValues}
, m_userPresetsStore{"UserPresets.json", StorePolicy::UniqueNames}
{
setParent(m_dialog);
connect(m_dialog.get(), &QObject::destroyed, this, &QObject::deleteLater);
m_recentsStore.setReverseOrder();
m_recentsStore.setMaximum(10);
@@ -89,9 +89,10 @@ QdsNewDialog::QdsNewDialog(QWidget *parent)
m_dialog->installEventFilter(this);
QObject::connect(&m_wizard, &WizardHandler::wizardCreationFailed, this, [this] {
QMessageBox::critical(m_dialog, tr("New Project"), tr("Failed to initialize data."));
// TODO: if the dialog itself could react on the error
// the would not be necessary
QMessageBox::critical(m_dialog.get(), tr("New Project"), tr("Failed to initialize data."));
reject();
deleteLater();
});
QObject::connect(m_styleModel.data(), &StyleModel::modelAboutToBeReset, this, [this] {
@@ -101,7 +102,7 @@ QdsNewDialog::QdsNewDialog(QWidget *parent)
bool QdsNewDialog::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_dialog && event->type() == QEvent::KeyPress
if (obj == m_dialog.get() && event->type() == QEvent::KeyPress
&& static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape) {
reject();
return true;
@@ -314,7 +315,7 @@ void QdsNewDialog::setWizardFactories(QList<Core::IWizardFactory *> factories_,
{
Utils::Id platform = Utils::Id::fromSetting("Desktop");
WizardFactories factories{factories_, m_dialog, platform};
WizardFactories factories{factories_, m_dialog.get(), platform};
std::vector<UserPresetData> recents = m_recentsStore.fetchAll();
std::vector<UserPresetData> userPresets = m_userPresetsStore.fetchAll();
@@ -404,8 +405,6 @@ void QdsNewDialog::accept()
m_recentsStore.save(preset);
m_dialog->close();
m_dialog->deleteLater();
m_dialog = nullptr;
}
void QdsNewDialog::reject()
@@ -415,12 +414,13 @@ void QdsNewDialog::reject()
m_wizard.destroyWizard();
m_dialog->close();
m_dialog = nullptr;
m_dialog.reset();
}
QString QdsNewDialog::chooseProjectLocation()
{
Utils::FilePath newPath = Utils::FileUtils::getExistingDirectory(m_dialog, tr("Choose Directory"),
Utils::FilePath newPath = Utils::FileUtils::getExistingDirectory(m_dialog.get(),
tr("Choose Directory"),
m_qmlProjectLocation);
return QDir::toNativeSeparators(newPath.toString());
@@ -473,7 +473,7 @@ void QdsNewDialog::savePresetDialogAccept()
UserPresetData preset = currentUserPresetData(m_qmlPresetName);
if (!m_userPresetsStore.save(preset)) {
QMessageBox::warning(m_dialog,
QMessageBox::warning(m_dialog.get(),
tr("Save Preset"),
tr("A preset with this name already exists."));
return;

View File

@@ -7,6 +7,7 @@
#include <coreplugin/dialogs/newdialog.h>
#include <utils/infolabel.h>
#include <utils/uniqueobjectptr.h>
#include "wizardhandler.h"
#include "presetmodel.h"
@@ -64,7 +65,7 @@ public:
explicit QdsNewDialog(QWidget *parent);
QWidget *widget() override { return m_dialog; }
QWidget *widget() override { return m_dialog.get(); }
void setWizardFactories(QList<Core::IWizardFactory *> factories, const Utils::FilePath &defaultLocation,
const QVariantMap &extraVariables) override;
@@ -139,7 +140,7 @@ private slots:
void onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel);
private:
QQuickWidget *m_dialog = nullptr;
Utils::UniqueObjectPtr<QQuickWidget> m_dialog;
PresetData m_presetData;
QPointer<PresetCategoryModel> m_categoryModel;

View File

@@ -53,7 +53,10 @@ void WizardHandler::setupWizard()
initializeProjectPage(m_wizard->page(0));
initializeFieldsPage(m_wizard->page(1));
if (!m_detailsPage) {
emit wizardCreationFailed();
return;
}
auto *screenFactorModel = getScreenFactorModel(m_detailsPage);
auto *styleModel = getStyleModel(m_detailsPage);

View File

@@ -2343,6 +2343,13 @@ void TextEditorWidget::selectWordUnderCursor()
setMultiTextCursor(cursor);
}
void TextEditorWidget::clearSelection()
{
MultiTextCursor cursor = multiTextCursor();
cursor.clearSelection();
setMultiTextCursor(cursor);
}
void TextEditorWidget::showContextMenu()
{
QTextCursor tc = textCursor();
@@ -4244,6 +4251,10 @@ void TextEditorWidgetPrivate::registerActions()
.setContext(m_editorContext)
.addOnTriggered([this] { q->selectWordUnderCursor(); })
.setScriptable(true);
ActionBuilder(this, CLEAR_SELECTION)
.setContext(m_editorContext)
.addOnTriggered([this] { q->clearSelection(); })
.setScriptable(true);
ActionBuilder(this, GOTO_DOCUMENT_START)
.setContext(m_editorContext)
@@ -4754,8 +4765,11 @@ void TextEditorWidgetPrivate::highlightSearchResults(const QTextBlock &block, co
break;
if (m_findFlags & FindWholeWords) {
auto posAtWordSeparator = [](const QString &text, int idx) {
if (idx < 0 || idx >= text.length())
return false;
if (idx < 0)
return QTC_GUARD(idx == -1);
int textLength = text.length();
if (idx >= textLength)
return QTC_GUARD(idx == textLength);
const QChar c = text.at(idx);
return !c.isLetterOrNumber() && c != QLatin1Char('_');
};

View File

@@ -430,6 +430,7 @@ public:
virtual bool selectBlockUp();
virtual bool selectBlockDown();
void selectWordUnderCursor();
void clearSelection();
void showContextMenu();

View File

@@ -143,6 +143,7 @@ const char GOTO_BLOCK_END_WITH_SELECTION[] = "TextEditor.GotoBlockEndWithSelecti
const char SELECT_BLOCK_UP[] = "TextEditor.SelectBlockUp";
const char SELECT_BLOCK_DOWN[] = "TextEditor.SelectBlockDown";
const char SELECT_WORD_UNDER_CURSOR[] = "TextEditor.SelectWordUnderCursor";
const char CLEAR_SELECTION[] = "TextEditor.ClearSelection";
const char VIEW_PAGE_UP[] = "TextEditor.viewPageUp";
const char VIEW_PAGE_DOWN[] = "TextEditor.viewPageDown";
const char VIEW_LINE_UP[] = "TextEditor.viewLineUp";

View File

@@ -544,6 +544,8 @@ void TextEditorPlugin::createEditorCommands()
.setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Shift+Alt+U")))
.addToContainer(M_EDIT_ADVANCED, G_EDIT_BLOCKS);
TextActionBuilder(this, SELECT_WORD_UNDER_CURSOR).setText(Tr::tr("Select Word Under Cursor"));
TextActionBuilder(this, CLEAR_SELECTION)
.setText(QCoreApplication::translate("QtC::Terminal", "Clear Selection"));
TextActionBuilder(this, GOTO_DOCUMENT_START).setText(Tr::tr("Go to Document Start"));
TextActionBuilder(this, GOTO_DOCUMENT_END).setText(Tr::tr("Go to Document End"));