Allow to show start/stop button for launcher
This commit is contained in:
parent
31bb92da89
commit
2112b00347
|
@ -210,12 +210,13 @@ void SyncthingApplet::setCurrentConnectionConfigIndex(int index)
|
|||
|
||||
// apply systemd settings, reconnect if required and possible
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
settings.systemd.apply(m_connection, currentConnectionConfig(), reconnectRequired);
|
||||
const auto systemdRelevantForReconnect = settings.systemd.apply(m_connection, currentConnectionConfig(), reconnectRequired).relevant;
|
||||
#else
|
||||
if (reconnectRequired || !m_connection.isConnected()) {
|
||||
const auto systemdRelevantForReconnect = false;
|
||||
#endif
|
||||
if (!systemdRelevantForReconnect && (reconnectRequired || !m_connection.isConnected())) {
|
||||
m_connection.reconnect();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SyncthingApplet::isStartStopEnabled() const
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "../../widgets/misc/otherdialogs.h"
|
||||
#include "../../widgets/misc/textviewdialog.h"
|
||||
#include "../../widgets/misc/syncthinglauncher.h"
|
||||
#include "../../widgets/settings/settingsdialog.h"
|
||||
#include "../../widgets/webview/webviewdialog.h"
|
||||
|
||||
|
@ -73,6 +74,7 @@ TrayWidget::TrayWidget(TrayMenu *parent)
|
|||
, m_devModel(m_connection)
|
||||
, m_dlModel(m_connection)
|
||||
, m_selectedConnection(nullptr)
|
||||
, m_startStopButtonTarget(StartStopButtonTarget::None)
|
||||
{
|
||||
m_instances.push_back(this);
|
||||
|
||||
|
@ -134,9 +136,6 @@ TrayWidget::TrayWidget(TrayMenu *parent)
|
|||
m_ui->localTextLabel->setPixmap(
|
||||
QIcon::fromTheme(QStringLiteral("user-home"), QIcon(QStringLiteral(":/icons/hicolor/scalable/places/user-home.svg"))).pixmap(16));
|
||||
updateTraffic();
|
||||
#ifndef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
delete m_ui->startStopPushButton;
|
||||
#endif
|
||||
|
||||
// connect signals and slots
|
||||
connect(m_ui->statusPushButton, &QPushButton::clicked, this, &TrayWidget::changeStatus);
|
||||
|
@ -161,9 +160,12 @@ TrayWidget::TrayWidget(TrayMenu *parent)
|
|||
connect(m_connectionsActionGroup, &QActionGroup::triggered, this, &TrayWidget::handleConnectionSelected);
|
||||
connect(m_ui->actionShowNotifications, &QAction::triggered, this, &TrayWidget::showNotifications);
|
||||
connect(m_ui->actionDismissNotifications, &QAction::triggered, this, &TrayWidget::dismissNotifications);
|
||||
connect(m_ui->startStopPushButton, &QPushButton::clicked, this, &TrayWidget::toggleRunning);
|
||||
if (const auto *const launcher = SyncthingLauncher::mainInstance()) {
|
||||
connect(launcher, &SyncthingLauncher::runningChanged, this, &TrayWidget::handleLauncherStatusChanged);
|
||||
}
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
if (const auto *const service = SyncthingService::mainInstance()) {
|
||||
connect(m_ui->startStopPushButton, &QPushButton::clicked, service, &SyncthingService::toggleRunning);
|
||||
connect(service, &SyncthingService::systemdAvailableChanged, this, &TrayWidget::handleSystemdStatusChanged);
|
||||
connect(service, &SyncthingService::stateChanged, this, &TrayWidget::handleSystemdStatusChanged);
|
||||
}
|
||||
|
@ -376,15 +378,22 @@ void TrayWidget::applySettings(const QString &connectionConfig)
|
|||
// apply notification settings
|
||||
settings.apply(m_notifier);
|
||||
|
||||
// apply systemd and launcher settings enforcing a reconnect if required and possible
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
// apply systemd settings, also enforce reconnect if required and possible
|
||||
applySystemdSettings(reconnectRequired);
|
||||
const auto systemdStatus = applySystemdSettings(reconnectRequired);
|
||||
const auto launcherStatus = applyLauncherSettings(reconnectRequired, systemdStatus.relevant, systemdStatus.showStartStopButton);
|
||||
const auto showStartStopButton = systemdStatus.showStartStopButton || launcherStatus.showStartStopButton;
|
||||
const auto systemdOrLauncherRelevantForReconnect = systemdStatus.relevant || launcherStatus.relevant;
|
||||
#else
|
||||
// reconnect if required, not checking whether possible
|
||||
if (reconnectRequired) {
|
||||
const auto launcherStatus = applyLauncherSettings(reconnectRequired);
|
||||
const auto showStartStopButton = launcherStatus.showStartStopButton;
|
||||
const auto systemdOrLauncherRelevantForReconnect = launcherStatus.relevant;
|
||||
#endif
|
||||
m_ui->startStopPushButton->setVisible(showStartStopButton);
|
||||
if (reconnectRequired && !systemdOrLauncherRelevantForReconnect) {
|
||||
// simply enforce the reconnect for this connection if the systemd or launcher status are relevant for it
|
||||
m_connection.reconnect();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
|
||||
// web view
|
||||
|
@ -538,38 +547,112 @@ void TrayWidget::updateOverallStatistics()
|
|||
m_ui->localStatisticsLabel->setText(directoryStatusString(overallStats.local));
|
||||
}
|
||||
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
bool TrayWidget::handleSystemdStatusChanged()
|
||||
void TrayWidget::toggleRunning()
|
||||
{
|
||||
return applySystemdSettings();
|
||||
switch(m_startStopButtonTarget) {
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
case StartStopButtonTarget::Service:
|
||||
if (auto *const service = SyncthingService::mainInstance()) {
|
||||
service->toggleRunning();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case StartStopButtonTarget::Launcher:
|
||||
if (auto *const launcher = SyncthingLauncher::mainInstance()) {
|
||||
if (launcher->isRunning()) {
|
||||
launcher->terminate();
|
||||
} else {
|
||||
launcher->launch(Settings::values().launcher);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
bool TrayWidget::applySystemdSettings(bool reconnectRequired)
|
||||
Settings::Launcher::LauncherStatus TrayWidget::handleLauncherStatusChanged()
|
||||
{
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
const auto systemdStatus = Settings::values().systemd.status(m_connection);
|
||||
const auto launcherStatus = applyLauncherSettings(false, systemdStatus.relevant, systemdStatus.showStartStopButton);
|
||||
const auto showStartStopButton = systemdStatus.showStartStopButton || launcherStatus.showStartStopButton;
|
||||
#else
|
||||
const auto launcherStatus = applyLauncherSettings(reconnectRequired);
|
||||
const auto showStartStopButton = launcherStatus.showStartStopButton;
|
||||
#endif
|
||||
m_ui->startStopPushButton->setVisible(showStartStopButton);
|
||||
return launcherStatus;
|
||||
}
|
||||
|
||||
Settings::Launcher::LauncherStatus TrayWidget::applyLauncherSettings(bool reconnectRequired, bool skipApplyingToConnection, bool skipStartStopButton)
|
||||
{
|
||||
// update connection
|
||||
const Settings::Systemd &systemdSettings(Settings::values().systemd);
|
||||
bool isServiceRelevant, isServiceRunning;
|
||||
tie(isServiceRelevant, isServiceRunning) = systemdSettings.apply(m_connection, m_selectedConnection, reconnectRequired);
|
||||
const auto &launcherSettings = Settings::values().launcher;
|
||||
const auto launcherStatus = skipApplyingToConnection
|
||||
? launcherSettings.status(m_connection)
|
||||
: launcherSettings.apply(m_connection, m_selectedConnection, reconnectRequired);
|
||||
|
||||
if (skipStartStopButton || !launcherStatus.showStartStopButton) {
|
||||
return launcherStatus;
|
||||
}
|
||||
|
||||
// update start/stop button
|
||||
if (isServiceRelevant && systemdSettings.showButton) {
|
||||
m_startStopButtonTarget = StartStopButtonTarget::Launcher;
|
||||
if (launcherStatus.running) {
|
||||
m_ui->startStopPushButton->setText(tr("Stop"));
|
||||
m_ui->startStopPushButton->setToolTip(tr("Stop Syncthing instance launched via tray icon"));
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("process-stop"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/process-stop.svg"))));
|
||||
} else {
|
||||
m_ui->startStopPushButton->setText(tr("Start"));
|
||||
m_ui->startStopPushButton->setToolTip(tr("Launch Syncthing instance via tray icon"));
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
|
||||
}
|
||||
return launcherStatus;
|
||||
}
|
||||
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
Settings::Systemd::ServiceStatus TrayWidget::handleSystemdStatusChanged()
|
||||
{
|
||||
const auto systemdStatus = applySystemdSettings();
|
||||
if (systemdStatus.showStartStopButton) {
|
||||
m_ui->startStopPushButton->setVisible(true);
|
||||
if (isServiceRunning) {
|
||||
m_ui->startStopPushButton->setText(tr("Stop"));
|
||||
m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user stop ") + systemdSettings.syncthingUnit);
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("process-stop"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/process-stop.svg"))));
|
||||
} else {
|
||||
m_ui->startStopPushButton->setText(tr("Start"));
|
||||
m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user start ") + systemdSettings.syncthingUnit);
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
|
||||
}
|
||||
return systemdStatus;
|
||||
}
|
||||
if (!systemdSettings.showButton || !isServiceRelevant) {
|
||||
m_ui->startStopPushButton->setVisible(false);
|
||||
|
||||
// update the start/stop button which might now control the internal launcher
|
||||
const auto launcherStatus = applyLauncherSettings(false, true, false);
|
||||
m_ui->startStopPushButton->setVisible(launcherStatus.showStartStopButton);
|
||||
|
||||
return systemdStatus;
|
||||
}
|
||||
|
||||
Settings::Systemd::ServiceStatus TrayWidget::applySystemdSettings(bool reconnectRequired)
|
||||
{
|
||||
// update connection
|
||||
const auto &systemdSettings = Settings::values().systemd;
|
||||
const auto serviceStatus = systemdSettings.apply(m_connection, m_selectedConnection, reconnectRequired);
|
||||
|
||||
if (!serviceStatus.showStartStopButton) {
|
||||
return serviceStatus;
|
||||
}
|
||||
return isServiceRelevant && isServiceRunning;
|
||||
|
||||
// update start/stop button
|
||||
m_startStopButtonTarget = StartStopButtonTarget::Service;
|
||||
if (serviceStatus.running) {
|
||||
m_ui->startStopPushButton->setText(tr("Stop"));
|
||||
m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user stop ") + systemdSettings.syncthingUnit);
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("process-stop"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/process-stop.svg"))));
|
||||
} else {
|
||||
m_ui->startStopPushButton->setText(tr("Start"));
|
||||
m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user start ") + systemdSettings.syncthingUnit);
|
||||
m_ui->startStopPushButton->setIcon(
|
||||
QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
|
||||
}
|
||||
return serviceStatus;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -76,9 +76,12 @@ private slots:
|
|||
void changeStatus();
|
||||
void updateTraffic();
|
||||
void updateOverallStatistics();
|
||||
void toggleRunning();
|
||||
Settings::Launcher::LauncherStatus handleLauncherStatusChanged();
|
||||
Settings::Launcher::LauncherStatus applyLauncherSettings(bool reconnectRequired = false, bool skipApplyingToConnection = false, bool skipStartStopButton = false);
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
bool handleSystemdStatusChanged();
|
||||
bool applySystemdSettings(bool reconnectRequired = false);
|
||||
Settings::Systemd::ServiceStatus handleSystemdStatusChanged();
|
||||
Settings::Systemd::ServiceStatus applySystemdSettings(bool reconnectRequired = false);
|
||||
#endif
|
||||
#ifndef SYNCTHINGWIDGETS_NO_WEBVIEW
|
||||
void handleWebViewDeleted();
|
||||
|
@ -106,6 +109,9 @@ private:
|
|||
Data::SyncthingConnectionSettings *m_selectedConnection;
|
||||
QMenu *m_notificationsMenu;
|
||||
std::vector<Data::SyncthingLogEntry> m_notifications;
|
||||
enum class StartStopButtonTarget {
|
||||
None, Service, Launcher
|
||||
} m_startStopButtonTarget;
|
||||
static std::vector<TrayWidget *> m_instances;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "./syncthinglauncher.h"
|
||||
|
||||
#include "../settings/settings.h"
|
||||
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -20,6 +22,7 @@ SyncthingLauncher::SyncthingLauncher(QObject *parent)
|
|||
connect(&m_process, &SyncthingProcess::readyRead, this, &SyncthingLauncher::handleProcessReadyRead);
|
||||
connect(&m_process, static_cast<void (SyncthingProcess::*)(int exitCode, QProcess::ExitStatus exitStatus)>(&SyncthingProcess::finished), this,
|
||||
&SyncthingLauncher::handleProcessFinished);
|
||||
connect(&m_process, &SyncthingProcess::stateChanged, this, &SyncthingLauncher::handleProcessStateChanged);
|
||||
connect(&m_process, &SyncthingProcess::errorOccurred, this, &SyncthingLauncher::errorOccurred);
|
||||
connect(&m_process, &SyncthingProcess::confirmKill, this, &SyncthingLauncher::confirmKill);
|
||||
}
|
||||
|
@ -57,6 +60,15 @@ void SyncthingLauncher::launch(const QString &program, const QStringList &argume
|
|||
}
|
||||
}
|
||||
|
||||
void SyncthingLauncher::launch(const Settings::Launcher &launcherSettings)
|
||||
{
|
||||
if (!launcherSettings.useLibSyncthing && launcherSettings.syncthingPath.isEmpty()) {
|
||||
emit errorOccurred(QProcess::FailedToStart);
|
||||
return;
|
||||
}
|
||||
launch(launcherSettings.useLibSyncthing ? QString() : launcherSettings.syncthingPath, SyncthingProcess::splitArguments(launcherSettings.syncthingArgs));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Launches a Syncthing instance using the internal library with the specified \a runtimeOptions.
|
||||
*/
|
||||
|
@ -102,9 +114,22 @@ void SyncthingLauncher::handleProcessReadyRead()
|
|||
emit outputAvailable(m_process.readAll());
|
||||
}
|
||||
|
||||
void SyncthingLauncher::handleProcessStateChanged(QProcess::ProcessState newState)
|
||||
{
|
||||
switch(newState) {
|
||||
case QProcess::NotRunning:
|
||||
emit runningChanged(false);
|
||||
break;
|
||||
case QProcess::Starting:
|
||||
emit runningChanged(true);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void SyncthingLauncher::handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
emit runningChanged(false);
|
||||
emit exited(exitCode, exitStatus);
|
||||
}
|
||||
|
||||
|
@ -143,8 +168,10 @@ void SyncthingLauncher::runLibSyncthing(const LibSyncthing::RuntimeOptions &runt
|
|||
{
|
||||
#ifdef SYNCTHINGWIDGETS_USE_LIBSYNCTHING
|
||||
LibSyncthing::setLoggingCallback(bind(&SyncthingLauncher::handleLoggingCallback, this, _1, _2, _3));
|
||||
emit runningChanged(true);
|
||||
const auto exitCode = LibSyncthing::runSyncthing(runtimeOptions);
|
||||
emit exited(static_cast<int>(exitCode), exitCode == 0 ? QProcess::NormalExit : QProcess::CrashExit);
|
||||
emit runningChanged(false);
|
||||
#else
|
||||
CPP_UTILITIES_UNUSED(runtimeOptions)
|
||||
emit outputAvailable("libsyncthing support not enabled");
|
||||
|
@ -156,8 +183,10 @@ void SyncthingLauncher::runLibSyncthing(const std::vector<string> &arguments)
|
|||
{
|
||||
#ifdef SYNCTHINGWIDGETS_USE_LIBSYNCTHING
|
||||
LibSyncthing::setLoggingCallback(bind(&SyncthingLauncher::handleLoggingCallback, this, _1, _2, _3));
|
||||
emit runningChanged(true);
|
||||
const auto exitCode = LibSyncthing::runSyncthing(arguments);
|
||||
emit exited(static_cast<int>(exitCode), exitCode == 0 ? QProcess::NormalExit : QProcess::CrashExit);
|
||||
emit runningChanged(false);
|
||||
#else
|
||||
CPP_UTILITIES_UNUSED(arguments)
|
||||
emit outputAvailable("libsyncthing support not enabled");
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace LibSyncthing {
|
|||
struct RuntimeOptions;
|
||||
}
|
||||
|
||||
namespace Settings {
|
||||
struct Launcher;
|
||||
}
|
||||
|
||||
namespace Data {
|
||||
|
||||
class SYNCTHINGWIDGETS_EXPORT SyncthingLauncher : public QObject {
|
||||
|
@ -43,12 +47,14 @@ Q_SIGNALS:
|
|||
public Q_SLOTS:
|
||||
void setUseLibSyncthing(bool useLibSyncthing);
|
||||
void launch(const QString &program, const QStringList &arguments);
|
||||
void launch(const Settings::Launcher &launcherSettings);
|
||||
void launch(const LibSyncthing::RuntimeOptions &runtimeOptions);
|
||||
void terminate();
|
||||
void kill();
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleProcessReadyRead();
|
||||
void handleProcessStateChanged(QProcess::ProcessState newState);
|
||||
void handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void handleLoggingCallback(LibSyncthing::LogLevel, const char *message, std::size_t messageSize);
|
||||
void runLibSyncthing(const LibSyncthing::RuntimeOptions &runtimeOptions);
|
||||
|
|
|
@ -2,14 +2,6 @@
|
|||
<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>
|
||||
|
@ -29,9 +21,6 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="launcherFormWidget" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="leftMargin">
|
||||
<number>30</number>
|
||||
|
@ -75,6 +64,13 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showButtonCheckBox">
|
||||
<property name="text">
|
||||
<string>Show start/stop button on tray for local instance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="considerForReconnectCheckBox">
|
||||
<property name="text">
|
||||
|
@ -198,22 +194,6 @@
|
|||
<include location="../resources/syncthingwidgetsicons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>enabledCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>launcherFormWidget</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>142</x>
|
||||
<y>17</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>142</x>
|
||||
<y>65</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>enabledCheckBox</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
|
|
|
@ -74,9 +74,8 @@ std::vector<SyncthingProcess *> Launcher::allProcesses()
|
|||
void Launcher::autostart() const
|
||||
{
|
||||
auto *const launcher(SyncthingLauncher::mainInstance());
|
||||
// TODO: allow using libsyncthing
|
||||
if (enabled && !syncthingPath.isEmpty() && launcher) {
|
||||
launcher->launch(useLibSyncthing ? QString() : syncthingPath, SyncthingProcess::splitArguments(syncthingArgs));
|
||||
if (autostartEnabled && launcher) {
|
||||
launcher->launch(*this);
|
||||
}
|
||||
for (auto i = tools.cbegin(), end = tools.cend(); i != end; ++i) {
|
||||
const ToolParameter &toolParams = i.value();
|
||||
|
@ -95,6 +94,62 @@ void Launcher::terminate()
|
|||
QtGui::SyncthingKiller(allProcesses()).waitForFinished();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Applies the launcher settings to the specified \a connection considering the status of the main SyncthingLauncher instance.
|
||||
* \remarks
|
||||
* - Called by TrayWidget when the launcher settings have been changed.
|
||||
* - \a currentConnectionSettings might be nullptr.
|
||||
* - Currently this is only about the auto-reconnect interval and connecting instantly.
|
||||
* \returns Returns the launcher status with respect to the specified \a connection.
|
||||
*/
|
||||
Launcher::LauncherStatus Launcher::apply(
|
||||
Data::SyncthingConnection &connection, const SyncthingConnectionSettings *currentConnectionSettings, bool reconnectRequired) const
|
||||
{
|
||||
auto *const launcher(SyncthingLauncher::mainInstance());
|
||||
if (!launcher) {
|
||||
return LauncherStatus{};
|
||||
}
|
||||
const auto isRelevant = connection.isLocal();
|
||||
const auto isRunning = launcher->isRunning();
|
||||
const auto consideredForReconnect = considerForReconnect && isRelevant;
|
||||
|
||||
if (currentConnectionSettings && (!considerForReconnect || !isRelevant || isRunning)) {
|
||||
// ensure auto-reconnect is configured according to settings
|
||||
connection.setAutoReconnectInterval(currentConnectionSettings->reconnectInterval);
|
||||
} else {
|
||||
// disable auto-reconnect regardless of the overall settings
|
||||
connection.setAutoReconnectInterval(0);
|
||||
}
|
||||
|
||||
// connect instantly if service is running
|
||||
if (consideredForReconnect) {
|
||||
// give the service (which has just started) a few seconds to initialize
|
||||
constexpr auto minActiveTimeInSeconds(5);
|
||||
if (reconnectRequired) {
|
||||
connection.reconnectLater(minActiveTimeInSeconds * 1000);
|
||||
} else if (isRunning && !connection.isConnected()) {
|
||||
connection.connectLater(minActiveTimeInSeconds * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
return LauncherStatus{isRelevant, isRunning, consideredForReconnect, showButton && isRelevant};
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the launcher status with respect to the specified \a connection.
|
||||
*/
|
||||
Launcher::LauncherStatus Launcher::status(SyncthingConnection &connection) const
|
||||
{
|
||||
auto *const launcher(SyncthingLauncher::mainInstance());
|
||||
if (!launcher) {
|
||||
return LauncherStatus{};
|
||||
}
|
||||
const auto isRelevant = connection.isLocal();
|
||||
return LauncherStatus{
|
||||
isRelevant, launcher->isRunning(), considerForReconnect && isRelevant, showButton && isRelevant
|
||||
};
|
||||
}
|
||||
|
||||
Settings &values()
|
||||
{
|
||||
static Settings settings;
|
||||
|
@ -181,11 +236,12 @@ void restore()
|
|||
|
||||
settings.beginGroup(QStringLiteral("startup"));
|
||||
auto &launcher = v.launcher;
|
||||
launcher.enabled = settings.value(QStringLiteral("syncthingAutostart"), launcher.enabled).toBool();
|
||||
launcher.autostartEnabled = settings.value(QStringLiteral("syncthingAutostart"), launcher.autostartEnabled).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();
|
||||
launcher.showButton = settings.value(QStringLiteral("showLauncherButton"), launcher.showButton).toBool();
|
||||
settings.beginGroup(QStringLiteral("tools"));
|
||||
for (const QString &tool : settings.childGroups()) {
|
||||
settings.beginGroup(tool);
|
||||
|
@ -270,11 +326,12 @@ void save()
|
|||
|
||||
settings.beginGroup(QStringLiteral("startup"));
|
||||
const auto &launcher = v.launcher;
|
||||
settings.setValue(QStringLiteral("syncthingAutostart"), launcher.enabled);
|
||||
settings.setValue(QStringLiteral("syncthingAutostart"), launcher.autostartEnabled);
|
||||
settings.setValue(QStringLiteral("useLibSyncthing"), launcher.useLibSyncthing);
|
||||
settings.setValue(QStringLiteral("syncthingPath"), launcher.syncthingPath);
|
||||
settings.setValue(QStringLiteral("syncthingArgs"), launcher.syncthingArgs);
|
||||
settings.setValue(QStringLiteral("considerLauncherForReconnect"), launcher.considerForReconnect);
|
||||
settings.setValue(QStringLiteral("showLauncherButton"), launcher.showButton);
|
||||
settings.beginGroup(QStringLiteral("tools"));
|
||||
for (auto i = launcher.tools.cbegin(), end = launcher.tools.cend(); i != end; ++i) {
|
||||
const ToolParameter &toolParams = i.value();
|
||||
|
@ -338,20 +395,21 @@ void Settings::apply(SyncthingNotifier ¬ifier) const
|
|||
/*!
|
||||
* \brief Applies the systemd settings to the specified \a connection considering the status of the global SyncthingService instance.
|
||||
* \remarks
|
||||
* - Called by SyncthingApplet and TrayWidget when the status of the SyncthingService changes.
|
||||
* - Called by SyncthingApplet and TrayWidget when the status of the SyncthingService changes or the systemd settings have been changed.
|
||||
* - \a currentConnectionSettings might be nullptr.
|
||||
* - Currently this is only about the auto-reconnect interval and connecting instantly.
|
||||
* \returns Returns whether the service is relevant and running.
|
||||
* \returns Returns the service status with respect to the specified \a connection.
|
||||
*/
|
||||
std::tuple<bool, bool> Systemd::apply(
|
||||
Systemd::ServiceStatus Systemd::apply(
|
||||
Data::SyncthingConnection &connection, const SyncthingConnectionSettings *currentConnectionSettings, bool reconnectRequired) const
|
||||
{
|
||||
auto *const service(SyncthingService::mainInstance());
|
||||
if (!service) {
|
||||
return make_tuple(false, false);
|
||||
return ServiceStatus{};
|
||||
}
|
||||
const auto isRelevant = service->isSystemdAvailable() && connection.isLocal();
|
||||
const auto isRunning = service->isRunning();
|
||||
const auto consideredForReconnect = considerForReconnect && isRelevant;
|
||||
|
||||
if (currentConnectionSettings && (!considerForReconnect || !isRelevant || isRunning)) {
|
||||
// ensure auto-reconnect is configured according to settings
|
||||
|
@ -362,7 +420,7 @@ std::tuple<bool, bool> Systemd::apply(
|
|||
}
|
||||
|
||||
// connect instantly if service is running
|
||||
if (considerForReconnect && isRelevant) {
|
||||
if (consideredForReconnect) {
|
||||
constexpr auto minActiveTimeInSeconds(5);
|
||||
if (reconnectRequired) {
|
||||
if (service->isActiveWithoutSleepFor(minActiveTimeInSeconds)) {
|
||||
|
@ -379,11 +437,22 @@ std::tuple<bool, bool> Systemd::apply(
|
|||
connection.connectLater(minActiveTimeInSeconds * 1000);
|
||||
}
|
||||
}
|
||||
} else if (reconnectRequired) {
|
||||
connection.reconnect();
|
||||
}
|
||||
|
||||
return make_tuple(isRelevant, isRunning);
|
||||
return ServiceStatus{isRelevant, isRunning, consideredForReconnect, showButton && isRelevant};
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the service status with respect to the specified \a connection.
|
||||
*/
|
||||
Systemd::ServiceStatus Systemd::status(SyncthingConnection &connection) const
|
||||
{
|
||||
auto *const service(SyncthingService::mainInstance());
|
||||
if (!service) {
|
||||
return ServiceStatus{};
|
||||
}
|
||||
const auto isRelevant = service->isSystemdAvailable() && connection.isLocal();
|
||||
return ServiceStatus{isRelevant, service->isRunning(), considerForReconnect && isRelevant, showButton && isRelevant};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ struct SYNCTHINGWIDGETS_EXPORT Connection {
|
|||
struct SYNCTHINGWIDGETS_EXPORT NotifyOn {
|
||||
bool disconnect = true;
|
||||
bool internalErrors = true;
|
||||
bool launcherErrors = true;
|
||||
bool localSyncComplete = false;
|
||||
bool remoteSyncComplete = false;
|
||||
bool syncthingErrors = true;
|
||||
|
@ -59,7 +60,7 @@ struct SYNCTHINGWIDGETS_EXPORT ToolParameter {
|
|||
};
|
||||
|
||||
struct SYNCTHINGWIDGETS_EXPORT Launcher {
|
||||
bool enabled = false;
|
||||
bool autostartEnabled = false;
|
||||
bool useLibSyncthing = false;
|
||||
QString syncthingPath =
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
|
@ -70,10 +71,21 @@ struct SYNCTHINGWIDGETS_EXPORT Launcher {
|
|||
QString syncthingArgs = QStringLiteral("-no-browser -no-restart -logflags=3");
|
||||
QHash<QString, ToolParameter> tools;
|
||||
bool considerForReconnect = false;
|
||||
bool showButton = false;
|
||||
|
||||
static Data::SyncthingProcess &toolProcess(const QString &tool);
|
||||
static std::vector<Data::SyncthingProcess *> allProcesses();
|
||||
void autostart() const;
|
||||
static void terminate();
|
||||
struct LauncherStatus {
|
||||
bool relevant = false;
|
||||
bool running = false;
|
||||
bool consideredForReconnect = false;
|
||||
bool showStartStopButton = false;
|
||||
};
|
||||
LauncherStatus apply(Data::SyncthingConnection &connection, const Data::SyncthingConnectionSettings *currentConnectionSettings,
|
||||
bool preventReconnect = false) const;
|
||||
LauncherStatus status(Data::SyncthingConnection &connection) const;
|
||||
};
|
||||
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
|
@ -82,10 +94,15 @@ struct SYNCTHINGWIDGETS_EXPORT Systemd {
|
|||
bool showButton = false;
|
||||
bool considerForReconnect = false;
|
||||
|
||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||
std::tuple<bool, bool> apply(Data::SyncthingConnection &connection, const Data::SyncthingConnectionSettings *currentConnectionSettings,
|
||||
struct ServiceStatus {
|
||||
bool relevant = false;
|
||||
bool running = false;
|
||||
bool consideredForReconnect = false;
|
||||
bool showStartStopButton = false;
|
||||
};
|
||||
ServiceStatus apply(Data::SyncthingConnection &connection, const Data::SyncthingConnectionSettings *currentConnectionSettings,
|
||||
bool preventReconnect = false) const;
|
||||
#endif
|
||||
ServiceStatus status(Data::SyncthingConnection &connection) const;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -759,18 +759,20 @@ QWidget *LauncherOptionPage::setupWidget()
|
|||
auto *const widget = LauncherOptionPageBase::setupWidget();
|
||||
|
||||
// adjust labels to use name of additional tool instead of "Syncthing"
|
||||
if (!m_tool.isEmpty()) {
|
||||
const auto isSyncthing = m_tool.isEmpty();
|
||||
if (!isSyncthing) {
|
||||
widget->setWindowTitle(tr("%1-launcher").arg(m_tool));
|
||||
ui()->enabledCheckBox->setText(tr("Launch %1 when starting the tray icon").arg(m_tool));
|
||||
ui()->syncthingPathLabel->setText(tr("%1 executable").arg(m_tool));
|
||||
ui()->logLabel->setText(tr("%1 log (interleaved stdout/stderr)").arg(m_tool));
|
||||
|
||||
// hide "consider for reconnect" and "show start/stop button on tray" checkboxes for tools
|
||||
ui()->considerForReconnectCheckBox->setVisible(false);
|
||||
ui()->showButtonCheckBox->setVisible(false);
|
||||
}
|
||||
|
||||
// hide "consider for reconnect" checkbox for tools
|
||||
ui()->considerForReconnectCheckBox->setVisible(m_tool.isEmpty());
|
||||
|
||||
// add "restore to defaults" action for arguments
|
||||
if (m_tool.isEmpty()) {
|
||||
// add "restore to defaults" action for Syncthing arguments
|
||||
if (isSyncthing) {
|
||||
m_restoreArgsButton = new IconButton(ui()->argumentsLineEdit);
|
||||
m_restoreArgsButton->setPixmap(
|
||||
QIcon::fromTheme(QStringLiteral("edit-undo"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/edit-paste.svg"))).pixmap(16));
|
||||
|
@ -794,6 +796,7 @@ QWidget *LauncherOptionPage::setupWidget()
|
|||
&LauncherOptionPage::handleSyncthingExited, Qt::QueuedConnection);
|
||||
connect(m_process, &SyncthingProcess::errorOccurred, this, &LauncherOptionPage::handleSyncthingError, Qt::QueuedConnection);
|
||||
} else if (m_launcher) {
|
||||
connect(m_launcher, &SyncthingLauncher::runningChanged, this, &LauncherOptionPage::handleSyncthingLaunched);
|
||||
connect(m_launcher, &SyncthingLauncher::outputAvailable, this, &LauncherOptionPage::handleSyncthingOutputAvailable, Qt::QueuedConnection);
|
||||
connect(m_launcher, &SyncthingLauncher::exited, this, &LauncherOptionPage::handleSyncthingExited, Qt::QueuedConnection);
|
||||
connect(m_launcher, &SyncthingLauncher::errorOccurred, this, &LauncherOptionPage::handleSyncthingError, Qt::QueuedConnection);
|
||||
|
@ -808,11 +811,12 @@ bool LauncherOptionPage::apply()
|
|||
{
|
||||
auto &settings = values().launcher;
|
||||
if (m_tool.isEmpty()) {
|
||||
settings.enabled = ui()->enabledCheckBox->isChecked();
|
||||
settings.autostartEnabled = ui()->enabledCheckBox->isChecked();
|
||||
settings.useLibSyncthing = ui()->useBuiltInVersionCheckBox->isChecked();
|
||||
settings.syncthingPath = ui()->syncthingPathSelection->lineEdit()->text();
|
||||
settings.syncthingArgs = ui()->argumentsLineEdit->text();
|
||||
settings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
||||
settings.showButton = ui()->showButtonCheckBox->isChecked();
|
||||
} else {
|
||||
ToolParameter ¶ms = settings.tools[m_tool];
|
||||
params.autostart = ui()->enabledCheckBox->isChecked();
|
||||
|
@ -826,12 +830,13 @@ void LauncherOptionPage::reset()
|
|||
{
|
||||
const auto &settings = values().launcher;
|
||||
if (m_tool.isEmpty()) {
|
||||
ui()->enabledCheckBox->setChecked(settings.enabled);
|
||||
ui()->enabledCheckBox->setChecked(settings.autostartEnabled);
|
||||
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);
|
||||
ui()->showButtonCheckBox->setChecked(settings.showButton);
|
||||
} else {
|
||||
const ToolParameter params = settings.tools.value(m_tool);
|
||||
ui()->useBuiltInVersionCheckBox->setChecked(false);
|
||||
|
@ -842,6 +847,17 @@ void LauncherOptionPage::reset()
|
|||
}
|
||||
}
|
||||
|
||||
void LauncherOptionPage::handleSyncthingLaunched(bool running)
|
||||
{
|
||||
if (!running) {
|
||||
return; // Syncthing being stopped is handled elsewhere
|
||||
}
|
||||
ui()->launchNowPushButton->hide();
|
||||
ui()->stopPushButton->show();
|
||||
ui()->stopPushButton->setText(tr("Stop launched instance"));
|
||||
m_kill = false;
|
||||
}
|
||||
|
||||
void LauncherOptionPage::handleSyncthingReadyRead()
|
||||
{
|
||||
handleSyncthingOutputAvailable(m_process->readAll());
|
||||
|
@ -943,10 +959,6 @@ void LauncherOptionPage::launch()
|
|||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
ui()->launchNowPushButton->hide();
|
||||
ui()->stopPushButton->show();
|
||||
ui()->stopPushButton->setText(tr("Stop launched instance"));
|
||||
m_kill = false;
|
||||
const auto launcherSettings(values().launcher);
|
||||
if (m_tool.isEmpty()) {
|
||||
m_launcher->launch(launcherSettings.useLibSyncthing ? QString() : launcherSettings.syncthingPath,
|
||||
|
@ -954,6 +966,7 @@ void LauncherOptionPage::launch()
|
|||
} else {
|
||||
const auto toolParams(launcherSettings.tools.value(m_tool));
|
||||
m_process->startSyncthing(toolParams.path, SyncthingProcess::splitArguments(toolParams.args));
|
||||
handleSyncthingLaunched(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1018,11 +1031,22 @@ QWidget *SystemdOptionPage::setupWidget()
|
|||
|
||||
bool SystemdOptionPage::apply()
|
||||
{
|
||||
auto &settings = values().systemd;
|
||||
settings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
|
||||
settings.showButton = ui()->showButtonCheckBox->isChecked();
|
||||
settings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
||||
return true;
|
||||
auto &settings = values();
|
||||
auto &systemdSettings = settings.systemd;
|
||||
auto &launcherSettings = settings.launcher;
|
||||
systemdSettings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
|
||||
systemdSettings.showButton = ui()->showButtonCheckBox->isChecked();
|
||||
systemdSettings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
||||
auto result = true;
|
||||
if (systemdSettings.showButton && launcherSettings.showButton) {
|
||||
errors().append(QCoreApplication::translate("QtGui::SystemdOptionPage", "It is not possible to show the start/stop button for the systemd service and the internal launcher at the same time. The systemd service precedes."));
|
||||
result = false;
|
||||
}
|
||||
if (systemdSettings.considerForReconnect && launcherSettings.considerForReconnect) {
|
||||
errors().append(QCoreApplication::translate("QtGui::SystemdOptionPage", "It is not possible to consider the systemd service and the internal launcher for reconnects at the same time. The systemd service precedes."));
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SystemdOptionPage::reset()
|
||||
|
|
|
@ -106,6 +106,7 @@ public:
|
|||
void reset() override;
|
||||
|
||||
private slots:
|
||||
void handleSyncthingLaunched(bool running);
|
||||
void handleSyncthingReadyRead();
|
||||
void handleSyncthingOutputAvailable(const QByteArray &output);
|
||||
void handleSyncthingExited(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
|
Loading…
Reference in New Issue