Overhaul systemd integration, support system-wide units
* Lazy initialize systemd interface and don't initialize it at all if the unit name is empty * Allow to supervise/control system-wide units in addition to user units (see https://github.com/Martchus/syncthingtray/issues/61) * Avoid redundant code
This commit is contained in:
parent
131050b275
commit
32f78b74fd
|
@ -58,7 +58,8 @@ constexpr DateTime dateTimeFromSystemdTimeStamp(qulonglong timeStamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncthingService *SyncthingService::s_mainInstance = nullptr;
|
SyncthingService *SyncthingService::s_mainInstance = nullptr;
|
||||||
OrgFreedesktopSystemd1ManagerInterface *SyncthingService::s_manager = nullptr;
|
OrgFreedesktopSystemd1ManagerInterface *SyncthingService::s_systemdUserInterface = nullptr;
|
||||||
|
OrgFreedesktopSystemd1ManagerInterface *SyncthingService::s_systemdSystemInterface = nullptr;
|
||||||
OrgFreedesktopLogin1ManagerInterface *SyncthingService::s_loginManager = nullptr;
|
OrgFreedesktopLogin1ManagerInterface *SyncthingService::s_loginManager = nullptr;
|
||||||
DateTime SyncthingService::s_lastWakeUp = DateTime();
|
DateTime SyncthingService::s_lastWakeUp = DateTime();
|
||||||
bool SyncthingService::s_fallingAsleep = false;
|
bool SyncthingService::s_fallingAsleep = false;
|
||||||
|
@ -68,37 +69,19 @@ bool SyncthingService::s_fallingAsleep = false;
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates a new SyncthingService instance.
|
* \brief Creates a new SyncthingService instance.
|
||||||
*/
|
*/
|
||||||
SyncthingService::SyncthingService(QObject *parent)
|
SyncthingService::SyncthingService(SystemdScope scope, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_unit(nullptr)
|
, m_unit(nullptr)
|
||||||
, m_service(nullptr)
|
, m_service(nullptr)
|
||||||
, m_properties(nullptr)
|
, m_properties(nullptr)
|
||||||
|
, m_currentSystemdInterface(nullptr)
|
||||||
|
, m_scope(scope)
|
||||||
, m_manuallyStopped(false)
|
, m_manuallyStopped(false)
|
||||||
, m_unitAvailable(false)
|
, m_unitAvailable(false)
|
||||||
{
|
{
|
||||||
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
setupFreedesktopLoginInterface();
|
||||||
if (!s_manager) {
|
|
||||||
// register custom data types
|
|
||||||
qDBusRegisterMetaType<ManagerDBusUnitFileChange>();
|
|
||||||
qDBusRegisterMetaType<ManagerDBusUnitFileChangeList>();
|
|
||||||
|
|
||||||
s_manager = new OrgFreedesktopSystemd1ManagerInterface(
|
#ifdef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
QStringLiteral("org.freedesktop.systemd1"), QStringLiteral("/org/freedesktop/systemd1"), QDBusConnection::sessionBus());
|
|
||||||
|
|
||||||
// enable systemd to emit signals
|
|
||||||
s_manager->Subscribe();
|
|
||||||
}
|
|
||||||
if (!s_loginManager) {
|
|
||||||
s_loginManager = new OrgFreedesktopLogin1ManagerInterface(
|
|
||||||
QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), QDBusConnection::systemBus());
|
|
||||||
connect(s_loginManager, &OrgFreedesktopLogin1ManagerInterface::PrepareForSleep, &SyncthingService::handlePrepareForSleep);
|
|
||||||
}
|
|
||||||
connect(s_manager, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
|
|
||||||
connect(s_manager, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
|
|
||||||
m_serviceWatcher = new QDBusServiceWatcher(s_manager->service(), s_manager->connection());
|
|
||||||
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &SyncthingService::handleServiceRegisteredChanged);
|
|
||||||
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &SyncthingService::handleServiceRegisteredChanged);
|
|
||||||
#else
|
|
||||||
// let the mocked service initially be stopped and simulate start after 5 seconds, then stop after 10 seconds and start after 15 seconds
|
// let the mocked service initially be stopped and simulate start after 5 seconds, then stop after 10 seconds and start after 15 seconds
|
||||||
QTimer::singleShot(5000, this, [this] {
|
QTimer::singleShot(5000, this, [this] {
|
||||||
m_activeSince = DateTime::gmtNow() - TimeSpan::fromMilliseconds(250);
|
m_activeSince = DateTime::gmtNow() - TimeSpan::fromMilliseconds(250);
|
||||||
|
@ -124,6 +107,147 @@ SyncthingService::SyncthingService(QObject *parent)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes m_currentSystemdInterface and its connection and service watcher for the current m_scope.
|
||||||
|
*/
|
||||||
|
void SyncthingService::setupSystemdInterface()
|
||||||
|
{
|
||||||
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
|
clearSystemdInterface();
|
||||||
|
|
||||||
|
// ensure the static systemd interface for the current scope is initialized
|
||||||
|
const auto isUserScope = m_scope == SystemdScope::User;
|
||||||
|
OrgFreedesktopSystemd1ManagerInterface *&staticSystemdInterface
|
||||||
|
= isUserScope ? s_systemdUserInterface : s_systemdSystemInterface;
|
||||||
|
if (!staticSystemdInterface) {
|
||||||
|
// register custom data types
|
||||||
|
qDBusRegisterMetaType<ManagerDBusUnitFileChange>();
|
||||||
|
qDBusRegisterMetaType<ManagerDBusUnitFileChangeList>();
|
||||||
|
|
||||||
|
staticSystemdInterface = new OrgFreedesktopSystemd1ManagerInterface(
|
||||||
|
QStringLiteral("org.freedesktop.systemd1"), QStringLiteral("/org/freedesktop/systemd1"), isUserScope ? QDBusConnection::sessionBus() : QDBusConnection::systemBus());
|
||||||
|
|
||||||
|
// enable systemd to emit signals
|
||||||
|
staticSystemdInterface->Subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the static systemd interface for the current scope
|
||||||
|
m_currentSystemdInterface = staticSystemdInterface;
|
||||||
|
connect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
|
||||||
|
connect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
|
||||||
|
m_serviceWatcher = new QDBusServiceWatcher(m_currentSystemdInterface->service(), m_currentSystemdInterface->connection());
|
||||||
|
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &SyncthingService::handleServiceRegisteredChanged);
|
||||||
|
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &SyncthingService::handleServiceRegisteredChanged);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes s_loginManager.
|
||||||
|
*/
|
||||||
|
void SyncthingService::setupFreedesktopLoginInterface()
|
||||||
|
{
|
||||||
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
|
// ensure the static login interface is initialized and use it
|
||||||
|
if (s_loginManager) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s_loginManager = new OrgFreedesktopLogin1ManagerInterface(
|
||||||
|
QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), QDBusConnection::systemBus());
|
||||||
|
connect(s_loginManager, &OrgFreedesktopLogin1ManagerInterface::PrepareForSleep, &SyncthingService::handlePrepareForSleep);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Registers the specified D-Bus \a call to invoke \a handler when it has been concluded.
|
||||||
|
*/
|
||||||
|
template<typename HandlerType>
|
||||||
|
void SyncthingService::makeAsyncCall(const QDBusPendingCall &call, HandlerType &&handler)
|
||||||
|
{
|
||||||
|
if (m_currentSystemdInterface) {
|
||||||
|
// disconnect from unit add/removed signals because these seem to be spammed when waiting for permissions
|
||||||
|
disconnect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
|
||||||
|
disconnect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
|
||||||
|
}
|
||||||
|
auto *const watcher = new QDBusPendingCallWatcher(call, this);
|
||||||
|
m_pendingCalls.emplace(watcher);
|
||||||
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Registers a generic error handler for the specifeid D-Bus \a call.
|
||||||
|
*/
|
||||||
|
void SyncthingService::registerErrorHandler(const QDBusPendingCall &call, const char *context)
|
||||||
|
{
|
||||||
|
makeAsyncCall(call, bind(&SyncthingService::handleError, this, context, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Determines whether the specified \a watcher is still relevant and ensures it is being deleted later.
|
||||||
|
*/
|
||||||
|
bool SyncthingService::concludeAsyncCall(QDBusPendingCallWatcher *watcher)
|
||||||
|
{
|
||||||
|
watcher->deleteLater();
|
||||||
|
|
||||||
|
const auto i = m_pendingCalls.find(watcher);
|
||||||
|
const auto resultStillRelevant = i != m_pendingCalls.cend();
|
||||||
|
if (resultStillRelevant) {
|
||||||
|
m_pendingCalls.erase(i);
|
||||||
|
}
|
||||||
|
if (m_currentSystemdInterface && m_pendingCalls.empty()) {
|
||||||
|
// ensure we listen to unit add/removed signals again if there are no pending calls anymore
|
||||||
|
connect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
|
||||||
|
connect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
|
||||||
|
}
|
||||||
|
return resultStillRelevant;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Unties the current instance from its current systemd interface.
|
||||||
|
*/
|
||||||
|
void Data::SyncthingService::clearSystemdInterface()
|
||||||
|
{
|
||||||
|
m_pendingCalls.clear();
|
||||||
|
if (m_currentSystemdInterface) {
|
||||||
|
disconnect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitNew, this, &SyncthingService::handleUnitAdded);
|
||||||
|
disconnect(m_currentSystemdInterface, &OrgFreedesktopSystemd1ManagerInterface::UnitRemoved, this, &SyncthingService::handleUnitRemoved);
|
||||||
|
delete m_serviceWatcher;
|
||||||
|
m_currentSystemdInterface = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears everything we know about the systemd unit.
|
||||||
|
*/
|
||||||
|
void SyncthingService::clearUnitData()
|
||||||
|
{
|
||||||
|
// clean up data from previous unit
|
||||||
|
delete m_service;
|
||||||
|
m_service = nullptr;
|
||||||
|
delete m_unit;
|
||||||
|
m_unit = nullptr;
|
||||||
|
delete m_properties;
|
||||||
|
m_properties = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Queries m_unit from m_currentSystemdInterface.
|
||||||
|
*/
|
||||||
|
void Data::SyncthingService::queryUnitFromSystemdInterface()
|
||||||
|
{
|
||||||
|
clearUnitData();
|
||||||
|
setProperties(false, QString(), QString(), QString(), QString());
|
||||||
|
|
||||||
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
|
if (!m_currentSystemdInterface) {
|
||||||
|
setupSystemdInterface();
|
||||||
|
}
|
||||||
|
if (!m_currentSystemdInterface->isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
makeAsyncCall(m_currentSystemdInterface->GetUnit(m_unitName), &SyncthingService::handleUnitGet);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the \a unitName of the systemd user service to be controlled/monitored, e.g. "syncthing.service".
|
* \brief Sets the \a unitName of the systemd user service to be controlled/monitored, e.g. "syncthing.service".
|
||||||
*/
|
*/
|
||||||
|
@ -134,20 +258,37 @@ void SyncthingService::setUnitName(const QString &unitName)
|
||||||
}
|
}
|
||||||
m_unitName = unitName;
|
m_unitName = unitName;
|
||||||
|
|
||||||
delete m_service, delete m_unit, delete m_properties;
|
if (!m_unitName.isEmpty()) {
|
||||||
m_service = nullptr, m_unit = nullptr, m_properties = nullptr;
|
queryUnitFromSystemdInterface();
|
||||||
setProperties(false, QString(), QString(), QString(), QString());
|
|
||||||
|
|
||||||
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
|
||||||
if (s_manager->isValid()) {
|
|
||||||
connect(new QDBusPendingCallWatcher(s_manager->GetUnit(m_unitName), this), &QDBusPendingCallWatcher::finished, this,
|
|
||||||
&SyncthingService::handleUnitGet);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
emit unitNameChanged(unitName);
|
emit unitNameChanged(unitName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the \a scope and \a unitName (see scope() and unitName()).
|
||||||
|
*/
|
||||||
|
void SyncthingService::setScopeAndUnitName(SystemdScope scope, const QString &unitName)
|
||||||
|
{
|
||||||
|
const auto scopeChanged = m_scope != scope;
|
||||||
|
const auto unitNameChanged = m_unitName != unitName;
|
||||||
|
if (!scopeChanged && !unitNameChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (scopeChanged) {
|
||||||
|
m_scope = scope;
|
||||||
|
clearSystemdInterface();
|
||||||
|
}
|
||||||
|
if (unitNameChanged) {
|
||||||
|
m_unitName = unitName;
|
||||||
|
}
|
||||||
|
if (!unitName.isEmpty()) {
|
||||||
|
queryUnitFromSystemdInterface();
|
||||||
|
}
|
||||||
|
if (unitNameChanged) {
|
||||||
|
emit this->unitNameChanged(unitName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether systemd (and specificly its D-Bus interface for user services) is available.
|
* \brief Returns whether systemd (and specificly its D-Bus interface for user services) is available.
|
||||||
* \remarks The availability might not be instantly detected and may change at any time. Use the systemdAvailableChanged()
|
* \remarks The availability might not be instantly detected and may change at any time. Use the systemdAvailableChanged()
|
||||||
|
@ -156,7 +297,7 @@ void SyncthingService::setUnitName(const QString &unitName)
|
||||||
bool SyncthingService::isSystemdAvailable() const
|
bool SyncthingService::isSystemdAvailable() const
|
||||||
{
|
{
|
||||||
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
return s_manager && s_manager->isValid();
|
return m_currentSystemdInterface && m_currentSystemdInterface->isValid();
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -194,6 +335,19 @@ bool SyncthingService::isActiveWithoutSleepFor(DateTime activeSince, unsigned in
|
||||||
return ((now - activeSince).totalSeconds() > atLeastSeconds) && (s_lastWakeUp.isNull() || ((now - s_lastWakeUp).totalSeconds() > atLeastSeconds));
|
return ((now - activeSince).totalSeconds() > atLeastSeconds) && (s_lastWakeUp.isNull() || ((now - s_lastWakeUp).totalSeconds() > atLeastSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the scope the current instance is tuned to.
|
||||||
|
*/
|
||||||
|
void SyncthingService::setScope(SystemdScope scope)
|
||||||
|
{
|
||||||
|
if (m_scope == scope) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_scope = scope;
|
||||||
|
clearSystemdInterface();
|
||||||
|
queryUnitFromSystemdInterface();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Starts the unit if \a running is true and stops the unit if \a running is false.
|
* \brief Starts the unit if \a running is true and stops the unit if \a running is false.
|
||||||
*/
|
*/
|
||||||
|
@ -201,10 +355,13 @@ void SyncthingService::setRunning(bool running)
|
||||||
{
|
{
|
||||||
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
m_manuallyStopped = !running;
|
m_manuallyStopped = !running;
|
||||||
|
if (!m_currentSystemdInterface) {
|
||||||
|
setupSystemdInterface();
|
||||||
|
}
|
||||||
if (running) {
|
if (running) {
|
||||||
registerErrorHandler(s_manager->StartUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("start unit"));
|
registerErrorHandler(m_currentSystemdInterface->StartUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("start unit"));
|
||||||
} else {
|
} else {
|
||||||
registerErrorHandler(s_manager->StopUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("stop unit"));
|
registerErrorHandler(m_currentSystemdInterface->StopUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("stop unit"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -215,10 +372,13 @@ void SyncthingService::setRunning(bool running)
|
||||||
void SyncthingService::setEnabled(bool enabled)
|
void SyncthingService::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
#ifndef LIB_SYNCTHING_CONNECTOR_SERVICE_MOCKED
|
||||||
|
if (!m_currentSystemdInterface) {
|
||||||
|
setupSystemdInterface();
|
||||||
|
}
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
registerErrorHandler(s_manager->EnableUnitFiles(QStringList(m_unitName), false, true), QT_TR_NOOP_UTF8("enable unit"));
|
registerErrorHandler(m_currentSystemdInterface->EnableUnitFiles(QStringList(m_unitName), false, true), QT_TR_NOOP_UTF8("enable unit"));
|
||||||
} else {
|
} else {
|
||||||
registerErrorHandler(s_manager->DisableUnitFiles(QStringList(m_unitName), false), QT_TR_NOOP_UTF8("disable unit"));
|
registerErrorHandler(m_currentSystemdInterface->DisableUnitFiles(QStringList(m_unitName), false), QT_TR_NOOP_UTF8("disable unit"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -249,13 +409,13 @@ void SyncthingService::handleUnitRemoved(const QString &unitName, const QDBusObj
|
||||||
*/
|
*/
|
||||||
void SyncthingService::handleUnitGet(QDBusPendingCallWatcher *watcher)
|
void SyncthingService::handleUnitGet(QDBusPendingCallWatcher *watcher)
|
||||||
{
|
{
|
||||||
watcher->deleteLater();
|
if (!concludeAsyncCall(watcher)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const QDBusPendingReply<QDBusObjectPath> unitReply = *watcher;
|
const QDBusPendingReply<QDBusObjectPath> unitReply = *watcher;
|
||||||
if (unitReply.isError()) {
|
if (unitReply.isError()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setUnit(unitReply.value());
|
setUnit(unitReply.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +467,9 @@ void SyncthingService::handlePropertiesChanged(
|
||||||
*/
|
*/
|
||||||
void SyncthingService::handleError(const char *context, QDBusPendingCallWatcher *watcher)
|
void SyncthingService::handleError(const char *context, QDBusPendingCallWatcher *watcher)
|
||||||
{
|
{
|
||||||
watcher->deleteLater();
|
if (!concludeAsyncCall(watcher)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const QDBusError error = watcher->error();
|
const QDBusError error = watcher->error();
|
||||||
if (error.isValid()) {
|
if (error.isValid()) {
|
||||||
emit errorOccurred(tr(context), error.name(), error.message());
|
emit errorOccurred(tr(context), error.name(), error.message());
|
||||||
|
@ -319,8 +481,8 @@ void SyncthingService::handleError(const char *context, QDBusPendingCallWatcher
|
||||||
*/
|
*/
|
||||||
void SyncthingService::handleServiceRegisteredChanged(const QString &service)
|
void SyncthingService::handleServiceRegisteredChanged(const QString &service)
|
||||||
{
|
{
|
||||||
if (service == s_manager->service()) {
|
if (m_currentSystemdInterface && service == m_currentSystemdInterface->service()) {
|
||||||
emit systemdAvailableChanged(s_manager->isValid());
|
emit systemdAvailableChanged(m_currentSystemdInterface->isValid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,36 +538,26 @@ bool SyncthingService::handlePropertyChanged(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Registers error handler for D-Bus errors.
|
|
||||||
*/
|
|
||||||
void SyncthingService::registerErrorHandler(const QDBusPendingCall &call, const char *context)
|
|
||||||
{
|
|
||||||
connect(new QDBusPendingCallWatcher(call, this), &QDBusPendingCallWatcher::finished, bind(&SyncthingService::handleError, this, context, _1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the current unit data.
|
* \brief Sets the current unit data.
|
||||||
*/
|
*/
|
||||||
void SyncthingService::setUnit(const QDBusObjectPath &objectPath)
|
void SyncthingService::setUnit(const QDBusObjectPath &objectPath)
|
||||||
{
|
{
|
||||||
// cleanup
|
clearUnitData();
|
||||||
delete m_service, delete m_unit, delete m_properties;
|
|
||||||
m_service = nullptr, m_unit = nullptr, m_properties = nullptr;
|
|
||||||
|
|
||||||
const QString path = objectPath.path();
|
const QString path = objectPath.path();
|
||||||
if (path.isEmpty()) {
|
if (!m_currentSystemdInterface || path.isEmpty()) {
|
||||||
setProperties(false, QString(), QString(), QString(), QString());
|
setProperties(false, QString(), QString(), QString(), QString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init unit
|
// init unit
|
||||||
m_unit = new OrgFreedesktopSystemd1UnitInterface(s_manager->service(), path, s_manager->connection());
|
m_unit = new OrgFreedesktopSystemd1UnitInterface(m_currentSystemdInterface->service(), path, m_currentSystemdInterface->connection());
|
||||||
m_activeSince = dateTimeFromSystemdTimeStamp(m_unit->activeEnterTimestamp());
|
m_activeSince = dateTimeFromSystemdTimeStamp(m_unit->activeEnterTimestamp());
|
||||||
setProperties(m_unit->isValid(), m_unit->activeState(), m_unit->subState(), m_unit->unitFileState(), m_unit->description());
|
setProperties(m_unit->isValid(), m_unit->activeState(), m_unit->subState(), m_unit->unitFileState(), m_unit->description());
|
||||||
|
|
||||||
// init properties
|
// init properties
|
||||||
m_properties = new OrgFreedesktopDBusPropertiesInterface(s_manager->service(), path, s_manager->connection());
|
m_properties = new OrgFreedesktopDBusPropertiesInterface(m_currentSystemdInterface->service(), path, m_currentSystemdInterface->connection());
|
||||||
connect(m_properties, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged, this, &SyncthingService::handlePropertiesChanged);
|
connect(m_properties, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged, this, &SyncthingService::handlePropertiesChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +595,6 @@ void SyncthingService::setProperties(
|
||||||
if (enabled != isEnabled()) {
|
if (enabled != isEnabled()) {
|
||||||
emit enabledChanged(isEnabled());
|
emit enabledChanged(isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_description != description) {
|
if (m_description != description) {
|
||||||
emit descriptionChanged(m_description = description);
|
emit descriptionChanged(m_description = description);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QDBusServiceWatcher)
|
QT_FORWARD_DECLARE_CLASS(QDBusServiceWatcher)
|
||||||
QT_FORWARD_DECLARE_CLASS(QDBusArgument)
|
QT_FORWARD_DECLARE_CLASS(QDBusArgument)
|
||||||
QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
|
QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
|
||||||
|
@ -31,6 +33,8 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, ManagerDBusUnitFi
|
||||||
|
|
||||||
typedef QList<ManagerDBusUnitFileChange> ManagerDBusUnitFileChangeList;
|
typedef QList<ManagerDBusUnitFileChange> ManagerDBusUnitFileChangeList;
|
||||||
|
|
||||||
|
enum class SystemdScope { System, User };
|
||||||
|
|
||||||
class SyncthingService : public QObject {
|
class SyncthingService : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString unitName READ unitName WRITE setUnitName NOTIFY unitNameChanged)
|
Q_PROPERTY(QString unitName READ unitName WRITE setUnitName NOTIFY unitNameChanged)
|
||||||
|
@ -44,9 +48,10 @@ class SyncthingService : public QObject {
|
||||||
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
|
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
|
||||||
Q_PROPERTY(bool enable READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
|
Q_PROPERTY(bool enable READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
|
||||||
Q_PROPERTY(bool manuallyStopped READ isManuallyStopped)
|
Q_PROPERTY(bool manuallyStopped READ isManuallyStopped)
|
||||||
|
Q_PROPERTY(SystemdScope scope READ scope WRITE setScope)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SyncthingService(QObject *parent = nullptr);
|
explicit SyncthingService(SystemdScope scope = SystemdScope::User, QObject *parent = nullptr);
|
||||||
|
|
||||||
const QString &unitName() const;
|
const QString &unitName() const;
|
||||||
bool isSystemdAvailable() const;
|
bool isSystemdAvailable() const;
|
||||||
|
@ -63,6 +68,9 @@ public:
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
bool isManuallyStopped() const;
|
bool isManuallyStopped() const;
|
||||||
|
SystemdScope scope() const;
|
||||||
|
void setScope(SystemdScope scope);
|
||||||
|
void setScopeAndUnitName(SystemdScope scope, const QString &unitName);
|
||||||
static SyncthingService *mainInstance();
|
static SyncthingService *mainInstance();
|
||||||
static void setMainInstance(SyncthingService *mainInstance);
|
static void setMainInstance(SyncthingService *mainInstance);
|
||||||
|
|
||||||
|
@ -102,13 +110,22 @@ private Q_SLOTS:
|
||||||
bool unitAvailable, const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description);
|
bool unitAvailable, const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setupSystemdInterface();
|
||||||
|
void setupFreedesktopLoginInterface();
|
||||||
|
template<typename HandlerType>
|
||||||
|
void makeAsyncCall(const QDBusPendingCall &call, HandlerType &&handler);
|
||||||
|
void registerErrorHandler(const QDBusPendingCall &call, const char *context);
|
||||||
|
bool concludeAsyncCall(QDBusPendingCallWatcher *watcher);
|
||||||
|
void clearSystemdInterface();
|
||||||
|
void clearUnitData();
|
||||||
|
void queryUnitFromSystemdInterface();
|
||||||
bool handlePropertyChanged(QString &variable, void (SyncthingService::*signal)(const QString &), const QString &propertyName,
|
bool handlePropertyChanged(QString &variable, void (SyncthingService::*signal)(const QString &), const QString &propertyName,
|
||||||
const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
|
const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
|
||||||
bool handlePropertyChanged(CppUtilities::DateTime &variable, const QString &propertyName, const QVariantMap &changedProperties,
|
bool handlePropertyChanged(CppUtilities::DateTime &variable, const QString &propertyName, const QVariantMap &changedProperties,
|
||||||
const QStringList &invalidatedProperties);
|
const QStringList &invalidatedProperties);
|
||||||
void registerErrorHandler(const QDBusPendingCall &call, const char *context);
|
|
||||||
|
|
||||||
static OrgFreedesktopSystemd1ManagerInterface *s_manager;
|
static OrgFreedesktopSystemd1ManagerInterface *s_systemdUserInterface;
|
||||||
|
static OrgFreedesktopSystemd1ManagerInterface *s_systemdSystemInterface;
|
||||||
static OrgFreedesktopLogin1ManagerInterface *s_loginManager;
|
static OrgFreedesktopLogin1ManagerInterface *s_loginManager;
|
||||||
static bool s_fallingAsleep;
|
static bool s_fallingAsleep;
|
||||||
static CppUtilities::DateTime s_lastWakeUp;
|
static CppUtilities::DateTime s_lastWakeUp;
|
||||||
|
@ -123,6 +140,9 @@ private:
|
||||||
QString m_subState;
|
QString m_subState;
|
||||||
QString m_unitFileState;
|
QString m_unitFileState;
|
||||||
CppUtilities::DateTime m_activeSince;
|
CppUtilities::DateTime m_activeSince;
|
||||||
|
OrgFreedesktopSystemd1ManagerInterface *m_currentSystemdInterface;
|
||||||
|
std::unordered_set<QDBusPendingCallWatcher *> m_pendingCalls;
|
||||||
|
SystemdScope m_scope;
|
||||||
bool m_manuallyStopped;
|
bool m_manuallyStopped;
|
||||||
bool m_unitAvailable;
|
bool m_unitAvailable;
|
||||||
};
|
};
|
||||||
|
@ -221,6 +241,14 @@ inline bool SyncthingService::isManuallyStopped() const
|
||||||
return m_manuallyStopped;
|
return m_manuallyStopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the scope the current instance is tuned to.
|
||||||
|
*/
|
||||||
|
inline SystemdScope SyncthingService::scope() const
|
||||||
|
{
|
||||||
|
return m_scope;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns since when the unit is active.
|
* \brief Returns since when the unit is active.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -111,7 +111,7 @@ void SyncthingApplet::init()
|
||||||
// initialize systemd service support
|
// initialize systemd service support
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
SyncthingService::setMainInstance(&m_service);
|
SyncthingService::setMainInstance(&m_service);
|
||||||
m_service.setUnitName(Settings::values().systemd.syncthingUnit);
|
Settings::values().systemd.setupService(m_service);
|
||||||
connect(&m_service, &SyncthingService::systemdAvailableChanged, this, &SyncthingApplet::handleSystemdStatusChanged);
|
connect(&m_service, &SyncthingService::systemdAvailableChanged, this, &SyncthingApplet::handleSystemdStatusChanged);
|
||||||
connect(&m_service, &SyncthingService::stateChanged, this, &SyncthingApplet::handleSystemdStatusChanged);
|
connect(&m_service, &SyncthingService::stateChanged, this, &SyncthingApplet::handleSystemdStatusChanged);
|
||||||
connect(&m_service, &SyncthingService::errorOccurred, this, &SyncthingApplet::handleSystemdServiceError);
|
connect(&m_service, &SyncthingService::errorOccurred, this, &SyncthingApplet::handleSystemdServiceError);
|
||||||
|
|
|
@ -40,11 +40,12 @@ ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
void handleSystemdServiceError(const QString &context, const QString &name, const QString &message)
|
void handleSystemdServiceError(const QString &context, const QString &name, const QString &message)
|
||||||
{
|
{
|
||||||
QMessageBox msgBox;
|
auto *const msgBox = new QMessageBox;
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
msgBox.setText(QCoreApplication::translate("main", "Unable to ") + context);
|
msgBox->setIcon(QMessageBox::Critical);
|
||||||
msgBox.setInformativeText(name % QStringLiteral(":\n") % message);
|
msgBox->setText(QCoreApplication::translate("main", "Unable to ") + context);
|
||||||
msgBox.exec();
|
msgBox->setInformativeText(name % QStringLiteral(":\n") % message);
|
||||||
|
msgBox->show();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -175,7 +176,7 @@ int runApplication(int argc, const char *const *argv)
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
SyncthingService service;
|
SyncthingService service;
|
||||||
SyncthingService::setMainInstance(&service);
|
SyncthingService::setMainInstance(&service);
|
||||||
service.setUnitName(Settings::values().systemd.syncthingUnit);
|
Settings::values().systemd.setupService(service);
|
||||||
QObject::connect(&service, &SyncthingService::errorOccurred, &handleSystemdServiceError);
|
QObject::connect(&service, &SyncthingService::errorOccurred, &handleSystemdServiceError);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,7 @@ void restore()
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
auto &systemd = v.systemd;
|
auto &systemd = v.systemd;
|
||||||
systemd.syncthingUnit = settings.value(QStringLiteral("syncthingUnit"), systemd.syncthingUnit).toString();
|
systemd.syncthingUnit = settings.value(QStringLiteral("syncthingUnit"), systemd.syncthingUnit).toString();
|
||||||
|
systemd.systemUnit = settings.value(QStringLiteral("systemUnit"), systemd.systemUnit).toBool();
|
||||||
systemd.showButton = settings.value(QStringLiteral("showButton"), systemd.showButton).toBool();
|
systemd.showButton = settings.value(QStringLiteral("showButton"), systemd.showButton).toBool();
|
||||||
systemd.considerForReconnect = settings.value(QStringLiteral("considerForReconnect"), systemd.considerForReconnect).toBool();
|
systemd.considerForReconnect = settings.value(QStringLiteral("considerForReconnect"), systemd.considerForReconnect).toBool();
|
||||||
#endif
|
#endif
|
||||||
|
@ -388,6 +389,7 @@ void save()
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
const auto &systemd = v.systemd;
|
const auto &systemd = v.systemd;
|
||||||
settings.setValue(QStringLiteral("syncthingUnit"), systemd.syncthingUnit);
|
settings.setValue(QStringLiteral("syncthingUnit"), systemd.syncthingUnit);
|
||||||
|
settings.setValue(QStringLiteral("systemUnit"), systemd.systemUnit);
|
||||||
settings.setValue(QStringLiteral("showButton"), systemd.showButton);
|
settings.setValue(QStringLiteral("showButton"), systemd.showButton);
|
||||||
settings.setValue(QStringLiteral("considerForReconnect"), systemd.considerForReconnect);
|
settings.setValue(QStringLiteral("considerForReconnect"), systemd.considerForReconnect);
|
||||||
#endif
|
#endif
|
||||||
|
@ -435,6 +437,14 @@ void Settings::apply(SyncthingNotifier ¬ifier) const
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
|
/*!
|
||||||
|
* \brief Sets the scope and unit name of the specified \a service according to the settings.
|
||||||
|
*/
|
||||||
|
void Systemd::setupService(SyncthingService &service) const
|
||||||
|
{
|
||||||
|
service.setScopeAndUnitName(systemUnit ? SystemdScope::System : SystemdScope::User, syncthingUnit);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Applies the systemd settings to the specified \a connection considering the status of the global SyncthingService instance.
|
* \brief Applies the systemd settings to the specified \a connection considering the status of the global SyncthingService instance.
|
||||||
* \remarks
|
* \remarks
|
||||||
|
@ -497,7 +507,6 @@ Systemd::ServiceStatus Systemd::status(SyncthingConnection &connection) const
|
||||||
const auto isRelevant = service->isSystemdAvailable() && connection.isLocal();
|
const auto isRelevant = service->isSystemdAvailable() && connection.isLocal();
|
||||||
return ServiceStatus{ isRelevant, service->isRunning(), considerForReconnect && isRelevant, showButton && isRelevant };
|
return ServiceStatus{ isRelevant, service->isRunning(), considerForReconnect && isRelevant, showButton && isRelevant };
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Data {
|
||||||
class SyncthingProcess;
|
class SyncthingProcess;
|
||||||
class SyncthingNotifier;
|
class SyncthingNotifier;
|
||||||
class SyncthingConnection;
|
class SyncthingConnection;
|
||||||
|
class SyncthingService;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
@ -101,6 +102,7 @@ struct SYNCTHINGWIDGETS_EXPORT Launcher {
|
||||||
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
|
||||||
struct SYNCTHINGWIDGETS_EXPORT Systemd {
|
struct SYNCTHINGWIDGETS_EXPORT Systemd {
|
||||||
QString syncthingUnit = QStringLiteral("syncthing.service");
|
QString syncthingUnit = QStringLiteral("syncthing.service");
|
||||||
|
bool systemUnit = false;
|
||||||
bool showButton = false;
|
bool showButton = false;
|
||||||
bool considerForReconnect = false;
|
bool considerForReconnect = false;
|
||||||
|
|
||||||
|
@ -110,6 +112,7 @@ struct SYNCTHINGWIDGETS_EXPORT Systemd {
|
||||||
bool consideredForReconnect = false;
|
bool consideredForReconnect = false;
|
||||||
bool showStartStopButton = false;
|
bool showStartStopButton = false;
|
||||||
};
|
};
|
||||||
|
void setupService(Data::SyncthingService &) const;
|
||||||
ServiceStatus apply(Data::SyncthingConnection &connection, const Data::SyncthingConnectionSettings *currentConnectionSettings,
|
ServiceStatus apply(Data::SyncthingConnection &connection, const Data::SyncthingConnectionSettings *currentConnectionSettings,
|
||||||
bool preventReconnect = false) const;
|
bool preventReconnect = false) const;
|
||||||
ServiceStatus status(Data::SyncthingConnection &connection) const;
|
ServiceStatus status(Data::SyncthingConnection &connection) const;
|
||||||
|
|
|
@ -1129,6 +1129,7 @@ QWidget *SystemdOptionPage::setupWidget()
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
QObject::connect(ui()->syncthingUnitLineEdit, &QLineEdit::textChanged, m_service, &SyncthingService::setUnitName);
|
QObject::connect(ui()->syncthingUnitLineEdit, &QLineEdit::textChanged, m_service, &SyncthingService::setUnitName);
|
||||||
|
QObject::connect(ui()->systemUnitCheckBox, &QCheckBox::clicked, m_service, bind(&SystemdOptionPage::handleSystemUnitChanged, this));
|
||||||
QObject::connect(ui()->startPushButton, &QPushButton::clicked, m_service, &SyncthingService::start);
|
QObject::connect(ui()->startPushButton, &QPushButton::clicked, m_service, &SyncthingService::start);
|
||||||
QObject::connect(ui()->stopPushButton, &QPushButton::clicked, m_service, &SyncthingService::stop);
|
QObject::connect(ui()->stopPushButton, &QPushButton::clicked, m_service, &SyncthingService::stop);
|
||||||
QObject::connect(ui()->enablePushButton, &QPushButton::clicked, m_service, &SyncthingService::enable);
|
QObject::connect(ui()->enablePushButton, &QPushButton::clicked, m_service, &SyncthingService::enable);
|
||||||
|
@ -1145,6 +1146,7 @@ bool SystemdOptionPage::apply()
|
||||||
auto &systemdSettings = settings.systemd;
|
auto &systemdSettings = settings.systemd;
|
||||||
auto &launcherSettings = settings.launcher;
|
auto &launcherSettings = settings.launcher;
|
||||||
systemdSettings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
|
systemdSettings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
|
||||||
|
systemdSettings.systemUnit = ui()->systemUnitCheckBox->isChecked();
|
||||||
systemdSettings.showButton = ui()->showButtonCheckBox->isChecked();
|
systemdSettings.showButton = ui()->showButtonCheckBox->isChecked();
|
||||||
systemdSettings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
systemdSettings.considerForReconnect = ui()->considerForReconnectCheckBox->isChecked();
|
||||||
auto result = true;
|
auto result = true;
|
||||||
|
@ -1167,6 +1169,7 @@ void SystemdOptionPage::reset()
|
||||||
{
|
{
|
||||||
const auto &settings = values().systemd;
|
const auto &settings = values().systemd;
|
||||||
ui()->syncthingUnitLineEdit->setText(settings.syncthingUnit);
|
ui()->syncthingUnitLineEdit->setText(settings.syncthingUnit);
|
||||||
|
ui()->systemUnitCheckBox->setChecked(settings.systemUnit);
|
||||||
ui()->showButtonCheckBox->setChecked(settings.showButton);
|
ui()->showButtonCheckBox->setChecked(settings.showButton);
|
||||||
ui()->considerForReconnectCheckBox->setChecked(settings.considerForReconnect);
|
ui()->considerForReconnectCheckBox->setChecked(settings.considerForReconnect);
|
||||||
if (!m_service) {
|
if (!m_service) {
|
||||||
|
@ -1177,6 +1180,11 @@ void SystemdOptionPage::reset()
|
||||||
handleEnabledChanged(m_service->unitFileState());
|
handleEnabledChanged(m_service->unitFileState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemdOptionPage::handleSystemUnitChanged()
|
||||||
|
{
|
||||||
|
m_service->setScope(ui()->systemUnitCheckBox->isChecked() ? SystemdScope::System : SystemdScope::User);
|
||||||
|
}
|
||||||
|
|
||||||
void SystemdOptionPage::handleDescriptionChanged(const QString &description)
|
void SystemdOptionPage::handleDescriptionChanged(const QString &description)
|
||||||
{
|
{
|
||||||
ui()->descriptionValueLabel->setText(description.isEmpty()
|
ui()->descriptionValueLabel->setText(description.isEmpty()
|
||||||
|
|
|
@ -134,6 +134,7 @@ private:
|
||||||
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SystemdOptionPage)
|
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SystemdOptionPage)
|
||||||
private:
|
private:
|
||||||
DECLARE_SETUP_WIDGETS
|
DECLARE_SETUP_WIDGETS
|
||||||
|
void handleSystemUnitChanged();
|
||||||
void handleDescriptionChanged(const QString &description);
|
void handleDescriptionChanged(const QString &description);
|
||||||
void handleStatusChanged(const QString &activeState, const QString &subState, CppUtilities::DateTime activeSince);
|
void handleStatusChanged(const QString &activeState, const QString &subState, CppUtilities::DateTime activeSince);
|
||||||
void handleEnabledChanged(const QString &unitFileState);
|
void handleEnabledChanged(const QString &unitFileState);
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QtUtilities::ClearLineEdit" name="syncthingUnitLineEdit"/>
|
<widget class="QtUtilities::ClearLineEdit" name="syncthingUnitLineEdit"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="descriptionLabel">
|
<widget class="QLabel" name="descriptionLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
@ -74,17 +74,23 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Description</string>
|
<string>Description</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="1">
|
||||||
<layout class="QHBoxLayout" name="descriptionHorizontalLayout">
|
<layout class="QHBoxLayout" name="descriptionHorizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="descriptionValueLabel">
|
<widget class="QLabel" name="descriptionValueLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
|
@ -102,7 +108,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="statusLabel">
|
<widget class="QLabel" name="statusLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
@ -115,7 +121,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<layout class="QHBoxLayout" name="statusHorizontalLayout">
|
<layout class="QHBoxLayout" name="statusHorizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="statusIndicator" native="true">
|
<widget class="QWidget" name="statusIndicator" native="true">
|
||||||
|
@ -179,7 +185,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="unitFileStateLabel">
|
<widget class="QLabel" name="unitFileStateLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
@ -192,7 +198,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<layout class="QHBoxLayout" name="unitFileStateHorizontalLayout">
|
<layout class="QHBoxLayout" name="unitFileStateHorizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="enabledIndicator" native="true">
|
<widget class="QWidget" name="enabledIndicator" native="true">
|
||||||
|
@ -256,9 +262,29 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="systemUnitCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>System unit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|
Loading…
Reference in New Issue