forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/7.0'
Change-Id: Icaa605bcaa44ad50a98a63251cb4553bfd411b0a
This commit is contained in:
@@ -307,7 +307,7 @@
|
|||||||
|
|
||||||
To view information about the C++ code model in the
|
To view information about the C++ code model in the
|
||||||
\uicontrol {C++ Code Model Inspector} dialog and write it to a log file,
|
\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}.
|
\uicontrol {Inspect C++ Code Model} or press \key {Ctrl+Shift+F12}.
|
||||||
|
|
||||||
\QC generates the code model inspection log file in a temporary folder.
|
\QC generates the code model inspection log file in a temporary folder.
|
||||||
|
@@ -206,12 +206,12 @@ void NodeInstanceClientProxy::writeCommand(const QVariant &command)
|
|||||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||||
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
|
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
|
||||||
{"name", cmd.name().toStdString()},
|
{"name", cmd.name().toStdString()},
|
||||||
{"counter", m_writeCommandCounter});
|
{"counter", int64_t(m_writeCommandCounter)});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
|
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
|
||||||
{"name", command.typeName()},
|
{"name", command.typeName()},
|
||||||
{"counter", m_writeCommandCounter});
|
{"counter", int64_t(m_writeCommandCounter)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -409,14 +409,14 @@ void NodeInstanceClientProxy::readDataStream()
|
|||||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||||
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
|
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
|
||||||
{"name", cmd.name().toStdString()},
|
{"name", cmd.name().toStdString()},
|
||||||
{"counter", readCommandCounter});
|
{"counter", int64_t(readCommandCounter)});
|
||||||
// Do not dispatch this command.
|
// Do not dispatch this command.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
|
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
|
||||||
{"name", command.typeName()},
|
{"name", command.typeName()},
|
||||||
{"counter", readCommandCounter});
|
{"counter", int64_t(readCommandCounter)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -35,7 +35,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Download Ninja and CMake
|
- name: Download Ninja and CMake
|
||||||
shell: cmake -P {0}
|
shell: cmake -P {0}
|
||||||
|
@@ -7,6 +7,5 @@ add_qtc_library(Nanotrace
|
|||||||
PROPERTIES
|
PROPERTIES
|
||||||
CXX_VISIBILITY_PRESET default
|
CXX_VISIBILITY_PRESET default
|
||||||
VISIBILITY_INLINES_HIDDEN OFF
|
VISIBILITY_INLINES_HIDDEN OFF
|
||||||
WINDOWS_EXPORT_ALL_SYMBOLS ON
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -25,6 +25,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#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 <string>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -68,7 +77,7 @@ using Units = std::chrono::nanoseconds;
|
|||||||
using Clock = std::chrono::high_resolution_clock;
|
using Clock = std::chrono::high_resolution_clock;
|
||||||
using TimePoint = std::chrono::time_point< Clock >;
|
using TimePoint = std::chrono::time_point< Clock >;
|
||||||
|
|
||||||
class Arg
|
class NANOTRACESHARED_EXPORT Arg
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using SupportedType = std::variant<int, int64_t, double, std::string>;
|
using SupportedType = std::variant<int, int64_t, double, std::string>;
|
||||||
@@ -82,19 +91,19 @@ private:
|
|||||||
SupportedType m_value;
|
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 &name,
|
||||||
const std::string &cat,
|
const std::string &cat,
|
||||||
char phase,
|
char phase,
|
||||||
std::initializer_list< Nanotrace::Arg > arguments);
|
std::initializer_list< Nanotrace::Arg > arguments);
|
||||||
|
|
||||||
class ScopeTracer
|
class NANOTRACESHARED_EXPORT ScopeTracer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScopeTracer(
|
ScopeTracer(
|
||||||
|
@@ -2,7 +2,6 @@ QtcLibrary {
|
|||||||
name: "Nanotrace"
|
name: "Nanotrace"
|
||||||
|
|
||||||
cpp.defines: base.concat("NANOTRACE_LIBRARY", "NANOTRACE_ENABLED")
|
cpp.defines: base.concat("NANOTRACE_LIBRARY", "NANOTRACE_ENABLED")
|
||||||
cpp.visibility: "default"
|
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
"nanotrace.cpp",
|
"nanotrace.cpp",
|
||||||
|
@@ -25,7 +25,6 @@ add_qtc_library(Utils
|
|||||||
commandline.cpp commandline.h
|
commandline.cpp commandline.h
|
||||||
completinglineedit.cpp completinglineedit.h
|
completinglineedit.cpp completinglineedit.h
|
||||||
completingtextedit.cpp completingtextedit.h
|
completingtextedit.cpp completingtextedit.h
|
||||||
consoleprocess.cpp consoleprocess.h
|
|
||||||
cpplanguage_details.h
|
cpplanguage_details.h
|
||||||
crumblepath.cpp crumblepath.h
|
crumblepath.cpp crumblepath.h
|
||||||
declarationmacros.h
|
declarationmacros.h
|
||||||
|
@@ -88,9 +88,7 @@ static FilePath findQmakeInDir(const FilePath &dir)
|
|||||||
|
|
||||||
// Prefer qmake-qt5 to qmake-qt4 by sorting the filenames in reverse order.
|
// Prefer qmake-qt5 to qmake-qt4 by sorting the filenames in reverse order.
|
||||||
const FilePaths candidates = dir.dirEntries(
|
const FilePaths candidates = dir.dirEntries(
|
||||||
BuildableHelperLibrary::possibleQMakeCommands(),
|
{BuildableHelperLibrary::possibleQMakeCommands(), QDir::Files},
|
||||||
QDir::Files,
|
|
||||||
QDirIterator::NoIteratorFlags,
|
|
||||||
QDir::Name | QDir::Reversed);
|
QDir::Name | QDir::Reversed);
|
||||||
for (const FilePath &candidate : candidates) {
|
for (const FilePath &candidate : candidates) {
|
||||||
if (candidate == qmakePath)
|
if (candidate == qmakePath)
|
||||||
|
@@ -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
|
|
@@ -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
|
|
@@ -718,19 +718,16 @@ bool FilePath::createDir() const
|
|||||||
return dir.mkpath(dir.absolutePath());
|
return dir.mkpath(dir.absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePaths FilePath::dirEntries(const QStringList &nameFilters,
|
FilePaths FilePath::dirEntries(const FileFilter &filter, QDir::SortFlags sort) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags,
|
|
||||||
QDir::SortFlags sort) const
|
|
||||||
{
|
{
|
||||||
FilePaths result;
|
FilePaths result;
|
||||||
|
|
||||||
if (needsDevice()) {
|
if (needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.iterateDirectory, return {});
|
QTC_ASSERT(s_deviceHooks.iterateDirectory, return {});
|
||||||
const auto callBack = [&result](const FilePath &path) { result.append(path); return true; };
|
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 {
|
} else {
|
||||||
QDirIterator dit(m_data, nameFilters, filters, flags);
|
QDirIterator dit(m_data, filter.nameFilters, filter.fileFilters, filter.iteratorFlags);
|
||||||
while (dit.hasNext())
|
while (dit.hasNext())
|
||||||
result.append(FilePath::fromString(dit.next()));
|
result.append(FilePath::fromString(dit.next()));
|
||||||
}
|
}
|
||||||
@@ -754,7 +751,7 @@ FilePaths FilePath::dirEntries(const QStringList &nameFilters,
|
|||||||
|
|
||||||
FilePaths FilePath::dirEntries(QDir::Filters filters) const
|
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
|
// 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.
|
// An empty \nameFilters list matches every name.
|
||||||
|
|
||||||
void FilePath::iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
|
void FilePath::iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const
|
|
||||||
{
|
{
|
||||||
if (needsDevice()) {
|
if (needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.iterateDirectory, return);
|
QTC_ASSERT(s_deviceHooks.iterateDirectory, return);
|
||||||
s_deviceHooks.iterateDirectory(*this, callBack, nameFilters, filters, flags);
|
s_deviceHooks.iterateDirectory(*this, callBack, filter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDirIterator it(m_data, nameFilters, filters, flags);
|
QDirIterator it(m_data, filter.nameFilters, filter.fileFilters, filter.iteratorFlags);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
if (!callBack(FilePath::fromString(it.next())))
|
if (!callBack(FilePath::fromString(it.next())))
|
||||||
return;
|
return;
|
||||||
@@ -1460,6 +1455,15 @@ QTextStream &operator<<(QTextStream &s, const FilePath &fn)
|
|||||||
return s << fn.toString();
|
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
|
} // namespace Utils
|
||||||
|
|
||||||
std::hash<Utils::FilePath>::result_type
|
std::hash<Utils::FilePath>::result_type
|
||||||
|
@@ -51,6 +51,18 @@ namespace Utils {
|
|||||||
class Environment;
|
class Environment;
|
||||||
class EnvironmentChange;
|
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
|
class QTCREATOR_UTILS_EXPORT FilePath
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -121,9 +133,7 @@ public:
|
|||||||
qint64 fileSize() const;
|
qint64 fileSize() const;
|
||||||
qint64 bytesAvailable() const;
|
qint64 bytesAvailable() const;
|
||||||
bool createDir() const;
|
bool createDir() const;
|
||||||
QList<FilePath> dirEntries(const QStringList &nameFilters,
|
QList<FilePath> dirEntries(const FileFilter &filter,
|
||||||
QDir::Filters filters = QDir::NoFilter,
|
|
||||||
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags,
|
|
||||||
QDir::SortFlags sort = QDir::NoSort) const;
|
QDir::SortFlags sort = QDir::NoSort) const;
|
||||||
QList<FilePath> dirEntries(QDir::Filters filters) const;
|
QList<FilePath> dirEntries(QDir::Filters filters) const;
|
||||||
QByteArray fileContents(qint64 maxSize = -1, qint64 offset = 0) const;
|
QByteArray fileContents(qint64 maxSize = -1, qint64 offset = 0) const;
|
||||||
@@ -160,9 +170,7 @@ public:
|
|||||||
[[nodiscard]] FilePath onDevice(const FilePath &deviceTemplate) const;
|
[[nodiscard]] FilePath onDevice(const FilePath &deviceTemplate) const;
|
||||||
[[nodiscard]] FilePath withNewPath(const QString &newPath) const;
|
[[nodiscard]] FilePath withNewPath(const QString &newPath) const;
|
||||||
void iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
|
void iterateDirectory(const std::function<bool(const FilePath &item)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const;
|
||||||
QDir::Filters filters = QDir::NoFilter,
|
|
||||||
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const;
|
|
||||||
|
|
||||||
// makes sure that capitalization of directories is canonical
|
// makes sure that capitalization of directories is canonical
|
||||||
// on Windows and macOS. This is rarely needed.
|
// on Windows and macOS. This is rarely needed.
|
||||||
|
@@ -82,9 +82,7 @@ public:
|
|||||||
std::function<QString(const FilePath &)> mapToDevicePath;
|
std::function<QString(const FilePath &)> mapToDevicePath;
|
||||||
std::function<void(const FilePath &,
|
std::function<void(const FilePath &,
|
||||||
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
||||||
const QStringList &,
|
const FileFilter &)> iterateDirectory;
|
||||||
QDir::Filters,
|
|
||||||
QDirIterator::IteratorFlags)> iterateDirectory;
|
|
||||||
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
|
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
|
||||||
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
|
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
|
||||||
std::function<QDateTime(const FilePath &)> lastModified;
|
std::function<QDateTime(const FilePath &)> lastModified;
|
||||||
|
@@ -221,7 +221,7 @@ FilePaths BackUpStrategy::readFileCandidates(const FilePath &baseFileName) const
|
|||||||
const QStringList filter(baseFileName.fileName() + '*');
|
const QStringList filter(baseFileName.fileName() + '*');
|
||||||
const FilePath baseFileDir = baseFileName.parentDir();
|
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,
|
int BackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
|
||||||
|
@@ -68,8 +68,6 @@ Project {
|
|||||||
"completinglineedit.h",
|
"completinglineedit.h",
|
||||||
"completingtextedit.cpp",
|
"completingtextedit.cpp",
|
||||||
"completingtextedit.h",
|
"completingtextedit.h",
|
||||||
"consoleprocess.cpp",
|
|
||||||
"consoleprocess.h",
|
|
||||||
"cpplanguage_details.h",
|
"cpplanguage_details.h",
|
||||||
"crumblepath.cpp",
|
"crumblepath.cpp",
|
||||||
"crumblepath.h",
|
"crumblepath.h",
|
||||||
|
@@ -382,8 +382,7 @@ QVector<int> AndroidConfig::availableNdkPlatforms(const QtVersion *qtVersion) co
|
|||||||
.toInt());
|
.toInt());
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
{"android-*"},
|
{{"android-*"}, QDir::Dirs});
|
||||||
QDir::Dirs);
|
|
||||||
|
|
||||||
Utils::sort(availableNdkPlatforms, std::greater<>());
|
Utils::sort(availableNdkPlatforms, std::greater<>());
|
||||||
return availableNdkPlatforms;
|
return availableNdkPlatforms;
|
||||||
|
@@ -663,34 +663,33 @@ AndroidDeviceManager::AndroidDeviceManager(QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Factory
|
// Factory
|
||||||
|
|
||||||
AndroidDeviceFactory::AndroidDeviceFactory()
|
AndroidDeviceFactory::AndroidDeviceFactory()
|
||||||
: ProjectExplorer::IDeviceFactory(Constants::ANDROID_DEVICE_TYPE),
|
: IDeviceFactory(Constants::ANDROID_DEVICE_TYPE),
|
||||||
m_androidConfig(AndroidConfigurations::currentConfig())
|
m_androidConfig(AndroidConfigurations::currentConfig())
|
||||||
{
|
{
|
||||||
setDisplayName(AndroidDevice::tr("Android Device"));
|
setDisplayName(AndroidDevice::tr("Android Device"));
|
||||||
setCombinedIcon(":/android/images/androiddevicesmall.png",
|
setCombinedIcon(":/android/images/androiddevicesmall.png",
|
||||||
":/android/images/androiddevice.png");
|
":/android/images/androiddevice.png");
|
||||||
|
|
||||||
setConstructionFunction(&AndroidDevice::create);
|
setConstructionFunction(&AndroidDevice::create);
|
||||||
setCanCreate(m_androidConfig.sdkToolsOk());
|
setCanCreate(m_androidConfig.sdkToolsOk());
|
||||||
}
|
setCreator([this] {
|
||||||
|
AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent());
|
||||||
|
if (dialog.exec() != QDialog::Accepted)
|
||||||
|
return IDevice::Ptr();
|
||||||
|
|
||||||
IDevice::Ptr AndroidDeviceFactory::create() const
|
const IDevice::Ptr dev = dialog.device();
|
||||||
{
|
if (const auto androidDev = static_cast<AndroidDevice *>(dev.data())) {
|
||||||
AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent());
|
qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".",
|
||||||
if (dialog.exec() != QDialog::Accepted)
|
qPrintable(androidDev->avdName()));
|
||||||
return ProjectExplorer::IDevice::Ptr();
|
} else {
|
||||||
|
AndroidDeviceWidget::criticalDialog(
|
||||||
|
AndroidDevice::tr("The device info returned from AvdDialog is invalid."));
|
||||||
|
}
|
||||||
|
|
||||||
const ProjectExplorer::IDevice::Ptr dev = dialog.device();
|
return IDevice::Ptr(dev);
|
||||||
const AndroidDevice *androidDev = static_cast<AndroidDevice*>(dev.data());
|
});
|
||||||
if (androidDev) {
|
|
||||||
qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".",
|
|
||||||
qPrintable(androidDev->avdName()));
|
|
||||||
} else {
|
|
||||||
AndroidDeviceWidget::criticalDialog(
|
|
||||||
QObject::tr("The device info returned from AvdDialog is invalid."));
|
|
||||||
}
|
|
||||||
|
|
||||||
return IDevice::Ptr(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -88,7 +88,6 @@ class AndroidDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidDeviceFactory();
|
AndroidDeviceFactory();
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const AndroidConfig &m_androidConfig;
|
const AndroidConfig &m_androidConfig;
|
||||||
|
@@ -423,7 +423,7 @@ QString AndroidManager::apkDevicePreferredAbi(const Target *target)
|
|||||||
QStringList apkAbis;
|
QStringList apkAbis;
|
||||||
const FilePaths libsPaths = libsPath.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot);
|
const FilePaths libsPaths = libsPath.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
for (const FilePath &abiDir : libsPaths) {
|
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();
|
apkAbis << abiDir.fileName();
|
||||||
}
|
}
|
||||||
return preferredAbi(apkAbis, target);
|
return preferredAbi(apkAbis, target);
|
||||||
|
@@ -256,7 +256,7 @@ static QImage scaleWithoutStretching(const QImage& original, const QSize& target
|
|||||||
|
|
||||||
static bool similarFilesExist(const FilePath &path)
|
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();
|
return !entries.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -73,9 +73,7 @@ static void setSdkFilesExecPermission( const FilePath &sdkExtractPath)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
{"*"},
|
{{"*"}, QDir::Files, QDirIterator::Subdirectories});
|
||||||
QDir::Files,
|
|
||||||
QDirIterator::Subdirectories);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &jdkPath, const FilePath &sdkExtractPath)
|
void AndroidSdkDownloader::downloadAndExtractSdk(const FilePath &jdkPath, const FilePath &sdkExtractPath)
|
||||||
|
@@ -322,7 +322,7 @@ void JLSClient::updateProjectFiles()
|
|||||||
const FilePath androidJar = sdkLocation / QString("platforms/%2/android.jar")
|
const FilePath androidJar = sdkLocation / QString("platforms/%2/android.jar")
|
||||||
.arg(targetSDK);
|
.arg(targetSDK);
|
||||||
FilePaths libs = {androidJar};
|
FilePaths libs = {androidJar};
|
||||||
libs << packageSourceDir.pathAppended("libs").dirEntries({"*.jar"}, QDir::Files);
|
libs << packageSourceDir.pathAppended("libs").dirEntries({{"*.jar"}, QDir::Files});
|
||||||
generateProjectFile(projectDir, qtSrc, project()->displayName());
|
generateProjectFile(projectDir, qtSrc, project()->displayName());
|
||||||
generateClassPathFile(projectDir, sourceDir, libs);
|
generateClassPathFile(projectDir, sourceDir, libs);
|
||||||
}
|
}
|
||||||
|
@@ -125,16 +125,14 @@ BareMetalDeviceFactory::BareMetalDeviceFactory()
|
|||||||
setDisplayName(BareMetalDevice::tr("Bare Metal Device"));
|
setDisplayName(BareMetalDevice::tr("Bare Metal Device"));
|
||||||
setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png",
|
setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png",
|
||||||
":/baremetal/images/baremetaldevice.png");
|
":/baremetal/images/baremetaldevice.png");
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&BareMetalDevice::create);
|
setConstructionFunction(&BareMetalDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator([] {
|
||||||
IDevice::Ptr BareMetalDeviceFactory::create() const
|
BareMetalDeviceConfigurationWizard wizard;
|
||||||
{
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
BareMetalDeviceConfigurationWizard wizard;
|
return IDevice::Ptr();
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
return wizard.device();
|
||||||
return {};
|
});
|
||||||
return wizard.device();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace Internal
|
} //namespace Internal
|
||||||
|
@@ -71,9 +71,7 @@ private:
|
|||||||
class BareMetalDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
class BareMetalDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BareMetalDeviceFactory();
|
BareMetalDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const final;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace Internal
|
} //namespace Internal
|
||||||
|
@@ -286,17 +286,14 @@ QdbLinuxDeviceFactory::QdbLinuxDeviceFactory()
|
|||||||
{
|
{
|
||||||
setDisplayName(QdbDevice::tr("Boot2Qt Device"));
|
setDisplayName(QdbDevice::tr("Boot2Qt Device"));
|
||||||
setCombinedIcon(":/qdb/images/qdbdevicesmall.png", ":/qdb/images/qdbdevice.png");
|
setCombinedIcon(":/qdb/images/qdbdevicesmall.png", ":/qdb/images/qdbdevice.png");
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&QdbDevice::create);
|
setConstructionFunction(&QdbDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator([] {
|
||||||
IDevice::Ptr QdbLinuxDeviceFactory::create() const
|
QdbDeviceWizard wizard(Core::ICore::dialogParent());
|
||||||
{
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
QdbDeviceWizard wizard(Core::ICore::dialogParent());
|
return IDevice::Ptr();
|
||||||
|
return wizard.device();
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
});
|
||||||
return IDevice::Ptr();
|
|
||||||
return wizard.device();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -65,9 +65,6 @@ class QdbLinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QdbLinuxDeviceFactory();
|
QdbLinuxDeviceFactory();
|
||||||
|
|
||||||
private:
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const final;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -109,8 +109,7 @@ void registerFlashAction(QObject *parentForAction)
|
|||||||
|
|
||||||
Core::ActionContainer *toolsContainer =
|
Core::ActionContainer *toolsContainer =
|
||||||
Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
||||||
toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS,
|
toolsContainer->insertGroup(Core::Constants::G_TOOLS_DEBUG, flashActionId);
|
||||||
flashActionId);
|
|
||||||
|
|
||||||
Core::Context globalContext(Core::Constants::C_GLOBAL);
|
Core::Context globalContext(Core::Constants::C_GLOBAL);
|
||||||
|
|
||||||
|
@@ -946,43 +946,45 @@ static bool isWindowsARM64(const Kit *k)
|
|||||||
&& targetAbi.wordWidth() == 64;
|
&& targetAbi.wordWidth() == 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList defaultInitialCMakeArguments(const Kit *k, const QString buildType)
|
static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString buildType)
|
||||||
{
|
{
|
||||||
// Generator:
|
// 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:
|
// CMAKE_BUILD_TYPE:
|
||||||
if (!buildType.isEmpty() && !CMakeGeneratorKitAspect::isMultiConfigGenerator(k)) {
|
if (!buildType.isEmpty() && !CMakeGeneratorKitAspect::isMultiConfigGenerator(k))
|
||||||
initialArgs.append(QString::fromLatin1("-DCMAKE_BUILD_TYPE:STRING=%1").arg(buildType));
|
cmd.addArg("-DCMAKE_BUILD_TYPE:STRING=" + buildType);
|
||||||
}
|
|
||||||
|
|
||||||
Internal::CMakeSpecificSettings *settings
|
Internal::CMakeSpecificSettings *settings
|
||||||
= Internal::CMakeProjectPlugin::projectTypeSpecificSettings();
|
= Internal::CMakeProjectPlugin::projectTypeSpecificSettings();
|
||||||
|
|
||||||
// Package manager
|
// Package manager
|
||||||
if (!isDocker(k) && settings->packageManagerAutoSetup.value())
|
if (!isDocker(k) && settings->packageManagerAutoSetup.value()) {
|
||||||
initialArgs.append(QString::fromLatin1("-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH=%1")
|
cmd.addArg("-DCMAKE_PROJECT_INCLUDE_BEFORE:PATH="
|
||||||
.arg("%{IDE:ResourcePath}/package-manager/auto-setup.cmake"));
|
"%{IDE:ResourcePath}/package-manager/auto-setup.cmake");
|
||||||
|
}
|
||||||
|
|
||||||
// Cross-compilation settings:
|
// Cross-compilation settings:
|
||||||
if (!isIos(k)) { // iOS handles this differently
|
if (!isIos(k)) { // iOS handles this differently
|
||||||
const QString sysRoot = SysRootKitAspect::sysRoot(k).path();
|
const QString sysRoot = SysRootKitAspect::sysRoot(k).path();
|
||||||
if (!sysRoot.isEmpty()) {
|
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)) {
|
if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) {
|
||||||
const QString targetTriple = tc->originalTargetTriple();
|
const QString targetTriple = tc->originalTargetTriple();
|
||||||
initialArgs.append(
|
cmd.addArg("-DCMAKE_C_COMPILER_TARGET:STRING=" + targetTriple);
|
||||||
QString::fromLatin1("-DCMAKE_C_COMPILER_TARGET:STRING=%1").arg(targetTriple));
|
cmd.addArg("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1" + targetTriple);
|
||||||
initialArgs.append(
|
|
||||||
QString::fromLatin1("-DCMAKE_CXX_COMPILER_TARGET:STRING=%1").arg(targetTriple));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initialArgs += CMakeConfigurationKitAspect::toArgumentsList(k);
|
cmd.addArgs(CMakeConfigurationKitAspect::toArgumentsList(k));
|
||||||
initialArgs += ProcessArgs::splitArgs(CMakeConfigurationKitAspect::additionalConfiguration(k));
|
cmd.addArgs(CMakeConfigurationKitAspect::additionalConfiguration(k), CommandLine::Raw);
|
||||||
|
|
||||||
return initialArgs;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -1067,19 +1069,19 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
setInitializer([this, target](const BuildInfo &info) {
|
setInitializer([this, target](const BuildInfo &info) {
|
||||||
const Kit *k = target->kit();
|
const Kit *k = target->kit();
|
||||||
|
|
||||||
QStringList initialArgs = defaultInitialCMakeArguments(k, info.typeName);
|
CommandLine cmd = defaultInitialCMakeCommand(k, info.typeName);
|
||||||
setIsMultiConfig(CMakeGeneratorKitAspect::isMultiConfigGenerator(k));
|
setIsMultiConfig(CMakeGeneratorKitAspect::isMultiConfigGenerator(k));
|
||||||
|
|
||||||
// Android magic:
|
// Android magic:
|
||||||
if (DeviceTypeKitAspect::deviceTypeId(k) == Android::Constants::ANDROID_DEVICE_TYPE) {
|
if (DeviceTypeKitAspect::deviceTypeId(k) == Android::Constants::ANDROID_DEVICE_TYPE) {
|
||||||
buildSteps()->appendStep(Android::Constants::ANDROID_BUILD_APK_ID);
|
buildSteps()->appendStep(Android::Constants::ANDROID_BUILD_APK_ID);
|
||||||
const auto &bs = buildSteps()->steps().constLast();
|
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());
|
+ bs->data(Android::Constants::AndroidNdkPlatform).toString());
|
||||||
auto ndkLocation = bs->data(Android::Constants::NdkLocation).value<FilePath>();
|
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());
|
+ ndkLocation.pathAppended("build/cmake/android.toolchain.cmake").path());
|
||||||
|
|
||||||
auto androidAbis = bs->data(Android::Constants::AndroidMkSpecAbis).toStringList();
|
auto androidAbis = bs->data(Android::Constants::AndroidMkSpecAbis).toStringList();
|
||||||
@@ -1092,9 +1094,9 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
} else {
|
} else {
|
||||||
preferredAbi = androidAbis.first();
|
preferredAbi = androidAbis.first();
|
||||||
}
|
}
|
||||||
initialArgs.append("-DANDROID_ABI:STRING=" + preferredAbi);
|
cmd.addArg("-DANDROID_ABI:STRING=" + preferredAbi);
|
||||||
initialArgs.append("-DANDROID_STL:STRING=c++_shared");
|
cmd.addArg("-DANDROID_STL:STRING=c++_shared");
|
||||||
initialArgs.append("-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}");
|
cmd.addArg("-DCMAKE_FIND_ROOT_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}");
|
||||||
|
|
||||||
QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
||||||
auto sdkLocation = bs->data(Android::Constants::SdkLocation).value<FilePath>();
|
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}) {
|
if (qt && qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) {
|
||||||
// Don't build apk under ALL target because Qt Creator will handle it
|
// Don't build apk under ALL target because Qt Creator will handle it
|
||||||
if (qt->qtVersion() >= QtSupport::QtVersionNumber{6, 1, 0})
|
if (qt->qtVersion() >= QtSupport::QtVersionNumber{6, 1, 0})
|
||||||
initialArgs.append("-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON");
|
cmd.addArg("-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON");
|
||||||
initialArgs.append("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
|
cmd.addArg("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
|
||||||
initialArgs.append("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
|
cmd.addArg("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
|
||||||
} else {
|
} 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
|
const QString sysroot = deviceType == Ios::Constants::IOS_DEVICE_TYPE
|
||||||
? QLatin1String("iphoneos")
|
? QLatin1String("iphoneos")
|
||||||
: QLatin1String("iphonesimulator");
|
: QLatin1String("iphonesimulator");
|
||||||
initialArgs.append(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
||||||
initialArgs.append("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture);
|
cmd.addArg("-DCMAKE_OSX_ARCHITECTURES:STRING=" + architecture);
|
||||||
initialArgs.append("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot);
|
cmd.addArg("-DCMAKE_OSX_SYSROOT:STRING=" + sysroot);
|
||||||
initialArgs.append("%{" + QLatin1String(DEVELOPMENT_TEAM_FLAG) + "}");
|
cmd.addArg("%{" + QLatin1String(DEVELOPMENT_TEAM_FLAG) + "}");
|
||||||
initialArgs.append("%{" + QLatin1String(PROVISIONING_PROFILE_FLAG) + "}");
|
cmd.addArg("%{" + QLatin1String(PROVISIONING_PROFILE_FLAG) + "}");
|
||||||
}
|
}
|
||||||
} else if (device && device->osType() == Utils::OsTypeMac) {
|
} 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)) {
|
if (isWebAssembly(k) || isQnx(k) || isWindowsARM64(k)) {
|
||||||
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
const QtSupport::QtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
||||||
if (qt && qt->qtVersion().majorVersion >= 6)
|
if (qt && qt->qtVersion().majorVersion >= 6)
|
||||||
initialArgs.append(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
cmd.addArg(CMAKE_QT6_TOOLCHAIN_FILE_ARG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.buildDirectory.isEmpty()) {
|
if (info.buildDirectory.isEmpty()) {
|
||||||
@@ -1155,7 +1157,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
|||||||
info.extraInfo.value<QVariantMap>().value(Constants::CMAKE_HOME_DIR)));
|
info.extraInfo.value<QVariantMap>().value(Constants::CMAKE_HOME_DIR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
setInitialCMakeArguments(initialArgs);
|
setInitialCMakeArguments(cmd.splitArguments());
|
||||||
setCMakeBuildType(info.typeName);
|
setCMakeBuildType(info.typeName);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1200,12 +1202,10 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
|
|||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
if (initialCMakeArguments().isEmpty()) {
|
if (initialCMakeArguments().isEmpty()) {
|
||||||
QStringList initialArgs = defaultInitialCMakeArguments(kit(), buildTypeName)
|
CommandLine cmd = defaultInitialCMakeCommand(kit(), buildTypeName);
|
||||||
+ Utils::transform(conf.toList(), [this](const CMakeConfigItem &i) {
|
for (const CMakeConfigItem &item : conf)
|
||||||
return i.toArgument(macroExpander());
|
cmd.addArg(item.toArgument(macroExpander()));
|
||||||
});
|
setInitialCMakeArguments(cmd.splitArguments());
|
||||||
|
|
||||||
setInitialCMakeArguments(initialArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -79,7 +79,7 @@ static QStringList scanDirectory(const FilePath &path, const QString &prefix)
|
|||||||
QStringList result;
|
QStringList result;
|
||||||
qCDebug(cmInputLog) << "Scanning for directories matching" << prefix << "in" << path;
|
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);
|
QTC_ASSERT(entry.isDir(), continue);
|
||||||
result.append(entry.toString());
|
result.append(entry.toString());
|
||||||
}
|
}
|
||||||
|
@@ -948,10 +948,7 @@ FilePath FileApiParser::scanForCMakeReplyFile(const FilePath &buildDirectory)
|
|||||||
if (!replyDir.exists())
|
if (!replyDir.exists())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const FilePaths entries = replyDir.dirEntries({"index-*.json"},
|
const FilePaths entries = replyDir.dirEntries({{"index-*.json"}, QDir::Files}, QDir::Name);
|
||||||
QDir::Files,
|
|
||||||
QDirIterator::NoIteratorFlags,
|
|
||||||
QDir::Name);
|
|
||||||
return entries.isEmpty() ? FilePath() : entries.first();
|
return entries.isEmpty() ? FilePath() : entries.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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_VIEW_PANES[] = "QtCreator.Menu.View.Panes";
|
||||||
const char M_TOOLS[] = "QtCreator.Menu.Tools";
|
const char M_TOOLS[] = "QtCreator.Menu.Tools";
|
||||||
const char M_TOOLS_EXTERNAL[] = "QtCreator.Menu.Tools.External";
|
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_WINDOW[] = "QtCreator.Menu.Window";
|
||||||
const char M_HELP[] = "QtCreator.Menu.Help";
|
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";
|
const char G_VIEW_PANES[] = "QtCreator.Group.View.Panes";
|
||||||
|
|
||||||
// Tools menu groups
|
// Tools menu groups
|
||||||
|
const char G_TOOLS_DEBUG[] = "QtCreator.Group.Tools.Debug";
|
||||||
const char G_TOOLS_OPTIONS[] = "QtCreator.Group.Tools.Options";
|
const char G_TOOLS_OPTIONS[] = "QtCreator.Group.Tools.Options";
|
||||||
|
|
||||||
// Window menu groups
|
// Window menu groups
|
||||||
|
@@ -701,16 +701,21 @@ void MainWindow::registerDefaultActions()
|
|||||||
cmd->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
|
cmd->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? tr("Meta+0") : tr("Ctrl+0")));
|
||||||
tmpaction->setEnabled(false);
|
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
|
// Options Action
|
||||||
mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
|
mtools->appendGroup(Constants::G_TOOLS_OPTIONS);
|
||||||
mtools->addSeparator(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 = new QAction(tr("&Options..."), this);
|
||||||
m_optionsAction->setMenuRole(QAction::PreferencesRole);
|
m_optionsAction->setMenuRole(QAction::PreferencesRole);
|
||||||
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS);
|
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS);
|
||||||
|
@@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/consoleprocess.h>
|
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/environmentdialog.h>
|
#include <utils/environmentdialog.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
@@ -413,12 +413,12 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
|
|||||||
cppModelManager, &CppModelManager::updateModifiedSourceFiles);
|
cppModelManager, &CppModelManager::updateModifiedSourceFiles);
|
||||||
cppToolsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
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);
|
QAction *inspectCppCodeModel = new QAction(tr("Inspect C++ Code Model..."), this);
|
||||||
cmd = ActionManager::registerAction(inspectCppCodeModel, Constants::INSPECT_CPP_CODEMODEL);
|
cmd = ActionManager::registerAction(inspectCppCodeModel, Constants::INSPECT_CPP_CODEMODEL);
|
||||||
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+Shift+F12") : tr("Ctrl+Shift+F12")));
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+Shift+F12") : tr("Ctrl+Shift+F12")));
|
||||||
connect(inspectCppCodeModel, &QAction::triggered, d, &CppEditorPluginPrivate::inspectCppCodeModel);
|
connect(inspectCppCodeModel, &QAction::triggered, d, &CppEditorPluginPrivate::inspectCppCodeModel);
|
||||||
cppToolsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
toolsDebug->addAction(cmd);
|
||||||
|
|
||||||
contextMenu->addSeparator(context);
|
contextMenu->addSeparator(context);
|
||||||
|
|
||||||
|
@@ -62,7 +62,6 @@
|
|||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/consoleprocess.h>
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
@@ -780,7 +780,7 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePaths &s
|
|||||||
|
|
||||||
const auto addSuspect = [&suspects](const FilePath &entry) { suspects.append(entry); return true; };
|
const auto addSuspect = [&suspects](const FilePath &entry) { suspects.append(entry); return true; };
|
||||||
for (const FilePath &path : paths)
|
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...")};
|
QStringList logMessages{tr("Searching debuggers...")};
|
||||||
for (const FilePath &command : qAsConst(suspects)) {
|
for (const FilePath &command : qAsConst(suspects)) {
|
||||||
|
@@ -1615,9 +1615,7 @@ QString GdbEngine::cleanupFullName(const QString &fileName)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
{"*"},
|
{{"*"}, QDir::NoFilter, QDirIterator::Subdirectories});
|
||||||
QDir::NoFilter,
|
|
||||||
QDirIterator::Subdirectories);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#include <debugger/debuggertooltipmanager.h>
|
#include <debugger/debuggertooltipmanager.h>
|
||||||
#include <debugger/debuggerprotocol.h>
|
#include <debugger/debuggerprotocol.h>
|
||||||
|
|
||||||
#include <utils/consoleprocess.h>
|
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
@@ -472,7 +472,7 @@ DiffEditorPluginPrivate::DiffEditorPluginPrivate()
|
|||||||
//register actions
|
//register actions
|
||||||
ActionContainer *toolsContainer
|
ActionContainer *toolsContainer
|
||||||
= ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
= 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");
|
ActionContainer *diffContainer = ActionManager::createMenu("Diff");
|
||||||
diffContainer->menu()->setTitle(tr("&Diff"));
|
diffContainer->menu()->setTitle(tr("&Diff"));
|
||||||
toolsContainer->addMenu(diffContainer, Constants::G_TOOLS_DIFF);
|
toolsContainer->addMenu(diffContainer, Constants::G_TOOLS_DIFF);
|
||||||
|
@@ -1455,17 +1455,20 @@ bool DockerDevice::setPermissions(const FilePath &filePath, QFileDevice::Permiss
|
|||||||
|
|
||||||
void DockerDevice::iterateWithFind(const FilePath &filePath,
|
void DockerDevice::iterateWithFind(const FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters) const
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(callBack, return);
|
QTC_ASSERT(callBack, return);
|
||||||
QTC_CHECK(filePath.isAbsolutePath());
|
QTC_CHECK(filePath.isAbsolutePath());
|
||||||
QStringList arguments{filePath.path(), "-maxdepth", "1"};
|
QStringList arguments{filePath.path()};
|
||||||
|
|
||||||
|
const QDir::Filters filters = filter.fileFilters;
|
||||||
if (filters & QDir::NoSymLinks)
|
if (filters & QDir::NoSymLinks)
|
||||||
arguments.prepend("-H");
|
arguments.prepend("-H");
|
||||||
else
|
else
|
||||||
arguments.prepend("-L");
|
arguments.prepend("-L");
|
||||||
|
|
||||||
|
if (!filter.iteratorFlags.testFlag(QDirIterator::Subdirectories))
|
||||||
|
arguments.append({"-maxdepth", "1"});
|
||||||
|
|
||||||
QStringList filterOptions;
|
QStringList filterOptions;
|
||||||
if (filters & QDir::Dirs)
|
if (filters & QDir::Dirs)
|
||||||
@@ -1493,12 +1496,12 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
|
|||||||
const QString nameOption = (filters & QDir::CaseSensitive) ? QString{"-name"}
|
const QString nameOption = (filters & QDir::CaseSensitive) ? QString{"-name"}
|
||||||
: QString{"-iname"};
|
: QString{"-iname"};
|
||||||
QStringList criticalWildcards;
|
QStringList criticalWildcards;
|
||||||
if (!nameFilters.isEmpty()) {
|
if (!filter.nameFilters.isEmpty()) {
|
||||||
const QRegularExpression oneChar("\\[.*?\\]");
|
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)
|
if (i > 0)
|
||||||
filterOptions << "-o";
|
filterOptions << "-o";
|
||||||
QString current = nameFilters.at(i);
|
QString current = filter.nameFilters.at(i);
|
||||||
if (current.indexOf(oneChar) != -1)
|
if (current.indexOf(oneChar) != -1)
|
||||||
criticalWildcards.append(current);
|
criticalWildcards.append(current);
|
||||||
current.replace(oneChar, "?"); // BAD! but still better than nothing
|
current.replace(oneChar, "?"); // BAD! but still better than nothing
|
||||||
@@ -1519,7 +1522,8 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
|
|||||||
continue;
|
continue;
|
||||||
const FilePath fp = FilePath::fromString(entry);
|
const FilePath fp = FilePath::fromString(entry);
|
||||||
|
|
||||||
if (!Utils::anyOf(criticalWildcards,
|
if (!criticalWildcards.isEmpty() &&
|
||||||
|
!Utils::anyOf(criticalWildcards,
|
||||||
[name = fp.fileName()](const QString &pattern) {
|
[name = fp.fileName()](const QString &pattern) {
|
||||||
const QRegularExpression regex(QRegularExpression::wildcardToRegularExpression(pattern));
|
const QRegularExpression regex(QRegularExpression::wildcardToRegularExpression(pattern));
|
||||||
if (regex.match(name).hasMatch())
|
if (regex.match(name).hasMatch())
|
||||||
@@ -1537,15 +1541,17 @@ void DockerDevice::iterateWithFind(const FilePath &filePath,
|
|||||||
static void filterEntriesHelper(const FilePath &base,
|
static void filterEntriesHelper(const FilePath &base,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &entries,
|
const QStringList &entries,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter)
|
||||||
QDir::Filters filters)
|
|
||||||
{
|
{
|
||||||
const QList<QRegularExpression> nameRegexps = transform(nameFilters, [](const QString &filter) {
|
QTC_CHECK(filter.iteratorFlags != QDirIterator::NoIteratorFlags); // FIXME: Not supported yet below.
|
||||||
QRegularExpression re;
|
|
||||||
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
|
const QList<QRegularExpression> nameRegexps =
|
||||||
QTC_CHECK(re.isValid());
|
transform(filter.nameFilters, [](const QString &filter) {
|
||||||
return re;
|
QRegularExpression re;
|
||||||
});
|
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
|
||||||
|
QTC_CHECK(re.isValid());
|
||||||
|
return re;
|
||||||
|
});
|
||||||
|
|
||||||
const auto nameMatches = [&nameRegexps](const QString &fileName) {
|
const auto nameMatches = [&nameRegexps](const QString &fileName) {
|
||||||
for (const QRegularExpression &re : nameRegexps) {
|
for (const QRegularExpression &re : nameRegexps) {
|
||||||
@@ -1557,7 +1563,7 @@ static void filterEntriesHelper(const FilePath &base,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Handle filters. For now bark on unsupported options.
|
// 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) {
|
for (const QString &entry : entries) {
|
||||||
if (!nameMatches(entry))
|
if (!nameMatches(entry))
|
||||||
@@ -1569,12 +1575,8 @@ static void filterEntriesHelper(const FilePath &base,
|
|||||||
|
|
||||||
void DockerDevice::iterateDirectory(const FilePath &filePath,
|
void DockerDevice::iterateDirectory(const FilePath &filePath,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(flags) // FIXME: Use it.
|
|
||||||
|
|
||||||
QTC_ASSERT(handlesFile(filePath), return);
|
QTC_ASSERT(handlesFile(filePath), return);
|
||||||
updateContainerAccess();
|
updateContainerAccess();
|
||||||
if (hasLocalFileAccess()) {
|
if (hasLocalFileAccess()) {
|
||||||
@@ -1582,12 +1584,12 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
|
|||||||
local.iterateDirectory([&callBack, this](const FilePath &entry) {
|
local.iterateDirectory([&callBack, this](const FilePath &entry) {
|
||||||
return callBack(mapFromLocalAccess(entry));
|
return callBack(mapFromLocalAccess(entry));
|
||||||
},
|
},
|
||||||
nameFilters, filters);
|
filter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_useFind) {
|
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
|
// d->m_useFind will be set to false if 'find' is not found. In this
|
||||||
// case fall back to 'ls' below.
|
// case fall back to 'ls' below.
|
||||||
if (d->m_useFind)
|
if (d->m_useFind)
|
||||||
@@ -1597,7 +1599,7 @@ void DockerDevice::iterateDirectory(const FilePath &filePath,
|
|||||||
// if we do not have find - use ls as fallback
|
// if we do not have find - use ls as fallback
|
||||||
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
|
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
|
||||||
const QStringList entries = output.split('\n', Qt::SkipEmptyParts);
|
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
|
QByteArray DockerDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const
|
||||||
@@ -1802,15 +1804,6 @@ QString DockerDevicePrivate::outputForRunInShell(const CommandLine &cmd) const
|
|||||||
|
|
||||||
// Factory
|
// 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
|
class DockerImageItem final : public TreeItem, public DockerDeviceData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1914,7 +1907,7 @@ public:
|
|||||||
m_process->start();
|
m_process->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
DockerDevice::Ptr device() const
|
IDevice::Ptr device() const
|
||||||
{
|
{
|
||||||
const QModelIndexList selectedRows = m_view->selectionModel()->selectedRows();
|
const QModelIndexList selectedRows = m_view->selectionModel()->selectedRows();
|
||||||
QTC_ASSERT(selectedRows.size() == 1, return {});
|
QTC_ASSERT(selectedRows.size() == 1, return {});
|
||||||
@@ -1939,14 +1932,6 @@ public:
|
|||||||
QString m_selectedId;
|
QString m_selectedId;
|
||||||
};
|
};
|
||||||
|
|
||||||
IDevice::Ptr DockerDeviceFactory::create() const
|
|
||||||
{
|
|
||||||
DockerDeviceSetupWizard wizard;
|
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
|
||||||
return IDevice::Ptr();
|
|
||||||
return wizard.device();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockerDeviceWidget::updateDaemonStateTexts()
|
void DockerDeviceWidget::updateDaemonStateTexts()
|
||||||
{
|
{
|
||||||
Utils::optional<bool> daemonState = DockerPlugin::isDaemonRunning();
|
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
|
} // Internal
|
||||||
} // Docker
|
} // Docker
|
||||||
|
@@ -62,7 +62,7 @@ public:
|
|||||||
static Ptr create(const DockerDeviceData &data) { return Ptr(new DockerDevice(data)); }
|
static Ptr create(const DockerDeviceData &data) { return Ptr(new DockerDevice(data)); }
|
||||||
|
|
||||||
ProjectExplorer::IDeviceWidget *createWidget() override;
|
ProjectExplorer::IDeviceWidget *createWidget() override;
|
||||||
QVector<ProjectExplorer::Task> validate() const override;
|
QList<ProjectExplorer::Task> validate() const override;
|
||||||
|
|
||||||
bool canCreateProcess() const override { return true; }
|
bool canCreateProcess() const override { return true; }
|
||||||
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
|
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
|
||||||
@@ -96,9 +96,7 @@ public:
|
|||||||
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
||||||
void iterateDirectory(const Utils::FilePath &filePath,
|
void iterateDirectory(const Utils::FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const Utils::FileFilter &filter) const override;
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const override;
|
|
||||||
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) 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;
|
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
||||||
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
||||||
@@ -127,8 +125,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void iterateWithFind(const Utils::FilePath &filePath,
|
void iterateWithFind(const Utils::FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const Utils::FileFilter &filter) const;
|
||||||
QDir::Filters filters) const;
|
|
||||||
|
|
||||||
void aboutToBeRemoved() const final;
|
void aboutToBeRemoved() const final;
|
||||||
|
|
||||||
@@ -160,8 +157,6 @@ class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DockerDeviceFactory();
|
DockerDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
@@ -70,7 +70,7 @@ static FilePath detectApp(const QString &defaultExe)
|
|||||||
if (!gitBinDir.endsWith("/usr/bin"))
|
if (!gitBinDir.endsWith("/usr/bin"))
|
||||||
return {};
|
return {};
|
||||||
path = gitBinDir.parentDir().parentDir();
|
path = gitBinDir.parentDir().parentDir();
|
||||||
const FilePaths entries = path.dirEntries({"mingw*"}, {});
|
const FilePaths entries = path.dirEntries({{"mingw*"}});
|
||||||
if (entries.isEmpty())
|
if (entries.isEmpty())
|
||||||
return {};
|
return {};
|
||||||
path = entries.first() / "bin" / defaultApp;
|
path = entries.first() / "bin" / defaultApp;
|
||||||
|
@@ -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_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_ID[] = "Workspace Functions and Methods";
|
||||||
const char LANGUAGECLIENT_WORKSPACE_METHOD_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("LanguageClient", "Functions and Methods in Workspace");
|
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 Constants
|
||||||
} // namespace LanguageClient
|
} // namespace LanguageClient
|
||||||
|
@@ -63,16 +63,12 @@ bool LanguageClientPlugin::initialize(const QStringList & /*arguments*/, QString
|
|||||||
[]() { return new StdIOSettings; }});
|
[]() { return new StdIOSettings; }});
|
||||||
|
|
||||||
//register actions
|
//register actions
|
||||||
ActionContainer *toolsContainer
|
ActionContainer *toolsDebugContainer = ActionManager::actionContainer(
|
||||||
= ActionManager::actionContainer(Core::Constants::M_TOOLS);
|
Core::Constants::M_TOOLS_DEBUG);
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
connect(inspectAction, &QAction::triggered, this, &LanguageClientManager::showInspector);
|
||||||
container->addAction(
|
toolsDebugContainer->addAction(
|
||||||
ActionManager::registerAction(inspectAction, "LanguageClient.InspectLanguageClients"));
|
ActionManager::registerAction(inspectAction, "LanguageClient.InspectLanguageClients"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -59,13 +59,9 @@ McuSupportDeviceFactory::McuSupportDeviceFactory()
|
|||||||
setDisplayName(McuSupportDevice::tr("MCU Device"));
|
setDisplayName(McuSupportDevice::tr("MCU Device"));
|
||||||
setCombinedIcon(":/mcusupport/images/mcusupportdevicesmall.png",
|
setCombinedIcon(":/mcusupport/images/mcusupportdevicesmall.png",
|
||||||
":/mcusupport/images/mcusupportdevice.png");
|
":/mcusupport/images/mcusupportdevice.png");
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&McuSupportDevice::create);
|
setConstructionFunction(&McuSupportDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator(&McuSupportDevice::create);
|
||||||
ProjectExplorer::IDevice::Ptr McuSupportDeviceFactory::create() const
|
|
||||||
{
|
|
||||||
return McuSupportDevice::create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -45,8 +45,6 @@ class McuSupportDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
McuSupportDeviceFactory();
|
McuSupportDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -217,8 +217,7 @@ static McuPackage *createRGLPackage()
|
|||||||
if (rglPath.exists()) {
|
if (rglPath.exists()) {
|
||||||
defaultPath = rglPath;
|
defaultPath = rglPath;
|
||||||
const FilePaths subDirs =
|
const FilePaths subDirs =
|
||||||
defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")},
|
defaultPath.dirEntries({{"rgl_ghs_D1Mx_*"}, QDir::Dirs | QDir::NoDotAndDotDot});
|
||||||
QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
if (subDirs.count() == 1)
|
if (subDirs.count() == 1)
|
||||||
defaultPath = subDirs.first();
|
defaultPath = subDirs.first();
|
||||||
}
|
}
|
||||||
@@ -272,8 +271,7 @@ static McuPackage *createMcuXpressoIdePackage()
|
|||||||
defaultPath = programPath;
|
defaultPath = programPath;
|
||||||
// If default dir has exactly one sub dir that could be the IDE path, pre-select that.
|
// If default dir has exactly one sub dir that could be the IDE path, pre-select that.
|
||||||
const FilePaths subDirs =
|
const FilePaths subDirs =
|
||||||
defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")},
|
defaultPath.dirEntries({{"MCUXpressoIDE*"}, QDir::Dirs | QDir::NoDotAndDotDot});
|
||||||
QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
if (subDirs.count() == 1)
|
if (subDirs.count() == 1)
|
||||||
defaultPath = subDirs.first();
|
defaultPath = subDirs.first();
|
||||||
}
|
}
|
||||||
@@ -304,8 +302,8 @@ static McuPackage *createCypressProgrammerPackage()
|
|||||||
const FilePath candidate = findInProgramFiles("Cypress");
|
const FilePath candidate = findInProgramFiles("Cypress");
|
||||||
if (candidate.exists()) {
|
if (candidate.exists()) {
|
||||||
// "Cypress Auto Flash Utility 1.0"
|
// "Cypress Auto Flash Utility 1.0"
|
||||||
const auto subDirs = candidate.dirEntries({"Cypress Auto Flash Utility*"},
|
const auto subDirs = candidate.dirEntries({{"Cypress Auto Flash Utility*"}, QDir::Dirs},
|
||||||
QDir::Dirs, QDirIterator::NoIteratorFlags, QDir::Unsorted);
|
QDir::Unsorted);
|
||||||
if (!subDirs.empty())
|
if (!subDirs.empty())
|
||||||
defaultPath = subDirs.first();
|
defaultPath = subDirs.first();
|
||||||
}
|
}
|
||||||
@@ -331,8 +329,8 @@ static McuPackage *createRenesasProgrammerPackage()
|
|||||||
const FilePath candidate = findInProgramFiles("Renesas Electronics/Programming Tools");
|
const FilePath candidate = findInProgramFiles("Renesas Electronics/Programming Tools");
|
||||||
if (candidate.exists()) {
|
if (candidate.exists()) {
|
||||||
// "Renesas Flash Programmer V3.09"
|
// "Renesas Flash Programmer V3.09"
|
||||||
const auto subDirs = candidate.dirEntries({"Renesas Flash Programmer*"},
|
const auto subDirs = candidate.dirEntries({{"Renesas Flash Programmer*"}, QDir::Dirs},
|
||||||
QDir::Dirs, QDirIterator::NoIteratorFlags, QDir::Unsorted);
|
QDir::Unsorted);
|
||||||
if (!subDirs.empty())
|
if (!subDirs.empty())
|
||||||
defaultPath = subDirs.first();
|
defaultPath = subDirs.first();
|
||||||
}
|
}
|
||||||
|
@@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
#include "copytaskhandler.h"
|
#include "copytaskhandler.h"
|
||||||
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
@@ -36,25 +34,27 @@
|
|||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace ProjectExplorer::Internal;
|
using namespace ProjectExplorer::Internal;
|
||||||
|
|
||||||
void CopyTaskHandler::handle(const Task &task)
|
void CopyTaskHandler::handle(const Tasks &tasks)
|
||||||
{
|
{
|
||||||
QString type;
|
QStringList lines;
|
||||||
switch (task.type) {
|
for (const Task &task : tasks) {
|
||||||
case Task::Error:
|
QString type;
|
||||||
//: Task is of type: error
|
switch (task.type) {
|
||||||
type = tr("error:") + QLatin1Char(' ');
|
case Task::Error:
|
||||||
break;
|
//: Task is of type: error
|
||||||
case Task::Warning:
|
type = tr("error:") + QLatin1Char(' ');
|
||||||
//: Task is of type: warning
|
break;
|
||||||
type = tr("warning:") + QLatin1Char(' ');
|
case Task::Warning:
|
||||||
break;
|
//: Task is of type: warning
|
||||||
default:
|
type = tr("warning:") + QLatin1Char(' ');
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lines << task.file.toUserOutput() + ':' + QString::number(task.line)
|
||||||
|
+ ": " + type + task.description();
|
||||||
}
|
}
|
||||||
|
QApplication::clipboard()->setText(lines.join('\n'));
|
||||||
QApplication::clipboard()->setText(task.file.toUserOutput() + QLatin1Char(':') +
|
|
||||||
QString::number(task.line) + QLatin1String(": ")
|
|
||||||
+ type + task.description());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Id CopyTaskHandler::actionManagerId() const
|
Utils::Id CopyTaskHandler::actionManagerId() const
|
||||||
|
@@ -35,8 +35,9 @@ class CopyTaskHandler : public ITaskHandler
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool canHandle(const Task &) const override { return true; }
|
CopyTaskHandler() : ITaskHandler(true) {}
|
||||||
void handle(const Task &task) override;
|
|
||||||
|
void handle(const Tasks &tasks) override;
|
||||||
Utils::Id actionManagerId() const override;
|
Utils::Id actionManagerId() const override;
|
||||||
QAction *createAction(QObject *parent) const override;
|
QAction *createAction(QObject *parent) const override;
|
||||||
};
|
};
|
||||||
|
@@ -177,13 +177,11 @@ bool DesktopDevice::handlesFile(const FilePath &filePath) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DesktopDevice::iterateDirectory(const FilePath &filePath,
|
void DesktopDevice::iterateDirectory(const FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const
|
|
||||||
{
|
{
|
||||||
QTC_CHECK(!filePath.needsDevice());
|
QTC_CHECK(!filePath.needsDevice());
|
||||||
filePath.iterateDirectory(callBack, nameFilters, filters, flags);
|
filePath.iterateDirectory(callBack, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 DesktopDevice::fileSize(const FilePath &filePath) const
|
qint64 DesktopDevice::fileSize(const FilePath &filePath) const
|
||||||
|
@@ -75,9 +75,7 @@ public:
|
|||||||
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
||||||
void iterateDirectory(const Utils::FilePath &filePath,
|
void iterateDirectory(const Utils::FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const Utils::FileFilter &filter) const override;
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const override;
|
|
||||||
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) 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;
|
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
||||||
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
qint64 fileSize(const Utils::FilePath &filePath) const override;
|
||||||
|
@@ -524,12 +524,10 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
|
|||||||
|
|
||||||
deviceHooks.iterateDirectory = [](const FilePath &filePath,
|
deviceHooks.iterateDirectory = [](const FilePath &filePath,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) {
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) {
|
|
||||||
auto device = DeviceManager::deviceForPath(filePath);
|
auto device = DeviceManager::deviceForPath(filePath);
|
||||||
QTC_ASSERT(device, return);
|
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) {
|
deviceHooks.fileContents = [](const FilePath &filePath, qint64 maxSize, qint64 offset) {
|
||||||
|
@@ -363,15 +363,11 @@ FilePath IDevice::symLinkTarget(const FilePath &filePath) const
|
|||||||
|
|
||||||
void IDevice::iterateDirectory(const FilePath &filePath,
|
void IDevice::iterateDirectory(const FilePath &filePath,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(filePath);
|
Q_UNUSED(filePath);
|
||||||
Q_UNUSED(callBack);
|
Q_UNUSED(callBack);
|
||||||
Q_UNUSED(nameFilters);
|
Q_UNUSED(filter);
|
||||||
Q_UNUSED(filters);
|
|
||||||
Q_UNUSED(flags);
|
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +543,7 @@ bool IDevice::isCompatibleWith(const Kit *k) const
|
|||||||
return DeviceTypeKitAspect::deviceTypeId(k) == type();
|
return DeviceTypeKitAspect::deviceTypeId(k) == type();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Task> IDevice::validate() const
|
QList<Task> IDevice::validate() const
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include <QAbstractSocket>
|
#include <QAbstractSocket>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
@@ -160,7 +159,7 @@ public:
|
|||||||
Utils::Id id() const;
|
Utils::Id id() const;
|
||||||
|
|
||||||
virtual bool isCompatibleWith(const Kit *k) const;
|
virtual bool isCompatibleWith(const Kit *k) const;
|
||||||
virtual QVector<Task> validate() const;
|
virtual QList<Task> validate() const;
|
||||||
|
|
||||||
QString displayType() const;
|
QString displayType() const;
|
||||||
Utils::OsType osType() const;
|
Utils::OsType osType() const;
|
||||||
@@ -257,13 +256,11 @@ public:
|
|||||||
virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
||||||
virtual Utils::FilePath searchExecutableInPath(const QString &fileName) const;
|
virtual Utils::FilePath searchExecutableInPath(const QString &fileName) const;
|
||||||
virtual Utils::FilePath searchExecutable(const QString &fileName,
|
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 Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const;
|
||||||
virtual void iterateDirectory(const Utils::FilePath &filePath,
|
virtual void iterateDirectory(const Utils::FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const Utils::FileFilter &filter) const;
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags) const;
|
|
||||||
virtual QByteArray fileContents(const Utils::FilePath &filePath,
|
virtual QByteArray fileContents(const Utils::FilePath &filePath,
|
||||||
qint64 limit,
|
qint64 limit,
|
||||||
qint64 offset) const;
|
qint64 offset) const;
|
||||||
|
@@ -81,6 +81,11 @@ bool IDeviceFactory::canCreate() const
|
|||||||
return m_canCreate;
|
return m_canCreate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDevice::Ptr IDeviceFactory::create() const
|
||||||
|
{
|
||||||
|
return m_creator ? m_creator() : IDevice::Ptr();
|
||||||
|
}
|
||||||
|
|
||||||
IDevice::Ptr IDeviceFactory::construct() const
|
IDevice::Ptr IDeviceFactory::construct() const
|
||||||
{
|
{
|
||||||
return m_constructor ? m_constructor() : IDevice::Ptr();
|
return m_constructor ? m_constructor() : IDevice::Ptr();
|
||||||
@@ -119,6 +124,11 @@ void IDeviceFactory::setCanCreate(bool canCreate)
|
|||||||
m_canCreate = 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)
|
void IDeviceFactory::setConstructionFunction(const std::function<IDevice::Ptr ()> &constructor)
|
||||||
{
|
{
|
||||||
m_constructor = constructor;
|
m_constructor = constructor;
|
||||||
|
@@ -44,8 +44,7 @@ public:
|
|||||||
QIcon icon() const { return m_icon; }
|
QIcon icon() const { return m_icon; }
|
||||||
bool canCreate() const;
|
bool canCreate() const;
|
||||||
IDevice::Ptr construct() const;
|
IDevice::Ptr construct() const;
|
||||||
|
IDevice::Ptr create() const;
|
||||||
virtual IDevice::Ptr create() const { return IDevice::Ptr(); }
|
|
||||||
|
|
||||||
virtual bool canRestore(const QVariantMap &) const { return true; }
|
virtual bool canRestore(const QVariantMap &) const { return true; }
|
||||||
|
|
||||||
@@ -61,8 +60,10 @@ protected:
|
|||||||
void setCombinedIcon(const Utils::FilePath &small, const Utils::FilePath &large);
|
void setCombinedIcon(const Utils::FilePath &small, const Utils::FilePath &large);
|
||||||
void setCanCreate(bool canCreate);
|
void setCanCreate(bool canCreate);
|
||||||
void setConstructionFunction(const std::function<IDevice::Ptr ()> &constructor);
|
void setConstructionFunction(const std::function<IDevice::Ptr ()> &constructor);
|
||||||
|
void setCreator(const std::function<IDevice::Ptr()> &creator);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::function<IDevice::Ptr()> m_creator;
|
||||||
const Utils::Id m_deviceType;
|
const Utils::Id m_deviceType;
|
||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
QIcon m_icon;
|
QIcon m_icon;
|
||||||
|
@@ -1126,7 +1126,8 @@ static FilePaths findCompilerCandidates(const IDevice::ConstPtr &device,
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
const FilePath globalDir = device->mapToGlobalPath(deviceDir);
|
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 {
|
} else {
|
||||||
// The normal, local host case.
|
// The normal, local host case.
|
||||||
@@ -1763,7 +1764,7 @@ ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) :
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove m_abiWidget row because the parent toolchain abi is going to be used.
|
// 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_abiWidget = nullptr;
|
||||||
|
|
||||||
m_parentToolchainCombo = new QComboBox(this);
|
m_parentToolchainCombo = new QComboBox(this);
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "projectexplorer_export.h"
|
#include "projectexplorer_export.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
#include <utils/id.h>
|
#include <utils/id.h>
|
||||||
|
|
||||||
@@ -37,21 +38,26 @@ class QAction;
|
|||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class Task;
|
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT ITaskHandler : public QObject
|
class PROJECTEXPLORER_EXPORT ITaskHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ITaskHandler();
|
explicit ITaskHandler(bool isMultiHandler = false);
|
||||||
~ITaskHandler() override;
|
~ITaskHandler() override;
|
||||||
|
|
||||||
virtual bool isDefaultHandler() const { return false; }
|
virtual bool isDefaultHandler() const { return false; }
|
||||||
virtual bool canHandle(const Task &) const = 0;
|
virtual bool canHandle(const Task &) const { return m_isMultiHandler; }
|
||||||
virtual void handle(const Task &) = 0;
|
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 Utils::Id actionManagerId() const { return Utils::Id(); }
|
||||||
virtual QAction *createAction(QObject *parent) const = 0;
|
virtual QAction *createAction(QObject *parent) const = 0;
|
||||||
|
|
||||||
|
bool canHandle(const Tasks &tasks) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_isMultiHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -423,10 +423,11 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
|
|||||||
continue;
|
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 QDir::SortFlags sortflags = QDir::Name|QDir::IgnoreCase;
|
||||||
const QDirIterator::IteratorFlag iteratorFlags = QDirIterator::NoIteratorFlags;
|
FilePaths dirs = path.dirEntries(filter, sortflags);
|
||||||
FilePaths dirs = path.dirEntries({}, filters, iteratorFlags, sortflags);
|
|
||||||
|
|
||||||
while (!dirs.isEmpty()) {
|
while (!dirs.isEmpty()) {
|
||||||
const FilePath currentDir = dirs.takeFirst();
|
const FilePath currentDir = dirs.takeFirst();
|
||||||
@@ -483,7 +484,7 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
|
|||||||
|
|
||||||
result << factory;
|
result << factory;
|
||||||
} else {
|
} else {
|
||||||
FilePaths subDirs = currentDir.dirEntries({}, filters, iteratorFlags, sortflags);
|
FilePaths subDirs = currentDir.dirEntries(filter, sortflags);
|
||||||
if (!subDirs.isEmpty()) {
|
if (!subDirs.isEmpty()) {
|
||||||
// There is no QList::prepend(QList)...
|
// There is no QList::prepend(QList)...
|
||||||
dirs.swap(subDirs);
|
dirs.swap(subDirs);
|
||||||
@@ -579,7 +580,7 @@ static QString qmlProjectName(const FilePath &folder)
|
|||||||
{
|
{
|
||||||
FilePath currentFolder = folder;
|
FilePath currentFolder = folder;
|
||||||
while (!currentFolder.isEmpty()) {
|
while (!currentFolder.isEmpty()) {
|
||||||
const QList<FilePath> fileList = currentFolder.dirEntries({"*.qmlproject"});
|
const FilePaths fileList = currentFolder.dirEntries({{"*.qmlproject"}});
|
||||||
if (!fileList.isEmpty())
|
if (!fileList.isEmpty())
|
||||||
return fileList.first().baseName();
|
return fileList.first().baseName();
|
||||||
currentFolder = currentFolder.parentDir();
|
currentFolder = currentFolder.parentDir();
|
||||||
|
@@ -694,7 +694,7 @@ static ProjectExplorerPluginPrivate *dd = nullptr;
|
|||||||
|
|
||||||
static FilePaths projectFilesInDirectory(const FilePath &path)
|
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)
|
static FilePaths projectsInDirectory(const FilePath &filePath)
|
||||||
|
@@ -33,9 +33,10 @@
|
|||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
void RemoveTaskHandler::handle(const Task &task)
|
void RemoveTaskHandler::handle(const Tasks &tasks)
|
||||||
{
|
{
|
||||||
TaskHub::removeTask(task);
|
for (const Task &task : tasks)
|
||||||
|
TaskHub::removeTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *RemoveTaskHandler::createAction(QObject *parent) const
|
QAction *RemoveTaskHandler::createAction(QObject *parent) const
|
||||||
|
@@ -35,8 +35,9 @@ class RemoveTaskHandler : public ITaskHandler
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool canHandle(const Task &) const override { return true; }
|
RemoveTaskHandler() : ITaskHandler(true) {}
|
||||||
void handle(const Task &task) override;
|
|
||||||
|
void handle(const Tasks &tasks) override;
|
||||||
QAction *createAction(QObject *parent) const override;
|
QAction *createAction(QObject *parent) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -791,8 +791,7 @@ QStringList SessionManager::sessions()
|
|||||||
{
|
{
|
||||||
if (d->m_sessions.isEmpty()) {
|
if (d->m_sessions.isEmpty()) {
|
||||||
// We are not initialized yet, so do that now
|
// We are not initialized yet, so do that now
|
||||||
const FilePaths sessionFiles = ICore::userResourcePath().dirEntries({"*.qws"},
|
const FilePaths sessionFiles = ICore::userResourcePath().dirEntries({{"*qws"}}, QDir::Time);
|
||||||
QDir::NoFilter, QDirIterator::NoIteratorFlags, QDir::Time);
|
|
||||||
for (const FilePath &file : sessionFiles) {
|
for (const FilePath &file : sessionFiles) {
|
||||||
const QString &name = file.completeBaseName();
|
const QString &name = file.completeBaseName();
|
||||||
d->m_sessionDateTimes.insert(name, file.lastModified());
|
d->m_sessionDateTimes.insert(name, file.lastModified());
|
||||||
|
@@ -138,7 +138,7 @@ public:
|
|||||||
DeploymentTask(TaskType type, const QString &description);
|
DeploymentTask(TaskType type, const QString &description);
|
||||||
};
|
};
|
||||||
|
|
||||||
using Tasks = QVector<Task>;
|
using Tasks = QList<Task>;
|
||||||
|
|
||||||
PROJECTEXPLORER_EXPORT QString toHtml(const Tasks &issues);
|
PROJECTEXPLORER_EXPORT QString toHtml(const Tasks &issues);
|
||||||
PROJECTEXPLORER_EXPORT bool containsType(const Tasks &issues, Task::TaskType);
|
PROJECTEXPLORER_EXPORT bool containsType(const Tasks &issues, Task::TaskType);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "taskhub.h"
|
#include "taskhub.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -286,6 +287,13 @@ Task TaskModel::task(const QModelIndex &index) const
|
|||||||
return m_tasks.at(row);
|
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> TaskModel::categoryIds() const
|
||||||
{
|
{
|
||||||
QList<Utils::Id> categories = m_categories.keys();
|
QList<Utils::Id> categories = m_categories.keys();
|
||||||
@@ -360,6 +368,12 @@ void TaskFilterModel::setFilterIncludesWarnings(bool b)
|
|||||||
invalidateFilter();
|
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 TaskFilterModel::issuesCount(int startRow, int endRow) const
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
Task task(const QModelIndex &index) const;
|
Task task(const QModelIndex &index) const;
|
||||||
|
Tasks tasks(const QModelIndexList &indexes) const;
|
||||||
|
|
||||||
QList<Utils::Id> categoryIds() const;
|
QList<Utils::Id> categoryIds() const;
|
||||||
QString categoryDisplayName(Utils::Id categoryId) const;
|
QString categoryDisplayName(Utils::Id categoryId) const;
|
||||||
@@ -142,6 +143,7 @@ public:
|
|||||||
void setFilteredCategories(const QList<Utils::Id> &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); }
|
void setFilteredCategories(const QList<Utils::Id> &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); }
|
||||||
|
|
||||||
Task task(const QModelIndex &index) const { return taskModel()->task(mapToSource(index)); }
|
Task task(const QModelIndex &index) const { return taskModel()->task(mapToSource(index)); }
|
||||||
|
Tasks tasks(const QModelIndexList &indexes) const;
|
||||||
int issuesCount(int startRow, int endRow) const;
|
int issuesCount(int startRow, int endRow) const;
|
||||||
|
|
||||||
bool hasFile(const QModelIndex &index) const
|
bool hasFile(const QModelIndex &index) const
|
||||||
|
@@ -67,7 +67,7 @@ namespace ProjectExplorer {
|
|||||||
|
|
||||||
static QList<ITaskHandler *> g_taskHandlers;
|
static QList<ITaskHandler *> g_taskHandlers;
|
||||||
|
|
||||||
ITaskHandler::ITaskHandler()
|
ITaskHandler::ITaskHandler(bool isMultiHandler) : m_isMultiHandler(isMultiHandler)
|
||||||
{
|
{
|
||||||
g_taskHandlers.append(this);
|
g_taskHandlers.append(this);
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,30 @@ ITaskHandler::~ITaskHandler()
|
|||||||
g_taskHandlers.removeOne(this);
|
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 {
|
namespace Internal {
|
||||||
|
|
||||||
class TaskView : public Utils::ListView
|
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->setModel(d->m_filter);
|
||||||
d->m_listview->setFrameStyle(QFrame::NoFrame);
|
d->m_listview->setFrameStyle(QFrame::NoFrame);
|
||||||
d->m_listview->setWindowTitle(displayName());
|
d->m_listview->setWindowTitle(displayName());
|
||||||
d->m_listview->setSelectionMode(QAbstractItemView::SingleSelection);
|
d->m_listview->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
auto *tld = new Internal::TaskDelegate(this);
|
auto *tld = new Internal::TaskDelegate(this);
|
||||||
d->m_listview->setItemDelegate(tld);
|
d->m_listview->setItemDelegate(tld);
|
||||||
d->m_listview->setWindowIcon(Icons::WINDOW.icon());
|
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,
|
connect(d->m_listview->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||||
tld, &TaskDelegate::currentChanged);
|
tld, &TaskDelegate::currentChanged);
|
||||||
|
|
||||||
connect(d->m_listview->selectionModel(), &QItemSelectionModel::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,
|
connect(d->m_listview, &QAbstractItemView::activated,
|
||||||
this, &TaskWindow::triggerDefaultHandler);
|
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);
|
d->m_contextMenu = new QMenu(d->m_listview);
|
||||||
|
|
||||||
@@ -417,6 +448,7 @@ void TaskWindow::delayedInitialization()
|
|||||||
d->m_defaultHandler = h;
|
d->m_defaultHandler = h;
|
||||||
|
|
||||||
QAction *action = h->createAction(this);
|
QAction *action = h->createAction(this);
|
||||||
|
action->setEnabled(false);
|
||||||
QTC_ASSERT(action, continue);
|
QTC_ASSERT(action, continue);
|
||||||
d->m_actionToHandlerMap.insert(action, h);
|
d->m_actionToHandlerMap.insert(action, h);
|
||||||
connect(action, &QAction::triggered, this, &TaskWindow::actionTriggered);
|
connect(action, &QAction::triggered, this, &TaskWindow::actionTriggered);
|
||||||
@@ -430,9 +462,6 @@ void TaskWindow::delayedInitialization()
|
|||||||
}
|
}
|
||||||
d->m_listview->addAction(action);
|
d->m_listview->addAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable everything for now:
|
|
||||||
currentChanged(QModelIndex());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
QList<QWidget*> TaskWindow::toolBarWidgets() const
|
||||||
@@ -468,16 +497,6 @@ void TaskWindow::setCategoryVisibility(Utils::Id categoryId, bool visible)
|
|||||||
d->m_filter->setFilteredCategories(categories);
|
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()
|
void TaskWindow::saveSettings()
|
||||||
{
|
{
|
||||||
QStringList categories = Utils::transform(d->m_filter->filteredCategories(), &Utils::Id::toString);
|
QStringList categories = Utils::transform(d->m_filter->filteredCategories(), &Utils::Id::toString);
|
||||||
@@ -605,12 +624,7 @@ void TaskWindow::actionTriggered()
|
|||||||
if (!h)
|
if (!h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QModelIndex index = d->m_listview->selectionModel()->currentIndex();
|
h->handle(d->m_filter->tasks(d->m_listview->selectionModel()->selectedIndexes()));
|
||||||
Task task = d->m_filter->task(index);
|
|
||||||
if (task.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
h->handle(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::setShowWarnings(bool show)
|
void TaskWindow::setShowWarnings(bool show)
|
||||||
@@ -774,11 +788,11 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
|
|||||||
initStyleOption(&opt, index);
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
auto view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
auto view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
||||||
const bool selected = (view->selectionModel()->currentIndex() == index);
|
const bool current = view->selectionModel()->currentIndex() == index;
|
||||||
QSize s;
|
QSize s;
|
||||||
s.setWidth(option.rect.width());
|
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);
|
s.setHeight(m_cachedHeight);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -790,7 +804,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
|
|||||||
auto model = static_cast<TaskFilterModel *>(view->model())->taskModel();
|
auto model = static_cast<TaskFilterModel *>(view->model())->taskModel();
|
||||||
Positions positions(option, model);
|
Positions positions(option, model);
|
||||||
|
|
||||||
if (selected) {
|
if (current) {
|
||||||
QString description = index.data(TaskModel::Description).toString();
|
QString description = index.data(TaskModel::Description).toString();
|
||||||
// Layout the description
|
// Layout the description
|
||||||
int leading = fontLeading;
|
int leading = fontLeading;
|
||||||
@@ -817,7 +831,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
|
|||||||
if (s.height() < Positions::minimumHeight())
|
if (s.height() < Positions::minimumHeight())
|
||||||
s.setHeight(Positions::minimumHeight());
|
s.setHeight(Positions::minimumHeight());
|
||||||
|
|
||||||
if (!selected) {
|
if (!current) {
|
||||||
m_cachedHeight = s.height();
|
m_cachedHeight = s.height();
|
||||||
m_cachedFont = option.font;
|
m_cachedFont = option.font;
|
||||||
}
|
}
|
||||||
@@ -856,7 +870,8 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|||||||
QColor textColor;
|
QColor textColor;
|
||||||
|
|
||||||
auto view = qobject_cast<const QAbstractItemView *>(opt.widget);
|
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) {
|
if (selected) {
|
||||||
painter->setBrush(opt.palette.highlight().color());
|
painter->setBrush(opt.palette.highlight().color());
|
||||||
@@ -885,7 +900,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|||||||
icon.pixmap(Positions::taskIconWidth(), Positions::taskIconHeight()));
|
icon.pixmap(Positions::taskIconWidth(), Positions::taskIconHeight()));
|
||||||
|
|
||||||
// Paint TextArea:
|
// Paint TextArea:
|
||||||
if (!selected) {
|
if (!current) {
|
||||||
// in small mode we lay out differently
|
// in small mode we lay out differently
|
||||||
QString bottom = index.data(TaskModel::Description).toString().split(QLatin1Char('\n')).first();
|
QString bottom = index.data(TaskModel::Description).toString().split(QLatin1Char('\n')).first();
|
||||||
painter->setClipRect(positions.textArea());
|
painter->setClipRect(positions.textArea());
|
||||||
@@ -908,7 +923,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|||||||
QTextLayout tl(description);
|
QTextLayout tl(description);
|
||||||
QVector<QTextLayout::FormatRange> formats = index.data(TaskModel::Task_t).value<Task>().formats;
|
QVector<QTextLayout::FormatRange> formats = index.data(TaskModel::Task_t).value<Task>().formats;
|
||||||
for (QTextLayout::FormatRange &format : formats)
|
for (QTextLayout::FormatRange &format : formats)
|
||||||
format.format.setForeground(opt.palette.highlightedText());
|
format.format.setForeground(textColor);
|
||||||
tl.setFormats(formats);
|
tl.setFormats(formats);
|
||||||
tl.beginLayout();
|
tl.beginLayout();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@@ -91,7 +91,6 @@ private:
|
|||||||
void openTask(const Task &task);
|
void openTask(const Task &task);
|
||||||
void clearTasks(Utils::Id categoryId);
|
void clearTasks(Utils::Id categoryId);
|
||||||
void setCategoryVisibility(Utils::Id categoryId, bool visible);
|
void setCategoryVisibility(Utils::Id categoryId, bool visible);
|
||||||
void currentChanged(const QModelIndex &index);
|
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
|
|
||||||
|
@@ -1556,25 +1556,16 @@ void DesignerActionManager::createDefaultAddResourceHandler()
|
|||||||
|
|
||||||
// Having a single image type category creates too large of a filter, so we split images into
|
// Having a single image type category creates too large of a filter, so we split images into
|
||||||
// categories according to their mime types
|
// categories according to their mime types
|
||||||
const QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
|
|
||||||
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
|
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
|
||||||
QHash<QByteArray, QStringList> imageFormats;
|
auto imageFormats = Utils::transform(QImageReader::supportedImageFormats(), transformer);
|
||||||
for (const auto &mimeType : mimeTypes)
|
imageFormats.push_back("*.hdr");
|
||||||
imageFormats.insert(mimeType, Utils::transform(QImageReader::imageFormatsForMimeType(mimeType), transformer));
|
imageFormats.push_back("*.ktx");
|
||||||
imageFormats.insert("image/vnd.radiance", {"*.hdr"});
|
|
||||||
imageFormats.insert("image/ktx", {"*.ktx"});
|
|
||||||
|
|
||||||
// The filters will be displayed in reverse order to these lists in file dialog,
|
// The filters will be displayed in reverse order to these lists in file dialog,
|
||||||
// so declare most common types last
|
// so declare most common types last
|
||||||
QHash<QByteArray, QStringList>::const_iterator i = imageFormats.constBegin();
|
registerHandlers(imageFormats,
|
||||||
while (i != imageFormats.constEnd()) {
|
ModelNodeOperations::addImageToProject,
|
||||||
registerHandlers(i.value(),
|
ComponentCoreConstants::addImagesDisplayString);
|
||||||
ModelNodeOperations::addImageToProject,
|
|
||||||
QObject::tr("%1: %2")
|
|
||||||
.arg(ComponentCoreConstants::addImagesDisplayString)
|
|
||||||
.arg(QString::fromLatin1(i.key())));
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
registerHandlers({"*.otf", "*.ttf"},
|
registerHandlers({"*.otf", "*.ttf"},
|
||||||
ModelNodeOperations::addFontToProject,
|
ModelNodeOperations::addFontToProject,
|
||||||
ComponentCoreConstants::addFontsDisplayString);
|
ComponentCoreConstants::addFontsDisplayString);
|
||||||
|
@@ -612,6 +612,19 @@ void ItemLibraryWidget::addImportForItem(const QString &importUrl)
|
|||||||
m_model->changeImports({import}, {});
|
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)
|
void ItemLibraryWidget::addResources(const QStringList &files)
|
||||||
{
|
{
|
||||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
@@ -637,8 +650,19 @@ void ItemLibraryWidget::addResources(const QStringList &files)
|
|||||||
|
|
||||||
QStringList filters { tr("All Files (%1)").arg("*.*") };
|
QStringList filters { tr("All Files (%1)").arg("*.*") };
|
||||||
QString filterTemplate = "%1 (%2)";
|
QString filterTemplate = "%1 (%2)";
|
||||||
for (const QString &key : qAsConst(sortedKeys))
|
for (const QString &key : qAsConst(sortedKeys)) {
|
||||||
filters.append(filterTemplate.arg(key, map.values(key).join(' ')));
|
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;
|
static QString lastDir;
|
||||||
const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir;
|
const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir;
|
||||||
|
@@ -134,7 +134,7 @@ void BaseConnectionManager::readDataStream(Connection &connection)
|
|||||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||||
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
|
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
|
||||||
{"name", cmd.name().toStdString()},
|
{"name", cmd.name().toStdString()},
|
||||||
{"counter", commandCounter});
|
{"counter", int64_t(commandCounter)});
|
||||||
|
|
||||||
writeCommand(command);
|
writeCommand(command);
|
||||||
// Do not dispatch this command.
|
// Do not dispatch this command.
|
||||||
@@ -143,7 +143,7 @@ void BaseConnectionManager::readDataStream(Connection &connection)
|
|||||||
} else {
|
} else {
|
||||||
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
|
NANOTRACE_INSTANT_ARGS("Update", "readCommand",
|
||||||
{"name", command.typeName()},
|
{"name", command.typeName()},
|
||||||
{"counter", commandCounter});
|
{"counter", int64_t(commandCounter)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -196,12 +196,12 @@ void NodeInstanceServerProxy::writeCommand(const QVariant &command)
|
|||||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||||
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
|
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
|
||||||
{"name", cmd.name().toStdString()},
|
{"name", cmd.name().toStdString()},
|
||||||
{"counter", m_connectionManager.writeCounter()});
|
{"counter", int64_t(m_connectionManager.writeCounter())});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
|
NANOTRACE_INSTANT_ARGS("Update", "writeCommand",
|
||||||
{"name", command.typeName()},
|
{"name", command.typeName()},
|
||||||
{"counter", m_connectionManager.writeCounter()});
|
{"counter", int64_t(m_connectionManager.writeCounter())});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -354,7 +354,7 @@ void generateModuleCmake(const FilePath &dir, const QString &uri)
|
|||||||
QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH);
|
QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH);
|
||||||
|
|
||||||
QString singletonContent;
|
QString singletonContent;
|
||||||
FilePaths qmldirFileList = dir.dirEntries(QStringList(FILENAME_QMLDIR), FILES_ONLY);
|
FilePaths qmldirFileList = dir.dirEntries({QStringList(FILENAME_QMLDIR), FILES_ONLY});
|
||||||
if (!qmldirFileList.isEmpty()) {
|
if (!qmldirFileList.isEmpty()) {
|
||||||
QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
|
QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
|
||||||
for (QString &singleton : singletons) {
|
for (QString &singleton : singletons) {
|
||||||
@@ -418,7 +418,7 @@ FilePaths getDirectoryQmls(const FilePath &dir)
|
|||||||
{
|
{
|
||||||
const QStringList qmlFilesOnly("*.qml");
|
const QStringList qmlFilesOnly("*.qml");
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
FilePaths allFiles = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
|
FilePaths allFiles = dir.dirEntries({qmlFilesOnly, FILES_ONLY});
|
||||||
FilePaths moduleFiles;
|
FilePaths moduleFiles;
|
||||||
for (FilePath &file : allFiles) {
|
for (FilePath &file : allFiles) {
|
||||||
if (!isFileBlacklisted(file.fileName()) &&
|
if (!isFileBlacklisted(file.fileName()) &&
|
||||||
@@ -436,7 +436,7 @@ QStringList getDirectoryTreeQmls(const FilePath &dir)
|
|||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
QStringList qmlFileList;
|
QStringList qmlFileList;
|
||||||
|
|
||||||
FilePaths thisDirFiles = dir.dirEntries(qmlFilesOnly, FILES_ONLY);
|
FilePaths thisDirFiles = dir.dirEntries({qmlFilesOnly, FILES_ONLY});
|
||||||
for (FilePath &file : thisDirFiles) {
|
for (FilePath &file : thisDirFiles) {
|
||||||
if (!isFileBlacklisted(file.fileName()) &&
|
if (!isFileBlacklisted(file.fileName()) &&
|
||||||
project->isKnownFile(file)) {
|
project->isKnownFile(file)) {
|
||||||
|
@@ -444,9 +444,8 @@ void QnxConfiguration::updateTargets()
|
|||||||
void QnxConfiguration::assignDebuggersToTargets()
|
void QnxConfiguration::assignDebuggersToTargets()
|
||||||
{
|
{
|
||||||
const FilePath hostUsrBinDir = m_qnxHost.pathAppended("usr/bin");
|
const FilePath hostUsrBinDir = m_qnxHost.pathAppended("usr/bin");
|
||||||
FilePaths debuggerNames = hostUsrBinDir.dirEntries(
|
const FilePaths debuggerNames = hostUsrBinDir.dirEntries(
|
||||||
QStringList(HostOsInfo::withExecutableSuffix("nto*-gdb")),
|
{{HostOsInfo::withExecutableSuffix("nto*-gdb")}, QDir::Files});
|
||||||
QDir::Files);
|
|
||||||
Environment sysEnv = Environment::systemEnvironment();
|
Environment sysEnv = Environment::systemEnvironment();
|
||||||
sysEnv.modify(qnxEnvironmentItems());
|
sysEnv.modify(qnxEnvironmentItems());
|
||||||
for (const FilePath &debuggerPath : debuggerNames) {
|
for (const FilePath &debuggerPath : debuggerNames) {
|
||||||
|
@@ -172,22 +172,19 @@ DeviceProcessSignalOperation::Ptr QnxDevice::signalOperation() const
|
|||||||
|
|
||||||
// Factory
|
// Factory
|
||||||
|
|
||||||
QnxDeviceFactory::QnxDeviceFactory()
|
QnxDeviceFactory::QnxDeviceFactory() : IDeviceFactory(Constants::QNX_QNX_OS_TYPE)
|
||||||
: ProjectExplorer::IDeviceFactory(Constants::QNX_QNX_OS_TYPE)
|
|
||||||
{
|
{
|
||||||
setDisplayName(QnxDevice::tr("QNX Device"));
|
setDisplayName(QnxDevice::tr("QNX Device"));
|
||||||
setCombinedIcon(":/qnx/images/qnxdevicesmall.png",
|
setCombinedIcon(":/qnx/images/qnxdevicesmall.png",
|
||||||
":/qnx/images/qnxdevice.png");
|
":/qnx/images/qnxdevice.png");
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&QnxDevice::create);
|
setConstructionFunction(&QnxDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator([] {
|
||||||
ProjectExplorer::IDevice::Ptr QnxDeviceFactory::create() const
|
QnxDeviceWizard wizard;
|
||||||
{
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
QnxDeviceWizard wizard;
|
return IDevice::Ptr();
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
return wizard.device();
|
||||||
return ProjectExplorer::IDevice::Ptr();
|
});
|
||||||
return wizard.device();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -70,8 +70,6 @@ class QnxDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QnxDeviceFactory();
|
QnxDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -144,9 +144,9 @@ FilePath QnxUtils::envFilePath(const FilePath &sdpPath)
|
|||||||
{
|
{
|
||||||
FilePaths entries;
|
FilePaths entries;
|
||||||
if (sdpPath.osType() == OsTypeWindows)
|
if (sdpPath.osType() == OsTypeWindows)
|
||||||
entries = sdpPath.dirEntries({"*-env.bat"});
|
entries = sdpPath.dirEntries({{"*-env.bat"}});
|
||||||
else
|
else
|
||||||
entries = sdpPath.dirEntries({"*-env.sh"});
|
entries = sdpPath.dirEntries({{"*-env.sh"}});
|
||||||
|
|
||||||
if (!entries.isEmpty())
|
if (!entries.isEmpty())
|
||||||
return entries.first();
|
return entries.first();
|
||||||
|
@@ -51,20 +51,18 @@ TestLinuxDeviceFactory::TestLinuxDeviceFactory()
|
|||||||
{
|
{
|
||||||
setDisplayName("Generic Linux Device");
|
setDisplayName("Generic Linux Device");
|
||||||
setIcon(QIcon());
|
setIcon(QIcon());
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&LinuxDevice::create);
|
setConstructionFunction(&LinuxDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator([] {
|
||||||
IDevice::Ptr TestLinuxDeviceFactory::create() const
|
LinuxDevice::Ptr newDev = LinuxDevice::create();
|
||||||
{
|
qDebug() << "device : " << newDev->type();
|
||||||
LinuxDevice::Ptr newDev = LinuxDevice::create();
|
newDev->setType("test");
|
||||||
qDebug() << "device : " << newDev->type();
|
QSsh::SshConnectionParameters sshParams = newDev->sshParameters();
|
||||||
newDev->setType("test");
|
sshParams.setHost(TEST_IP);
|
||||||
QSsh::SshConnectionParameters sshParams = newDev->sshParameters();
|
sshParams.setPort(22);
|
||||||
sshParams.setHost(TEST_IP);
|
newDev->setSshParameters(sshParams);
|
||||||
sshParams.setPort(22);
|
return newDev;
|
||||||
newDev->setSshParameters(sshParams);
|
});
|
||||||
return newDev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath createFile(const QString &name)
|
FilePath createFile(const QString &name)
|
||||||
@@ -114,8 +112,7 @@ void FileSystemAccessTest::testDirStatuses()
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
{"test"},
|
{{"test"}, QDir::Files});
|
||||||
QDir::Files);
|
|
||||||
|
|
||||||
QVERIFY(fileExists);
|
QVERIFY(fileExists);
|
||||||
QVERIFY(testFilePath.removeFile());
|
QVERIFY(testFilePath.removeFile());
|
||||||
|
@@ -37,8 +37,6 @@ class TestLinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestLinuxDeviceFactory();
|
TestLinuxDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileSystemAccessTest : public QObject
|
class FileSystemAccessTest : public QObject
|
||||||
|
@@ -679,16 +679,15 @@ bool LinuxDevice::setPermissions(const Utils::FilePath &filePath, QFileDevice::P
|
|||||||
static void filterEntriesHelper(const FilePath &base,
|
static void filterEntriesHelper(const FilePath &base,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &entries,
|
const QStringList &entries,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter)
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags)
|
|
||||||
{
|
{
|
||||||
const QList<QRegularExpression> nameRegexps = transform(nameFilters, [](const QString &filter) {
|
const QList<QRegularExpression> nameRegexps =
|
||||||
QRegularExpression re;
|
transform(filter.nameFilters, [](const QString &filter) {
|
||||||
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
|
QRegularExpression re;
|
||||||
QTC_CHECK(re.isValid());
|
re.setPattern(QRegularExpression::wildcardToRegularExpression(filter));
|
||||||
return re;
|
QTC_CHECK(re.isValid());
|
||||||
});
|
return re;
|
||||||
|
});
|
||||||
|
|
||||||
const auto nameMatches = [&nameRegexps](const QString &fileName) {
|
const auto nameMatches = [&nameRegexps](const QString &fileName) {
|
||||||
for (const QRegularExpression &re : nameRegexps) {
|
for (const QRegularExpression &re : nameRegexps) {
|
||||||
@@ -700,8 +699,8 @@ static void filterEntriesHelper(const FilePath &base,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Handle filters. For now bark on unsupported options.
|
// FIXME: Handle filters. For now bark on unsupported options.
|
||||||
QTC_CHECK(filters == QDir::NoFilter);
|
QTC_CHECK(filter.fileFilters == QDir::NoFilter);
|
||||||
QTC_CHECK(flags == QDirIterator::NoIteratorFlags);
|
QTC_CHECK(filter.iteratorFlags == QDirIterator::NoIteratorFlags);
|
||||||
|
|
||||||
for (const QString &entry : entries) {
|
for (const QString &entry : entries) {
|
||||||
if (!nameMatches(entry))
|
if (!nameMatches(entry))
|
||||||
@@ -713,15 +712,13 @@ static void filterEntriesHelper(const FilePath &base,
|
|||||||
|
|
||||||
void LinuxDevice::iterateDirectory(const FilePath &filePath,
|
void LinuxDevice::iterateDirectory(const FilePath &filePath,
|
||||||
const std::function<bool(const FilePath &)> &callBack,
|
const std::function<bool(const FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const FileFilter &filter) const
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(handlesFile(filePath), return);
|
QTC_ASSERT(handlesFile(filePath), return);
|
||||||
// if we do not have find - use ls as fallback
|
// if we do not have find - use ls as fallback
|
||||||
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
|
const QString output = d->outputForRunInShell({"ls", {"-1", "-b", "--", filePath.path()}});
|
||||||
const QStringList entries = output.split('\n', Qt::SkipEmptyParts);
|
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
|
QByteArray LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const
|
||||||
@@ -757,17 +754,15 @@ LinuxDeviceFactory::LinuxDeviceFactory()
|
|||||||
{
|
{
|
||||||
setDisplayName(LinuxDevice::tr("Generic Linux Device"));
|
setDisplayName(LinuxDevice::tr("Generic Linux Device"));
|
||||||
setIcon(QIcon());
|
setIcon(QIcon());
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&LinuxDevice::create);
|
setConstructionFunction(&LinuxDevice::create);
|
||||||
|
setCanCreate(true);
|
||||||
|
setCreator([] {
|
||||||
|
GenericLinuxDeviceConfigurationWizard wizard(Core::ICore::dialogParent());
|
||||||
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
|
return IDevice::Ptr();
|
||||||
|
return wizard.device();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
IDevice::Ptr LinuxDeviceFactory::create() const
|
} // namespace Internal
|
||||||
{
|
|
||||||
GenericLinuxDeviceConfigurationWizard wizard(Core::ICore::dialogParent());
|
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
|
||||||
return IDevice::Ptr();
|
|
||||||
return wizard.device();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
@@ -78,9 +78,7 @@ public:
|
|||||||
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
||||||
void iterateDirectory(const Utils::FilePath &filePath,
|
void iterateDirectory(const Utils::FilePath &filePath,
|
||||||
const std::function<bool(const Utils::FilePath &)> &callBack,
|
const std::function<bool(const Utils::FilePath &)> &callBack,
|
||||||
const QStringList &nameFilters,
|
const Utils::FileFilter &filter) const override;
|
||||||
QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags) const override;
|
|
||||||
QByteArray fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) 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;
|
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
||||||
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
||||||
@@ -102,8 +100,6 @@ class LinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LinuxDeviceFactory();
|
LinuxDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -58,7 +58,7 @@ FilePath findFallbackDefinitionsLocation()
|
|||||||
FilePath("/opt") / kateSyntaxPath
|
FilePath("/opt") / kateSyntaxPath
|
||||||
};
|
};
|
||||||
for (const FilePath &path : paths) {
|
for (const FilePath &path : paths) {
|
||||||
if (path.exists() && !path.dirEntries({"*.xml"}).isEmpty())
|
if (path.exists() && !path.dirEntries({{"*.xml"}}).isEmpty())
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ FilePath findFallbackDefinitionsLocation()
|
|||||||
const FilePath dir = FilePath::fromString(output);
|
const FilePath dir = FilePath::fromString(output);
|
||||||
for (auto &kateSyntaxPath : kateSyntaxPaths) {
|
for (auto &kateSyntaxPath : kateSyntaxPaths) {
|
||||||
const FilePath path = dir / kateSyntaxPath;
|
const FilePath path = dir / kateSyntaxPath;
|
||||||
if (path.exists() && !path.dirEntries({"*.xml"}).isEmpty())
|
if (path.exists() && !path.dirEntries({{"*.xml"}}).isEmpty())
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ FilePath findFallbackDefinitionsLocation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FilePath dir = Core::ICore::resourcePath("generic-highlighter");
|
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 dir;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@@ -95,7 +95,8 @@ SnippetsCollection *SnippetsCollection::instance()
|
|||||||
// SnippetsCollection
|
// SnippetsCollection
|
||||||
SnippetsCollection::SnippetsCollection()
|
SnippetsCollection::SnippetsCollection()
|
||||||
: m_userSnippetsFile(Core::ICore::userResourcePath("snippets/snippets.xml")),
|
: 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,
|
connect(Core::ICore::instance(), &Core::ICore::coreOpened,
|
||||||
|
@@ -47,10 +47,9 @@ WebAssemblyDevice::WebAssemblyDevice()
|
|||||||
setOsType(OsTypeOther);
|
setOsType(OsTypeOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr WebAssemblyDevice::create()
|
IDevice::Ptr WebAssemblyDevice::create()
|
||||||
{
|
{
|
||||||
auto device = new WebAssemblyDevice;
|
return IDevice::Ptr(new WebAssemblyDevice);
|
||||||
return ProjectExplorer::IDevice::Ptr(device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
|
WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
|
||||||
@@ -59,13 +58,9 @@ WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
|
|||||||
setDisplayName(WebAssemblyDevice::tr("WebAssembly Runtime"));
|
setDisplayName(WebAssemblyDevice::tr("WebAssembly Runtime"));
|
||||||
setCombinedIcon(":/webassembly/images/webassemblydevicesmall.png",
|
setCombinedIcon(":/webassembly/images/webassemblydevicesmall.png",
|
||||||
":/webassembly/images/webassemblydevice.png");
|
":/webassembly/images/webassemblydevice.png");
|
||||||
setCanCreate(true);
|
|
||||||
setConstructionFunction(&WebAssemblyDevice::create);
|
setConstructionFunction(&WebAssemblyDevice::create);
|
||||||
}
|
setCanCreate(true);
|
||||||
|
setCreator(&WebAssemblyDevice::create);
|
||||||
ProjectExplorer::IDevice::Ptr WebAssemblyDeviceFactory::create() const
|
|
||||||
{
|
|
||||||
return WebAssemblyDevice::create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -45,8 +45,6 @@ class WebAssemblyDeviceFactory final : public ProjectExplorer::IDeviceFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebAssemblyDeviceFactory();
|
WebAssemblyDeviceFactory();
|
||||||
|
|
||||||
ProjectExplorer::IDevice::Ptr create() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
Reference in New Issue
Block a user