mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-28 14:43:09 +00:00
kcms/time: Overhaul UI
The old UI was very confusing to use, I changed it so that: - Dialogs are used for the time and date picker, with user confirmation for changes - Tumblers are not used for the time picker, use the time picker component from kclock - Removed seconds selector (since it was always wrong) - Fixed the time zone selector (it didn't work before) - Properly support 24 hour time in the time picker Fixes https://invent.kde.org/plasma/plasma-mobile/-/issues/286
This commit is contained in:
parent
bcc553325c
commit
2329e0a15d
6 changed files with 476 additions and 355 deletions
|
|
@ -4,14 +4,12 @@
|
|||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import org.kde.kirigami 2.5 as Kirigami
|
||||
//import "private"
|
||||
|
||||
//FIXME: shouldn't be a FrameSvgItem
|
||||
Item {
|
||||
id: root
|
||||
clip: true
|
||||
|
||||
//////// API
|
||||
property int day
|
||||
|
|
@ -38,17 +36,17 @@ Item {
|
|||
/////// Implementation
|
||||
Connections {
|
||||
target: root
|
||||
onDayChanged: clockRow.day = root.day
|
||||
onMonthChanged: clockRow.month = root.month
|
||||
onYearChanged: clockRow.year = root.year
|
||||
function onDayChanged() {
|
||||
clockRow.day = root.day;
|
||||
}
|
||||
function onMonthChanged() {
|
||||
clockRow.month = root.month;
|
||||
}
|
||||
function onYearChanged() {
|
||||
clockRow.year = root.year;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//imagePath: "widgets/picker"
|
||||
width: clockRow.width + root._margin * 2
|
||||
height: clockRow.height + root._margin * 2
|
||||
|
||||
|
||||
Timer {
|
||||
id: userConfiguringTimer
|
||||
repeat: false
|
||||
|
|
@ -62,11 +60,10 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
RowLayout {
|
||||
id: clockRow
|
||||
spacing: 3
|
||||
x: root._margin
|
||||
y: root._margin
|
||||
anchors.margins: _margin
|
||||
anchors.fill: parent
|
||||
|
||||
property int day
|
||||
property int month
|
||||
|
|
@ -79,6 +76,7 @@ Item {
|
|||
|
||||
Digit {
|
||||
id: dayDigit
|
||||
Layout.fillWidth: true
|
||||
model: {
|
||||
var dd = new Date(year, month, 0);
|
||||
return dd.getDate()
|
||||
|
|
@ -96,17 +94,20 @@ Item {
|
|||
text: index+1
|
||||
color: Kirigami.Theme.textColor
|
||||
font.pointSize: root.fontSize
|
||||
opacity: PathView.itemOpacity
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
Digit {
|
||||
id: monthDigit
|
||||
Layout.fillWidth: true
|
||||
model: 12
|
||||
currentIndex: month -1
|
||||
onSelectedIndexChanged: {
|
||||
|
|
@ -132,14 +133,18 @@ Item {
|
|||
text: "0000"
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
Digit {
|
||||
id: yearDigit
|
||||
Layout.fillWidth: true
|
||||
//FIXME: yes, this is a tad lame ;)
|
||||
model: 3000
|
||||
currentIndex: year
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ Item {
|
|||
text: index < 10 ? "0"+index : index
|
||||
color: Kirigami.Theme.textColor
|
||||
font.pointSize: root.fontSize
|
||||
opacity: PathView.itemOpacity
|
||||
}
|
||||
|
||||
onMovingChanged: {
|
||||
|
|
|
|||
|
|
@ -1,214 +1,117 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
|
||||
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import QtQuick 2.1
|
||||
import org.kde.kcmutils
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.kirigami 2.4 as Kirigami
|
||||
|
||||
|
||||
//FIXME: shouldn't be a FrameSvgItem
|
||||
Item {
|
||||
RowLayout {
|
||||
id: root
|
||||
clip: true
|
||||
|
||||
property int hours: 0
|
||||
property int minutes: 0
|
||||
readonly property bool twelveHourTime: !kcm.twentyFour // am/pm
|
||||
|
||||
onHoursChanged: updateHours()
|
||||
onMinutesChanged: minutesSpinbox.value = minutes
|
||||
onTwelveHourTimeChanged: updateHours()
|
||||
|
||||
//////// API
|
||||
property alias hours: clockRow.hours
|
||||
property alias minutes: clockRow.minutes
|
||||
property alias seconds: clockRow.seconds
|
||||
|
||||
property bool userConfiguring: false
|
||||
property bool twentyFour: true
|
||||
|
||||
property int fontSize: 14
|
||||
property int _margin: Kirigami.Units.gridUnit
|
||||
|
||||
property string timeString: clockRow.twoDigitString(hours) + ":" + clockRow.twoDigitString(minutes) + ":" + clockRow.twoDigitString(seconds)
|
||||
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
// onHoursChanged: print("H : " + root.hours)
|
||||
// onMinutesChanged: print("M : " + root.minutes)
|
||||
// onSecondsChanged: print("S : " + root.seconds)
|
||||
Component.onCompleted: {
|
||||
// needs to manually be triggered because onHoursChanged doesn't emit when set to 0
|
||||
updateHours();
|
||||
}
|
||||
|
||||
Behavior on width {
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: 250
|
||||
}
|
||||
NumberAnimation {
|
||||
//duration: Kirigami.Units.longDuration
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
function updateHours() {
|
||||
// manually do this instead of a binding so we can set the value without worrying about binding eval order
|
||||
hoursSpinbox.from = root.twelveHourTime ? 1 : 0;
|
||||
hoursSpinbox.to = root.twelveHourTime ? 12 : 23;
|
||||
|
||||
if (twelveHourTime) {
|
||||
hoursSpinbox.value = ((hours % 12) == 0) ? 12 : hours % 12;
|
||||
} else {
|
||||
hoursSpinbox.value = hours;
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
// KLocale.Locale {
|
||||
// id: locale
|
||||
// }
|
||||
|
||||
//imagePath: "widgets/picker"
|
||||
width: clockRow.width + root._margin
|
||||
height: clockRow.height + root._margin * 2
|
||||
|
||||
Timer {
|
||||
id: userConfiguringTimer
|
||||
repeat: false
|
||||
interval: 1500
|
||||
running: false
|
||||
onTriggered: {
|
||||
root.hours = clockRow.hours
|
||||
root.minutes = clockRow.minutes
|
||||
root.seconds = clockRow.seconds
|
||||
userConfiguring = false
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
opacity: 0.3
|
||||
border.color: Kirigami.Theme.textColor
|
||||
border.width: 1
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Row {
|
||||
id: clockRow
|
||||
spacing: Kirigami.Units.gridUnit
|
||||
x: root._margin
|
||||
y: root._margin
|
||||
|
||||
property int hours
|
||||
property int minutes
|
||||
property int seconds
|
||||
|
||||
function twoDigitString(number)
|
||||
{
|
||||
return number < 10 ? "0"+number : number
|
||||
}
|
||||
|
||||
Digit {
|
||||
id: hoursDigit
|
||||
model: root.twentyFour ? 24 : 12
|
||||
currentIndex: root.twentyFour || hours < 12 ? hours : hours - 12
|
||||
delegate: Text {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
width: hoursDigit.width
|
||||
property int ownIndex: index
|
||||
text: (!root.twentyFour && index == 0) ? "12" : clockRow.twoDigitString(index)
|
||||
font.pointSize: root.fontSize
|
||||
color: Kirigami.Theme.textColor
|
||||
opacity: PathView.itemOpacity
|
||||
}
|
||||
onSelectedIndexChanged: {
|
||||
print("Bah");
|
||||
if (selectedIndex > -1) {
|
||||
if (root.twentyFour ||
|
||||
meridiaeDigit.isAm) {
|
||||
hours = selectedIndex
|
||||
// note: for 12-hour time, we have hours from 1-12 (0'o clock displays as 12)
|
||||
// for 24-hour time, we have hours from 0-23
|
||||
TimePickerSpinBox {
|
||||
id: hoursSpinbox
|
||||
|
||||
onValueModified: {
|
||||
if (root.twelveHourTime) {
|
||||
if (root.hours >= 12) {
|
||||
root.hours = value % 12 + 12;
|
||||
} else {
|
||||
hours = selectedIndex + 12
|
||||
root.hours = value % 12;
|
||||
}
|
||||
} else {
|
||||
root.hours = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
level: 1
|
||||
text: ":"
|
||||
}
|
||||
|
||||
TimePickerSpinBox {
|
||||
id: minutesSpinbox
|
||||
from: 0
|
||||
to: 59
|
||||
|
||||
onValueModified: {
|
||||
root.minutes = value;
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: amPmToggle
|
||||
visible: root.twelveHourTime
|
||||
leftPadding: Kirigami.Units.largeSpacing
|
||||
rightPadding: Kirigami.Units.largeSpacing
|
||||
topPadding: Kirigami.Units.largeSpacing
|
||||
bottomPadding: Kirigami.Units.largeSpacing
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: label.implicitWidth
|
||||
implicitHeight: label.implicitHeight
|
||||
Label {
|
||||
id: label
|
||||
anchors.centerIn: parent
|
||||
font.weight: Font.Light
|
||||
font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.3
|
||||
text: i18n(hours < 12 ? i18n("AM") : i18n("PM"))
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
border.color: {
|
||||
if (amPmToggle.enabled && (amPmToggle.visualFocus || amPmToggle.hovered || amPmToggle.down)) {
|
||||
return Kirigami.Theme.focusColor
|
||||
} else {
|
||||
return Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
|
||||
}
|
||||
}
|
||||
border.width: 1
|
||||
color: amPmToggle.down ? Kirigami.Theme.alternateBackgroundColor : Kirigami.Theme.backgroundColor
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Digit {
|
||||
id: minutesDigit
|
||||
model: 60
|
||||
currentIndex: minutes
|
||||
onSelectedIndexChanged: {
|
||||
if (selectedIndex > -1) {
|
||||
minutes = selectedIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Digit {
|
||||
id: secondsDigit
|
||||
model: 60
|
||||
currentIndex: seconds
|
||||
onSelectedIndexChanged: {
|
||||
if (selectedIndex > -1) {
|
||||
seconds = selectedIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.Separator {
|
||||
opacity: meridiaeDigit.opacity == 0 ? 0 : 1
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
Digit {
|
||||
id: meridiaeDigit
|
||||
visible: opacity != 0
|
||||
opacity: root.twentyFour ? 0 : 1
|
||||
property bool isAm: (selectedIndex > -1) ? (selectedIndex < 1) : (currentIndex < 1)
|
||||
model: ListModel {
|
||||
ListElement {
|
||||
meridiae: "AM"
|
||||
}
|
||||
ListElement {
|
||||
meridiae: "PM"
|
||||
}
|
||||
}
|
||||
delegate: Text {
|
||||
width: meridiaeDigit.width
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
property int ownIndex: index
|
||||
text: meridiae
|
||||
color: Kirigami.Theme.textColor
|
||||
font.pointSize: root.fontSize
|
||||
//opacity: PathView.itemOpacity
|
||||
}
|
||||
currentIndex: hours > 12 ? 1 : 0
|
||||
onSelectedIndexChanged: {
|
||||
if (selectedIndex > -1) {
|
||||
//AM
|
||||
if (selectedIndex == 0) {
|
||||
hours -= 12
|
||||
//PM
|
||||
} else {
|
||||
hours += 12
|
||||
}
|
||||
}
|
||||
}
|
||||
width: meridiaePlaceHolder.width + root._margin
|
||||
Text {
|
||||
id: meridiaePlaceHolder
|
||||
visible: false
|
||||
font.pointSize: root.fontSize
|
||||
text: "00"
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
onClicked: {
|
||||
if (root.hours >= 12) {
|
||||
root.hours -= 12;
|
||||
} else {
|
||||
root.hours += 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
158
kcms/time/ui/TimePickerSpinBox.qml
Normal file
158
kcms/time/ui/TimePickerSpinBox.qml
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Templates as T
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property alias from: spinBox.from
|
||||
property alias to: spinBox.to
|
||||
property alias value: spinBox.value
|
||||
|
||||
signal valueModified()
|
||||
|
||||
T.SpinBox {
|
||||
id: spinBox
|
||||
visible: false
|
||||
stepSize: 1
|
||||
|
||||
onValueModified: root.valueModified()
|
||||
|
||||
validator: IntValidator {
|
||||
locale: spinBox.locale.name
|
||||
bottom: Math.min(spinBox.from, spinBox.to)
|
||||
top: Math.max(spinBox.from, spinBox.to)
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
Kirigami.Theme.inherit: false
|
||||
|
||||
implicitWidth: Kirigami.Units.gridUnit * 4
|
||||
implicitHeight: column.implicitHeight
|
||||
|
||||
readonly property color buttonColor: Kirigami.Theme.backgroundColor
|
||||
readonly property color buttonHoverColor: Qt.darker(buttonColor, 1.05)
|
||||
readonly property color buttonPressedColor: Qt.darker(buttonColor, 1.2)
|
||||
readonly property color buttonBorderColor: Qt.alpha(Kirigami.Theme.textColor, 0.3)
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: 0
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
TimePickerSpinBoxButton {
|
||||
Layout.fillWidth: true
|
||||
onClicked: {
|
||||
spinBox.increase();
|
||||
spinBox.valueModified();
|
||||
}
|
||||
icon.name: 'list-add-symbolic'
|
||||
isStart: true
|
||||
isEnd: false
|
||||
enabled: spinBox.value < spinBox.to
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: textInput.implicitHeight
|
||||
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
color: Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
color: Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
|
||||
}
|
||||
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
property int wheelDelta: 0
|
||||
|
||||
onExited: wheelDelta = 0
|
||||
onWheel: {
|
||||
wheelDelta += wheel.angleDelta.y;
|
||||
// magic number 120 for common "one click"
|
||||
// See: http://qt-project.org/doc/qt-5/qml-qtquick-wheelevent.html#angleDelta-prop
|
||||
while (wheelDelta >= 120) {
|
||||
wheelDelta -= 120;
|
||||
spinBox.increase();
|
||||
spinBox.valueModified();
|
||||
}
|
||||
while (wheelDelta <= -120) {
|
||||
wheelDelta += 120;
|
||||
spinBox.decrease();
|
||||
spinBox.valueModified();
|
||||
}
|
||||
}
|
||||
|
||||
// Normally the TextInput does this automatically, but the MouseArea on
|
||||
// top of it blocks that behavior, so we need to explicitly do it here
|
||||
cursorShape: Qt.IBeamCursor
|
||||
|
||||
TextInput {
|
||||
id: textInput
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 2.5)
|
||||
font.weight: Font.Light
|
||||
|
||||
color: Kirigami.Theme.textColor
|
||||
selectionColor: Kirigami.Theme.highlightColor
|
||||
selectedTextColor: Kirigami.Theme.highlightedTextColor
|
||||
selectByMouse: true
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||
|
||||
function applyTextBinding() {
|
||||
text = Qt.binding(function () { return spinBox.displayText.length == 1 ? '0' + spinBox.displayText : spinBox.displayText });
|
||||
}
|
||||
|
||||
Component.onCompleted: applyTextBinding()
|
||||
onEditingFinished: {
|
||||
spinBox.value = parseInt(text);
|
||||
spinBox.valueModified();
|
||||
applyTextBinding();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimePickerSpinBoxButton {
|
||||
Layout.fillWidth: true
|
||||
onClicked: {
|
||||
spinBox.decrease();
|
||||
spinBox.valueModified();
|
||||
}
|
||||
icon.name: 'list-remove-symbolic'
|
||||
isStart: false
|
||||
isEnd: true
|
||||
enabled: spinBox.value > spinBox.from
|
||||
}
|
||||
}
|
||||
}
|
||||
50
kcms/time/ui/TimePickerSpinBoxButton.qml
Normal file
50
kcms/time/ui/TimePickerSpinBoxButton.qml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2023 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
QQC2.Button {
|
||||
id: root
|
||||
autoRepeat: true
|
||||
|
||||
required property bool isEnd
|
||||
required property bool isStart
|
||||
|
||||
readonly property color borderColor: if (enabled && (visualFocus || hovered || down)) {
|
||||
return Kirigami.Theme.focusColor
|
||||
} else {
|
||||
return Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
|
||||
}
|
||||
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
contentItem: Item {
|
||||
implicitHeight: Kirigami.Units.gridUnit * 2
|
||||
Kirigami.Icon {
|
||||
source: root.icon.name
|
||||
anchors.centerIn: parent
|
||||
implicitHeight: Kirigami.Units.iconSizes.small
|
||||
implicitWidth: Kirigami.Units.iconSizes.small
|
||||
}
|
||||
}
|
||||
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Button
|
||||
color: root.down ? Kirigami.Theme.alternateBackgroundColor : Kirigami.Theme.backgroundColor
|
||||
|
||||
corners {
|
||||
topLeftRadius: root.isStart ? 4 : 0
|
||||
topRightRadius: root.isStart ? 4 : 0
|
||||
bottomLeftRadius: root.isEnd ? 4 : 0
|
||||
bottomRightRadius: root.isEnd ? 4 : 0
|
||||
}
|
||||
|
||||
border {
|
||||
width: 1
|
||||
color: root.borderColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// -*- coding: iso-8859-1 -*-
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2011 Sebastian Kügler <sebas@kde.org>
|
||||
* SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
|
@ -47,7 +48,7 @@ SimpleKCM {
|
|||
id: timeZoneSelect
|
||||
text: i18n("Timezone")
|
||||
description: kcm.timeZone
|
||||
onClicked: timeZonePickerSheet.open()
|
||||
onClicked: timeZonePickerDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,8 +65,8 @@ SimpleKCM {
|
|||
onCheckedChanged: {
|
||||
kcm.useNtp = checked
|
||||
if (!checked) {
|
||||
kcm.ntpServer = ""
|
||||
kcm.saveTime()
|
||||
kcm.ntpServer = "";
|
||||
kcm.saveTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,168 +77,173 @@ SimpleKCM {
|
|||
id: timeSelect
|
||||
enabled: !ntpCheckBox.checked
|
||||
icon.name: "clock"
|
||||
text: i18n("Current Time")
|
||||
description: Qt.formatTime(kcm.currentTime, Locale.LongFormat)
|
||||
onClicked: timePickerSheet.open()
|
||||
text: i18n("System Time")
|
||||
description: Qt.formatTime(kcm.currentTime, kcm.twentyFour ? 'hh:mm' : 'hh:mm ap')
|
||||
onClicked: timePickerDialog.open()
|
||||
}
|
||||
|
||||
FormCard.FormDelegateSeparator { above: timeSelect; below: dateSelect }
|
||||
|
||||
FormCard.FormButtonDelegate {
|
||||
id: dateSelect
|
||||
enabled: !ntpCheckBox.checked
|
||||
icon.name: "view-calendar"
|
||||
text: i18n("Date")
|
||||
text: i18n("System Date")
|
||||
description: Qt.formatDate(kcm.currentDate, Locale.LongFormat)
|
||||
onClicked: datePickerSheet.open()
|
||||
icon.name: "view-calendar"
|
||||
enabled: !ntpCheckBox.checked
|
||||
onClicked: datePickerDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data: Kirigami.OverlaySheet {
|
||||
id: timeZonePickerSheet
|
||||
data: [
|
||||
Kirigami.Dialog {
|
||||
id: timeZonePickerDialog
|
||||
title: i18nc("@title:window", "Pick Timezone")
|
||||
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
|
||||
|
||||
header: ColumnLayout {
|
||||
Kirigami.Heading {
|
||||
text: i18nc("@title:window", "Pick Timezone")
|
||||
Layout.fillWidth: true
|
||||
property string selectedTimeZoneId
|
||||
|
||||
onOpened: {
|
||||
selectedTimeZoneId = kcm.timeZone;
|
||||
}
|
||||
|
||||
Kirigami.SearchField {
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: kcm.timeZonesModel.filterString = text
|
||||
onAccepted: {
|
||||
kcm.saveTimeZone(selectedTimeZoneId)
|
||||
}
|
||||
}
|
||||
|
||||
footer: RowLayout {
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
ListView {
|
||||
id: listView
|
||||
headerPositioning: ListView.OverlayHeader
|
||||
implicitWidth: 18 * Kirigami.Units.gridUnit
|
||||
implicitHeight: 18 * Kirigami.Units.gridUnit
|
||||
|
||||
text: i18nc("@action:button", "Close")
|
||||
header: Controls.Control {
|
||||
z: 1
|
||||
|
||||
onClicked: timeZonePickerSheet.close()
|
||||
}
|
||||
}
|
||||
topPadding: Kirigami.Units.smallSpacing
|
||||
bottomPadding: 0
|
||||
leftPadding: Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
|
||||
background: Rectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
|
||||
clip: true
|
||||
implicitWidth: 18 * Kirigami.Units.gridUnit
|
||||
|
||||
topMargin: Math.round(Kirigami.Units.smallSpacing / 2)
|
||||
bottomMargin: Math.round(Kirigami.Units.smallSpacing / 2)
|
||||
|
||||
model: kcm.timeZonesModel
|
||||
delegate: Delegates.RoundedItemDelegate {
|
||||
required property string region
|
||||
required property string city
|
||||
|
||||
width: ListView.view.width
|
||||
|
||||
text: {
|
||||
if (region) {
|
||||
return "%1 / %2".arg(region).arg(city)
|
||||
} else {
|
||||
return city
|
||||
contentItem: ColumnLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
Kirigami.SearchField {
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: kcm.timeZonesModel.filterString = text
|
||||
}
|
||||
Kirigami.Separator { Layout.fillWidth: true }
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
timeZonePickerSheet.close()
|
||||
kcm.saveTimeZone(model.timeZoneId)
|
||||
model: kcm.timeZonesModel
|
||||
delegate: Controls.RadioDelegate {
|
||||
z: -1
|
||||
width: ListView.view.width
|
||||
checked: timeZonePickerDialog.selectedTimeZoneId == model.timeZoneId
|
||||
|
||||
text: {
|
||||
if (model.region) {
|
||||
return "%1 / %2".arg(model.region).arg(model.city);
|
||||
} else {
|
||||
return model.city;
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
timeZonePickerDialog.selectedTimeZoneId = model.timeZoneId;
|
||||
checked = Qt.binding(() => timeZonePickerDialog.selectedTimeZoneId == model.timeZoneId);
|
||||
console.log(timeZonePickerDialog.selectedTimeZoneId + ' ' + model.timeZoneId + ' ' + (timeZonePickerDialog.selectedTimeZoneId == model.timeZoneId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: timePickerSheet
|
||||
header: Kirigami.Heading { text: i18n("Pick Time") }
|
||||
TimePicker {
|
||||
id: timePicker
|
||||
enabled: !ntpCheckBox.checked
|
||||
twentyFour: hourFormatSwitch.checked
|
||||
Kirigami.PromptDialog {
|
||||
id: datePickerDialog
|
||||
title: i18n("Pick System Date")
|
||||
topPadding: Kirigami.Units.largeSpacing
|
||||
bottomPadding: Kirigami.Units.largeSpacing
|
||||
preferredWidth: Kirigami.Units.gridUnit * 15
|
||||
preferredHeight: Kirigami.Units.gridUnit * 13
|
||||
|
||||
implicitWidth: Kirigami.Units.gridUnit * 15
|
||||
standardButtons: Kirigami.Dialog.Save | Kirigami.Dialog.Cancel
|
||||
|
||||
Component.onCompleted: {
|
||||
onAccepted: {
|
||||
kcm.currentDate = datePicker.isoDate;
|
||||
kcm.saveTime();
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
let date = new Date(kcm.currentDate)
|
||||
datePicker.day = date.getDate();
|
||||
datePicker.month = date.getMonth() + 1;
|
||||
datePicker.year = date.getFullYear();
|
||||
}
|
||||
|
||||
DatePicker {
|
||||
id: datePicker
|
||||
implicitHeight: Kirigami.Units.gridUnit * 6
|
||||
|
||||
Connections {
|
||||
target: kcm
|
||||
function onCurrentDateChanged() {
|
||||
if (datePickerDialog.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
let date = new Date(kcm.currentDate);
|
||||
datePicker.day = date.getDate();
|
||||
datePicker.month = date.getMonth() + 1;
|
||||
datePicker.year = date.getFullYear();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Kirigami.PromptDialog {
|
||||
id: timePickerDialog
|
||||
title: i18n("Pick System Time")
|
||||
preferredWidth: Kirigami.Units.gridUnit * 15
|
||||
topPadding: Kirigami.Units.largeSpacing
|
||||
bottomPadding: Kirigami.Units.largeSpacing
|
||||
|
||||
standardButtons: Kirigami.Dialog.Save | Kirigami.Dialog.Cancel
|
||||
|
||||
onAccepted: {
|
||||
kcm.currentTime = String(timePicker.hours).padStart(2, '0')
|
||||
+ ':'
|
||||
+ String(timePicker.minutes).padStart(2, '0')
|
||||
+ ':00';
|
||||
kcm.saveTime();
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
var date = new Date(kcm.currentTime);
|
||||
timePicker.hours = date.getHours();
|
||||
timePicker.minutes = date.getMinutes();
|
||||
timePicker.seconds = date.getSeconds();
|
||||
console.log(date + ' ' + date.getHours() + date.getMinutes())
|
||||
}
|
||||
Connections {
|
||||
target: kcm
|
||||
function onCurrentTimeChanged() {
|
||||
if (timePicker.userConfiguring) {
|
||||
return;
|
||||
}
|
||||
|
||||
var date = new Date(kcm.currentTime);
|
||||
timePicker.hours = date.getHours();
|
||||
timePicker.minutes = date.getMinutes();
|
||||
timePicker.seconds = date.getSeconds();
|
||||
TimePicker {
|
||||
id: timePicker
|
||||
|
||||
Connections {
|
||||
target: kcm
|
||||
function onCurrentTimeChanged() {
|
||||
if (timePicker.userConfiguring) {
|
||||
return;
|
||||
}
|
||||
|
||||
var date = new Date(kcm.currentTime);
|
||||
timePicker.hours = date.getHours();
|
||||
timePicker.minutes = date.getMinutes();
|
||||
}
|
||||
}
|
||||
}
|
||||
onUserConfiguringChanged: {
|
||||
kcm.currentTime = timeString
|
||||
kcm.saveTime()
|
||||
}
|
||||
}
|
||||
footer: RowLayout {
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
text: i18nc("@action:button", "Close")
|
||||
|
||||
onClicked: timePickerSheet.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: datePickerSheet
|
||||
header: Kirigami.Heading { text: i18n("Pick Date") }
|
||||
DatePicker {
|
||||
id: datePicker
|
||||
enabled: !ntpCheckBox.checked
|
||||
|
||||
implicitWidth: width > Kirigami.Units.gridUnit * 15 ? width : Kirigami.Units.gridUnit * 15
|
||||
|
||||
Component.onCompleted: {
|
||||
var date = new Date(kcm.currentDate)
|
||||
datePicker.day = date.getDate()
|
||||
datePicker.month = date.getMonth()+1
|
||||
datePicker.year = date.getFullYear()
|
||||
}
|
||||
Connections {
|
||||
target: kcm
|
||||
function onCurrentDateChanged() {
|
||||
if (datePicker.userConfiguring) {
|
||||
return
|
||||
}
|
||||
|
||||
var date = new Date(kcm.currentDate)
|
||||
|
||||
datePicker.day = date.getDate()
|
||||
datePicker.month = date.getMonth()+1
|
||||
datePicker.year = date.getFullYear()
|
||||
}
|
||||
}
|
||||
onUserConfiguringChanged: {
|
||||
kcm.currentDate = isoDate
|
||||
kcm.saveTime()
|
||||
}
|
||||
}
|
||||
footer: RowLayout {
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
text: i18nc("@action:button", "Close")
|
||||
|
||||
onClicked: datePickerSheet.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue