Refactor launcher
* Pass program and arguments directly * Prevent failure on white space in executable path * Use own parser for arguments * Make libsyncthing accessible from launcher
This commit is contained in:
parent
a36bc4524b
commit
0d635e5ad5
|
@ -21,30 +21,91 @@ SyncthingProcess::SyncthingProcess(QObject *parent)
|
|||
connect(&m_killTimer, &QTimer::timeout, this, &SyncthingProcess::confirmKill);
|
||||
}
|
||||
|
||||
void SyncthingProcess::restartSyncthing(const QString &cmd)
|
||||
QStringList SyncthingProcess::splitArguments(const QString &arguments)
|
||||
{
|
||||
enum { Any, Quote, Slash, Space } lastInput = Any;
|
||||
bool inQuotes = false;
|
||||
QStringList result;
|
||||
QString currentArg;
|
||||
for (const auto c : arguments) {
|
||||
switch (c.unicode()) {
|
||||
case '\"':
|
||||
case '\'':
|
||||
switch (lastInput) {
|
||||
case Slash:
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
break;
|
||||
default:
|
||||
inQuotes = !inQuotes;
|
||||
lastInput = Quote;
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
switch (lastInput) {
|
||||
case Slash:
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
break;
|
||||
default:
|
||||
lastInput = Slash;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
switch (lastInput) {
|
||||
case Slash:
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
break;
|
||||
case Space:
|
||||
if (inQuotes) {
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (inQuotes) {
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
} else {
|
||||
result << currentArg;
|
||||
currentArg.clear();
|
||||
lastInput = Space;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
currentArg += c;
|
||||
lastInput = Any;
|
||||
}
|
||||
}
|
||||
if (!currentArg.isEmpty()) {
|
||||
result << currentArg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SyncthingProcess::restartSyncthing(const QString &program, const QStringList &arguments)
|
||||
{
|
||||
if (!isRunning()) {
|
||||
startSyncthing(cmd);
|
||||
startSyncthing(program, arguments);
|
||||
return;
|
||||
}
|
||||
m_cmd = cmd;
|
||||
m_program = program;
|
||||
m_arguments = arguments;
|
||||
m_manuallyStopped = true;
|
||||
m_killTimer.start();
|
||||
terminate();
|
||||
}
|
||||
|
||||
void SyncthingProcess::startSyncthing(const QString &cmd)
|
||||
void SyncthingProcess::startSyncthing(const QString &program, const QStringList &arguments)
|
||||
{
|
||||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
m_manuallyStopped = false;
|
||||
m_killTimer.stop();
|
||||
if (cmd.isEmpty()) {
|
||||
start(QProcess::ReadOnly);
|
||||
} else {
|
||||
start(cmd, QProcess::ReadOnly);
|
||||
}
|
||||
start(program, arguments, QProcess::ReadOnly);
|
||||
}
|
||||
|
||||
void SyncthingProcess::stopSyncthing()
|
||||
|
@ -78,15 +139,16 @@ void SyncthingProcess::handleFinished(int exitCode, QProcess::ExitStatus exitSta
|
|||
Q_UNUSED(exitStatus)
|
||||
m_activeSince = DateTime();
|
||||
m_killTimer.stop();
|
||||
if (!m_cmd.isEmpty()) {
|
||||
startSyncthing(m_cmd);
|
||||
m_cmd.clear();
|
||||
if (!m_program.isEmpty()) {
|
||||
startSyncthing(m_program, m_arguments);
|
||||
m_program.clear();
|
||||
m_arguments.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void SyncthingProcess::killToRestart()
|
||||
{
|
||||
if (!m_cmd.isEmpty()) {
|
||||
if (!m_program.isEmpty()) {
|
||||
kill();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,14 @@ public:
|
|||
bool isManuallyStopped() const;
|
||||
static SyncthingProcess *mainInstance();
|
||||
static void setMainInstance(SyncthingProcess *mainInstance);
|
||||
static QStringList splitArguments(const QString &arguments);
|
||||
|
||||
Q_SIGNALS:
|
||||
void confirmKill();
|
||||
|
||||
public Q_SLOTS:
|
||||
void restartSyncthing(const QString &cmd);
|
||||
void startSyncthing(const QString &cmd);
|
||||
void restartSyncthing(const QString &program, const QStringList &arguments);
|
||||
void startSyncthing(const QString &program, const QStringList &arguments);
|
||||
void stopSyncthing();
|
||||
void killSyncthing();
|
||||
|
||||
|
@ -40,7 +41,8 @@ private Q_SLOTS:
|
|||
void killToRestart();
|
||||
|
||||
private:
|
||||
QString m_cmd;
|
||||
QString m_program;
|
||||
QStringList m_arguments;
|
||||
ChronoUtilities::DateTime m_activeSince;
|
||||
QTimer m_killTimer;
|
||||
bool m_manuallyStopped;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "../syncthingconfig.h"
|
||||
#include "../syncthingconnection.h"
|
||||
#include "../syncthingconnectionsettings.h"
|
||||
#include "../syncthingprocess.h"
|
||||
#include "../syncthingservice.h"
|
||||
#include "../utils.h"
|
||||
|
||||
|
@ -29,6 +30,7 @@ using namespace CPPUNIT_NS;
|
|||
class MiscTests : public TestFixture {
|
||||
CPPUNIT_TEST_SUITE(MiscTests);
|
||||
CPPUNIT_TEST(testParsingConfig);
|
||||
CPPUNIT_TEST(testSplittingArguments);
|
||||
CPPUNIT_TEST(testUtils);
|
||||
CPPUNIT_TEST(testService);
|
||||
CPPUNIT_TEST(testConnectionSettingsAndLoadingSelfSignedCert);
|
||||
|
@ -39,6 +41,7 @@ public:
|
|||
MiscTests();
|
||||
|
||||
void testParsingConfig();
|
||||
void testSplittingArguments();
|
||||
void testUtils();
|
||||
void testService();
|
||||
void testConnectionSettingsAndLoadingSelfSignedCert();
|
||||
|
@ -94,6 +97,19 @@ void MiscTests::testParsingConfig()
|
|||
CPPUNIT_ASSERT(httpsCert.isEmpty() || QFile::exists(httpsCert));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Test splitting arguments via SyncthingProcess::splitArguments().
|
||||
*/
|
||||
void MiscTests::testSplittingArguments()
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL(QStringList(), SyncthingProcess::splitArguments(QString()));
|
||||
CPPUNIT_ASSERT_EQUAL(QStringList({ QStringLiteral("-simple") }), SyncthingProcess::splitArguments(QStringLiteral("-simple")));
|
||||
CPPUNIT_ASSERT_EQUAL(QStringList({ QStringLiteral("-home"), QStringLiteral("some dir"), QStringLiteral("-no-restart") }),
|
||||
SyncthingProcess::splitArguments(QStringLiteral("-home \"some dir\" -no-restart")));
|
||||
CPPUNIT_ASSERT_EQUAL(QStringList({ QStringLiteral("-home"), QStringLiteral("\"some"), QStringLiteral("dir\""), QStringLiteral("-no-restart") }),
|
||||
SyncthingProcess::splitArguments(QStringLiteral("-home \\\"some dir\\\" -no-restart")));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tests utils.
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,7 @@ SyncthingLauncher *SyncthingLauncher::s_mainInstance = nullptr;
|
|||
|
||||
SyncthingLauncher::SyncthingLauncher(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_useLibSyncthing(false)
|
||||
{
|
||||
connect(&m_process, &SyncthingProcess::readyRead, this, &SyncthingLauncher::handleProcessReadyRead);
|
||||
connect(&m_process, static_cast<void (SyncthingProcess::*)(int exitCode, QProcess::ExitStatus exitStatus)>(&SyncthingProcess::finished), this,
|
||||
|
@ -31,22 +32,41 @@ bool SyncthingLauncher::isLibSyncthingAvailable()
|
|||
#endif
|
||||
}
|
||||
|
||||
void SyncthingLauncher::launch(const QString &cmd)
|
||||
/*!
|
||||
* \brief Launches a Syncthing instance using the specified \a arguments.
|
||||
* \remarks To use the internal library, leave \a program empty. Otherwise it must be the path the external Syncthing executable.
|
||||
*/
|
||||
void SyncthingLauncher::launch(const QString &program, const QStringList &arguments)
|
||||
{
|
||||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
m_manuallyStopped = false;
|
||||
m_process.startSyncthing(cmd);
|
||||
if (!program.isEmpty()) {
|
||||
m_process.startSyncthing(program, arguments);
|
||||
} else {
|
||||
vector<string> utf8Arguments{ "-no-restart", "-no-browser" };
|
||||
utf8Arguments.reserve(utf8Arguments.size() + static_cast<size_t>(arguments.size()));
|
||||
for (const auto &arg : arguments) {
|
||||
const auto utf8Data(arg.toUtf8());
|
||||
utf8Arguments.emplace_back(utf8Data.data(), utf8Data.size());
|
||||
}
|
||||
m_future = QtConcurrent::run(
|
||||
this, static_cast<void (SyncthingLauncher::*)(const std::vector<std::string> &)>(&SyncthingLauncher::runLibSyncthing), utf8Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Launches a Syncthing instance using the internal library with the specified \a runtimeOptions.
|
||||
*/
|
||||
void SyncthingLauncher::launch(const LibSyncthing::RuntimeOptions &runtimeOptions)
|
||||
{
|
||||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
m_manuallyStopped = false;
|
||||
m_future = QtConcurrent::run(this, &SyncthingLauncher::runLibSyncthing, runtimeOptions);
|
||||
m_future = QtConcurrent::run(
|
||||
this, static_cast<void (SyncthingLauncher::*)(const LibSyncthing::RuntimeOptions &)>(&SyncthingLauncher::runLibSyncthing), runtimeOptions);
|
||||
}
|
||||
|
||||
void SyncthingLauncher::terminate()
|
||||
|
@ -87,13 +107,28 @@ void SyncthingLauncher::handleProcessFinished(int exitCode, QProcess::ExitStatus
|
|||
emit exited(exitCode, exitStatus);
|
||||
}
|
||||
|
||||
static const char *const logLevelStrings[] = {
|
||||
"[DEBUG] ",
|
||||
"[VERBOSE] ",
|
||||
"[INFO] ",
|
||||
"[WARNING] ",
|
||||
"[FATAL] ",
|
||||
};
|
||||
|
||||
void SyncthingLauncher::handleLoggingCallback(LibSyncthing::LogLevel level, const char *message, size_t messageSize)
|
||||
{
|
||||
#ifdef SYNCTHING_WIDGETS_USE_LIBSYNCTHING
|
||||
if (level < LibSyncthing::LogLevel::Info) {
|
||||
return;
|
||||
}
|
||||
emit outputAvailable(QByteArray(message, static_cast<int>(max<size_t>(numeric_limits<int>::max(), messageSize))));
|
||||
QByteArray messageData;
|
||||
messageSize = min<size_t>(numeric_limits<int>::max() - 20, messageSize);
|
||||
messageData.reserve(static_cast<int>(messageSize) + 20);
|
||||
messageData.append(logLevelStrings[static_cast<int>(level)]);
|
||||
messageData.append(message, static_cast<int>(messageSize));
|
||||
messageData.append('\n');
|
||||
|
||||
emit outputAvailable(move(messageData));
|
||||
#else
|
||||
VAR_UNUSED(level)
|
||||
VAR_UNUSED(message)
|
||||
|
@ -114,6 +149,19 @@ void SyncthingLauncher::runLibSyncthing(const LibSyncthing::RuntimeOptions &runt
|
|||
#endif
|
||||
}
|
||||
|
||||
void SyncthingLauncher::runLibSyncthing(const std::vector<string> &arguments)
|
||||
{
|
||||
#ifdef SYNCTHING_WIDGETS_USE_LIBSYNCTHING
|
||||
LibSyncthing::setLoggingCallback(bind(&SyncthingLauncher::handleLoggingCallback, this, _1, _2, _3));
|
||||
const auto exitCode = LibSyncthing::runSyncthing(arguments);
|
||||
emit exited(static_cast<int>(exitCode), exitCode == 0 ? QProcess::NormalExit : QProcess::CrashExit);
|
||||
#else
|
||||
VAR_UNUSED(arguments)
|
||||
emit outputAvailable("libsyncthing support not enabled");
|
||||
emit exited(-1, QProcess::CrashExit);
|
||||
#endif
|
||||
}
|
||||
|
||||
SyncthingLauncher &syncthingLauncher()
|
||||
{
|
||||
static SyncthingLauncher launcher;
|
||||
|
|
|
@ -19,6 +19,7 @@ class SYNCTHINGWIDGETS_EXPORT SyncthingLauncher : public QObject {
|
|||
Q_PROPERTY(bool running READ isRunning NOTIFY runningChanged)
|
||||
Q_PROPERTY(ChronoUtilities::DateTime activeSince READ activeSince)
|
||||
Q_PROPERTY(bool manuallyStopped READ isManuallyStopped)
|
||||
Q_PROPERTY(bool useLibSyncthing READ isUseLibSyncthing WRITE setUseLibSyncthing)
|
||||
|
||||
public:
|
||||
explicit SyncthingLauncher(QObject *parent = nullptr);
|
||||
|
@ -27,6 +28,7 @@ public:
|
|||
ChronoUtilities::DateTime activeSince() const;
|
||||
bool isActiveFor(unsigned int atLeastSeconds) const;
|
||||
bool isManuallyStopped() const;
|
||||
bool isUseLibSyncthing() const;
|
||||
static bool isLibSyncthingAvailable();
|
||||
static SyncthingLauncher *mainInstance();
|
||||
static void setMainInstance(SyncthingLauncher *mainInstance);
|
||||
|
@ -38,7 +40,8 @@ Q_SIGNALS:
|
|||
void exited(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
||||
public Q_SLOTS:
|
||||
void launch(const QString &cmd);
|
||||
void setUseLibSyncthing(bool useLibSyncthing);
|
||||
void launch(const QString &program, const QStringList &arguments);
|
||||
void launch(const LibSyncthing::RuntimeOptions &runtimeOptions);
|
||||
void terminate();
|
||||
void kill();
|
||||
|
@ -48,12 +51,14 @@ private Q_SLOTS:
|
|||
void handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void handleLoggingCallback(LibSyncthing::LogLevel, const char *message, std::size_t messageSize);
|
||||
void runLibSyncthing(const LibSyncthing::RuntimeOptions &runtimeOptions);
|
||||
void runLibSyncthing(const std::vector<std::string> &arguments);
|
||||
|
||||
private:
|
||||
SyncthingProcess m_process;
|
||||
QFuture<void> m_future;
|
||||
ChronoUtilities::DateTime m_futureStarted;
|
||||
bool m_manuallyStopped;
|
||||
bool m_useLibSyncthing;
|
||||
static SyncthingLauncher *s_mainInstance;
|
||||
};
|
||||
|
||||
|
@ -83,6 +88,16 @@ inline bool SyncthingLauncher::isManuallyStopped() const
|
|||
return m_manuallyStopped;
|
||||
}
|
||||
|
||||
inline bool SyncthingLauncher::isUseLibSyncthing() const
|
||||
{
|
||||
return m_useLibSyncthing;
|
||||
}
|
||||
|
||||
inline void SyncthingLauncher::setUseLibSyncthing(bool useLibSyncthing)
|
||||
{
|
||||
m_useLibSyncthing = useLibSyncthing;
|
||||
}
|
||||
|
||||
inline SyncthingLauncher *SyncthingLauncher::mainInstance()
|
||||
{
|
||||
return s_mainInstance;
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::LauncherOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::LauncherOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>507</width>
|
||||
<height>391</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Syncthing launcher</string>
|
||||
</property>
|
||||
|
@ -47,16 +55,23 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="Widgets::PathSelection" name="syncthingPathSelection" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="argumentsLabel">
|
||||
<property name="text">
|
||||
<string>Arguments</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="2" column="1">
|
||||
<widget class="Widgets::ClearLineEdit" name="argumentsLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="useBuiltInVersionCheckBox">
|
||||
<property name="text">
|
||||
<string>Use built-in Syncthing library (experimental)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -215,5 +230,21 @@
|
|||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>useBuiltInVersionCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>syncthingPathSelection</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>320</x>
|
||||
<y>58</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>320</x>
|
||||
<y>36</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
|
@ -52,20 +52,6 @@ namespace Settings {
|
|||
*/
|
||||
static unordered_map<QString, SyncthingProcess> toolProcesses;
|
||||
|
||||
QString Launcher::syncthingCmd() const
|
||||
{
|
||||
return syncthingPath % QChar(' ') % syncthingArgs;
|
||||
}
|
||||
|
||||
QString Launcher::toolCmd(const QString &tool) const
|
||||
{
|
||||
const ToolParameter toolParams = tools.value(tool);
|
||||
if (toolParams.path.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
return toolParams.path % QChar(' ') % toolParams.args;
|
||||
}
|
||||
|
||||
SyncthingProcess &Launcher::toolProcess(const QString &tool)
|
||||
{
|
||||
return toolProcesses[tool];
|
||||
|
@ -92,12 +78,12 @@ void Launcher::autostart() const
|
|||
auto *const launcher(SyncthingLauncher::mainInstance());
|
||||
// TODO: allow using libsyncthing
|
||||
if (enabled && !syncthingPath.isEmpty() && launcher) {
|
||||
launcher->launch(syncthingCmd());
|
||||
launcher->launch(useLibSyncthing ? QString() : syncthingPath, SyncthingProcess::splitArguments(syncthingArgs));
|
||||
}
|
||||
for (auto i = tools.cbegin(), end = tools.cend(); i != end; ++i) {
|
||||
const ToolParameter &toolParams = i.value();
|
||||
if (toolParams.autostart && !toolParams.path.isEmpty()) {
|
||||
toolProcesses[i.key()].startSyncthing(toolParams.path % QChar(' ') % toolParams.args);
|
||||
toolProcesses[i.key()].startSyncthing(toolParams.path, SyncthingProcess::splitArguments(toolParams.args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +180,7 @@ void restore()
|
|||
settings.beginGroup(QStringLiteral("startup"));
|
||||
auto &launcher = v.launcher;
|
||||
launcher.enabled = settings.value(QStringLiteral("syncthingAutostart"), launcher.enabled).toBool();
|
||||
launcher.useLibSyncthing = settings.value(QStringLiteral("useLibSyncthing"), launcher.useLibSyncthing).toBool();
|
||||
launcher.syncthingPath = settings.value(QStringLiteral("syncthingPath"), launcher.syncthingPath).toString();
|
||||
launcher.syncthingArgs = settings.value(QStringLiteral("syncthingArgs"), launcher.syncthingArgs).toString();
|
||||
launcher.considerForReconnect = settings.value(QStringLiteral("considerLauncherForReconnect"), launcher.considerForReconnect).toBool();
|
||||
|
@ -206,8 +193,6 @@ void restore()
|
|||
toolParams.args = settings.value(QStringLiteral("args"), toolParams.args).toString();
|
||||
settings.endGroup();
|
||||
}
|
||||
for (auto i = launcher.tools.cbegin(), end = launcher.tools.cend(); i != end; ++i) {
|
||||
}
|
||||
settings.endGroup();
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
auto &systemd = v.systemd;
|
||||
|
@ -280,6 +265,7 @@ void save()
|
|||
settings.beginGroup(QStringLiteral("startup"));
|
||||
const auto &launcher = v.launcher;
|
||||
settings.setValue(QStringLiteral("syncthingAutostart"), launcher.enabled);
|
||||
settings.setValue(QStringLiteral("useLibSyncthing"), launcher.useLibSyncthing);
|
||||
settings.setValue(QStringLiteral("syncthingPath"), launcher.syncthingPath);
|
||||
settings.setValue(QStringLiteral("syncthingArgs"), launcher.syncthingArgs);
|
||||
settings.setValue(QStringLiteral("considerLauncherForReconnect"), launcher.considerForReconnect);
|
||||
|
|
|
@ -59,6 +59,7 @@ struct SYNCTHINGWIDGETS_EXPORT ToolParameter {
|
|||
|
||||
struct SYNCTHINGWIDGETS_EXPORT Launcher {
|
||||
bool enabled = false;
|
||||
bool useLibSyncthing = false;
|
||||
QString syncthingPath =
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
QStringLiteral("syncthing.exe");
|
||||
|
@ -68,8 +69,6 @@ struct SYNCTHINGWIDGETS_EXPORT Launcher {
|
|||
QString syncthingArgs;
|
||||
QHash<QString, ToolParameter> tools;
|
||||
bool considerForReconnect = false;
|
||||
QString syncthingCmd() const;
|
||||
QString toolCmd(const QString &tool) const;
|
||||
static Data::SyncthingProcess &toolProcess(const QString &tool);
|
||||
static std::vector<Data::SyncthingProcess *> allProcesses();
|
||||
void autostart() const;
|
||||
|
|
|
@ -648,6 +648,7 @@ QWidget *LauncherOptionPage::setupWidget()
|
|||
const auto running(isRunning());
|
||||
ui()->launchNowPushButton->setHidden(running);
|
||||
ui()->stopPushButton->setHidden(!running);
|
||||
ui()->useBuiltInVersionCheckBox->setHidden(!SyncthingLauncher::isLibSyncthingAvailable());
|
||||
// connect signals & slots
|
||||
if (m_process) {
|
||||
m_connections << QObject::connect(m_process, &SyncthingProcess::readyRead, bind(&LauncherOptionPage::handleSyncthingReadyRead, this));
|
||||
|
@ -655,8 +656,8 @@ QWidget *LauncherOptionPage::setupWidget()
|
|||
static_cast<void (SyncthingProcess::*)(int exitCode, QProcess::ExitStatus exitStatus)>(&SyncthingProcess::finished),
|
||||
bind(&LauncherOptionPage::handleSyncthingExited, this, _1, _2));
|
||||
} else if (m_launcher) {
|
||||
m_connections << QObject::connect(
|
||||
m_launcher, &SyncthingLauncher::outputAvailable, bind(&LauncherOptionPage::handleSyncthingOutputAvailable, this, _1));
|
||||
m_connections << QObject::connect(m_launcher, &SyncthingLauncher::outputAvailable, ui()->logTextEdit,
|
||||
bind(&LauncherOptionPage::handleSyncthingOutputAvailable, this, _1), Qt::QueuedConnection);
|
||||
m_connections << QObject::connect(m_launcher, &SyncthingLauncher::exited, bind(&LauncherOptionPage::handleSyncthingExited, this, _1, _2));
|
||||
}
|
||||
QObject::connect(ui()->launchNowPushButton, &QPushButton::clicked, bind(&LauncherOptionPage::launch, this));
|
||||
|
@ -669,6 +670,7 @@ bool LauncherOptionPage::apply()
|
|||
auto &settings = values().launcher;
|
||||
if (m_tool.isEmpty()) {
|
||||
settings.enabled = ui()->enabledCheckBox->isChecked();
|
||||
settings.useLibSyncthing = ui()->useBuiltInVersionCheckBox->isChecked();
|
||||
settings.syncthingPath = ui()->syncthingPathSelection->lineEdit()->text();
|
||||
settings.syncthingArgs = ui()->argumentsLineEdit->text();
|
||||
settings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
||||
|
@ -686,11 +688,15 @@ void LauncherOptionPage::reset()
|
|||
const auto &settings = values().launcher;
|
||||
if (m_tool.isEmpty()) {
|
||||
ui()->enabledCheckBox->setChecked(settings.enabled);
|
||||
ui()->useBuiltInVersionCheckBox->setChecked(settings.useLibSyncthing);
|
||||
ui()->useBuiltInVersionCheckBox->setVisible(settings.useLibSyncthing || SyncthingLauncher::isLibSyncthingAvailable());
|
||||
ui()->syncthingPathSelection->lineEdit()->setText(settings.syncthingPath);
|
||||
ui()->argumentsLineEdit->setText(settings.syncthingArgs);
|
||||
ui()->considerForReconnectCheckBox->setChecked(settings.considerForReconnect);
|
||||
} else {
|
||||
const ToolParameter params = settings.tools.value(m_tool);
|
||||
ui()->useBuiltInVersionCheckBox->setChecked(false);
|
||||
ui()->useBuiltInVersionCheckBox->setVisible(false);
|
||||
ui()->enabledCheckBox->setChecked(params.autostart);
|
||||
ui()->syncthingPathSelection->lineEdit()->setText(params.path);
|
||||
ui()->argumentsLineEdit->setText(params.args);
|
||||
|
@ -709,7 +715,7 @@ void LauncherOptionPage::handleSyncthingOutputAvailable(const QByteArray &output
|
|||
}
|
||||
QTextCursor cursor(ui()->logTextEdit->textCursor());
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
cursor.insertText(QString::fromLocal8Bit(output));
|
||||
cursor.insertText(QString::fromUtf8(output));
|
||||
if (ui()->ensureCursorVisibleCheckBox->isChecked()) {
|
||||
ui()->logTextEdit->ensureCursorVisible();
|
||||
}
|
||||
|
@ -754,11 +760,13 @@ void LauncherOptionPage::launch()
|
|||
ui()->stopPushButton->show();
|
||||
ui()->stopPushButton->setText(QCoreApplication::translate("QtGui::LauncherOptionPage", "Stop launched instance"));
|
||||
m_kill = false;
|
||||
const auto launcherSettings(values().launcher);
|
||||
if (m_tool.isEmpty()) {
|
||||
// TODO: allow using libsyncthing
|
||||
m_launcher->launch(values().launcher.syncthingCmd());
|
||||
m_launcher->launch(launcherSettings.useLibSyncthing ? QString() : launcherSettings.syncthingPath,
|
||||
SyncthingProcess::splitArguments(launcherSettings.syncthingArgs));
|
||||
} else {
|
||||
m_process->startSyncthing(values().launcher.toolCmd(m_tool));
|
||||
const auto toolParams(launcherSettings.tools.value(m_tool));
|
||||
m_process->startSyncthing(toolParams.path, SyncthingProcess::splitArguments(toolParams.args));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue