/**
* Battery Buddy, a Sailfish application to prolong battery lifetime
*
* Copyright (C) 2019-2020 Matti Viljanen
*
* Battery Buddy is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Battery Buddy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details. You should have received a copy of the GNU
* General Public License along with Battery Buddy. If not, see .
*
* Author: Matti Viljanen
*/
import QtQuick 2.2
import Sailfish.Silica 1.0
import Process 1.0
import "../components"
Page {
id: settingsPage
allowedOrientations: Orientation.Portrait | Orientation.Landscape | Orientation.LandscapeInverted
Component.onCompleted: {
}
//////////////////////////////////////////////////
//
// TIMERS AND PROCESSES
//
//////////////////////////////////////////////////
Timer {
id: startupTimer
interval: 100
repeat: false
running: true
onTriggered: {
autoStopCharging.checked = settings.limitEnabled
highLimitSlider.value = settings.highLimit
lowLimitSlider.value = settings.lowLimit
highAlertSlider.value = settings.highAlert
healthSelector.currentIndex = settings.healthAlert
lowAlertSlider.value = settings.lowAlert
highIntervalSlider.value = settings.highNotificationsInterval
lowIntervalSlider.value = settings.lowNotificationsInterval
healthIntervalSlider.value = settings.healthNotificationsInterval
if(logger.debug) logger.log("SettingsPage values updated")
daemonCheck.start()
}
}
Timer {
id: daemonToggle
interval: 100
running: false
repeat: false
onTriggered: {
var action = daemonEnabledSwitch.checked ? "disable" : "enable"
if(logger.verbose) logger.log("Action: " + action)
_toggleProcess.start("systemctl", ["--user", action, "harbour-batterybuddy.service"])
}
}
Process {
// Only used by daemonToggle timer
id: _toggleProcess
onFinished: {
daemonCheck.start()
if(logger.debug) logger.log("Service toggle " + (errorCode() === 0 ? "succeeded" : "failed"))
}
}
Timer {
id: daemonCheck
interval: 0
running: false
repeat: false
onTriggered: {
_checkProcess.start("systemctl", ["--user", "is-enabled", "harbour-batterybuddy.service"])
}
}
Process {
// Only used by daemonCheck timer
id: _checkProcess
onFinished: {
if(errorCode() === 0) {
daemonEnabledSwitch.checked = true
}
else {
daemonEnabledSwitch.checked = false
}
daemonEnabledSwitch.busy = false
if(logger.verbose) logger.log("Service is " + (errorCode() === 0 ? "enabled" : "disabled"))
}
}
//////////////////////////////////////////////////
//
// MAIN CONTENT
//
//////////////////////////////////////////////////
SilicaFlickable {
anchors.fill: parent
contentHeight: flow.height + Theme.horizontalPageMargin
PullDownMenu {
MenuItem {
text: qsTr("View log")
onClicked: pageStack.push(Qt.resolvedUrl("LogPage.qml"))
}
MenuItem {
text: qsTr("About", "About this application")
onClicked: pageStack.push(Qt.resolvedUrl("AboutPage.qml"))
}
}
Flow {
id: flow
anchors {
top: parent.top
left: parent.left
right: parent.right
}
height: header.height + Math.max(columnOne.heigh, columnTwo.height)
PageHeader {
id: header
title: qsTr("Settings")
}
//////////////////////////////////////////////////
//
// THE LEFT/TOP COLUMN
//
//////////////////////////////////////////////////
Column {
id: columnOne
width: isPortrait ? parent.width : parent.width / 2
spacing: Theme.paddingMedium
Label {
x: Theme.paddingLarge
text: qsTr("Background service")
color: Theme.highlightColor
}
TextSwitch {
id: daemonEnabledSwitch
text: qsTr("Start background service at startup")
checked: true
onClicked: {
busy = true
checked = !checked
daemonToggle.start()
}
}
Label {
x: Theme.paddingLarge
text: qsTr("Charging settings")
color: Theme.highlightColor
}
Label {
text: qsTr("This option disables charging automatically when the battery has charged above the pausing percentage and enables it again when the battery has depleted below the resuming percentage.")
anchors {
left: parent.left
right: parent.right
leftMargin: Theme.horizontalPageMargin*2
rightMargin: Theme.horizontalPageMargin
}
color: Theme.primaryColor
font.pixelSize: Theme.fontSizeExtraSmall
wrapMode: Text.Wrap
}
TextSwitch {
id: autoStopCharging
text: qsTr("Automatic charging control")
onCheckedChanged: settings.limitEnabled = checked
}
SectionHeader { text: qsTr("Pause charging limit") }
MySlider {
id: highLimitSlider
minimumValue: 6
maximumValue: 100
stepSize: 1
valueText: value + "%"
onValueChanged: {
if(lowLimitSlider.value >= value)
lowLimitSlider.value = value - 1
}
onReleased: save()
function save() {
settings.lowLimit = lowLimitSlider.value
settings.highLimit = value
}
}
AdjustmentButtons {
targetSlider: highLimitSlider
smallChange: 1
largeChange: 5
}
SectionHeader { text: qsTr("Resume charging limit") }
MySlider {
id: lowLimitSlider
minimumValue: 5
maximumValue: 99
stepSize: 1
valueText: value + "%"
onValueChanged: {
if(highLimitSlider.value <= value)
highLimitSlider.value = value + 1
}
onReleased: save()
function save() {
settings.lowLimit = value
settings.highLimit = highLimitSlider.value
}
}
AdjustmentButtons {
targetSlider: lowLimitSlider
smallChange: 1
largeChange: 5
}
}
//////////////////////////////////////////////////
//
// THE RIGHT/BOTTOM COLUMN
//
//////////////////////////////////////////////////
Column {
id: columnTwo
width: isPortrait ? parent.width : parent.width / 2
spacing: Theme.paddingMedium
Label {
x: Theme.paddingLarge
text: qsTr("Notification settings")
color: Theme.highlightColor
}
Label {
text: qsTr("Display visual and audible notifications about reached battery charge levels, when the battery charge is below or above desired percentage.")
anchors {
left: parent.left
right: parent.right
leftMargin: Theme.horizontalPageMargin*2
rightMargin: Theme.horizontalPageMargin
}
color: Theme.primaryColor
font.pixelSize: Theme.fontSizeExtraSmall
wrapMode: Text.Wrap
}
SectionHeader { text: qsTr("Battery full notification") }
MySlider {
id: highAlertSlider
minimumValue: 6
maximumValue: 100
stepSize: 1
valueText: value + "%"
onValueChanged: {
if(lowAlertSlider.value >= value)
lowAlertSlider.value = value - 1
}
onReleased: save()
function save() {
settings.lowAlert = lowAlertSlider.value
settings.highAlert = value
}
}
AdjustmentButtons {
targetSlider: highAlertSlider
smallChange: 1
largeChange: 5
}
SectionHeader { text: qsTr("Battery low notification") }
MySlider {
id: lowAlertSlider
minimumValue: 5
maximumValue: 99
stepSize: 1
valueText: value + "%"
onValueChanged: {
if(highAlertSlider.value <= value)
highAlertSlider.value = value + 1
}
onReleased: save()
function save(){
settings.lowAlert = value
settings.highAlert = highAlertSlider.value
}
}
AdjustmentButtons {
targetSlider: lowAlertSlider
smallChange: 1
largeChange: 5
}
SectionHeader { text: qsTr("Battery high notification interval") }
MySlider {
id: highIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
}
onReleased: save()
function save() {
settings.highNotificationsInterval = value
}
}
AdjustmentButtons {
targetSlider: highIntervalSlider
smallChange: 10
largeChange: 60
}
SectionHeader { text: qsTr("Battery low notification interval") }
MySlider {
id: lowIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
}
onReleased: save()
function save() {
settings.lowNotificationsInterval = value
}
}
AdjustmentButtons {
targetSlider: lowIntervalSlider
smallChange: 10
largeChange: 60
}
Label {
x: Theme.paddingLarge
text: qsTr("Health Notification settings")
color: Theme.highlightColor
}
Label {
text: qsTr("Display visual and audible notifications about battery health, when the battery status exceeds safe values.
This usually means high temperature but can be affected by other factors depending on the hardware.")
anchors {
left: parent.left
right: parent.right
leftMargin: Theme.horizontalPageMargin*2
rightMargin: Theme.horizontalPageMargin
}
color: Theme.primaryColor
font.pixelSize: Theme.fontSizeExtraSmall
wrapMode: Text.Wrap
}
SectionHeader { text: qsTr("Health notification") }
ComboBox {
id: healthSelector
width: parent.width
label: qsTr("Notify on Health status" + ":")
currentIndex: settings.healthAlert
menu: ContextMenu {
MenuItem { text: qsTr("Never") }
MenuItem { text: qsTr("Warning") }
MenuItem { text: qsTr("Critical") }
}
onValueChanged: save()
function save() {
settings.healthAlert = healthSelector.currentIndex
}
}
SectionHeader { text: qsTr("Health notification interval") }
MySlider {
id: healthIntervalSlider
minimumValue: 50
maximumValue: 610
stepSize: 10
valueText: updateValueText()
onValueChanged: updateValueText()
function updateValueText() {
if(value == 50)
return qsTr("Once")
if(value == 610)
return qsTr("Never")
return Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60)
}
onReleased: save()
function save() {
settings.healthNotificationsInterval = value
}
}
AdjustmentButtons {
targetSlider: healthIntervalSlider
smallChange: 10
largeChange: 60
}
}
}
}
}