LocationTab: add setting for first day of the week

Calendar: replace MonthGrid with custom solution to allow changing first
day of the week
This commit is contained in:
lysec
2025-10-19 16:46:53 +02:00
parent 8b5f06aec6
commit af7498155c
12 changed files with 185 additions and 44 deletions
+97 -30
View File
@@ -22,7 +22,24 @@ NPanel {
anchors.margins: Style.marginL
spacing: Style.marginM
readonly property int firstDayOfWeek: Qt.locale().firstDayOfWeek
readonly property int firstDayOfWeek: {
var setting = Settings.data.location.firstDayOfWeek
if (!setting)
return Qt.Monday
switch (setting) {
case "auto":
return Qt.locale().firstDayOfWeek
case "monday":
return Qt.Monday
case "saturday":
return 6 // Qt.Saturday
case "sunday":
return Qt.Sunday
default:
return Qt.Monday
}
}
property bool isCurrentMonth: checkIsCurrentMonth()
readonly property bool weatherReady: Settings.data.location.weatherEnabled && (LocationService.data.weather !== null)
@@ -278,7 +295,7 @@ NPanel {
}
}
// ... (rest of the file is unchanged) ...
// Weather forecast
RowLayout {
visible: weatherReady
Layout.fillWidth: true
@@ -446,38 +463,88 @@ NPanel {
}
}
}
MonthGrid {
GridLayout {
id: grid
Layout.fillWidth: true
Layout.fillHeight: true
spacing: Style.marginXXS
month: Time.date.getMonth()
year: Time.date.getFullYear()
locale: Qt.locale()
delegate: Item {
Rectangle {
width: Style.baseWidgetSize * 0.9
height: Style.baseWidgetSize * 0.9
anchors.centerIn: parent
radius: Style.radiusM
color: model.today ? Color.mSecondary : Color.transparent
NText {
anchors.centerIn: parent
text: model.day
color: {
if (model.today)
return Color.mOnSecondary
if (model.month === grid.month)
return Color.mOnSurface
return Color.mOnSurfaceVariant
}
opacity: model.month === grid.month ? 1.0 : 0.4
pointSize: Style.fontSizeM
font.weight: model.today ? Style.fontWeightBold : Style.fontWeightMedium
columns: 7
rowSpacing: Style.marginXXS
columnSpacing: Style.marginXXS
property int month: Time.date.getMonth()
property int year: Time.date.getFullYear()
Repeater {
model: 42 // 6 rows × 7 days
delegate: Item {
id: cellItem
Layout.fillWidth: true
Layout.fillHeight: true
required property int index
property int cellDay: {
let firstOfMonth = new Date(grid.year, grid.month, 1)
let firstDayOfWeek = content.firstDayOfWeek
let firstOfMonthDayOfWeek = firstOfMonth.getDay()
let daysBeforeFirst = (firstOfMonthDayOfWeek - firstDayOfWeek + 7) % 7
let startDate = new Date(grid.year, grid.month, 1 - daysBeforeFirst)
let currentDate = new Date(startDate)
currentDate.setDate(startDate.getDate() + cellItem.index)
return currentDate.getDate()
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
property int cellMonth: {
let firstOfMonth = new Date(grid.year, grid.month, 1)
let firstDayOfWeek = content.firstDayOfWeek
let firstOfMonthDayOfWeek = firstOfMonth.getDay()
let daysBeforeFirst = (firstOfMonthDayOfWeek - firstDayOfWeek + 7) % 7
let startDate = new Date(grid.year, grid.month, 1 - daysBeforeFirst)
let currentDate = new Date(startDate)
currentDate.setDate(startDate.getDate() + cellItem.index)
return currentDate.getMonth()
}
property int cellYear: {
let firstOfMonth = new Date(grid.year, grid.month, 1)
let firstDayOfWeek = content.firstDayOfWeek
let firstOfMonthDayOfWeek = firstOfMonth.getDay()
let daysBeforeFirst = (firstOfMonthDayOfWeek - firstDayOfWeek + 7) % 7
let startDate = new Date(grid.year, grid.month, 1 - daysBeforeFirst)
let currentDate = new Date(startDate)
currentDate.setDate(startDate.getDate() + cellItem.index)
return currentDate.getFullYear()
}
property bool isToday: cellDay === Time.date.getDate() && cellMonth === Time.date.getMonth() && cellYear === Time.date.getFullYear()
property bool isCurrentMonth: cellMonth === grid.month
Rectangle {
width: Style.baseWidgetSize * 0.9
height: Style.baseWidgetSize * 0.9
anchors.centerIn: parent
radius: Style.radiusM
color: parent.isToday ? Color.mSecondary : Color.transparent
NText {
anchors.centerIn: parent
text: cellItem.cellDay
color: {
if (cellItem.isToday)
return Color.mOnSecondary
if (cellItem.isCurrentMonth)
return Color.mOnSurface
return Color.mOnSurfaceVariant
}
opacity: cellItem.isCurrentMonth ? 1.0 : 0.5
pointSize: Style.fontSizeM
font.weight: cellItem.isToday ? Style.fontWeightBold : Style.fontWeightSemiBold
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
}
+16 -12
View File
@@ -204,20 +204,24 @@ ColumnLayout {
Layout.fillWidth: true
label: I18n.tr("settings.general.language.select.label")
description: I18n.tr("settings.general.language.select.description")
model: [
{ "key": "", "name": I18n.tr("settings.general.language.select.auto-detect") + " (" + I18n.systemDetectedLangCode + ")" }
].concat(I18n.availableLanguages.map(function(langCode) {
return { "key": langCode, "name": langCode }
}))
model: [{
"key": "",
"name": I18n.tr("settings.general.language.select.auto-detect") + " (" + I18n.systemDetectedLangCode + ")"
}].concat(I18n.availableLanguages.map(function (langCode) {
return {
"key": langCode,
"name": langCode
}
}))
currentKey: Settings.data.general.language
onSelected: key => {
Settings.data.general.language = key
if (key === "") {
I18n.detectLanguage() // Re-detect system language if "Automatic" is selected
} else {
I18n.setLanguage(key) // Set specific language
}
}
Settings.data.general.language = key
if (key === "") {
I18n.detectLanguage() // Re-detect system language if "Automatic" is selected
} else {
I18n.setLanguage(key) // Set specific language
}
}
}
}
+21
View File
@@ -117,6 +117,27 @@ ColumnLayout {
checked: Settings.data.location.showWeekNumberInCalendar
onToggled: checked => Settings.data.location.showWeekNumberInCalendar = checked
}
NComboBox {
label: I18n.tr("settings.location.date-time.first-day-of-week.label")
description: I18n.tr("settings.location.date-time.first-day-of-week.description")
minimumWidth: 220 * Style.uiScaleRatio
model: [{
"key": "auto",
"name": I18n.tr("settings.location.date-time.first-day-of-week.auto")
}, {
"key": "monday",
"name": I18n.tr("settings.location.date-time.first-day-of-week.monday")
}, {
"key": "saturday",
"name": I18n.tr("settings.location.date-time.first-day-of-week.saturday")
}, {
"key": "sunday",
"name": I18n.tr("settings.location.date-time.first-day-of-week.sunday")
}]
currentKey: Settings.data.location.firstDayOfWeek
onSelected: key => Settings.data.location.firstDayOfWeek = key
}
}
NDivider {