Merge remote-tracking branch 'origin/7.0'

Change-Id: Icaa605bcaa44ad50a98a63251cb4553bfd411b0a
This commit is contained in:
Eike Ziller
2022-01-27 09:41:53 +01:00
85 changed files with 442 additions and 1410 deletions

View File

@@ -307,7 +307,7 @@
To view information about the C++ code model in the
\uicontrol {C++ Code Model Inspector} dialog and write it to a log file,
select \uicontrol Tools > \uicontrol {C++} >
select \uicontrol Tools > \uicontrol {Debug \QC } >
\uicontrol {Inspect C++ Code Model} or press \key {Ctrl+Shift+F12}.
\QC generates the code model inspection log file in a temporary folder.

View File

@@ -206,12 +206,12 @@ void NodeInstanceClientProxy::writeCommand(const QVariant &command)
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
{"name", cmd.name().toStdString()},
{"counter", m_writeCommandCounter});
{"counter", int64_t(m_writeCommandCounter)});
} else {
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
{"name", command.typeName()},
{"counter", m_writeCommandCounter});
{"counter", int64_t(m_writeCommandCounter)});
}
}
#endif
@@ -409,14 +409,14 @@ void NodeInstanceClientProxy::readDataStream()
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
{"name", cmd.name().toStdString()},
{"counter", readCommandCounter});
{"counter", int64_t(readCommandCounter)});
// Do not dispatch this command.
continue;
} else {
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
{"name", command.typeName()},
{"counter", readCommandCounter});
{"counter", int64_t(readCommandCounter)});
}
}
#endif

View File

@@ -35,7 +35,7 @@ jobs:
}
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Download Ninja and CMake
shell: cmake -P {0}

View File

@@ -7,6 +7,5 @@ add_qtc_library(Nanotrace
PROPERTIES
CXX_VISIBILITY_PRESET default
VISIBILITY_INLINES_HIDDEN OFF
WINDOWS_EXPORT_ALL_SYMBOLS ON
)

View File

@@ -25,6 +25,15 @@
#pragma once
#include <QtGlobal>
#if defined(NANOTRACE_LIBRARY)
# define NANOTRACESHARED_EXPORT Q_DECL_EXPORT
#else
# define NANOTRACESHARED_EXPORT Q_DECL_IMPORT
#endif
#include <string>
#include <variant>
#include <vector>
@@ -68,7 +77,7 @@ using Units = std::chrono::nanoseconds;
using Clock = std::chrono::high_resolution_clock;
using TimePoint = std::chrono::time_point< Clock >;
class Arg
class NANOTRACESHARED_EXPORT Arg
{
public:
using SupportedType = std::variant<int, int64_t, double, std::string>;
@@ -82,19 +91,19 @@ private:
SupportedType m_value;
};
void init(const std::string &process, const std::string &thread, const std::string &path);
NANOTRACESHARED_EXPORT void init(const std::string &process, const std::string &thread, const std::string &path);
void shutdown();
NANOTRACESHARED_EXPORT void shutdown();
void flush();
NANOTRACESHARED_EXPORT void flush();
void addTracePoint(
NANOTRACESHARED_EXPORT void addTracePoint(
const std::string &name,
const std::string &cat,
char phase,
std::initializer_list< Nanotrace::Arg > arguments);
class ScopeTracer
class NANOTRACESHARED_EXPORT ScopeTracer
{
public:
ScopeTracer(

View File

@@ -2,7 +2,6 @@ QtcLibrary {
name: "Nanotrace"
cpp.defines: base.concat("NANOTRACE_LIBRARY", "NANOTRACE_ENABLED")
cpp.visibility: "default"
files: [
"nanotrace.cpp",

View File

@@ -25,7 +25,6 @@ add_qtc_library(Utils
commandline.cpp commandline.h
completinglineedit.cpp completinglineedit.h
completingtextedit.cpp completingtextedit.h
consoleprocess.cpp consoleprocess.h
cpplanguage_details.h
crumblepath.cpp crumblepath.h
declarationmacros.h

View File

@@ -88,9 +88,7 @@ static FilePath findQmakeInDir(const FilePath &dir)
// Prefer qmake-qt5 to qmake-qt4 by sorting the filenames in reverse order.
const FilePaths candidates = dir.dirEntries(
BuildableHelperLibrary::possibleQMakeCommands(),
QDir::Files,
QDirIterator::NoIteratorFlags,
{BuildableHelperLibrary::possibleQMakeCommands(), QDir::Files},
QDir::Name | QDir::Reversed);
for (const FilePath &candidate : candidates) {
if (candidate == qmakePath)

View File

@@ -1,866 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "consoleprocess.h"
#include <utils/environment.h>
#include <utils/hostosinfo.h>
#include <utils/commandline.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/terminalcommand.h>
#include <utils/winutils.h>
#include <QAbstractEventDispatcher>
#include <QCoreApplication>
#include <QDir>
#include <QLocalServer>
#include <QLocalSocket>
#include <QRegularExpression>
#include <QTemporaryFile>
#include <QTextCodec>
#include <QTimer>
#include <QWinEventNotifier>
#ifdef Q_OS_WIN
# include <windows.h>
# include <stdlib.h>
# include <cstring>
#else
# include <sys/stat.h>
# include <sys/types.h>
# include <errno.h>
# include <string.h>
# include <unistd.h>
#endif
namespace Utils {
static QString modeOption(ConsoleProcess::Mode m)
{
switch (m) {
case ConsoleProcess::Debug:
return QLatin1String("debug");
case ConsoleProcess::Suspend:
return QLatin1String("suspend");
case ConsoleProcess::Run:
break;
}
return QLatin1String("run");
}
static QString msgCommChannelFailed(const QString &error)
{
return ConsoleProcess::tr("Cannot set up communication channel: %1").arg(error);
}
static QString msgPromptToClose()
{
// Shown in a terminal which might have a different character set on Windows.
return ConsoleProcess::tr("Press <RETURN> to close this window...");
}
static QString msgCannotCreateTempFile(const QString &why)
{
return ConsoleProcess::tr("Cannot create temporary file: %1").arg(why);
}
static QString msgCannotWriteTempFile()
{
return ConsoleProcess::tr("Cannot write temporary file. Disk full?");
}
static QString msgCannotCreateTempDir(const QString & dir, const QString &why)
{
return ConsoleProcess::tr("Cannot create temporary directory \"%1\": %2").arg(dir, why);
}
static QString msgUnexpectedOutput(const QByteArray &what)
{
return ConsoleProcess::tr("Unexpected output from helper program (%1).").arg(QString::fromLatin1(what));
}
static QString msgCannotChangeToWorkDir(const FilePath &dir, const QString &why)
{
return ConsoleProcess::tr("Cannot change to working directory \"%1\": %2").arg(dir.toString(), why);
}
static QString msgCannotExecute(const QString & p, const QString &why)
{
return ConsoleProcess::tr("Cannot execute \"%1\": %2").arg(p, why);
}
// ConsoleProcessPrivate
class ConsoleProcessPrivate
{
public:
ConsoleProcessPrivate() = default;
ConsoleProcess::Mode m_mode = ConsoleProcess::Run;
FilePath m_workingDir;
Environment m_environment;
qint64 m_processId = 0;
int m_exitCode = 0;
CommandLine m_commandLine;
QProcess::ExitStatus m_appStatus = QProcess::NormalExit;
QLocalServer m_stubServer;
QLocalSocket *m_stubSocket = nullptr;
QTemporaryFile *m_tempFile = nullptr;
QProcess::ProcessError m_error = QProcess::UnknownError;
QString m_errorString;
bool m_abortOnMetaChars = true;
bool m_runAsRoot = false;
// Used on Unix only
QtcProcess m_process;
QTimer *m_stubConnectTimer = nullptr;
QByteArray m_stubServerDir;
// Used on Windows only
qint64 m_appMainThreadId = 0;
#ifdef Q_OS_WIN
PROCESS_INFORMATION *m_pid = nullptr;
HANDLE m_hInferior = NULL;
QWinEventNotifier *inferiorFinishedNotifier = nullptr;
QWinEventNotifier *processFinishedNotifier = nullptr;
#endif
};
// ConsoleProcess
ConsoleProcess::ConsoleProcess(QObject *parent) :
QObject(parent), d(new ConsoleProcessPrivate)
{
connect(&d->m_stubServer, &QLocalServer::newConnection,
this, &ConsoleProcess::stubConnectionAvailable);
d->m_process.setProcessChannelMode(QProcess::ForwardedChannels);
}
ConsoleProcess::~ConsoleProcess()
{
stopProcess();
delete d;
}
void ConsoleProcess::setCommand(const CommandLine &command)
{
d->m_commandLine = command;
}
const CommandLine &ConsoleProcess::commandLine() const
{
return d->m_commandLine;
}
static QString quoteWinCommand(const QString &program)
{
const QChar doubleQuote = QLatin1Char('"');
// add the program as the first arg ... it works better
QString programName = program;
programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
if (!programName.startsWith(doubleQuote) && !programName.endsWith(doubleQuote)
&& programName.contains(QLatin1Char(' '))) {
programName.prepend(doubleQuote);
programName.append(doubleQuote);
}
return programName;
}
static QString quoteWinArgument(const QString &arg)
{
if (arg.isEmpty())
return QString::fromLatin1("\"\"");
QString ret(arg);
// Quotes are escaped and their preceding backslashes are doubled.
ret.replace(QRegularExpression("(\\\\*)\""), "\\1\\1\\\"");
if (ret.contains(QRegularExpression("\\s"))) {
// The argument must not end with a \ since this would be interpreted
// as escaping the quote -- rather put the \ behind the quote: e.g.
// rather use "foo"\ than "foo\"
int i = ret.length();
while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
--i;
ret.insert(i, QLatin1Char('"'));
ret.prepend(QLatin1Char('"'));
}
return ret;
}
// Quote a Windows command line correctly for the "CreateProcess" API
static QString createWinCommandline(const QString &program, const QStringList &args)
{
QString programName = quoteWinCommand(program);
for (const QString &arg : args) {
programName += QLatin1Char(' ');
programName += quoteWinArgument(arg);
}
return programName;
}
static QString createWinCommandline(const QString &program, const QString &args)
{
QString programName = quoteWinCommand(program);
if (!args.isEmpty()) {
programName += QLatin1Char(' ');
programName += args;
}
return programName;
}
bool ConsoleProcess::startTerminalEmulator(const QString &workingDir, const Environment &env)
{
#ifdef Q_OS_WIN
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pinfo;
ZeroMemory(&pinfo, sizeof(pinfo));
QString cmdLine = createWinCommandline(
QString::fromLocal8Bit(qgetenv("COMSPEC")), QString());
// cmdLine is assumed to be detached -
// https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083
QString totalEnvironment = env.toStringList().join(QChar(QChar::Null)) + QChar(QChar::Null);
LPVOID envPtr = (env != Environment::systemEnvironment())
? (WCHAR *)(totalEnvironment.utf16()) : nullptr;
bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(),
0, 0, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
envPtr, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(),
&si, &pinfo);
if (success) {
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
}
return success;
#else
const TerminalCommand term = TerminalCommand::terminalEmulator();
QProcess process;
process.setProgram(term.command);
process.setArguments(ProcessArgs::splitArgs(term.openArgs));
process.setProcessEnvironment(env.toProcessEnvironment());
process.setWorkingDirectory(workingDir);
return process.startDetached();
#endif
}
void ConsoleProcess::setAbortOnMetaChars(bool abort)
{
d->m_abortOnMetaChars = abort;
}
qint64 ConsoleProcess::applicationMainThreadID() const
{
if (HostOsInfo::isWindowsHost())
return d->m_appMainThreadId;
return -1;
}
void ConsoleProcess::start()
{
if (isRunning())
return;
d->m_errorString.clear();
d->m_error = QProcess::UnknownError;
#ifdef Q_OS_WIN
QString pcmd;
QString pargs;
if (d->m_mode != Run) { // The debugger engines already pre-process the arguments.
pcmd = d->m_commandLine.executable().toString();
pargs = d->m_commandLine.arguments();
} else {
ProcessArgs outArgs;
ProcessArgs::prepareCommand(d->m_commandLine, &pcmd, &outArgs,
&d->m_environment, &d->m_workingDir);
pargs = outArgs.toWindowsArgs();
}
const QString err = stubServerListen();
if (!err.isEmpty()) {
emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
return;
}
QStringList env = d->m_environment.toStringList();
if (!env.isEmpty()) {
d->m_tempFile = new QTemporaryFile();
if (!d->m_tempFile->open()) {
cleanupAfterStartFailure(msgCannotCreateTempFile(d->m_tempFile->errorString()));
return;
}
QString outString;
QTextStream out(&outString);
// Add PATH and SystemRoot environment variables in case they are missing
const QStringList fixedEnvironment = [env] {
QStringList envStrings = env;
// add PATH if necessary (for DLL loading)
if (envStrings.filter(QRegularExpression("^PATH=.*", QRegularExpression::CaseInsensitiveOption)).isEmpty()) {
QByteArray path = qgetenv("PATH");
if (!path.isEmpty())
envStrings.prepend(QString::fromLatin1("PATH=%1").arg(QString::fromLocal8Bit(path)));
}
// add systemroot if needed
if (envStrings.filter(QRegularExpression("^SystemRoot=.*", QRegularExpression::CaseInsensitiveOption)).isEmpty()) {
QByteArray systemRoot = qgetenv("SystemRoot");
if (!systemRoot.isEmpty())
envStrings.prepend(QString::fromLatin1("SystemRoot=%1").arg(QString::fromLocal8Bit(systemRoot)));
}
return envStrings;
}();
for (const QString &var : fixedEnvironment)
out << var << QChar(0);
out << QChar(0);
const QTextCodec *textCodec = QTextCodec::codecForName("UTF-16LE");
QTC_CHECK(textCodec);
const QByteArray outBytes = textCodec ? textCodec->fromUnicode(outString) : QByteArray();
if (!textCodec || d->m_tempFile->write(outBytes) < 0) {
cleanupAfterStartFailure(msgCannotWriteTempFile());
return;
}
d->m_tempFile->flush();
}
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
d->m_pid = new PROCESS_INFORMATION;
ZeroMemory(d->m_pid, sizeof(PROCESS_INFORMATION));
QString workDir = workingDirectory().toUserOutput();
if (!workDir.isEmpty() && !workDir.endsWith(QLatin1Char('\\')))
workDir.append(QLatin1Char('\\'));
QStringList stubArgs;
stubArgs << modeOption(d->m_mode)
<< d->m_stubServer.fullServerName()
<< workDir
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString())
<< createWinCommandline(pcmd, pargs)
<< msgPromptToClose();
const QString cmdLine = createWinCommandline(
QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub.exe"), stubArgs);
bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
0, 0, FALSE, CREATE_NEW_CONSOLE,
0, 0,
&si, d->m_pid);
if (!success) {
delete d->m_pid;
d->m_pid = nullptr;
const QString msg = tr("The process \"%1\" could not be started: %2")
.arg(cmdLine, winErrorMessage(GetLastError()));
cleanupAfterStartFailure(msg);
return;
}
d->processFinishedNotifier = new QWinEventNotifier(d->m_pid->hProcess, this);
connect(d->processFinishedNotifier, &QWinEventNotifier::activated,
this, &ConsoleProcess::stubExited);
#else
ProcessArgs::SplitError perr;
ProcessArgs pargs = ProcessArgs::prepareArgs(d->m_commandLine.arguments(),
&perr,
HostOsInfo::hostOs(),
&d->m_environment,
&d->m_workingDir,
d->m_abortOnMetaChars);
QString pcmd;
if (perr == ProcessArgs::SplitOk) {
pcmd = d->m_commandLine.executable().toString();
} else {
if (perr != ProcessArgs::FoundMeta) {
emitError(QProcess::FailedToStart, tr("Quoting error in command."));
return;
}
if (d->m_mode == Debug) {
// FIXME: QTCREATORBUG-2809
emitError(QProcess::FailedToStart, tr("Debugging complex shell commands in a terminal"
" is currently not supported."));
return;
}
pcmd = qEnvironmentVariable("SHELL", "/bin/sh");
pargs = ProcessArgs::createUnixArgs(
{"-c", (ProcessArgs::quoteArg(d->m_commandLine.executable().toString())
+ ' ' + d->m_commandLine.arguments())});
}
ProcessArgs::SplitError qerr;
const TerminalCommand terminal = TerminalCommand::terminalEmulator();
const ProcessArgs terminalArgs = ProcessArgs::prepareArgs(terminal.executeArgs,
&qerr,
HostOsInfo::hostOs(),
&d->m_environment,
&d->m_workingDir);
if (qerr != ProcessArgs::SplitOk) {
emitError(QProcess::FailedToStart, qerr == ProcessArgs::BadQuoting
? tr("Quoting error in terminal command.")
: tr("Terminal command may not be a shell command."));
return;
}
const QString err = stubServerListen();
if (!err.isEmpty()) {
emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
return;
}
d->m_environment.unset(QLatin1String("TERM"));
const QStringList env = d->m_environment.toStringList();
if (!env.isEmpty()) {
d->m_tempFile = new QTemporaryFile();
if (!d->m_tempFile->open()) {
cleanupAfterStartFailure(msgCannotCreateTempFile(d->m_tempFile->errorString()));
return;
}
QByteArray contents;
for (const QString &var : env) {
const QByteArray l8b = var.toLocal8Bit();
contents.append(l8b.constData(), l8b.size() + 1);
}
if (d->m_tempFile->write(contents) != contents.size() || !d->m_tempFile->flush()) {
cleanupAfterStartFailure(msgCannotWriteTempFile());
return;
}
}
const QString stubPath = QCoreApplication::applicationDirPath()
+ QLatin1String("/" RELATIVE_LIBEXEC_PATH "/qtcreator_process_stub");
QStringList allArgs = terminalArgs.toUnixArgs();
if (d->m_runAsRoot)
allArgs << "sudo" << "-A";
allArgs << stubPath
<< modeOption(d->m_mode)
<< d->m_stubServer.fullServerName()
<< msgPromptToClose()
<< workingDirectory().path()
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString())
<< QString::number(getpid())
<< pcmd
<< pargs.toUnixArgs();
if (terminal.needsQuotes)
allArgs = QStringList { ProcessArgs::joinArgs(allArgs) };
d->m_process.setEnvironment(d->m_environment);
d->m_process.setCommand({FilePath::fromString(terminal.command), allArgs});
d->m_process.start();
if (!d->m_process.waitForStarted()) {
const QString msg = tr("Cannot start the terminal emulator \"%1\", change the setting in the "
"Environment options.").arg(terminal.command);
cleanupAfterStartFailure(msg);
return;
}
d->m_stubConnectTimer = new QTimer(this);
connect(d->m_stubConnectTimer, &QTimer::timeout, this, &ConsoleProcess::stopProcess);
d->m_stubConnectTimer->setSingleShot(true);
d->m_stubConnectTimer->start(10000);
#endif
}
void ConsoleProcess::cleanupAfterStartFailure(const QString &errorMessage)
{
stubServerShutdown();
emitError(QProcess::FailedToStart, errorMessage);
delete d->m_tempFile;
d->m_tempFile = nullptr;
}
void ConsoleProcess::finish(int exitCode, QProcess::ExitStatus exitStatus)
{
d->m_processId = 0;
d->m_exitCode = exitCode;
d->m_appStatus = exitStatus;
emit finished();
}
void Utils::ConsoleProcess::kickoffProcess()
{
#ifdef Q_OS_WIN
// Not used.
#else
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
d->m_stubSocket->write("c", 1);
d->m_stubSocket->flush();
}
#endif
}
void ConsoleProcess::interruptProcess()
{
#ifdef Q_OS_WIN
// Not used.
#else
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
d->m_stubSocket->write("i", 1);
d->m_stubSocket->flush();
}
#endif
}
void ConsoleProcess::killProcess()
{
#ifdef Q_OS_WIN
if (d->m_hInferior != NULL) {
TerminateProcess(d->m_hInferior, (unsigned)-1);
cleanupInferior();
}
#else
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
d->m_stubSocket->write("k", 1);
d->m_stubSocket->flush();
}
#endif
d->m_processId = 0;
}
void ConsoleProcess::killStub()
{
#ifdef Q_OS_WIN
if (d->m_pid) {
TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
WaitForSingleObject(d->m_pid->hProcess, INFINITE);
cleanupStub();
}
#else
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
d->m_stubSocket->write("s", 1);
d->m_stubSocket->flush();
}
stubServerShutdown();
#endif
}
void ConsoleProcess::stopProcess()
{
killProcess();
killStub();
if (isRunning() && HostOsInfo::isAnyUnixHost()) {
d->m_process.terminate();
if (!d->m_process.waitForFinished(1000) && d->m_process.state() == QProcess::Running) {
d->m_process.kill();
d->m_process.waitForFinished();
}
}
}
bool ConsoleProcess::isRunning() const
{
#ifdef Q_OS_WIN
return d->m_pid != nullptr;
#else
return d->m_process.state() != QProcess::NotRunning
|| (d->m_stubSocket && d->m_stubSocket->isOpen());
#endif
}
QString ConsoleProcess::stubServerListen()
{
#ifdef Q_OS_WIN
if (d->m_stubServer.listen(QString::fromLatin1("creator-%1-%2")
.arg(QCoreApplication::applicationPid())
.arg(rand())))
return QString();
return d->m_stubServer.errorString();
#else
// We need to put the socket in a private directory, as some systems simply do not
// check the file permissions of sockets.
QString stubFifoDir;
while (true) {
{
QTemporaryFile tf;
if (!tf.open())
return msgCannotCreateTempFile(tf.errorString());
stubFifoDir = tf.fileName();
}
// By now the temp file was deleted again
d->m_stubServerDir = QFile::encodeName(stubFifoDir);
if (!::mkdir(d->m_stubServerDir.constData(), 0700))
break;
if (errno != EEXIST)
return msgCannotCreateTempDir(stubFifoDir, QString::fromLocal8Bit(strerror(errno)));
}
const QString stubServer = stubFifoDir + QLatin1String("/stub-socket");
if (!d->m_stubServer.listen(stubServer)) {
::rmdir(d->m_stubServerDir.constData());
return tr("Cannot create socket \"%1\": %2").arg(stubServer, d->m_stubServer.errorString());
}
return QString();
#endif
}
void ConsoleProcess::stubServerShutdown()
{
#ifdef Q_OS_WIN
delete d->m_stubSocket;
d->m_stubSocket = nullptr;
if (d->m_stubServer.isListening())
d->m_stubServer.close();
#else
if (d->m_stubSocket) {
readStubOutput(); // we could get the shutdown signal before emptying the buffer
d->m_stubSocket->disconnect(); // avoid getting queued readyRead signals
d->m_stubSocket->deleteLater(); // we might be called from the disconnected signal of m_stubSocket
}
d->m_stubSocket = nullptr;
if (d->m_stubServer.isListening()) {
d->m_stubServer.close();
::rmdir(d->m_stubServerDir.constData());
}
#endif
}
void ConsoleProcess::stubConnectionAvailable()
{
if (d->m_stubConnectTimer) {
delete d->m_stubConnectTimer;
d->m_stubConnectTimer = nullptr;
}
d->m_stubSocket = d->m_stubServer.nextPendingConnection();
connect(d->m_stubSocket, &QIODevice::readyRead, this, &ConsoleProcess::readStubOutput);
if (HostOsInfo::isAnyUnixHost())
connect(d->m_stubSocket, &QLocalSocket::disconnected, this, &ConsoleProcess::stubExited);
}
static QString errorMsg(int code)
{
return QString::fromLocal8Bit(strerror(code));
}
void ConsoleProcess::readStubOutput()
{
while (d->m_stubSocket->canReadLine()) {
QByteArray out = d->m_stubSocket->readLine();
#ifdef Q_OS_WIN
out.chop(2); // \r\n
if (out.startsWith("err:chdir ")) {
emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), winErrorMessage(out.mid(10).toInt())));
} else if (out.startsWith("err:exec ")) {
emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toUserOutput(), winErrorMessage(out.mid(9).toInt())));
} else if (out.startsWith("thread ")) { // Windows only
d->m_appMainThreadId = out.mid(7).toLongLong();
} else if (out.startsWith("pid ")) {
// Will not need it any more
delete d->m_tempFile;
d->m_tempFile = nullptr;
d->m_processId = out.mid(4).toLongLong();
d->m_hInferior = OpenProcess(
SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE,
FALSE, d->m_processId);
if (d->m_hInferior == NULL) {
emitError(QProcess::FailedToStart, tr("Cannot obtain a handle to the inferior: %1")
.arg(winErrorMessage(GetLastError())));
// Uhm, and now what?
continue;
}
d->inferiorFinishedNotifier = new QWinEventNotifier(d->m_hInferior, this);
connect(d->inferiorFinishedNotifier, &QWinEventNotifier::activated, this, [this] {
DWORD chldStatus;
if (!GetExitCodeProcess(d->m_hInferior, &chldStatus))
emitError(QProcess::UnknownError, tr("Cannot obtain exit status from inferior: %1")
.arg(winErrorMessage(GetLastError())));
cleanupInferior();
finish(chldStatus, QProcess::NormalExit);
});
emit started();
} else {
emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
break;
}
#else
out.chop(1); // \n
if (out.startsWith("err:chdir ")) {
emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), errorMsg(out.mid(10).toInt())));
} else if (out.startsWith("err:exec ")) {
emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toString(), errorMsg(out.mid(9).toInt())));
} else if (out.startsWith("spid ")) {
delete d->m_tempFile;
d->m_tempFile = nullptr;
} else if (out.startsWith("pid ")) {
d->m_processId = out.mid(4).toInt();
emit started();
} else if (out.startsWith("exit ")) {
finish(out.mid(5).toInt(), QProcess::NormalExit);
} else if (out.startsWith("crash ")) {
finish(out.mid(6).toInt(), QProcess::CrashExit);
} else {
emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
d->m_process.terminate();
break;
}
#endif
} // while
}
void ConsoleProcess::stubExited()
{
// The stub exit might get noticed before we read the pid for the kill on Windows
// or the error status elsewhere.
if (d->m_stubSocket && d->m_stubSocket->state() == QLocalSocket::ConnectedState)
d->m_stubSocket->waitForDisconnected();
#ifdef Q_OS_WIN
cleanupStub();
if (d->m_hInferior != NULL) {
TerminateProcess(d->m_hInferior, (unsigned)-1);
cleanupInferior();
finish(-1, QProcess::CrashExit);
}
#else
stubServerShutdown();
delete d->m_tempFile;
d->m_tempFile = nullptr;
if (d->m_processId)
finish(-1, QProcess::CrashExit);
#endif
}
void ConsoleProcess::cleanupInferior()
{
#ifdef Q_OS_WIN
delete d->inferiorFinishedNotifier;
d->inferiorFinishedNotifier = nullptr;
CloseHandle(d->m_hInferior);
d->m_hInferior = NULL;
#endif
}
void ConsoleProcess::cleanupStub()
{
#ifdef Q_OS_WIN
stubServerShutdown();
delete d->processFinishedNotifier;
d->processFinishedNotifier = nullptr;
CloseHandle(d->m_pid->hThread);
CloseHandle(d->m_pid->hProcess);
delete d->m_pid;
d->m_pid = nullptr;
delete d->m_tempFile;
d->m_tempFile = nullptr;
#endif
}
void ConsoleProcess::setMode(Mode m)
{
d->m_mode = m;
}
ConsoleProcess::Mode ConsoleProcess::mode() const
{
return d->m_mode;
}
qint64 ConsoleProcess::processId() const
{
return d->m_processId;
}
int ConsoleProcess::exitCode() const
{
return d->m_exitCode;
} // This will be the signal number if exitStatus == CrashExit
QProcess::ExitStatus ConsoleProcess::exitStatus() const
{
return d->m_appStatus;
}
void ConsoleProcess::setWorkingDirectory(const FilePath &dir)
{
d->m_workingDir = dir;
}
FilePath ConsoleProcess::workingDirectory() const
{
return d->m_workingDir;
}
void ConsoleProcess::setEnvironment(const Environment &env)
{
d->m_environment = env;
}
const Utils::Environment &ConsoleProcess::environment() const
{
return d->m_environment;
}
void Utils::ConsoleProcess::setRunAsRoot(bool on)
{
d->m_runAsRoot = on;
}
QProcess::ProcessError ConsoleProcess::error() const
{
return d->m_error;
}
QString ConsoleProcess::errorString() const
{
return d->m_errorString;
}
void ConsoleProcess::emitError(QProcess::ProcessError err, const QString &errorString)
{
d->m_error = err;
d->m_errorString = errorString;
emit errorOccurred(err);
}
} // Utils

View File

@@ -1,108 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "utils_global.h"
#include <QProcess>
namespace Utils {
class CommandLine;
class Environment;
class FilePath;
class QTCREATOR_UTILS_EXPORT ConsoleProcess : public QObject
{
Q_OBJECT
public:
enum Mode { Run, Debug, Suspend };
explicit ConsoleProcess(QObject *parent = nullptr);
~ConsoleProcess() override;
void setCommand(const Utils::CommandLine &command);
const Utils::CommandLine &commandLine() const;
void setAbortOnMetaChars(bool abort);
void setWorkingDirectory(const Utils::FilePath &dir);
Utils::FilePath workingDirectory() const;
void setEnvironment(const Environment &env);
const Environment &environment() const;
void setRunAsRoot(bool on);
QProcess::ProcessError error() const;
QString errorString() const;
void start();
void stopProcess();
public:
void setMode(Mode m);
Mode mode() const;
bool isRunning() const; // This reflects the state of the console+stub
qint64 processId() const;
void kickoffProcess();
void interruptProcess();
qint64 applicationMainThreadID() const;
int exitCode() const;
QProcess::ExitStatus exitStatus() const;
static bool startTerminalEmulator(const QString &workingDir, const Utils::Environment &env);
signals:
void errorOccurred(QProcess::ProcessError error);
// These reflect the state of the actual client process
void started();
void finished();
private:
void stubConnectionAvailable();
void readStubOutput();
void stubExited();
void cleanupAfterStartFailure(const QString &errorMessage);
void finish(int exitCode, QProcess::ExitStatus exitStatus);
void killProcess();
void killStub();
void emitError(QProcess::ProcessError err, const QString &errorString);
QString stubServerListen();
void stubServerShutdown();
void cleanupStub();
void cleanupInferior();
class ConsoleProcessPrivate *d;
};
} // Utils

View File

@@ -718,19 +718,16 @@ bool FilePath::createDir() const
return dir.mkpath(dir.absolutePath());
}
FilePaths FilePath::dirEntries(const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags,
QDir::SortFlags sort) const
FilePaths FilePath::dirEntries(const FileFilter &filter, QDir::SortFlags sort) const
{
FilePaths result;
if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.iterateDirectory, return {});
const auto callBack = [&result](const FilePath &path) { result.append(path); return true; };
s_deviceHooks.iterateDirectory(*this, callBack, nameFilters, filters, flags);
s_deviceHooks.iterateDirectory(*this, callBack, filter);
} else {
QDirIterator dit(m_data, nameFilters, filters, flags);
QDirIterator dit(m_data, filter.nameFilters, filter.fileFilters, filter.iteratorFlags);
while (dit.hasNext())
result.append(FilePath::fromString(dit.next()));
}
@@ -754,7 +751,7 @@ FilePaths FilePath::dirEntries(const QStringList &nameFilters,
FilePaths FilePath::dirEntries(QDir::Filters filters) const
{
return dirEntries({}, filters);
return dirEntries(FileFilter({}, filters));
}
// This runs \a callBack on each directory entry matching all \a filters and
@@ -762,17 +759,15 @@ FilePaths FilePath::dirEntries(QDir::Filters filters) const
// An empty \nameFilters list matches every name.
void FilePath::iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const FileFilter &filter) const
{
if (needsDevice()) {
QTC_ASSERT(s_deviceHooks.iterateDirectory, return);
s_deviceHooks.iterateDirectory(*this, callBack, nameFilters, filters, flags);
s_deviceHooks.iterateDirectory(*this, callBack, filter);
return;
}
QDirIterator it(m_data, nameFilters, filters, flags);
QDirIterator it(m_data, filter.nameFilters, filter.fileFilters, filter.iteratorFlags);
while (it.hasNext()) {
if (!callBack(FilePath::fromString(it.next())))
return;
@@ -1460,6 +1455,15 @@ QTextStream &operator<<(QTextStream &s, const FilePath &fn)
return s << fn.toString();
}
FileFilter::FileFilter(const QStringList &nameFilters,
const QDir::Filters fileFilters,
const QDirIterator::IteratorFlags flags)
: nameFilters(nameFilters),
fileFilters(fileFilters),
iteratorFlags(flags)
{
}
} // namespace Utils
std::hash<Utils::FilePath>::result_type

View File

@@ -51,6 +51,18 @@ namespace Utils {
class Environment;
class EnvironmentChange;
class QTCREATOR_UTILS_EXPORT FileFilter
{
public:
FileFilter(const QStringList &nameFilters,
const QDir::Filters fileFilters = QDir::NoFilter,
const QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags);
const QStringList nameFilters;
const QDir::Filters fileFilters = QDir::NoFilter;
const QDirIterator::IteratorFlags iteratorFlags = QDirIterator::NoIteratorFlags;
};
class QTCREATOR_UTILS_EXPORT FilePath
{
public:
@@ -121,9 +133,7 @@ public:
qint64 fileSize() const;
qint64 bytesAvailable() const;
bool createDir() const;
QList<FilePath> dirEntries(const QStringList &nameFilters,
QDir::Filters filters = QDir::NoFilter,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags,
QList<FilePath> dirEntries(const FileFilter &filter,
QDir::SortFlags sort = QDir::NoSort) const;
QList<FilePath> dirEntries(QDir::Filters filters) const;
QByteArray fileContents(qint64 maxSize = -1, qint64 offset = 0) const;
@@ -160,9 +170,7 @@ public:
[[nodiscard]] FilePath onDevice(const FilePath &deviceTemplate) const;
[[nodiscard]] FilePath withNewPath(const QString &newPath) const;
void iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters = QDir::NoFilter,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const;
const FileFilter &filter) const;
// makes sure that capitalization of directories is canonical
// on Windows and macOS. This is rarely needed.

View File

@@ -82,9 +82,7 @@ public:
std::function<QString(const FilePath &)> mapToDevicePath;
std::function<void(const FilePath &,
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
const QStringList &,
QDir::Filters,
QDirIterator::IteratorFlags)> iterateDirectory;
const FileFilter &)> iterateDirectory;
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
std::function<QDateTime(const FilePath &)> lastModified;

View File

@@ -221,7 +221,7 @@ FilePaths BackUpStrategy::readFileCandidates(const FilePath &baseFileName) const
const QStringList filter(baseFileName.fileName() + '*');
const FilePath baseFileDir = baseFileName.parentDir();
return baseFileDir.dirEntries(filter, QDir::Files | QDir::Hidden | QDir::System);
return baseFileDir.dirEntries({filter, QDir::Files | QDir::Hidden | QDir::System});
}
int BackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,

View File

@@ -68,8 +68,6 @@ Project {
"completinglineedit.h",
"completingtextedit.cpp",
"completingtextedit.h",
"consoleprocess.cpp",
"consoleprocess.h",
"cpplanguage_details.h",
"crumblepath.cpp",
"crumblepath.h",

View File

@@ -382,8 +382,7 @@ QVector<int> AndroidConfig::availableNdkPlatforms(const QtVersion *qtVersion) co
.toInt());
return true;
},
{"android-*"},
QDir::Dirs);
{{"android-*"}, QDir::Dirs});
Utils::sort(availableNdkPlatforms, std::greater<>());
return availableNdkPlatforms;

View File

@@ -663,34 +663,33 @@ AndroidDeviceManager::AndroidDeviceManager(QObject *parent)
}
// Factory
AndroidDeviceFactory::AndroidDeviceFactory()
: ProjectExplorer::IDeviceFactory(Constants::ANDROID_DEVICE_TYPE),
: IDeviceFactory(Constants::ANDROID_DEVICE_TYPE),
m_androidConfig(AndroidConfigurations::currentConfig())
{
setDisplayName(AndroidDevice::tr("Android Device"));
setCombinedIcon(":/android/images/androiddevicesmall.png",
":/android/images/androiddevice.png");
setConstructionFunction(&AndroidDevice::create);
setCanCreate(m_androidConfig.sdkToolsOk());
}
IDevice::Ptr AndroidDeviceFactory::create() const
{
setCreator([this] {
AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent());
if (dialog.exec() != QDialog::Accepted)
return ProjectExplorer::IDevice::Ptr();
return IDevice::Ptr();
const ProjectExplorer::IDevice::Ptr dev = dialog.device();
const AndroidDevice *androidDev = static_cast<AndroidDevice*>(dev.data());
if (androidDev) {
const IDevice::Ptr dev = dialog.device();
if (const auto androidDev = static_cast<AndroidDevice *>(dev.data())) {
qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".",
qPrintable(androidDev->avdName()));
} else {
AndroidDeviceWidget::criticalDialog(
QObject::tr("The device info returned from AvdDialog is invalid."));
AndroidDevice::tr("The device info returned from AvdDialog is invalid."));
}
return IDevice::Ptr(dev);
});
}
} // namespace Internal

View File

@@ -88,7 +88,6 @@ class AndroidDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
AndroidDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
private:
const AndroidConfig &m_androidConfig;

View File

@@ -423,7 +423,7 @@ QString AndroidManager::apkDevicePreferredAbi(const Target *target)
QStringList apkAbis;
const FilePaths libsPaths = libsPath.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot);
for (const FilePath &abiDir : libsPaths) {
if (!abiDir.dirEntries(QStringList("*.so"), QDir::Files | QDir::NoDotAndDotDot).isEmpty())
if (!abiDir.dirEntries({{"*.so"}, QDir::Files | QDir::NoDotAndDotDot}).isEmpty())
apkAbis << abiDir.fileName();
}
return preferredAbi(apkAbis, target);

View File

@@ -256,7 +256,7 @@ static QImage scaleWithoutStretching(const QImage& original, const QSize& target
static bool similarFilesExist(const FilePath &path)
{
const FilePaths entries = path.parentDir().dirEntries({path.completeBaseName() + ".*"}, {});
const FilePaths entries = path.parentDir().dirEntries({{path.completeBaseName() + ".*"}});
return !entries.empty();
}

View File

@@ -73,9 +73,7 @@ static void setSdkFilesExecPermission( const FilePath &sdkExtractPath)
}
return true;
},
{"*"},
QDir::Files,
QDirIterator::Subdirectories);
{{"*"}, QDir::Files, QDirIterator::Subdirectories});
}
void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &jdkPath, const FilePath &sdkExtractPath)

View File

@@ -322,7 +322,7 @@ void JLSClient::updateProjectFiles()
const FilePath androidJar = sdkLocation / QString("platforms/%2/android.jar")
.arg(targetSDK);
FilePaths libs = {androidJar};
libs << packageSourceDir.pathAppended("libs").dirEntries({"*.jar"}, QDir::Files);
libs << packageSourceDir.pathAppended("libs").dirEntries({{"*.jar"}, QDir::Files});
generateProjectFile(projectDir, qtSrc, project()->displayName());
generateClassPathFile(projectDir, sourceDir, libs);
}

View File

@@ -125,16 +125,14 @@ BareMetalDeviceFactory::BareMetalDeviceFactory()
setDisplayName(BareMetalDevice::tr("Bare Metal Device"));
setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png",
":/baremetal/images/baremetaldevice.png");
setCanCreate(true);
setConstructionFunction(&BareMetalDevice::create);
}
IDevice::Ptr BareMetalDeviceFactory::create() const
{
setCanCreate(true);
setCreator([] {
BareMetalDeviceConfigurationWizard wizard;
if (wizard.exec() != QDialog::Accepted)
return {};
return IDevice::Ptr();
return wizard.device();
});
}
} //namespace Internal

View File

@@ -71,9 +71,7 @@ private:
class BareMetalDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
explicit BareMetalDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const final;
BareMetalDeviceFactory();
};
} //namespace Internal

View File

@@ -286,17 +286,14 @@ QdbLinuxDeviceFactory::QdbLinuxDeviceFactory()
{
setDisplayName(QdbDevice::tr("Boot2Qt Device"));
setCombinedIcon(":/qdb/images/qdbdevicesmall.png", ":/qdb/images/qdbdevice.png");
setCanCreate(true);
setConstructionFunction(&QdbDevice::create);
}
IDevice::Ptr QdbLinuxDeviceFactory::create() const
{
setCanCreate(true);
setCreator([] {
QdbDeviceWizard wizard(Core::ICore::dialogParent());
if (wizard.exec() != QDialog::Accepted)
return IDevice::Ptr();
return wizard.device();
});
}
} // namespace Internal

View File

@@ -65,9 +65,6 @@ class QdbLinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
QdbLinuxDeviceFactory();
private:
ProjectExplorer::IDevice::Ptr create() const final;
};
} // namespace Internal

View File

@@ -109,8 +109,7 @@ void registerFlashAction(QObject *parentForAction)
Core::ActionContainer *toolsContainer =
Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS,
flashActionId);
toolsContainer->insertGroup(Core::Constants::G_TOOLS_DEBUG, flashActionId);
Core::Context globalContext(Core::Constants::C_GLOBAL);

View File

@@ -946,43 +946,45 @@ static bool isWindowsARM64(const Kit *k)
&& targetAbi.wordWidth() == 64;
}
static QStringList defaultInitialCMakeArguments(const Kit *k, const QString buildType)
static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildType)
{
// Generator:
QStringList initialArgs = CMakeGeneratorKitAspect::generatorArguments(k);
CMakeTool *tool = CMakeKitAspect::cmakeTool(k);
QTC_ASSERT(tool, return {});
CommandLine cmd{tool->cmakeExecutable()};
cmd.addArgs(CMakeGeneratorKitAspect::generatorArguments(k));
// CMAKE_BUILD_TYPE:
if (!buildType.isEmpty() && !CMakeGeneratorKitAspect::isMultiConfigGenerator(k)) {
initialArgs.append(QString::fromLatin1("-DCMAKE_BUILD_TYPE:STRING=%1").arg(buildType));
}
if (!buildType.isEmpty() && !CMakeGeneratorKitAspect::isMultiConfigGenerator(k))
cmd.addArg("-DCMAKE_BUILD_TYPE:STRING=" + buildType);
Internal::CMakeSpecificSettings *settings
= Internal::CMakeProjectPlugin::projectTypeSpecificSettings();
// Package manager
if (!isDocker(k) && settings->packageManagerAutoSetup.value())
initialArgs.append(QString::fromLatin1("-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%1")
.arg("%{IDE:ResourcePath}/package-manager/auto-setup.cmake"));
if (!isDocker(k) && settings->packageManagerAutoSetup.value()) {
cmd.addArg("-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH="
"%{IDE:ResourcePath}/package-manager/auto-setup.cmake");
}
// Cross-compilation settings:
if (!isIos(k)) { // iOS handles this differently
const QString sysRoot = SysRootKitAspect::sysRoot(k).path();
if (!sysRoot.isEmpty()) {
initialArgs.append(QString::fromLatin1("-DCMAKE_SYSROOT:PATH=%1").arg(sysRoot));
cmd.addArg("-DCMAKE_SYSROOT:PATH" + sysRoot);
if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) {
const QString targetTriple = tc->originalTargetTriple();
initialArgs.append(
QString::fromLatin1("-DCMAKE_C_COMPILER_TARGET:STRING=%1").arg(targetTriple));
initialArgs.append(
QString::fromLatin1("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1").arg(targetTriple));
cmd.addArg("-DCMAKE_C_COMPILER_TARGET:STRING=" + targetTriple);
cmd.addArg("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1" + targetTriple);
}
}
}
initialArgs += CMakeConfigurationKitAspect::toArgumentsList(k);
initialArgs += ProcessArgs::splitArgs(CMakeConfigurationKitAspect::additionalConfiguration(k));
cmd.addArgs(CMakeConfigurationKitAspect::toArgumentsList(k));
cmd.addArgs(CMakeConfigurationKitAspect::additionalConfiguration(k), CommandLine::Raw);
return initialArgs;
return cmd;
}
} // namespace Internal
@@ -1067,19 +1069,19 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
setInitializer([this, target](const BuildInfo &info) {
const Kit *k = target->kit();
QStringList initialArgs = defaultInitialCMakeArguments(k, info.typeName);
CommandLine cmd = defaultInitialCMakeCommand(k, info.typeName);
setIsMultiConfig(CMakeGeneratorKitAspect::isMultiConfigGenerator(k));
// Android magic:
if (DeviceTypeKitAspect::deviceTypeId(k) == Android::Constants::ANDROID_DEVICE_TYPE) {
buildSteps()->appendStep(Android::Constants::ANDROID_BUILD_APK_ID);
const auto &bs = buildSteps()->steps().constLast();
initialArgs.append("-DANDROID_NATIVE_API_LEVEL:STRING="
cmd.addArg("-DANDROID_NATIVE_API_LEVEL:STRING="
+ bs->data(Android::Constants::AndroidNdkPlatform).toString());
auto ndkLocation = bs->data(Android::Constants::NdkLocation).value<FilePath>();
initialArgs.append("-DANDROID_NDK:PATH=" + ndkLocation.path());
cmd.addArg("-DANDROID_NDK:PATH=" + ndkLocation.path());
initialArgs.append("-DCMAKE_TOOLCHAIN_FILE:PATH="
cmd.addArg("-DCMAKE_TOOLCHAIN_FILE:PATH="
+ ndkLocation.pathAppended("build/cmake/android.toolchain.cmake").path());
auto androidAbis = bs->data(Android::Constants::AndroidMkSpecAbis).toStringList();
@@ -1092,9 +1094,9 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
} else {
preferredAbi = androidAbis.first();
}
initialArgs.append("-DANDROID_ABI:STRING=" + preferredAbi);
initialArgs.append("-DANDROID_STL:STRING=c++_shared");
initialArgs.append("-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}");
cmd.addArg("-DANDROID_ABI:STRING=" + preferredAbi);
cmd.addArg("-DANDROID_STL:STRING=c++_shared");
cmd.addArg("-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}");
QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
auto sdkLocation = bs->data(Android::Constants::SdkLocation).value<FilePath>();
@@ -1102,11 +1104,11 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
if (qt && qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) {
// Don't build apk under ALL target because Qt Creator will handle it
if (qt->qtVersion() >= QtSupport::QtVersionNumber{6, 1, 0})
initialArgs.append("-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON");
initialArgs.append("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
initialArgs.append("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
cmd.addArg("-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON");
cmd.addArg("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
cmd.addArg("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
} else {
initialArgs.append("-DANDROID_SDK:PATH=" + sdkLocation.path());
cmd.addArg("-DANDROID_SDK:PATH=" + sdkLocation.path());
}
}
@@ -1127,20 +1129,20 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
const QString sysroot = deviceType == Ios::Constants::IOS_DEVICE_TYPE
? QLatin1String("iphoneos")
: QLatin1String("iphonesimulator");
initialArgs.append(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
initialArgs.append("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture);
initialArgs.append("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot);
initialArgs.append("%{" + QLatin1String(DEVELOPMENT_TEAM_FLAG) + "}");
initialArgs.append("%{" + QLatin1String(PROVISIONING_PROFILE_FLAG) + "}");
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
cmd.addArg("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture);
cmd.addArg("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot);
cmd.addArg("%{" + QLatin1String(DEVELOPMENT_TEAM_FLAG) + "}");
cmd.addArg("%{" + QLatin1String(PROVISIONING_PROFILE_FLAG) + "}");
}
} else if (device && device->osType() == Utils::OsTypeMac) {
initialArgs.append("%{" + QLatin1String(CMAKE_OSX_ARCHITECTURES_FLAG) + "}");
cmd.addArg("%{" + QLatin1String(CMAKE_OSX_ARCHITECTURES_FLAG) + "}");
}
if (isWebAssembly(k) || isQnx(k) || isWindowsARM64(k)) {
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
if (qt && qt->qtVersion().majorVersion >= 6)
initialArgs.append(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
}
if (info.buildDirectory.isEmpty()) {
@@ -1155,7 +1157,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
info.extraInfo.value<QVariantMap>().value(Constants::CMAKE_HOME_DIR)));
}
setInitialCMakeArguments(initialArgs);
setInitialCMakeArguments(cmd.splitArguments());
setCMakeBuildType(info.typeName);
});
@@ -1200,12 +1202,10 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
}
}();
if (initialCMakeArguments().isEmpty()) {
QStringList initialArgs = defaultInitialCMakeArguments(kit(), buildTypeName)
+ Utils::transform(conf.toList(), [this](const CMakeConfigItem &i) {
return i.toArgument(macroExpander());
});
setInitialCMakeArguments(initialArgs);
CommandLine cmd = defaultInitialCMakeCommand(kit(), buildTypeName);
for (const CMakeConfigItem &item : conf)
cmd.addArg(item.toArgument(macroExpander()));
setInitialCMakeArguments(cmd.splitArguments());
}
return true;

View File

@@ -79,7 +79,7 @@ static QStringList scanDirectory(const FilePath &path, const QString &prefix)
QStringList result;
qCDebug(cmInputLog) << "Scanning for directories matching" << prefix << "in" << path;
foreach (const FilePath &entry, path.dirEntries({prefix + "*"}, QDir::Dirs | QDir::NoDotAndDotDot)) {
foreach (const FilePath &entry, path.dirEntries({{prefix + "*"}, QDir::Dirs | QDir::NoDotAndDotDot})) {
QTC_ASSERT(entry.isDir(), continue);
result.append(entry.toString());
}

View File

@@ -948,10 +948,7 @@ FilePath FileApiParser::scanForCMakeReplyFile(const FilePath &buildDirectory)
if (!replyDir.exists())
return {};
const FilePaths entries = replyDir.dirEntries({"index-*.json"},
QDir::Files,
QDirIterator::NoIteratorFlags,
QDir::Name);
const FilePaths entries = replyDir.dirEntries({{"index-*.json"}, QDir::Files}, QDir::Name);
return entries.isEmpty() ? FilePath() : entries.first();
}

View File

@@ -55,6 +55,7 @@ const char M_VIEW_VIEWS[] = "QtCreator.Menu.View.Views";
const char M_VIEW_PANES[] = "QtCreator.Menu.View.Panes";
const char M_TOOLS[] = "QtCreator.Menu.Tools";
const char M_TOOLS_EXTERNAL[] = "QtCreator.Menu.Tools.External";
const char M_TOOLS_DEBUG[] = "QtCreator.Menu.Tools.Debug";
const char M_WINDOW[] = "QtCreator.Menu.Window";
const char M_HELP[] = "QtCreator.Menu.Help";
@@ -186,6 +187,7 @@ const char G_VIEW_VIEWS[] = "QtCreator.Group.View.Views";
const char G_VIEW_PANES[] = "QtCreator.Group.View.Panes";
// Tools menu groups
const char G_TOOLS_DEBUG[] = "QtCreator.Group.Tools.Debug";
const char G_TOOLS_OPTIONS[] = "QtCreator.Group.Tools.Options";
// Window menu groups

View File

@@ -701,16 +701,21 @@ void MainWindow::registerDefaultActions()
cmd->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
tmpaction->setEnabled(false);
// Debug Qt Creator menu
mtools->appendGroup(Constants::G_TOOLS_DEBUG);
ActionContainer *mtoolsdebug = ActionManager::createMenu(Constants::M_TOOLS_DEBUG);
mtoolsdebug->menu()->setTitle(tr("Debug %1").arg(Constants::IDE_DISPLAY_NAME));
mtools->addMenu(mtoolsdebug, Constants::G_TOOLS_DEBUG);
m_loggerAction = new QAction(tr("Show Logs..."), this);
cmd = ActionManager::registerAction(m_loggerAction, Constants::LOGGER);
mtoolsdebug->addAction(cmd);
connect(m_loggerAction, &QAction::triggered, this, [] { LoggingViewer::showLoggingView(); });
// Options Action
mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
mtools->addSeparator(Constants::G_TOOLS_OPTIONS);
m_loggerAction = new QAction(tr("Logger..."), this);
cmd = ActionManager::registerAction(m_loggerAction, Constants::LOGGER);
mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
connect(m_loggerAction, &QAction::triggered, this, [] { LoggingViewer::showLoggingView(); });
mtools->addSeparator(Constants::G_TOOLS_OPTIONS);
m_optionsAction = new QAction(tr("&Options..."), this);
m_optionsAction->setMenuRole(QAction::PreferencesRole);
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS);

View File

@@ -39,7 +39,6 @@
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/consoleprocess.h>
#include <utils/environment.h>
#include <utils/environmentdialog.h>
#include <utils/hostosinfo.h>

View File

@@ -413,12 +413,12 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
cppModelManager, &CppModelManager::updateModifiedSourceFiles);
cppToolsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
cppToolsMenu->addSeparator(Core::Constants::G_DEFAULT_THREE);
ActionContainer *toolsDebug = ActionManager::actionContainer(Core::Constants::M_TOOLS_DEBUG);
QAction *inspectCppCodeModel = new QAction(tr("Inspect C++ Code Model..."), this);
cmd = ActionManager::registerAction(inspectCppCodeModel, Constants::INSPECT_CPP_CODEMODEL);
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+Shift+F12") : tr("Ctrl+Shift+F12")));
connect(inspectCppCodeModel, &QAction::triggered, d, &CppEditorPluginPrivate::inspectCppCodeModel);
cppToolsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
toolsDebug->addAction(cmd);
contextMenu->addSeparator(context);

View File

@@ -62,7 +62,6 @@
#include <texteditor/texteditor.h>
#include <utils/checkablemessagebox.h>
#include <utils/consoleprocess.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>

View File

@@ -780,7 +780,7 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePaths &s
const auto addSuspect = [&suspects](const FilePath &entry) { suspects.append(entry); return true; };
for (const FilePath &path : paths)
path.iterateDirectory(addSuspect, filters, QDir::Files | QDir::Executable);
path.iterateDirectory(addSuspect, {filters, QDir::Files | QDir::Executable});
QStringList logMessages{tr("Searching debuggers...")};
for (const FilePath &command : qAsConst(suspects)) {

View File

@@ -1615,9 +1615,7 @@ QString GdbEngine::cleanupFullName(const QString &fileName)
}
return true;
},
{"*"},
QDir::NoFilter,
QDirIterator::Subdirectories);
{{"*"}, QDir::NoFilter, QDirIterator::Subdirectories});
}
}

View File

@@ -33,7 +33,6 @@
#include <debugger/debuggertooltipmanager.h>
#include <debugger/debuggerprotocol.h>
#include <utils/consoleprocess.h>
#include <utils/qtcprocess.h>
#include <QPointer>

View File

@@ -472,7 +472,7 @@ DiffEditorPluginPrivate::DiffEditorPluginPrivate()
//register actions
ActionContainer *toolsContainer
= ActionManager::actionContainer(Core::Constants::M_TOOLS);
toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS, Constants::G_TOOLS_DIFF);
toolsContainer->insertGroup(Core::Constants::G_TOOLS_DEBUG, Constants::G_TOOLS_DIFF);
ActionContainer *diffContainer = ActionManager::createMenu("Diff");
diffContainer->menu()->setTitle(tr("&Diff"));
toolsContainer->addMenu(diffContainer, Constants::G_TOOLS_DIFF);

View File

@@ -1455,17 +1455,20 @@ bool DockerDevice::setPermissions(const FilePath &filePath, QFileDevice::Permiss
void DockerDevice::iterateWithFind(const FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters) const
const FileFilter &filter) const
{
QTC_ASSERT(callBack, return);
QTC_CHECK(filePath.isAbsolutePath());
QStringList arguments{filePath.path(), "-maxdepth", "1"};
QStringList arguments{filePath.path()};
const QDir::Filters filters = filter.fileFilters;
if (filters & QDir::NoSymLinks)
arguments.prepend("-H");
else
arguments.prepend("-L");
if (!filter.iteratorFlags.testFlag(QDirIterator::Subdirectories))
arguments.append({"-maxdepth", "1"});
QStringList filterOptions;
if (filters & QDir::Dirs)
@@ -1493,12 +1496,12 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
const QString nameOption = (filters & QDir::CaseSensitive) ? QString{"-name"}
: QString{"-iname"};
QStringList criticalWildcards;
if (!nameFilters.isEmpty()) {
if (!filter.nameFilters.isEmpty()) {
const QRegularExpression oneChar("\\[.*?\\]");
for (int i = 0, len = nameFilters.size(); i < len; ++i) {
for (int i = 0, len = filter.nameFilters.size(); i < len; ++i) {
if (i > 0)
filterOptions << "-o";
QString current = nameFilters.at(i);
QString current = filter.nameFilters.at(i);
if (current.indexOf(oneChar) != -1)
criticalWildcards.append(current);
current.replace(oneChar, "?"); // BAD! but still better than nothing
@@ -1519,7 +1522,8 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
continue;
const FilePath fp = FilePath::fromString(entry);
if (!Utils::anyOf(criticalWildcards,
if (!criticalWildcards.isEmpty() &&
!Utils::anyOf(criticalWildcards,
[name = fp.fileName()](const QString &pattern) {
const QRegularExpression regex(QRegularExpression::wildcardToRegularExpression(pattern));
if (regex.match(name).hasMatch())
@@ -1537,10 +1541,12 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
static void filterEntriesHelper(const FilePath &base,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &entries,
const QStringList &nameFilters,
QDir::Filters filters)
const FileFilter &filter)
{
const QList<QRegularExpression> nameRegexps = transform(nameFilters, [](const QString &filter) {
QTC_CHECK(filter.iteratorFlags != QDirIterator::NoIteratorFlags); // FIXME: Not supported yet below.
const QList<QRegularExpression> nameRegexps =
transform(filter.nameFilters, [](const QString &filter) {
QRegularExpression re;
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
QTC_CHECK(re.isValid());
@@ -1557,7 +1563,7 @@ static void filterEntriesHelper(const FilePath &base,
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filters == QDir::NoFilter);
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
for (const QString &entry : entries) {
if (!nameMatches(entry))
@@ -1569,12 +1575,8 @@ static void filterEntriesHelper(const FilePath &base,
void DockerDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const FileFilter &filter) const
{
Q_UNUSED(flags) // FIXME: Use it.
QTC_ASSERT(handlesFile(filePath), return);
updateContainerAccess();
if (hasLocalFileAccess()) {
@@ -1582,12 +1584,12 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
local.iterateDirectory([&callBack, this](const FilePath &entry) {
return callBack(mapFromLocalAccess(entry));
},
nameFilters, filters);
filter);
return;
}
if (d->m_useFind) {
iterateWithFind(filePath, callBack, nameFilters, filters);
iterateWithFind(filePath, callBack, filter);
// d->m_useFind will be set to false if 'find' is not found. In this
// case fall back to 'ls' below.
if (d->m_useFind)
@@ -1597,7 +1599,7 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
// if we do not have find - use ls as fallback
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
const QStringList entries = output.split('\n', Qt::SkipEmptyParts);
filterEntriesHelper(filePath, callBack, entries, nameFilters, filters);
filterEntriesHelper(filePath, callBack, entries, filter);
}
QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const
@@ -1802,15 +1804,6 @@ QString DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) const
// Factory
DockerDeviceFactory::DockerDeviceFactory()
: IDeviceFactory(Constants::DOCKER_DEVICE_TYPE)
{
setDisplayName(DockerDevice::tr("Docker Device"));
setIcon(QIcon());
setCanCreate(true);
setConstructionFunction([] { return DockerDevice::create({}); });
}
class DockerImageItem final : public TreeItem, public DockerDeviceData
{
public:
@@ -1914,7 +1907,7 @@ public:
m_process->start();
}
DockerDevice::Ptr device() const
IDevice::Ptr device() const
{
const QModelIndexList selectedRows = m_view->selectionModel()->selectedRows();
QTC_ASSERT(selectedRows.size() == 1, return {});
@@ -1939,14 +1932,6 @@ public:
QString m_selectedId;
};
IDevice::Ptr DockerDeviceFactory::create() const
{
DockerDeviceSetupWizard wizard;
if (wizard.exec() != QDialog::Accepted)
return IDevice::Ptr();
return wizard.device();
}
void DockerDeviceWidget::updateDaemonStateTexts()
{
Utils::optional<bool> daemonState = DockerPlugin::isDaemonRunning();
@@ -1962,5 +1947,22 @@ void DockerDeviceWidget::updateDaemonStateTexts()
}
}
// Factory
DockerDeviceFactory::DockerDeviceFactory()
: IDeviceFactory(Constants::DOCKER_DEVICE_TYPE)
{
setDisplayName(DockerDevice::tr("Docker Device"));
setIcon(QIcon());
setCanCreate(true);
setCreator([] {
DockerDeviceSetupWizard wizard;
if (wizard.exec() != QDialog::Accepted)
return IDevice::Ptr();
return wizard.device();
});
setConstructionFunction([] { return DockerDevice::create({}); });
}
} // Internal
} // Docker

View File

@@ -62,7 +62,7 @@ public:
static Ptr create(const DockerDeviceData &data) { return Ptr(new DockerDevice(data)); }
ProjectExplorer::IDeviceWidget *createWidget() override;
QVector<ProjectExplorer::Task> validate() const override;
QList<ProjectExplorer::Task> validate() const override;
bool canCreateProcess() const override { return true; }
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
@@ -96,9 +96,7 @@ public:
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
void iterateDirectory(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const override;
const Utils::FileFilter &filter) const override;
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override;
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
QDateTime lastModified(const Utils::FilePath &filePath) const override;
@@ -127,8 +125,7 @@ protected:
private:
void iterateWithFind(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters) const;
const Utils::FileFilter &filter) const;
void aboutToBeRemoved() const final;
@@ -160,8 +157,6 @@ class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
DockerDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // Internal

View File

@@ -70,7 +70,7 @@ static FilePath detectApp(const QString &defaultExe)
if (!gitBinDir.endsWith("/usr/bin"))
return {};
path = gitBinDir.parentDir().parentDir();
const FilePaths entries = path.dirEntries({"mingw*"}, {});
const FilePaths entries = path.dirEntries({{"mingw*"}});
if (entries.isEmpty())
return {};
path = entries.first() / "bin" / defaultApp;

View File

@@ -48,7 +48,6 @@ const char LANGUAGECLIENT_WORKSPACE_CLASS_FILTER_ID[] = "Workspace Classes and S
const char LANGUAGECLIENT_WORKSPACE_CLASS_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("LanguageClient", "Classes and Structs in Workspace");
const char LANGUAGECLIENT_WORKSPACE_METHOD_FILTER_ID[] = "Workspace Functions and Methods";
const char LANGUAGECLIENT_WORKSPACE_METHOD_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("LanguageClient", "Functions and Methods in Workspace");
const char G_TOOLS_LANGUAGECLIENT[] = "QtCreator.Group.Tools.LanguageClient";
} // namespace Constants
} // namespace LanguageClient

View File

@@ -63,16 +63,12 @@ bool LanguageClientPlugin::initialize(const QStringList & /*arguments*/, QString
[]() { return new StdIOSettings; }});
//register actions
ActionContainer *toolsContainer
= ActionManager::actionContainer(Core::Constants::M_TOOLS);
toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS, Constants::G_TOOLS_LANGUAGECLIENT);
ActionContainer *container = ActionManager::createMenu("Language Client");
container->menu()->setTitle(tr("&Language Client"));
toolsContainer->addMenu(container, Constants::G_TOOLS_LANGUAGECLIENT);
ActionContainer *toolsDebugContainer = ActionManager::actionContainer(
Core::Constants::M_TOOLS_DEBUG);
auto inspectAction = new QAction(tr("Inspect Language Clients"), this);
auto inspectAction = new QAction(tr("Inspect Language Clients..."), this);
connect(inspectAction, &QAction::triggered, this, &LanguageClientManager::showInspector);
container->addAction(
toolsDebugContainer->addAction(
ActionManager::registerAction(inspectAction, "LanguageClient.InspectLanguageClients"));
return true;

View File

@@ -59,13 +59,9 @@ McuSupportDeviceFactory::McuSupportDeviceFactory()
setDisplayName(McuSupportDevice::tr("MCU Device"));
setCombinedIcon(":/mcusupport/images/mcusupportdevicesmall.png",
":/mcusupport/images/mcusupportdevice.png");
setCanCreate(true);
setConstructionFunction(&McuSupportDevice::create);
}
ProjectExplorer::IDevice::Ptr McuSupportDeviceFactory::create() const
{
return McuSupportDevice::create();
setCanCreate(true);
setCreator(&McuSupportDevice::create);
}
} // namespace Internal

View File

@@ -45,8 +45,6 @@ class McuSupportDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
McuSupportDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // namespace Internal

View File

@@ -217,8 +217,7 @@ static McuPackage *createRGLPackage()
if (rglPath.exists()) {
defaultPath = rglPath;
const FilePaths subDirs =
defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")},
QDir::Dirs | QDir::NoDotAndDotDot);
defaultPath.dirEntries({{"rgl_ghs_D1Mx_*"}, QDir::Dirs | QDir::NoDotAndDotDot});
if (subDirs.count() == 1)
defaultPath = subDirs.first();
}
@@ -272,8 +271,7 @@ static McuPackage *createMcuXpressoIdePackage()
defaultPath = programPath;
// If default dir has exactly one sub dir that could be the IDE path, pre-select that.
const FilePaths subDirs =
defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")},
QDir::Dirs | QDir::NoDotAndDotDot);
defaultPath.dirEntries({{"MCUXpressoIDE*"}, QDir::Dirs | QDir::NoDotAndDotDot});
if (subDirs.count() == 1)
defaultPath = subDirs.first();
}
@@ -304,8 +302,8 @@ static McuPackage *createCypressProgrammerPackage()
const FilePath candidate = findInProgramFiles("Cypress");
if (candidate.exists()) {
// "Cypress Auto Flash Utility 1.0"
const auto subDirs = candidate.dirEntries({"Cypress Auto Flash Utility*"},
QDir::Dirs, QDirIterator::NoIteratorFlags, QDir::Unsorted);
const auto subDirs = candidate.dirEntries({{"Cypress Auto Flash Utility*"}, QDir::Dirs},
QDir::Unsorted);
if (!subDirs.empty())
defaultPath = subDirs.first();
}
@@ -331,8 +329,8 @@ static McuPackage *createRenesasProgrammerPackage()
const FilePath candidate = findInProgramFiles("Renesas Electronics/Programming Tools");
if (candidate.exists()) {
// "Renesas Flash Programmer V3.09"
const auto subDirs = candidate.dirEntries({"Renesas Flash Programmer*"},
QDir::Dirs, QDirIterator::NoIteratorFlags, QDir::Unsorted);
const auto subDirs = candidate.dirEntries({{"Renesas Flash Programmer*"}, QDir::Dirs},
QDir::Unsorted);
if (!subDirs.empty())
defaultPath = subDirs.first();
}

View File

@@ -25,8 +25,6 @@
#include "copytaskhandler.h"
#include "task.h"
#include <coreplugin/coreconstants.h>
#include <QAction>
@@ -36,8 +34,10 @@
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
void CopyTaskHandler::handle(const Task &task)
void CopyTaskHandler::handle(const Tasks &tasks)
{
QStringList lines;
for (const Task &task : tasks) {
QString type;
switch (task.type) {
case Task::Error:
@@ -51,10 +51,10 @@ void CopyTaskHandler::handle(const Task &task)
default:
break;
}
QApplication::clipboard()->setText(task.file.toUserOutput() + QLatin1Char(':') +
QString::number(task.line) + QLatin1String(": ")
+ type + task.description());
lines << task.file.toUserOutput() + ':' + QString::number(task.line)
+ ": " + type + task.description();
}
QApplication::clipboard()->setText(lines.join('\n'));
}
Utils::Id CopyTaskHandler::actionManagerId() const

View File

@@ -35,8 +35,9 @@ class CopyTaskHandler : public ITaskHandler
Q_OBJECT
public:
bool canHandle(const Task &) const override { return true; }
void handle(const Task &task) override;
CopyTaskHandler() : ITaskHandler(true) {}
void handle(const Tasks &tasks) override;
Utils::Id actionManagerId() const override;
QAction *createAction(QObject *parent) const override;
};

View File

@@ -177,13 +177,11 @@ bool DesktopDevice::handlesFile(const FilePath &filePath) const
}
void DesktopDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const std::function<bool(const FilePath &)> &callBack,
const FileFilter &filter) const
{
QTC_CHECK(!filePath.needsDevice());
filePath.iterateDirectory(callBack, nameFilters, filters, flags);
filePath.iterateDirectory(callBack, filter);
}
qint64 DesktopDevice::fileSize(const FilePath &filePath) const

View File

@@ -75,9 +75,7 @@ public:
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
void iterateDirectory(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const override;
const Utils::FileFilter &filter) const override;
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override;
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
qint64 fileSize(const Utils::FilePath &filePath) const override;

View File

@@ -524,12 +524,10 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
deviceHooks.iterateDirectory = [](const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) {
const FileFilter &filter) {
auto device = DeviceManager::deviceForPath(filePath);
QTC_ASSERT(device, return);
device->iterateDirectory(filePath, callBack, nameFilters, filters, flags);
device->iterateDirectory(filePath, callBack, filter);
};
deviceHooks.fileContents = [](const FilePath &filePath, qint64 maxSize, qint64 offset) {

View File

@@ -363,15 +363,11 @@ FilePath IDevice::symLinkTarget(const FilePath &filePath) const
void IDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const FileFilter &filter) const
{
Q_UNUSED(filePath);
Q_UNUSED(callBack);
Q_UNUSED(nameFilters);
Q_UNUSED(filters);
Q_UNUSED(flags);
Q_UNUSED(filter);
QTC_CHECK(false);
}
@@ -547,7 +543,7 @@ bool IDevice::isCompatibleWith(const Kit *k) const
return DeviceTypeKitAspect::deviceTypeId(k) == type();
}
QVector<Task> IDevice::validate() const
QList<Task> IDevice::validate() const
{
return {};
}

View File

@@ -33,7 +33,6 @@
#include <QAbstractSocket>
#include <QCoreApplication>
#include <QDir>
#include <QList>
#include <QObject>
#include <QSharedPointer>
@@ -160,7 +159,7 @@ public:
Utils::Id id() const;
virtual bool isCompatibleWith(const Kit *k) const;
virtual QVector<Task> validate() const;
virtual QList<Task> validate() const;
QString displayType() const;
Utils::OsType osType() const;
@@ -257,13 +256,11 @@ public:
virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
virtual Utils::FilePath searchExecutableInPath(const QString &fileName) const;
virtual Utils::FilePath searchExecutable(const QString &fileName,
const QList<Utils::FilePath> &dirs) const;
const Utils::FilePaths &dirs) const;
virtual Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const;
virtual void iterateDirectory(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const;
const Utils::FileFilter &filter) const;
virtual QByteArray fileContents(const Utils::FilePath &filePath,
qint64 limit,
qint64 offset) const;

View File

@@ -81,6 +81,11 @@ bool IDeviceFactory::canCreate() const
return m_canCreate;
}
IDevice::Ptr IDeviceFactory::create() const
{
return m_creator ? m_creator() : IDevice::Ptr();
}
IDevice::Ptr IDeviceFactory::construct() const
{
return m_constructor ? m_constructor() : IDevice::Ptr();
@@ -119,6 +124,11 @@ void IDeviceFactory::setCanCreate(bool canCreate)
m_canCreate = canCreate;
}
void IDeviceFactory::setCreator(const std::function<IDevice::Ptr ()> &creator)
{
m_creator = creator;
}
void IDeviceFactory::setConstructionFunction(const std::function<IDevice::Ptr ()> &constructor)
{
m_constructor = constructor;

View File

@@ -44,8 +44,7 @@ public:
QIcon icon() const { return m_icon; }
bool canCreate() const;
IDevice::Ptr construct() const;
virtual IDevice::Ptr create() const { return IDevice::Ptr(); }
IDevice::Ptr create() const;
virtual bool canRestore(const QVariantMap &) const { return true; }
@@ -61,8 +60,10 @@ protected:
void setCombinedIcon(const Utils::FilePath &small, const Utils::FilePath &large);
void setCanCreate(bool canCreate);
void setConstructionFunction(const std::function<IDevice::Ptr ()> &constructor);
void setCreator(const std::function<IDevice::Ptr()> &creator);
private:
std::function<IDevice::Ptr()> m_creator;
const Utils::Id m_deviceType;
QString m_displayName;
QIcon m_icon;

View File

@@ -1126,7 +1126,8 @@ static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
return true;
};
const FilePath globalDir = device->mapToGlobalPath(deviceDir);
device->iterateDirectory(globalDir, callBack, nameFilters, QDir::Files | QDir::Executable);
device->iterateDirectory(globalDir, callBack,
{nameFilters, QDir::Files | QDir::Executable});
}
} else {
// The normal, local host case.
@@ -1763,7 +1764,7 @@ ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) :
return;
// Remove m_abiWidget row because the parent toolchain abi is going to be used.
m_mainLayout->removeRow(m_mainLayout->rowCount() - 2);
m_mainLayout->removeRow(m_mainLayout->rowCount() - 3); // FIXME: Do something sane instead.
m_abiWidget = nullptr;
m_parentToolchainCombo = new QComboBox(this);

View File

@@ -26,6 +26,7 @@
#pragma once
#include "projectexplorer_export.h"
#include "task.h"
#include <utils/id.h>
@@ -37,21 +38,26 @@ class QAction;
QT_END_NAMESPACE
namespace ProjectExplorer {
class Task;
class PROJECTEXPLORER_EXPORT ITaskHandler : public QObject
{
Q_OBJECT
public:
ITaskHandler();
explicit ITaskHandler(bool isMultiHandler = false);
~ITaskHandler() override;
virtual bool isDefaultHandler() const { return false; }
virtual bool canHandle(const Task &) const = 0;
virtual void handle(const Task &) = 0;
virtual bool canHandle(const Task &) const { return m_isMultiHandler; }
virtual void handle(const Task &); // Non-multi-handlers should implement this.
virtual void handle(const Tasks &tasks); // Multi-handlers should implement this.
virtual Utils::Id actionManagerId() const { return Utils::Id(); }
virtual QAction *createAction(QObject *parent) const = 0;
bool canHandle(const Tasks &tasks) const;
private:
const bool m_isMultiHandler;
};
} // namespace ProjectExplorer

View File

@@ -423,10 +423,11 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
continue;
}
const QDir::Filters filters = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
const FileFilter filter {
{}, QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags
};
const QDir::SortFlags sortflags = QDir::Name|QDir::IgnoreCase;
const QDirIterator::IteratorFlag iteratorFlags = QDirIterator::NoIteratorFlags;
FilePaths dirs = path.dirEntries({}, filters, iteratorFlags, sortflags);
FilePaths dirs = path.dirEntries(filter, sortflags);
while (!dirs.isEmpty()) {
const FilePath currentDir = dirs.takeFirst();
@@ -483,7 +484,7 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
result << factory;
} else {
FilePaths subDirs = currentDir.dirEntries({}, filters, iteratorFlags, sortflags);
FilePaths subDirs = currentDir.dirEntries(filter, sortflags);
if (!subDirs.isEmpty()) {
// There is no QList::prepend(QList)...
dirs.swap(subDirs);
@@ -579,7 +580,7 @@ static QString qmlProjectName(const FilePath &folder)
{
FilePath currentFolder = folder;
while (!currentFolder.isEmpty()) {
const QList<FilePath> fileList = currentFolder.dirEntries({"*.qmlproject"});
const FilePaths fileList = currentFolder.dirEntries({{"*.qmlproject"}});
if (!fileList.isEmpty())
return fileList.first().baseName();
currentFolder = currentFolder.parentDir();

View File

@@ -694,7 +694,7 @@ static ProjectExplorerPluginPrivate *dd = nullptr;
static FilePaths projectFilesInDirectory(const FilePath &path)
{
return path.dirEntries(ProjectExplorerPlugin::projectFileGlobs(), QDir::Files);
return path.dirEntries({ProjectExplorerPlugin::projectFileGlobs(), QDir::Files});
}
static FilePaths projectsInDirectory(const FilePath &filePath)

View File

@@ -33,8 +33,9 @@
namespace ProjectExplorer {
namespace Internal {
void RemoveTaskHandler::handle(const Task &task)
void RemoveTaskHandler::handle(const Tasks &tasks)
{
for (const Task &task : tasks)
TaskHub::removeTask(task);
}

View File

@@ -35,8 +35,9 @@ class RemoveTaskHandler : public ITaskHandler
Q_OBJECT
public:
bool canHandle(const Task &) const override { return true; }
void handle(const Task &task) override;
RemoveTaskHandler() : ITaskHandler(true) {}
void handle(const Tasks &tasks) override;
QAction *createAction(QObject *parent) const override;
};

View File

@@ -791,8 +791,7 @@ QStringList SessionManager::sessions()
{
if (d->m_sessions.isEmpty()) {
// We are not initialized yet, so do that now
const FilePaths sessionFiles = ICore::userResourcePath().dirEntries({"*.qws"},
QDir::NoFilter, QDirIterator::NoIteratorFlags, QDir::Time);
const FilePaths sessionFiles = ICore::userResourcePath().dirEntries({{"*qws"}}, QDir::Time);
for (const FilePath &file : sessionFiles) {
const QString &name = file.completeBaseName();
d->m_sessionDateTimes.insert(name, file.lastModified());

View File

@@ -138,7 +138,7 @@ public:
DeploymentTask(TaskType type, const QString &description);
};
using Tasks = QVector<Task>;
using Tasks = QList<Task>;
PROJECTEXPLORER_EXPORT QString toHtml(const Tasks &issues);
PROJECTEXPLORER_EXPORT bool containsType(const Tasks &issues, Task::TaskType);

View File

@@ -29,6 +29,7 @@
#include "task.h"
#include "taskhub.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QFileInfo>
@@ -286,6 +287,13 @@ Task TaskModel::task(const QModelIndex &index) const
return m_tasks.at(row);
}
Tasks TaskModel::tasks(const QModelIndexList &indexes) const
{
return Utils::filtered(
Utils::transform<Tasks>(indexes, [this](const QModelIndex &i) { return task(i); }),
[](const Task &t) { return !t.isNull(); });
}
QList<Utils::Id> TaskModel::categoryIds() const
{
QList<Utils::Id> categories = m_categories.keys();
@@ -360,6 +368,12 @@ void TaskFilterModel::setFilterIncludesWarnings(bool b)
invalidateFilter();
}
Tasks TaskFilterModel::tasks(const QModelIndexList &indexes) const
{
return taskModel()->tasks(Utils::transform(indexes, [this](const QModelIndex &i) {
return mapToSource(i); }));
}
int TaskFilterModel::issuesCount(int startRow, int endRow) const
{
int count = 0;

View File

@@ -49,6 +49,7 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Task task(const QModelIndex &index) const;
Tasks tasks(const QModelIndexList &indexes) const;
QList<Utils::Id> categoryIds() const;
QString categoryDisplayName(Utils::Id categoryId) const;
@@ -142,6 +143,7 @@ public:
void setFilteredCategories(const QList<Utils::Id> &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); }
Task task(const QModelIndex &index) const { return taskModel()->task(mapToSource(index)); }
Tasks tasks(const QModelIndexList &indexes) const;
int issuesCount(int startRow, int endRow) const;
bool hasFile(const QModelIndex &index) const

View File

@@ -67,7 +67,7 @@ namespace ProjectExplorer {
static QList<ITaskHandler *> g_taskHandlers;
ITaskHandler::ITaskHandler()
ITaskHandler::ITaskHandler(bool isMultiHandler) : m_isMultiHandler(isMultiHandler)
{
g_taskHandlers.append(this);
}
@@ -77,6 +77,30 @@ ITaskHandler::~ITaskHandler()
g_taskHandlers.removeOne(this);
}
void ITaskHandler::handle(const Task &task)
{
QTC_ASSERT(m_isMultiHandler, return);
handle(Tasks{task});
}
void ITaskHandler::handle(const Tasks &tasks)
{
QTC_ASSERT(canHandle(tasks), return);
QTC_ASSERT(!m_isMultiHandler, return);
handle(tasks.first());
}
bool ITaskHandler::canHandle(const Tasks &tasks) const
{
if (tasks.isEmpty())
return false;
if (m_isMultiHandler)
return true;
if (tasks.size() > 1)
return false;
return canHandle(tasks.first());
}
namespace Internal {
class TaskView : public Utils::ListView
@@ -322,7 +346,7 @@ TaskWindow::TaskWindow() : d(std::make_unique<TaskWindowPrivate>())
d->m_listview->setModel(d->m_filter);
d->m_listview->setFrameStyle(QFrame::NoFrame);
d->m_listview->setWindowTitle(displayName());
d->m_listview->setSelectionMode(QAbstractItemView::SingleSelection);
d->m_listview->setSelectionMode(QAbstractItemView::ExtendedSelection);
auto *tld = new Internal::TaskDelegate(this);
d->m_listview->setItemDelegate(tld);
d->m_listview->setWindowIcon(Icons::WINDOW.icon());
@@ -336,11 +360,18 @@ TaskWindow::TaskWindow() : d(std::make_unique<TaskWindowPrivate>())
connect(d->m_listview->selectionModel(), &QItemSelectionModel::currentChanged,
tld, &TaskDelegate::currentChanged);
connect(d->m_listview->selectionModel(), &QItemSelectionModel::currentChanged,
this, &TaskWindow::currentChanged);
this, [this](const QModelIndex &index) { d->m_listview->scrollTo(index); });
connect(d->m_listview, &QAbstractItemView::activated,
this, &TaskWindow::triggerDefaultHandler);
connect(d->m_listview->selectionModel(), &QItemSelectionModel::selectionChanged,
this, [this] {
const Tasks tasks = d->m_filter->tasks(d->m_listview->selectionModel()->selectedIndexes());
for (QAction * const action : qAsConst(d->m_actions)) {
ITaskHandler * const h = d->handler(action);
action->setEnabled(h && h->canHandle(tasks));
}
});
d->m_contextMenu = new QMenu(d->m_listview);
@@ -417,6 +448,7 @@ void TaskWindow::delayedInitialization()
d->m_defaultHandler = h;
QAction *action = h->createAction(this);
action->setEnabled(false);
QTC_ASSERT(action, continue);
d->m_actionToHandlerMap.insert(action, h);
connect(action, &QAction::triggered, this, &TaskWindow::actionTriggered);
@@ -430,9 +462,6 @@ void TaskWindow::delayedInitialization()
}
d->m_listview->addAction(action);
}
// Disable everything for now:
currentChanged(QModelIndex());
}
QList<QWidget*> TaskWindow::toolBarWidgets() const
@@ -468,16 +497,6 @@ void TaskWindow::setCategoryVisibility(Utils::Id categoryId, bool visible)
d->m_filter->setFilteredCategories(categories);
}
void TaskWindow::currentChanged(const QModelIndex &index)
{
const Task task = index.isValid() ? d->m_filter->task(index) : Task();
foreach (QAction *action, d->m_actions) {
ITaskHandler *h = d->handler(action);
action->setEnabled((task.isNull() || !h) ? false : h->canHandle(task));
}
d->m_listview->scrollTo(index);
}
void TaskWindow::saveSettings()
{
QStringList categories = Utils::transform(d->m_filter->filteredCategories(), &Utils::Id::toString);
@@ -605,12 +624,7 @@ void TaskWindow::actionTriggered()
if (!h)
return;
QModelIndex index = d->m_listview->selectionModel()->currentIndex();
Task task = d->m_filter->task(index);
if (task.isNull())
return;
h->handle(task);
h->handle(d->m_filter->tasks(d->m_listview->selectionModel()->selectedIndexes()));
}
void TaskWindow::setShowWarnings(bool show)
@@ -774,11 +788,11 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
initStyleOption(&opt, index);
auto view = qobject_cast<const QAbstractItemView *>(opt.widget);
const bool selected = (view->selectionModel()->currentIndex() == index);
const bool current = view->selectionModel()->currentIndex() == index;
QSize s;
s.setWidth(option.rect.width());
if (!selected && option.font == m_cachedFont && m_cachedHeight > 0) {
if (!current && option.font == m_cachedFont && m_cachedHeight > 0) {
s.setHeight(m_cachedHeight);
return s;
}
@@ -790,7 +804,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
auto model = static_cast<TaskFilterModel *>(view->model())->taskModel();
Positions positions(option, model);
if (selected) {
if (current) {
QString description = index.data(TaskModel::Description).toString();
// Layout the description
int leading = fontLeading;
@@ -817,7 +831,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
if (s.height() < Positions::minimumHeight())
s.setHeight(Positions::minimumHeight());
if (!selected) {
if (!current) {
m_cachedHeight = s.height();
m_cachedFont = option.font;
}
@@ -856,7 +870,8 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
QColor textColor;
auto view = qobject_cast<const QAbstractItemView *>(opt.widget);
bool selected = view->selectionModel()->currentIndex() == index;
const bool selected = view->selectionModel()->isSelected(index);
const bool current = view->selectionModel()->currentIndex() == index;
if (selected) {
painter->setBrush(opt.palette.highlight().color());
@@ -885,7 +900,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
icon.pixmap(Positions::taskIconWidth(), Positions::taskIconHeight()));
// Paint TextArea:
if (!selected) {
if (!current) {
// in small mode we lay out differently
QString bottom = index.data(TaskModel::Description).toString().split(QLatin1Char('\n')).first();
painter->setClipRect(positions.textArea());
@@ -908,7 +923,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
QTextLayout tl(description);
QVector<QTextLayout::FormatRange> formats = index.data(TaskModel::Task_t).value<Task>().formats;
for (QTextLayout::FormatRange &format : formats)
format.format.setForeground(opt.palette.highlightedText());
format.format.setForeground(textColor);
tl.setFormats(formats);
tl.beginLayout();
while (true) {

View File

@@ -91,7 +91,6 @@ private:
void openTask(const Task &task);
void clearTasks(Utils::Id categoryId);
void setCategoryVisibility(Utils::Id categoryId, bool visible);
void currentChanged(const QModelIndex &index);
void saveSettings();
void loadSettings();

View File

@@ -1556,25 +1556,16 @@ void DesignerActionManager::createDefaultAddResourceHandler()
// Having a single image type category creates too large of a filter, so we split images into
// categories according to their mime types
const QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
QHash<QByteArray, QStringList> imageFormats;
for (const auto &mimeType : mimeTypes)
imageFormats.insert(mimeType, Utils::transform(QImageReader::imageFormatsForMimeType(mimeType), transformer));
imageFormats.insert("image/vnd.radiance", {"*.hdr"});
imageFormats.insert("image/ktx", {"*.ktx"});
auto imageFormats = Utils::transform(QImageReader::supportedImageFormats(), transformer);
imageFormats.push_back("*.hdr");
imageFormats.push_back("*.ktx");
// The filters will be displayed in reverse order to these lists in file dialog,
// so declare most common types last
QHash<QByteArray, QStringList>::const_iterator i = imageFormats.constBegin();
while (i != imageFormats.constEnd()) {
registerHandlers(i.value(),
registerHandlers(imageFormats,
ModelNodeOperations::addImageToProject,
QObject::tr("%1: %2")
.arg(ComponentCoreConstants::addImagesDisplayString)
.arg(QString::fromLatin1(i.key())));
++i;
}
ComponentCoreConstants::addImagesDisplayString);
registerHandlers({"*.otf", "*.ttf"},
ModelNodeOperations::addFontToProject,
ComponentCoreConstants::addFontsDisplayString);

View File

@@ -612,6 +612,19 @@ void ItemLibraryWidget::addImportForItem(const QString &importUrl)
m_model->changeImports({import}, {});
}
static QHash<QByteArray, QStringList> allImageFormats()
{
const QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
QHash<QByteArray, QStringList> imageFormats;
for (const auto &mimeType : mimeTypes)
imageFormats.insert(mimeType, Utils::transform(QImageReader::imageFormatsForMimeType(mimeType), transformer));
imageFormats.insert("image/vnd.radiance", {"*.hdr"});
imageFormats.insert("image/ktx", {"*.ktx"});
return imageFormats;
}
void ItemLibraryWidget::addResources(const QStringList &files)
{
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
@@ -637,8 +650,19 @@ void ItemLibraryWidget::addResources(const QStringList &files)
QStringList filters { tr("All Files (%1)").arg("*.*") };
QString filterTemplate = "%1 (%2)";
for (const QString &key : qAsConst(sortedKeys))
filters.append(filterTemplate.arg(key, map.values(key).join(' ')));
for (const QString &key : qAsConst(sortedKeys)) {
const QStringList values = map.values(key);
if (values.contains("*.png")) { // Avoid long filter for images by splitting
const QHash<QByteArray, QStringList> imageFormats = allImageFormats();
QHash<QByteArray, QStringList>::const_iterator i = imageFormats.constBegin();
while (i != imageFormats.constEnd()) {
filters.append(filterTemplate.arg(key + QString::fromLatin1(i.key()), i.value().join(' ')));
++i;
}
} else {
filters.append(filterTemplate.arg(key, values.join(' ')));
}
}
static QString lastDir;
const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir;

View File

@@ -134,7 +134,7 @@ void BaseConnectionManager::readDataStream(Connection &connection)
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
{"name", cmd.name().toStdString()},
{"counter", commandCounter});
{"counter", int64_t(commandCounter)});
writeCommand(command);
// Do not dispatch this command.
@@ -143,7 +143,7 @@ void BaseConnectionManager::readDataStream(Connection &connection)
} else {
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
{"name", command.typeName()},
{"counter", commandCounter});
{"counter", int64_t(commandCounter)});
}
}
#endif

View File

@@ -196,12 +196,12 @@ void NodeInstanceServerProxy::writeCommand(const QVariant &command)
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
{"name", cmd.name().toStdString()},
{"counter", m_connectionManager.writeCounter()});
{"counter", int64_t(m_connectionManager.writeCounter())});
} else {
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
{"name", command.typeName()},
{"counter", m_connectionManager.writeCounter()});
{"counter", int64_t(m_connectionManager.writeCounter())});
}
#endif

View File

@@ -354,7 +354,7 @@ void generateModuleCmake(const FilePath &dir, const QString &uri)
QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH);
QString singletonContent;
FilePaths qmldirFileList = dir.dirEntries(QStringList(FILENAME_QMLDIR), FILES_ONLY);
FilePaths qmldirFileList = dir.dirEntries({QStringList(FILENAME_QMLDIR), FILES_ONLY});
if (!qmldirFileList.isEmpty()) {
QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
for (QString &singleton : singletons) {
@@ -418,7 +418,7 @@ FilePaths getDirectoryQmls(const FilePath &dir)
{
const QStringList qmlFilesOnly("*.qml");
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
FilePaths allFiles = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
FilePaths allFiles = dir.dirEntries({qmlFilesOnly, FILES_ONLY});
FilePaths moduleFiles;
for (FilePath &file : allFiles) {
if (!isFileBlacklisted(file.fileName()) &&
@@ -436,7 +436,7 @@ QStringList getDirectoryTreeQmls(const FilePath &dir)
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QStringList qmlFileList;
FilePaths thisDirFiles = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
FilePaths thisDirFiles = dir.dirEntries({qmlFilesOnly, FILES_ONLY});
for (FilePath &file : thisDirFiles) {
if (!isFileBlacklisted(file.fileName()) &&
project->isKnownFile(file)) {

View File

@@ -444,9 +444,8 @@ void QnxConfiguration::updateTargets()
void QnxConfiguration::assignDebuggersToTargets()
{
const FilePath hostUsrBinDir = m_qnxHost.pathAppended("usr/bin");
FilePaths debuggerNames = hostUsrBinDir.dirEntries(
QStringList(HostOsInfo::withExecutableSuffix("nto*-gdb")),
QDir::Files);
const FilePaths debuggerNames = hostUsrBinDir.dirEntries(
{{HostOsInfo::withExecutableSuffix("nto*-gdb")}, QDir::Files});
Environment sysEnv = Environment::systemEnvironment();
sysEnv.modify(qnxEnvironmentItems());
for (const FilePath &debuggerPath : debuggerNames) {

View File

@@ -172,22 +172,19 @@ DeviceProcessSignalOperation::Ptr QnxDevice::signalOperation() const
// Factory
QnxDeviceFactory::QnxDeviceFactory()
: ProjectExplorer::IDeviceFactory(Constants::QNX_QNX_OS_TYPE)
QnxDeviceFactory::QnxDeviceFactory() : IDeviceFactory(Constants::QNX_QNX_OS_TYPE)
{
setDisplayName(QnxDevice::tr("QNX Device"));
setCombinedIcon(":/qnx/images/qnxdevicesmall.png",
":/qnx/images/qnxdevice.png");
setCanCreate(true);
setConstructionFunction(&QnxDevice::create);
}
ProjectExplorer::IDevice::Ptr QnxDeviceFactory::create() const
{
setCanCreate(true);
setCreator([] {
QnxDeviceWizard wizard;
if (wizard.exec() != QDialog::Accepted)
return ProjectExplorer::IDevice::Ptr();
return IDevice::Ptr();
return wizard.device();
});
}
} // namespace Internal

View File

@@ -70,8 +70,6 @@ class QnxDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
QnxDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // namespace Internal

View File

@@ -144,9 +144,9 @@ FilePath QnxUtils::envFilePath(const FilePath &sdpPath)
{
FilePaths entries;
if (sdpPath.osType() == OsTypeWindows)
entries = sdpPath.dirEntries({"*-env.bat"});
entries = sdpPath.dirEntries({{"*-env.bat"}});
else
entries = sdpPath.dirEntries({"*-env.sh"});
entries = sdpPath.dirEntries({{"*-env.sh"}});
if (!entries.isEmpty())
return entries.first();

View File

@@ -51,12 +51,9 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
{
setDisplayName("Generic Linux Device");
setIcon(QIcon());
setCanCreate(true);
setConstructionFunction(&LinuxDevice::create);
}
IDevice::Ptr TestLinuxDeviceFactory::create() const
{
setCanCreate(true);
setCreator([] {
LinuxDevice::Ptr newDev = LinuxDevice::create();
qDebug() << "device : " << newDev->type();
newDev->setType("test");
@@ -65,6 +62,7 @@ IDevice::Ptr TestLinuxDeviceFactory::create() const
sshParams.setPort(22);
newDev->setSshParameters(sshParams);
return newDev;
});
}
FilePath createFile(const QString &name)
@@ -114,8 +112,7 @@ void FileSystemAccessTest::testDirStatuses()
}
return false;
},
{"test"},
QDir::Files);
{{"test"}, QDir::Files});
QVERIFY(fileExists);
QVERIFY(testFilePath.removeFile());

View File

@@ -37,8 +37,6 @@ class TestLinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
TestLinuxDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
class FileSystemAccessTest : public QObject

View File

@@ -679,11 +679,10 @@ bool LinuxDevice::setPermissions(const Utils::FilePath &filePath, QFileDevice::P
static void filterEntriesHelper(const FilePath &base,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &entries,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags)
const FileFilter &filter)
{
const QList<QRegularExpression> nameRegexps = transform(nameFilters, [](const QString &filter) {
const QList<QRegularExpression> nameRegexps =
transform(filter.nameFilters, [](const QString &filter) {
QRegularExpression re;
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
QTC_CHECK(re.isValid());
@@ -700,8 +699,8 @@ static void filterEntriesHelper(const FilePath &base,
};
// FIXME: Handle filters. For now bark on unsupported options.
QTC_CHECK(filters == QDir::NoFilter);
QTC_CHECK(flags == QDirIterator::NoIteratorFlags);
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
QTC_CHECK(filter.iteratorFlags == QDirIterator::NoIteratorFlags);
for (const QString &entry : entries) {
if (!nameMatches(entry))
@@ -713,15 +712,13 @@ static void filterEntriesHelper(const FilePath &base,
void LinuxDevice::iterateDirectory(const FilePath &filePath,
const std::function<bool(const FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const
const FileFilter &filter) const
{
QTC_ASSERT(handlesFile(filePath), return);
// if we do not have find - use ls as fallback
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
const QStringList entries = output.split('\n', Qt::SkipEmptyParts);
filterEntriesHelper(filePath, callBack, entries, nameFilters, filters, flags);
filterEntriesHelper(filePath, callBack, entries, filter);
}
QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const
@@ -757,17 +754,15 @@ LinuxDeviceFactory::LinuxDeviceFactory()
{
setDisplayName(LinuxDevice::tr("Generic Linux Device"));
setIcon(QIcon());
setCanCreate(true);
setConstructionFunction(&LinuxDevice::create);
}
IDevice::Ptr LinuxDeviceFactory::create() const
{
setCanCreate(true);
setCreator([] {
GenericLinuxDeviceConfigurationWizard wizard(Core::ICore::dialogParent());
if (wizard.exec() != QDialog::Accepted)
return IDevice::Ptr();
return wizard.device();
});
}
}
} // namespace Internal
} // namespace RemoteLinux

View File

@@ -78,9 +78,7 @@ public:
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
void iterateDirectory(const Utils::FilePath &filePath,
const std::function<bool(const Utils::FilePath &)> &callBack,
const QStringList &nameFilters,
QDir::Filters filters,
QDirIterator::IteratorFlags flags) const override;
const Utils::FileFilter &filter) const override;
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override;
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
QDateTime lastModified(const Utils::FilePath &filePath) const override;
@@ -102,8 +100,6 @@ class LinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
LinuxDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // namespace Internal

View File

@@ -58,7 +58,7 @@ FilePath findFallbackDefinitionsLocation()
FilePath("/opt") / kateSyntaxPath
};
for (const FilePath &path : paths) {
if (path.exists() && !path.dirEntries({"*.xml"}).isEmpty())
if (path.exists() && !path.dirEntries({{"*.xml"}}).isEmpty())
return path;
}
}
@@ -76,7 +76,7 @@ FilePath findFallbackDefinitionsLocation()
const FilePath dir = FilePath::fromString(output);
for (auto &kateSyntaxPath : kateSyntaxPaths) {
const FilePath path = dir / kateSyntaxPath;
if (path.exists() && !path.dirEntries({"*.xml"}).isEmpty())
if (path.exists() && !path.dirEntries({{"*.xml"}}).isEmpty())
return path;
}
}
@@ -84,7 +84,7 @@ FilePath findFallbackDefinitionsLocation()
}
const FilePath dir = Core::ICore::resourcePath("generic-highlighter");
if (dir.exists() && !dir.dirEntries({"*.xml"}).isEmpty())
if (dir.exists() && !dir.dirEntries({{"*.xml"}}).isEmpty())
return dir;
return {};

View File

@@ -95,7 +95,8 @@ SnippetsCollection *SnippetsCollection::instance()
// SnippetsCollection
SnippetsCollection::SnippetsCollection()
: m_userSnippetsFile(Core::ICore::userResourcePath("snippets/snippets.xml")),
m_builtInSnippetsFiles(Core::ICore::resourcePath("snippets").dirEntries({"*.xml"}))
m_builtInSnippetsFiles(Core::ICore::resourcePath("snippets")
.dirEntries(FileFilter({"*.xml"})))
{
connect(Core::ICore::instance(), &Core::ICore::coreOpened,

View File

@@ -47,10 +47,9 @@ WebAssemblyDevice::WebAssemblyDevice()
setOsType(OsTypeOther);
}
ProjectExplorer::IDevice::Ptr WebAssemblyDevice::create()
IDevice::Ptr WebAssemblyDevice::create()
{
auto device = new WebAssemblyDevice;
return ProjectExplorer::IDevice::Ptr(device);
return IDevice::Ptr(new WebAssemblyDevice);
}
WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
@@ -59,13 +58,9 @@ WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
setDisplayName(WebAssemblyDevice::tr("WebAssembly Runtime"));
setCombinedIcon(":/webassembly/images/webassemblydevicesmall.png",
":/webassembly/images/webassemblydevice.png");
setCanCreate(true);
setConstructionFunction(&WebAssemblyDevice::create);
}
ProjectExplorer::IDevice::Ptr WebAssemblyDeviceFactory::create() const
{
return WebAssemblyDevice::create();
setCanCreate(true);
setCreator(&WebAssemblyDevice::create);
}
} // namespace Internal

View File

@@ -45,8 +45,6 @@ class WebAssemblyDeviceFactory final : public ProjectExplorer::IDeviceFactory
{
public:
WebAssemblyDeviceFactory();
ProjectExplorer::IDevice::Ptr create() const override;
};
} // namespace Internal