Allow controlling Syncthing systemd service

This commit is contained in:
Martchus 2016-12-18 16:50:35 +01:00
parent 13debf42cc
commit 78450a2b7e
20 changed files with 2337 additions and 7 deletions

View File

@ -45,6 +45,35 @@ list(APPEND CMAKE_MODULE_PATH ${QT_UTILITIES_MODULE_DIRS})
# link also explicitely against the following Qt 5 modules
list(APPEND ADDITIONAL_QT_MODULES Network)
# configure support for D-Bus notifications
option(SYSTEMD_SUPPORT "enables support for controlling Syncthing systemd service" ${UNIX})
if(DBUS_NOTIFICATIONS)
list(APPEND HEADER_FILES
syncthingservice.h
)
list(APPEND SRC_FILES
syncthingservice.cpp
)
list(APPEND DBUS_FILES
org.freedesktop.DBus.Properties.xml
org.freedesktop.systemd1.Manager.xml
org.freedesktop.systemd1.Service.xml
org.freedesktop.systemd1.Unit.xml
)
set_source_files_properties(
org.freedesktop.systemd1.Manager.xml
PROPERTIES INCLUDE syncthingservice.h
)
list(APPEND META_PUBLIC_COMPILE_DEFINITIONS LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD)
message(STATUS "systemd support enabled")
else()
list(APPEND DOC_ONLY_FILES
syncthingservice.h
syncthingservice.cpp
)
message(STATUS "systemd support disabled")
endif()
# include modules to apply configuration
include(BasicConfig)
include(QtConfig)

View File

@ -0,0 +1,26 @@
<node>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface" direction="in" type="s" />
<arg name="property" direction="in" type="s" />
<arg name="value" direction="out" type="v" />
</method>
<method name="GetAll">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="interface" direction="in" type="s" />
<arg name="properties" direction="out" type="a{sv}" />
</method>
<method name="Set">
<arg name="interface" direction="in" type="s" />
<arg name="property" direction="in" type="s" />
<arg name="value" direction="in" type="v" />
</method>
<signal name="PropertiesChanged">
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
<arg type="s" name="interface" />
<arg type="a{sv}" name="changed_properties" />
<arg type="as" name="invalidated_properties" />
</signal>
</interface>
</node>

View File

@ -0,0 +1,573 @@
<node>
<interface name="org.freedesktop.systemd1.Manager">
<method name="GetUnit">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="GetUnitByPID">
<arg type="u" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="GetUnitByInvocationID">
<arg type="ay" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="LoadUnit">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="StartUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="StartUnitReplace">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="StopUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="ReloadUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="RestartUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="TryRestartUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="ReloadOrRestartUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="ReloadOrTryRestartUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="KillUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="i" direction="in" />
</method>
<method name="ResetFailedUnit">
<arg type="s" direction="in" />
</method>
<!--<method name="SetUnitProperties">
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sv)" direction="in" />
</method>-->
<method name="RefUnit">
<arg type="s" direction="in" />
</method>
<method name="UnrefUnit">
<arg type="s" direction="in" />
</method>
<!--<method name="StartTransientUnit">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="a(sv)" direction="in" />
<arg type="a(sa(sv))" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="GetUnitProcesses">
<arg type="s" direction="in" />
<arg type="a(sus)" direction="out" />
</method>-->
<method name="GetJob">
<arg type="u" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="CancelJob">
<arg type="u" direction="in" />
</method>
<method name="ClearJobs"></method>
<method name="ResetFailed"></method>
<!--<method name="ListUnits">
<arg type="a(ssssssouso)" direction="out" />
</method>
<method name="ListUnitsFiltered">
<arg type="as" direction="in" />
<arg type="a(ssssssouso)" direction="out" />
</method>
<method name="ListUnitsByPatterns">
<arg type="as" direction="in" />
<arg type="as" direction="in" />
<arg type="a(ssssssouso)" direction="out" />
</method>
<method name="ListUnitsByNames">
<arg type="as" direction="in" />
<arg type="a(ssssssouso)" direction="out" />
</method>
<method name="ListJobs">
<arg type="a(usssoo)" direction="out" />
</method>-->
<method name="Subscribe"></method>
<method name="Unsubscribe"></method>
<method name="Dump">
<arg type="s" direction="out" />
</method>
<method name="CreateSnapshot">
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="RemoveSnapshot">
<arg type="s" direction="in" />
</method>
<method name="Reload"></method>
<method name="Reexecute"></method>
<method name="Exit"></method>
<method name="Reboot"></method>
<method name="PowerOff"></method>
<method name="Halt"></method>
<method name="KExec"></method>
<method name="SwitchRoot">
<arg type="s" direction="in" />
<arg type="s" direction="in" />
</method>
<method name="SetEnvironment">
<arg type="as" direction="in" />
</method>
<method name="UnsetEnvironment">
<arg type="as" direction="in" />
</method>
<method name="UnsetAndSetEnvironment">
<arg type="as" direction="in" />
<arg type="as" direction="in" />
</method>
<!--<method name="ListUnitFiles">
<arg type="a(ss)" direction="out" />
</method>
<method name="ListUnitFilesByPatterns">
<arg type="as" direction="in" />
<arg type="as" direction="in" />
<arg type="a(ss)" direction="out" />
</method>-->
<method name="GetUnitFileState">
<arg type="s" direction="in" />
<arg type="s" direction="out" />
</method>
<method name="EnableUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="out" />
<arg type="a(sss)" direction="out" />
</method>
<method name="DisableUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="ReenableUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="out" />
<arg type="a(sss)" direction="out" />
</method>
<method name="LinkUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="PresetUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="out" />
<arg type="a(sss)" direction="out" />
</method>
<method name="PresetUnitFilesWithMode">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="out" />
<arg type="a(sss)" direction="out" />
</method>
<method name="MaskUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="UnmaskUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="RevertUnitFiles">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="as" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="SetDefaultTarget">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Data::ManagerDBusUnitFileChangeList"/>
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="GetDefaultTarget">
<arg type="s" direction="out" />
</method>
<!--<method name="PresetAllUnitFiles">
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>
<method name="AddDependencyUnitFiles">
<arg type="as" direction="in" />
<arg type="s" direction="in" />
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="b" direction="in" />
<arg type="a(sss)" direction="out" />
</method>-->
<method name="GetUnitFileLinks">
<arg type="s" direction="in" />
<arg type="b" direction="in" />
<arg type="as" direction="out" />
</method>
<method name="SetExitCode">
<arg type="y" direction="in" />
</method>
<method name="LookupDynamicUserByName">
<arg type="s" direction="in" />
<arg type="u" direction="out" />
</method>
<method name="LookupDynamicUserByUID">
<arg type="u" direction="in" />
<arg type="s" direction="out" />
</method>
<signal name="UnitNew">
<arg type="s" />
<arg type="o" />
</signal>
<signal name="UnitRemoved">
<arg type="s" />
<arg type="o" />
</signal>
<signal name="JobNew">
<arg type="u" />
<arg type="o" />
<arg type="s" />
</signal>
<signal name="JobRemoved">
<arg type="u" />
<arg type="o" />
<arg type="s" />
<arg type="s" />
</signal>
<signal name="StartupFinished">
<arg type="t" />
<arg type="t" />
<arg type="t" />
<arg type="t" />
<arg type="t" />
<arg type="t" />
</signal>
<signal name="UnitFilesChanged"></signal>
<signal name="Reloading">
<arg type="b" />
</signal>
<property name="Version" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Features" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Virtualization" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Architecture" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Tainted" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="FirmwareTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="FirmwareTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LoaderTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LoaderTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="KernelTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="KernelTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="InitRDTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="InitRDTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UserspaceTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UserspaceTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="FinishTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="FinishTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SecurityStartTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SecurityStartTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SecurityFinishTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SecurityFinishTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="GeneratorsStartTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="GeneratorsStartTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="GeneratorsFinishTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="GeneratorsFinishTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitsLoadStartTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitsLoadStartTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitsLoadFinishTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitsLoadFinishTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LogLevel" type="s" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="LogTarget" type="s" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="NNames" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="NFailedUnits" type="u" access="read"></property>
<property name="NJobs" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="NInstalledJobs" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="NFailedJobs" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Progress" type="d" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Environment" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="ConfirmSpawn" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ShowStatus" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitPath" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultStandardOutput" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultStandardError" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RuntimeWatchdogUSec" type="t" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="ShutdownWatchdogUSec" type="t" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="ControlGroup" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="SystemState" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="ExitCode" type="y" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="DefaultTimerAccuracyUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultTimeoutStartUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultTimeoutStopUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultRestartUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultStartLimitIntervalSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultStartLimitBurst" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultCPUAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultBlockIOAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultMemoryAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultTasksAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitCPU" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitCPUSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitFSIZE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitFSIZESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitDATA" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitDATASoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitSTACK" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitSTACKSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitCORE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitCORESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRSS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRSSSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNOFILE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNOFILESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitAS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitASSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNPROC" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNPROCSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitMEMLOCK" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitMEMLOCKSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitLOCKS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitLOCKSSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitSIGPENDING" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitSIGPENDINGSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitMSGQUEUE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitMSGQUEUESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNICE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitNICESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRTPRIO" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRTPRIOSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRTTIME" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultLimitRTTIMESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultTasksMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TimerSlackNSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
</interface>
</node>

View File

@ -0,0 +1,524 @@
<node>
<interface name="org.freedesktop.systemd1.Service">
<!--<method name="GetProcesses">
<arg type="a(sus)" direction="out" />
</method>-->
<property name="Type" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Restart" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PIDFile" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="NotifyAccess" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RestartUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TimeoutStartUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TimeoutStopUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RuntimeMaxUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="WatchdogUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="WatchdogTimestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="WatchdogTimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="FailureAction" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PermissionsStartOnly" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RootDirectoryStartOnly" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RemainAfterExit" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="GuessMainPID" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="MainPID" type="u" access="read"></property>
<property name="ControlPID" type="u" access="read"></property>
<property name="BusName" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="FileDescriptorStoreMax" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="NFileDescriptorStore" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StatusText" type="s" access="read"></property>
<property name="StatusErrno" type="i" access="read"></property>
<property name="Result" type="s" access="read"></property>
<property name="USBFunctionDescriptors" type="s" access="read"></property>
<property name="USBFunctionStrings" type="s" access="read"></property>
<property name="UID" type="u" access="read"></property>
<property name="GID" type="u" access="read"></property>
<property name="ExecMainStartTimestamp" type="t" access="read"></property>
<property name="ExecMainStartTimestampMonotonic" type="t" access="read"></property>
<property name="ExecMainExitTimestamp" type="t" access="read"></property>
<property name="ExecMainExitTimestampMonotonic" type="t" access="read"></property>
<property name="ExecMainPID" type="u" access="read"></property>
<property name="ExecMainCode" type="i" access="read"></property>
<property name="ExecMainStatus" type="i" access="read"></property>
<!--<property name="ExecStartPre" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>
<property name="ExecStart" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>
<property name="ExecStartPost" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>
<property name="ExecReload" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>
<property name="ExecStop" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>
<property name="ExecStopPost" type="a(sasbttttuii)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates" />
</property>-->
<property name="Slice" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="ControlGroup" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemoryCurrent" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="CPUUsageNSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="TasksCurrent" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Delegate" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="CPUAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="CPUWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StartupCPUWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="CPUShares" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StartupCPUShares" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="CPUQuotaPerSecUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StartupIOWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<!--<property name="IODeviceWeight" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOReadBandwidthMax" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOWriteBandwidthMax" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOReadIOPSMax" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="IOWriteIOPSMax" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>-->
<property name="BlockIOAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="BlockIOWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StartupBlockIOWeight" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<!--<property name="BlockIODeviceWeight" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="BlockIOReadBandwidth" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="BlockIOWriteBandwidth" type="a(st)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>-->
<property name="MemoryAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemoryLow" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemoryHigh" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemoryMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemorySwapMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="MemoryLimit" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="DevicePolicy" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<!--<property name="DeviceAllow" type="a(ss)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>-->
<property name="TasksAccounting" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="TasksMax" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Environment" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<!--<property name="EnvironmentFiles" type="a(sb)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>-->
<property name="PassEnvironment" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UMask" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitCPU" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitCPUSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitFSIZE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitFSIZESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitDATA" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitDATASoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitSTACK" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitSTACKSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitCORE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitCORESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRSS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRSSSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNOFILE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNOFILESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitAS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitASSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNPROC" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNPROCSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitMEMLOCK" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitMEMLOCKSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitLOCKS" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitLOCKSSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitSIGPENDING" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitSIGPENDINGSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitMSGQUEUE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitMSGQUEUESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNICE" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitNICESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRTPRIO" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRTPRIOSoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRTTIME" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LimitRTTIMESoft" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="WorkingDirectory" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RootDirectory" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="OOMScoreAdjust" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Nice" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="IOScheduling" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CPUSchedulingPolicy" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CPUSchedulingPriority" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CPUAffinity" type="ay" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TimerSlackNSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CPUSchedulingResetOnFork" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="NonBlocking" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardInput" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardInputFileDescriptorName" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardOutput" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardOutputFileDescriptorName" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardError" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StandardErrorFileDescriptorName" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TTYPath" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TTYReset" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TTYVHangup" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TTYVTDisallocate" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SyslogPriority" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SyslogIdentifier" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SyslogLevelPrefix" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SyslogLevel" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SyslogFacility" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SecureBits" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CapabilityBoundingSet" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="AmbientCapabilities" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="User" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Group" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DynamicUser" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RemoveIPC" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SupplementaryGroups" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PAMName" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ReadWritePaths" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ReadOnlyPaths" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="InaccessiblePaths" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="MountFlags" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PrivateTmp" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PrivateDevices" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ProtectKernelTunables" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ProtectKernelModules" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ProtectControlGroups" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PrivateNetwork" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PrivateUsers" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ProtectHome" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ProtectSystem" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SameProcessGroup" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UtmpIdentifier" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UtmpMode" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<!--<property name="SELinuxContext" type="(bs)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="ExecuteDBusSELinuxContext"/>
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="AppArmorProfile" type="(bs)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="ExecuteDBusAppArmorProfile"/>
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SmackProcessLabel" type="(bs)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="ExecuteDBusSmackProcessLabel"/>
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>-->
<property name="IgnoreSIGPIPE" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="NoNewPrivileges" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<!--><property name="SystemCallFilter" type="(bas)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>-->
<property name="SystemCallArchitectures" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SystemCallErrorNumber" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Personality" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<!--<property name="RestrictAddressFamilies" type="(bas)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>-->
<property name="RuntimeDirectoryMode" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RuntimeDirectory" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="MemoryDenyWriteExecute" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RestrictRealtime" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="KillMode" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="KillSignal" type="i" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SendSIGKILL" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SendSIGHUP" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
</interface>
</node>

View File

@ -0,0 +1,233 @@
<node>
<interface name="org.freedesktop.systemd1.Unit">
<method name="Start">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="Stop">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="Reload">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="Restart">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="TryRestart">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="ReloadOrRestart">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="ReloadOrTryRestart">
<arg type="s" direction="in" />
<arg type="o" direction="out" />
</method>
<method name="Kill">
<arg type="s" direction="in" />
<arg type="i" direction="in" />
</method>
<method name="ResetFailed"></method>
<!--<method name="SetProperties">
<arg type="b" direction="in" />
<arg type="a(sv)" direction="in" />
</method>-->
<method name="Ref"></method>
<method name="Unref"></method>
<property name="Id" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Names" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Following" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Requires" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Requisite" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Wants" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="BindsTo" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PartOf" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RequiredBy" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RequisiteOf" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="WantedBy" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="BoundBy" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ConsistsOf" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Conflicts" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ConflictedBy" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Before" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="After" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="OnFailure" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Triggers" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="TriggeredBy" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="PropagatesReloadTo" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ReloadPropagatedFrom" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="JoinsNamespaceOf" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RequiresMountsFor" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Documentation" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Description" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="LoadState" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ActiveState" type="s" access="read"></property>
<property name="SubState" type="s" access="read"></property>
<property name="FragmentPath" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="SourcePath" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DropInPaths" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="UnitFileState" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="UnitFilePreset" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="StateChangeTimestamp" type="t" access="read"></property>
<property name="StateChangeTimestampMonotonic" type="t" access="read"></property>
<property name="InactiveExitTimestamp" type="t" access="read"></property>
<property name="InactiveExitTimestampMonotonic" type="t" access="read"></property>
<property name="ActiveEnterTimestamp" type="t" access="read"></property>
<property name="ActiveEnterTimestampMonotonic" type="t" access="read"></property>
<property name="ActiveExitTimestamp" type="t" access="read"></property>
<property name="ActiveExitTimestampMonotonic" type="t" access="read"></property>
<property name="InactiveEnterTimestamp" type="t" access="read"></property>
<property name="InactiveEnterTimestampMonotonic" type="t" access="read"></property>
<property name="CanStart" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CanStop" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CanReload" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="CanIsolate" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<!--<property name="Job" type="(uo)" access="read"></property>-->
<property name="StopWhenUnneeded" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RefuseManualStart" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RefuseManualStop" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="AllowIsolate" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="DefaultDependencies" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="OnFailureJobMode" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="IgnoreOnIsolate" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="NeedDaemonReload" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="JobTimeoutUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="JobTimeoutAction" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="JobTimeoutRebootArgument" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="ConditionResult" type="b" access="read"></property>
<property name="AssertResult" type="b" access="read"></property>
<property name="ConditionTimestamp" type="t" access="read"></property>
<property name="ConditionTimestampMonotonic" type="t" access="read"></property>
<property name="AssertTimestamp" type="t" access="read"></property>
<property name="AssertTimestampMonotonic" type="t" access="read"></property>
<!--<property name="Conditions" type="a(sbbsi)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="Asserts" type="a(sbbsi)" access="read">-->
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
<property name="LoadError" type="(ss)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Transient" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="Perpetual" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StartLimitIntervalSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StartLimitBurst" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="StartLimitAction" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="RebootArgument" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" />
</property>
<property name="InvocationID" type="ay" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false" />
</property>
</interface>
</node>

View File

@ -1,6 +1,7 @@
#include "./syncthingconnection.h"
#include "./syncthingconfig.h"
#include "./syncthingconnectionsettings.h"
#include "./utils.h"
#include <c++utilities/conversion/conversionexception.h>
#include <c++utilities/conversion/stringconversion.h>
@ -632,11 +633,7 @@ void SyncthingConnection::loadSelfSignedCertificate()
}
// only possible if the Syncthing instance is running on the local machine
const QString host(syncthingUrl.host());
const QHostAddress hostAddress(host);
if(host.compare(QLatin1String("localhost"), Qt::CaseInsensitive) != 0
&& !hostAddress.isLoopback()
&& !QNetworkInterface::allAddresses().contains(hostAddress)) {
if(!isLocal(syncthingUrl)) {
return;
}

View File

@ -0,0 +1,248 @@
#include "./syncthingservice.h"
#include "managerinterface.h"
#include "unitinterface.h"
#include "serviceinterface.h"
#include "propertiesinterface.h"
#include <QDBusArgument>
#include <QDBusConnection>
#include <QDBusServiceWatcher>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QDBusObjectPath>
#include <QDBusMetaType>
#include <functional>
using namespace std;
using namespace std::placeholders;
namespace Data {
QDBusArgument &operator<<(QDBusArgument &argument, const ManagerDBusUnitFileChange &unitFileChange)
{
argument.beginStructure();
argument << unitFileChange.type << unitFileChange.path << unitFileChange.source;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, ManagerDBusUnitFileChange &unitFileChange)
{
argument.beginStructure();
argument >> unitFileChange.type >> unitFileChange.path >> unitFileChange.source;
argument.endStructure();
return argument;
}
OrgFreedesktopSystemd1ManagerInterface *SyncthingService::s_manager = nullptr;
SyncthingService::SyncthingService(QObject *parent) :
QObject(parent),
m_unit(nullptr),
m_service(nullptr),
m_properties(nullptr)
{
if(!s_manager) {
// register custom data types
qDBusRegisterMetaType<ManagerDBusUnitFileChange>();
qDBusRegisterMetaType<ManagerDBusUnitFileChangeList>();
s_manager = new OrgFreedesktopSystemd1ManagerInterface(
QStringLiteral("org.freedesktop.systemd1"),
QStringLiteral("/org/freedesktop/systemd1"),
QDBusConnection::sessionBus()
);
// enable systemd to emit signals
s_manager->Subscribe();
}
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());
}
void SyncthingService::setUnitName(const QString &unitName)
{
if(m_unitName != unitName) {
m_unitName = unitName;
delete m_service, delete m_unit, delete m_properties;
m_service = nullptr, m_unit = nullptr, m_properties = nullptr;
setProperties(QString(), QString(), QString(), QString());
if(s_manager->isValid()) {
connect(new QDBusPendingCallWatcher(s_manager->GetUnit(m_unitName), this), &QDBusPendingCallWatcher::finished, this, &SyncthingService::handleUnitGet);
}
}
}
bool SyncthingService::isSystemdAvailable() const
{
return s_manager && s_manager->isValid();
}
bool SyncthingService::isUnitAvailable() const
{
return m_unit && m_unit->isValid();
}
void SyncthingService::setRunning(bool running)
{
if(running) {
registerErrorHandler(s_manager->StartUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("starting unit"));
} else {
registerErrorHandler(s_manager->StopUnit(m_unitName, QStringLiteral("replace")), QT_TR_NOOP_UTF8("stopping unit"));
}
}
void SyncthingService::setEnabled(bool enabled)
{
if(enabled) {
registerErrorHandler(s_manager->EnableUnitFiles(QStringList(m_unitName), false, true), QT_TR_NOOP_UTF8("enabling unit"));
} else {
registerErrorHandler(s_manager->DisableUnitFiles(QStringList(m_unitName), false), QT_TR_NOOP_UTF8("disabling unit"));
}
}
void SyncthingService::handleUnitAdded(const QString &unitName, const QDBusObjectPath &unitPath)
{
if(unitName == m_unitName) {
setUnit(unitPath);
}
}
void SyncthingService::handleUnitRemoved(const QString &unitName, const QDBusObjectPath &unitPath)
{
Q_UNUSED(unitPath)
if(unitName == m_unitName) {
setUnit(QDBusObjectPath());
}
}
void SyncthingService::handleUnitGet(QDBusPendingCallWatcher *watcher)
{
watcher->deleteLater();
const QDBusPendingReply<QDBusObjectPath> unitReply = *watcher;
if(unitReply.isError()) {
return;
}
setUnit(unitReply.value());
}
void SyncthingService::handlePropertiesChanged(const QString &interface, const QVariantMap &changedProperties, const QStringList &invalidatedProperties)
{
if(interface == m_unit->interface()) {
const bool running = isRunning();
if(handlePropertyChanged(m_activeState, &SyncthingService::activeStateChanged, QStringLiteral("ActiveState"), changedProperties, invalidatedProperties)
| handlePropertyChanged(m_subState, &SyncthingService::subStateChanged, QStringLiteral("SubState"), changedProperties, invalidatedProperties)) {
emit stateChanged(m_activeState, m_subState);
}
if(running != isRunning()) {
emit runningChanged(isRunning());
}
const bool enabled = isEnabled();
handlePropertyChanged(m_unitFileState, &SyncthingService::unitFileStateChanged, QStringLiteral("UnitFileState"), changedProperties, invalidatedProperties);
if(enabled != isEnabled()) {
emit enabledChanged(isEnabled());
}
handlePropertyChanged(m_description, &SyncthingService::descriptionChanged, QStringLiteral("Description"), changedProperties, invalidatedProperties);
}
}
void SyncthingService::handleError(const char *context, QDBusPendingCallWatcher *watcher)
{
watcher->deleteLater();
const QDBusError error = watcher->error();
if(error.isValid()) {
emit errorOccurred(tr(context), error.name(), error.message());
}
}
bool SyncthingService::handlePropertyChanged(QString &variable, void (SyncthingService::*signal)(const QString &), const QString &propertyName, const QVariantMap &changedProperties, const QStringList &invalidatedProperties)
{
const QVariant valueVariant(changedProperties[propertyName]);
if(valueVariant.isValid()) {
const QString valueString(valueVariant.toString());
if(valueString != variable) {
emit (this->*signal)(variable = valueString);
return true;
}
} else if(invalidatedProperties.contains(propertyName) && !variable.isEmpty()) {
variable.clear();
emit (this->*signal)(variable);
return true;
}
return false;
}
void SyncthingService::registerErrorHandler(const QDBusPendingCall &call, const char *context)
{
connect(new QDBusPendingCallWatcher(call, this), &QDBusPendingCallWatcher::finished, bind(&SyncthingService::handleError, this, context, _1));
}
void SyncthingService::setUnit(const QDBusObjectPath &objectPath)
{
// cleanup
delete m_service, delete m_unit, delete m_properties;
m_service = nullptr, m_unit = nullptr, m_properties = nullptr;
const QString path = objectPath.path();
if(path.isEmpty()) {
setProperties(QString(), QString(), QString(), QString());
return;
}
// init unit
m_unit = new OrgFreedesktopSystemd1UnitInterface(s_manager->service(), path, s_manager->connection());
setProperties(m_unit->activeState(), m_unit->subState(), m_unit->unitFileState(), m_unit->description());
// init properties
m_properties = new OrgFreedesktopDBusPropertiesInterface(s_manager->service(), path, s_manager->connection());
connect(m_properties, &OrgFreedesktopDBusPropertiesInterface::PropertiesChanged, this, &SyncthingService::handlePropertiesChanged);
}
void SyncthingService::setProperties(const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description)
{
const bool running = isRunning();
bool anyStateChanged = false;
if(m_activeState != activeState) {
emit activeStateChanged(m_activeState = activeState);
anyStateChanged = true;
}
if(m_subState != subState) {
emit subStateChanged(m_subState = subState);
anyStateChanged = true;
}
if(anyStateChanged) {
emit stateChanged(m_activeState, m_subState);
}
if(running != isRunning()) {
emit runningChanged(isRunning());
}
const bool enabled = isEnabled();
if(m_unitFileState != unitFileState) {
emit unitFileStateChanged(m_unitFileState = unitFileState);
}
if(enabled != isEnabled()) {
emit enabledChanged(isEnabled());
}
if(m_description != description) {
emit descriptionChanged(m_description = description);
}
}
SyncthingService &syncthingService()
{
static SyncthingService service;
return service;
}
} // namespace Data

View File

@ -0,0 +1,170 @@
#ifndef DATA_SYNCTHINGSERVICE_H
#define DATA_SYNCTHINGSERVICE_H
#include <QObject>
#include <QVariantMap>
QT_FORWARD_DECLARE_CLASS(QDBusServiceWatcher)
QT_FORWARD_DECLARE_CLASS(QDBusArgument)
QT_FORWARD_DECLARE_CLASS(QDBusObjectPath)
QT_FORWARD_DECLARE_CLASS(QDBusPendingCall)
QT_FORWARD_DECLARE_CLASS(QDBusPendingCallWatcher)
class OrgFreedesktopSystemd1ManagerInterface;
class OrgFreedesktopSystemd1UnitInterface;
class OrgFreedesktopSystemd1ServiceInterface;
class OrgFreedesktopDBusPropertiesInterface;
namespace Data {
struct ManagerDBusUnitFileChange {
QString type;
QString path;
QString source;
};
QDBusArgument &operator<<(QDBusArgument &argument, const ManagerDBusUnitFileChange &unitFileChange);
const QDBusArgument &operator>>(const QDBusArgument &argument, ManagerDBusUnitFileChange &unitFileChange);
typedef QList<ManagerDBusUnitFileChange> ManagerDBusUnitFileChangeList;
class SyncthingService : public QObject
{
Q_OBJECT
Q_PROPERTY(QString unitName READ unitName WRITE setUnitName)
Q_PROPERTY(bool systemdAvailable READ isSystemdAvailable NOTIFY systemdAvailableChanged)
Q_PROPERTY(bool unitAvailable READ isUnitAvailable)
Q_PROPERTY(QString activeState READ activeState NOTIFY activeStateChanged)
Q_PROPERTY(QString subState READ subState NOTIFY subStateChanged)
Q_PROPERTY(QString unitFileState READ unitFileState NOTIFY unitFileStateChanged)
Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
Q_PROPERTY(bool enable READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
public:
SyncthingService(QObject *parent = nullptr);
const QString &unitName() const;
bool isSystemdAvailable() const;
bool isUnitAvailable() const;
const QString &activeState() const;
const QString &subState() const;
const QString &unitFileState() const;
const QString &description() const;
bool isRunning() const;
bool isEnabled() const;
public Q_SLOTS:
void setUnitName(const QString &unitName);
void setRunning(bool running);
void start();
void stop();
void toggleRunning();
void setEnabled(bool enable);
void enable();
void disable();
Q_SIGNALS:
void systemdAvailableChanged(bool available);
void stateChanged(const QString &activeState, const QString &subState);
void activeStateChanged(const QString &activeState);
void subStateChanged(const QString &subState);
void unitFileStateChanged(const QString &unitFileState);
void descriptionChanged(const QString &description);
void runningChanged(bool running);
void enabledChanged(bool enable);
void errorOccurred(const QString &context, const QString &name, const QString &message);
private Q_SLOTS:
void handleUnitAdded(const QString &unitName, const QDBusObjectPath &unitPath);
void handleUnitRemoved(const QString &unitName, const QDBusObjectPath &unitPath);
void handleUnitGet(QDBusPendingCallWatcher *watcher);
void handlePropertiesChanged(const QString &interface, const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
void handleError(const char *error, QDBusPendingCallWatcher *watcher);
void setUnit(const QDBusObjectPath &objectPath);
void setProperties(const QString &activeState, const QString &subState, const QString &unitFileState, const QString &description);
private:
bool handlePropertyChanged(QString &variable, void(SyncthingService::*signal)(const QString &), const QString &propertyName, const QVariantMap &changedProperties, const QStringList &invalidatedProperties);
void registerErrorHandler(const QDBusPendingCall &call, const char *context);
static OrgFreedesktopSystemd1ManagerInterface *s_manager;
QString m_unitName;
QDBusServiceWatcher *m_serviceWatcher;
OrgFreedesktopSystemd1UnitInterface *m_unit;
OrgFreedesktopSystemd1ServiceInterface *m_service;
OrgFreedesktopDBusPropertiesInterface *m_properties;
QString m_description;
QString m_activeState;
QString m_subState;
QString m_unitFileState;
};
inline const QString &SyncthingService::unitName() const
{
return m_unitName;
}
inline const QString &SyncthingService::activeState() const
{
return m_activeState;
}
inline const QString &SyncthingService::subState() const
{
return m_subState;
}
inline const QString &SyncthingService::unitFileState() const
{
return m_unitFileState;
}
inline const QString &SyncthingService::description() const
{
return m_description;
}
inline bool SyncthingService::isRunning() const
{
return m_activeState == QLatin1String("active") && m_subState == QLatin1String("running");
}
inline void SyncthingService::start()
{
setRunning(true);
}
inline void SyncthingService::stop()
{
setRunning(false);
}
inline void SyncthingService::toggleRunning()
{
setRunning(!isRunning());
}
inline bool SyncthingService::isEnabled() const
{
return m_unitFileState == QLatin1String("enabled");
}
inline void SyncthingService::enable()
{
setEnabled(true);
}
inline void SyncthingService::disable()
{
setEnabled(false);
}
SyncthingService &syncthingService();
} // namespace Data
Q_DECLARE_METATYPE(Data::ManagerDBusUnitFileChange)
Q_DECLARE_METATYPE(Data::ManagerDBusUnitFileChangeList)
#endif // DATA_SYNCTHINGSERVICE_H

View File

@ -3,20 +3,38 @@
#include <c++utilities/chrono/datetime.h>
#include <QString>
#include <QUrl>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QCoreApplication>
using namespace ChronoUtilities;
namespace Data {
/*!
* \brief Returns a string like "2 min 45 s ago" for the specified \a dateTime.
*/
QString agoString(DateTime dateTime)
{
const TimeSpan delta(DateTime::now() - dateTime);
if(!delta.isNegative() && static_cast<uint64>(delta.totalTicks()) > (TimeSpan::ticksPerMinute / 4uL)) {
return QCoreApplication::translate("Data::Utils", "%1 ago").arg(QString::fromLatin1(delta.toString(TimeSpanOutputFormat::WithMeasures, true).data()));
return QCoreApplication::translate("Data::Utils", "%1 ago").arg(QString::fromUtf8(delta.toString(TimeSpanOutputFormat::WithMeasures, true).data()));
} else {
return QCoreApplication::translate("Data::Utils", "right now");
}
}
/*!
* \brief Returns whether the host specified by the given \a url is the local machine.
*/
bool isLocal(const QUrl &url)
{
const QString host(url.host());
const QHostAddress hostAddress(host);
return host.compare(QLatin1String("localhost"), Qt::CaseInsensitive) == 0
|| hostAddress.isLoopback()
|| QNetworkInterface::allAddresses().contains(hostAddress);
}
}

View File

@ -6,6 +6,7 @@
#include <QtGlobal>
QT_FORWARD_DECLARE_CLASS(QString)
QT_FORWARD_DECLARE_CLASS(QUrl)
namespace ChronoUtilities {
class DateTime;
@ -14,6 +15,7 @@ class DateTime;
namespace Data {
QString LIB_SYNCTHING_CONNECTOR_EXPORT agoString(ChronoUtilities::DateTime dateTime);
bool LIB_SYNCTHING_CONNECTOR_EXPORT isLocal(const QUrl &url);
}

View File

@ -52,6 +52,7 @@ set(WIDGETS_UI_FILES
gui/appearanceoptionpage.ui
gui/autostartoptionpage.ui
gui/launcheroptionpage.ui
gui/systemdoptionpage.ui
gui/webviewoptionpage.ui
)

View File

@ -5,6 +5,9 @@
#include "../gui/traywidget.h"
#include "../../connector/syncthingprocess.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
# include "../../connector/syncthingservice.h"
#endif
#include "resources/config.h"
@ -20,6 +23,7 @@
#include <QApplication>
#include <QNetworkAccessManager>
#include <QMessageBox>
#include <QStringBuilder>
#include <iostream>
@ -28,9 +32,25 @@ using namespace ApplicationUtilities;
using namespace QtGui;
using namespace Data;
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
void handleSystemdServiceError(const QString &context, const QString &name, const QString &message)
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(QCoreApplication::translate("main", "Unable to ") + context);
msgBox.setInformativeText(name % QStringLiteral(": ") % message);
msgBox.exec();
}
#endif
int initSyncthingTray(bool windowed, bool waitForTray)
{
auto &v = Settings::values();
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
SyncthingService &service = syncthingService();
service.setUnitName(v.systemd.syncthingUnit);
QObject::connect(&service, &SyncthingService::errorOccurred, &handleSystemdServiceError);
#endif
if(windowed) {
if(v.launcher.enabled) {
syncthingProcess().startSyncthing(v.launcher.syncthingCmd());

View File

@ -96,6 +96,11 @@ void restore()
launcher.enabled = settings.value(QStringLiteral("launchSynchting"), launcher.enabled).toBool();
launcher.syncthingPath = settings.value(QStringLiteral("syncthingPath"), launcher.syncthingPath).toString();
launcher.syncthingArgs = settings.value(QStringLiteral("syncthingArgs"), launcher.syncthingArgs).toString();
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
auto &systemd = v.systemd;
systemd.syncthingUnit = settings.value(QStringLiteral("syncthingUnit"), systemd.syncthingUnit).toString();
systemd.showButton = settings.value(QStringLiteral("showButton"), systemd.showButton).toBool();
#endif
settings.endGroup();
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)
@ -158,6 +163,11 @@ void save()
settings.setValue(QStringLiteral("launchSynchting"), launcher.enabled);
settings.setValue(QStringLiteral("syncthingPath"), launcher.syncthingPath);
settings.setValue(QStringLiteral("syncthingArgs"), launcher.syncthingArgs);
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const auto &systemd = v.systemd;
settings.setValue(QStringLiteral("syncthingUnit"), systemd.syncthingUnit);
settings.setValue(QStringLiteral("showButton"), systemd.showButton);
#endif
settings.endGroup();
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)

View File

@ -62,6 +62,14 @@ struct Launcher
QString syncthingCmd() const;
};
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
struct Systemd
{
QString syncthingUnit = QStringLiteral("syncthing.service");
bool showButton = true;
};
#endif
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)
struct WebView
{
@ -82,6 +90,9 @@ struct Settings
#endif
Appearance appearance;
Launcher launcher;
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
Systemd systemd;
#endif
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)
WebView webView;
#endif

View File

@ -3,12 +3,19 @@
#include "../../connector/syncthingconnection.h"
#include "../../connector/syncthingconfig.h"
#include "../../connector/syncthingprocess.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
# include "../../connector/syncthingservice.h"
# include "../../model/colors.h"
#endif
#include "ui_connectionoptionpage.h"
#include "ui_notificationsoptionpage.h"
#include "ui_appearanceoptionpage.h"
#include "ui_autostartoptionpage.h"
#include "ui_launcheroptionpage.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
# include "ui_systemdoptionpage.h"
#endif
#include "ui_webviewoptionpage.h"
#include "resources/config.h"
@ -19,6 +26,9 @@
#ifdef QT_UTILITIES_SUPPORT_DBUS_NOTIFICATIONS
# include <qtutilities/misc/dbusnotification.h>
#endif
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
# include <qtutilities/misc/dialogutils.h>
#endif
#include <QFileDialog>
#include <QMessageBox>
@ -556,6 +566,98 @@ void LauncherOptionPage::stop()
}
}
// SystemdOptionPage
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
SystemdOptionPage::SystemdOptionPage(QWidget *parentWidget) :
SystemdOptionPageBase(parentWidget),
m_service(syncthingService())
{}
SystemdOptionPage::~SystemdOptionPage()
{}
QWidget *SystemdOptionPage::setupWidget()
{
auto *widget = SystemdOptionPageBase::setupWidget();
QObject::connect(ui()->syncthingUnitLineEdit, &QLineEdit::textChanged, &m_service, &SyncthingService::setUnitName);
QObject::connect(ui()->startPushButton, &QPushButton::clicked, &m_service, &SyncthingService::start);
QObject::connect(ui()->stopPushButton, &QPushButton::clicked, &m_service, &SyncthingService::stop);
QObject::connect(ui()->enablePushButton, &QPushButton::clicked, &m_service, &SyncthingService::enable);
QObject::connect(ui()->disablePushButton, &QPushButton::clicked, &m_service, &SyncthingService::disable);
QObject::connect(&m_service, &SyncthingService::descriptionChanged, bind(&SystemdOptionPage::handleDescriptionChanged, this, _1));
QObject::connect(&m_service, &SyncthingService::stateChanged, bind(&SystemdOptionPage::handleStatusChanged, this, _1, _2));
QObject::connect(&m_service, &SyncthingService::unitFileStateChanged, bind(&SystemdOptionPage::handleEnabledChanged, this, _1));
return widget;
}
bool SystemdOptionPage::apply()
{
if(hasBeenShown()) {
auto &settings = values().systemd;
settings.syncthingUnit = ui()->syncthingUnitLineEdit->text();
settings.showButton = ui()->showButtonCheckBox->isChecked();
}
return true;
}
void SystemdOptionPage::reset()
{
if(hasBeenShown()) {
const auto &settings = values().systemd;
ui()->syncthingUnitLineEdit->setText(settings.syncthingUnit);
ui()->showButtonCheckBox->setChecked(settings.showButton);
handleDescriptionChanged(m_service.description());
handleStatusChanged(m_service.activeState(), m_service.subState());
handleEnabledChanged(m_service.unitFileState());
}
}
void SystemdOptionPage::handleDescriptionChanged(const QString &description)
{
ui()->descriptionValueLabel->setText(description.isEmpty() ? QCoreApplication::translate("QtGui::SystemdOptionPage", "specified unit is unknown") : description);
}
void setIndicatorColor(QWidget *indicator, const QColor &color)
{
indicator->setStyleSheet(QStringLiteral("border-radius:8px;background-color:") + color.name());
}
void SystemdOptionPage::handleStatusChanged(const QString &activeState, const QString &subState)
{
QStringList status;
if(!activeState.isEmpty()) {
status << activeState;
}
if(!subState.isEmpty()) {
status << subState;
}
const bool isRunning = m_service.isRunning();
ui()->statusValueLabel->setText(status.isEmpty()
? QCoreApplication::translate("QtGui::SystemdOptionPage", "unknown")
: status.join(QStringLiteral(" - ")));
setIndicatorColor(ui()->statusIndicator, status.isEmpty()
? Colors::gray(values().appearance.brightTextColors)
: (isRunning
? Colors::green(values().appearance.brightTextColors)
: Colors::red(values().appearance.brightTextColors))
);
ui()->startPushButton->setVisible(!status.isEmpty() && !isRunning);
ui()->stopPushButton->setVisible(!status.isEmpty() && isRunning);
}
void SystemdOptionPage::handleEnabledChanged(const QString &unitFileState)
{
const bool isEnabled = m_service.isEnabled();
ui()->unitFileStateValueLabel->setText(unitFileState.isEmpty() ? QCoreApplication::translate("QtGui::SystemdOptionPage", "unknown") : unitFileState);
setIndicatorColor(ui()->enabledIndicator, isEnabled
? Colors::green(values().appearance.brightTextColors)
: Colors::gray(values().appearance.brightTextColors));
ui()->enablePushButton->setVisible(!unitFileState.isEmpty() && !isEnabled);
ui()->disablePushButton->setVisible(!unitFileState.isEmpty() && isEnabled);
}
#endif
// WebViewOptionPage
WebViewOptionPage::WebViewOptionPage(QWidget *parentWidget) :
WebViewOptionPageBase(parentWidget)
@ -621,7 +723,11 @@ SettingsDialog::SettingsDialog(Data::SyncthingConnection *connection, QWidget *p
category = new OptionCategory(this);
category->setDisplayName(tr("Startup"));
category->assignPages(QList<Dialogs::OptionPage *>() << new AutostartOptionPage << new LauncherOptionPage);
category->assignPages(QList<Dialogs::OptionPage *>() << new AutostartOptionPage << new LauncherOptionPage
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
<< new SystemdOptionPage
#endif
);
category->setIcon(QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
categories << category;
@ -647,6 +753,9 @@ INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, NotificationsOptionPage)
INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, AppearanceOptionPage)
INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, AutostartOptionPage)
INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, LauncherOptionPage)
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, SystemdOptionPage)
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
INSTANTIATE_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, WebViewOptionPage)
#endif

View File

@ -12,6 +12,7 @@
namespace Data {
class SyncthingConnection;
class SyncthingService;
}
namespace QtGui {
@ -52,6 +53,17 @@ private:
bool m_kill;
END_DECLARE_OPTION_PAGE
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(SystemdOptionPage)
private:
DECLARE_SETUP_WIDGETS
void handleDescriptionChanged(const QString &description);
void handleStatusChanged(const QString &activeState, const QString &subState);
void handleEnabledChanged(const QString &unitFileState);
Data::SyncthingService &m_service;
END_DECLARE_OPTION_PAGE
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
DECLARE_UI_FILE_BASED_OPTION_PAGE(WebViewOptionPage)
#else
@ -73,6 +85,9 @@ DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, NotificationsOptionPage)
DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, AppearanceOptionPage)
DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, AutostartOptionPage)
DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, LauncherOptionPage)
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, SystemdOptionPage)
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
DECLARE_EXTERN_UI_FILE_BASED_OPTION_PAGE_NS(QtGui, WebViewOptionPage)
#endif

View File

@ -0,0 +1,278 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QtGui::SystemdOptionPage</class>
<widget class="QWidget" name="QtGui::SystemdOptionPage">
<property name="windowTitle">
<string>Systemd</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="showButtonCheckBox">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Show start/stop button on tray for local instance when specified unit available</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="systemdFormWidget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="leftMargin">
<number>30</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="syncthingUnitLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Syncthing unit</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Widgets::ClearLineEdit" name="syncthingUnitLineEdit"/>
</item>
<item row="1" column="1">
<widget class="Line" name="line1">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="descriptionHorizontalLayout">
<item>
<widget class="QLabel" name="descriptionValueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>unknown</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="statusLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Current status</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="statusHorizontalLayout">
<item>
<widget class="QWidget" name="statusIndicator" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusValueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>unknown</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startPushButton">
<property name="text">
<string>Start</string>
</property>
<property name="icon">
<iconset theme="system-run">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stopPushButton">
<property name="text">
<string>Stop</string>
</property>
<property name="icon">
<iconset theme="process-stop">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="unitFileStateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Unit file state</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="unitFileStateHorizontalLayout">
<item>
<widget class="QWidget" name="enabledIndicator" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="unitFileStateValueLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>unknown</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="enablePushButton">
<property name="text">
<string>Enable</string>
</property>
<property name="icon">
<iconset theme="emblem-checked">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="disablePushButton">
<property name="text">
<string>Disable</string>
</property>
<property name="icon">
<iconset theme="emblem-remove">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Widgets::ClearLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">qtutilities/widgets/clearlineedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>showButtonCheckBox</tabstop>
<tabstop>syncthingUnitLineEdit</tabstop>
<tabstop>startPushButton</tabstop>
<tabstop>stopPushButton</tabstop>
<tabstop>enablePushButton</tabstop>
<tabstop>disablePushButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -7,6 +7,11 @@
#include "../application/settings.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
# include "../../connector/syncthingservice.h"
# include "../../connector/utils.h"
#endif
#include "resources/config.h"
#include "ui_traywidget.h"
@ -129,6 +134,11 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
connect(m_ui->notificationsPushButton, &QPushButton::clicked, this, &TrayWidget::showNotifications);
connect(restartButton, &QPushButton::clicked, this, &TrayWidget::restartSyncthing);
connect(m_connectionsActionGroup, &QActionGroup::triggered, this, &TrayWidget::handleConnectionSelected);
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
const SyncthingService &service = syncthingService();
connect(m_ui->startStopPushButton, &QPushButton::clicked, &service, &SyncthingService::toggleRunning);
connect(&service, &SyncthingService::stateChanged, this, &TrayWidget::updateStartStopButton);
#endif
}
TrayWidget::~TrayWidget()
@ -354,6 +364,11 @@ void TrayWidget::applySettings()
}
#endif
// systemd
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
instance->updateStartStopButton();
#endif
// update visual appearance
instance->m_ui->trafficFormWidget->setVisible(settings.appearance.showTraffic);
instance->m_ui->trafficIconLabel->setVisible(settings.appearance.showTraffic);
@ -458,6 +473,29 @@ void TrayWidget::updateTraffic()
}
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
void TrayWidget::updateStartStopButton()
{
const SyncthingService &service = syncthingService();
const Settings::Systemd &settings = Settings::values().systemd;
if(settings.showButton && service.isUnitAvailable() && m_selectedConnection && isLocal(QUrl(m_selectedConnection->syncthingUrl))) {
m_ui->startStopPushButton->setVisible(true);
if(service.isRunning()) {
m_ui->startStopPushButton->setText(tr("Stop"));
m_ui->startStopPushButton->setToolTip(QStringLiteral("systemctl --user stop ") + service.unitName());
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 ") + service.unitName());
m_ui->startStopPushButton->setIcon(QIcon::fromTheme(QStringLiteral("system-run"), QIcon(QStringLiteral(":/icons/hicolor/scalable/apps/system-run.svg"))));
}
} else {
m_ui->startStopPushButton->setVisible(false);
}
}
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
void TrayWidget::handleWebViewDeleted()
{
@ -480,6 +518,9 @@ void TrayWidget::handleConnectionSelected(QAction *connectionAction)
: &Settings::values().connection.secondary[static_cast<size_t>(index - 1)];
m_ui->connectionsPushButton->setText(m_selectedConnection->label);
m_connection.reconnect(*m_selectedConnection);
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
updateStartStopButton();
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
if(m_webViewDlg) {
m_webViewDlg->applySettings(*m_selectedConnection);

View File

@ -70,6 +70,9 @@ private slots:
void pauseResumeDev(const Data::SyncthingDev &dev);
void changeStatus();
void updateTraffic();
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
void updateStartStopButton();
#endif
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
void handleWebViewDeleted();
#endif

View File

@ -2,6 +2,14 @@
<ui version="4.0">
<class>QtGui::TrayWidget</class>
<widget class="QWidget" name="QtGui::TrayWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>314</height>
</rect>
</property>
<property name="windowTitle">
<string>Syncthing Tray</string>
</property>
@ -107,6 +115,20 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startStopPushButton">
<property name="text">
<string>Start</string>
</property>
<property name="icon">
<iconset theme="system-run" resource="../resources/icons.qrc">
<normaloff>:/icons/hicolor/scalable/apps/system-run.svg</normaloff>:/icons/hicolor/scalable/apps/system-run.svg</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">