add noctalia and fuzzel

This commit is contained in:
2026-05-23 21:20:58 +02:00
parent 364801f1a3
commit 9a3eceb3ab
599 changed files with 204318 additions and 0 deletions
@@ -0,0 +1,164 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
property list<var> cardsModel: []
property list<var> cardsDefault: [
{
"id": "calendar-header-card",
"text": I18n.tr("panels.location.calendar-header-label"),
"enabled": true,
"required": true
},
{
"id": "calendar-month-card",
"text": I18n.tr("panels.location.calendar-month-label"),
"enabled": true,
"required": false
},
{
"id": "weather-card",
"text": I18n.tr("common.weather"),
"enabled": true,
"required": false
}
]
function saveCards() {
var toSave = [];
for (var i = 0; i < cardsModel.length; i++) {
toSave.push({
"id": cardsModel[i].id,
"enabled": cardsModel[i].enabled
});
}
Settings.data.calendar.cards = toSave;
}
Component.onCompleted: {
// Starts empty
cardsModel = [];
// Add the cards available in settings
for (var i = 0; i < Settings.data.calendar.cards.length; i++) {
const settingCard = Settings.data.calendar.cards[i];
for (var j = 0; j < cardsDefault.length; j++) {
if (settingCard.id === cardsDefault[j].id) {
var card = cardsDefault[j];
card.enabled = settingCard.enabled;
// Auto-disable weather card if weather is disabled
if (card.id === "weather-card" && !Settings.data.location.weatherEnabled) {
card.enabled = false;
}
cardsModel.push(card);
}
}
}
// Add any missing cards from default
for (var i = 0; i < cardsDefault.length; i++) {
var found = false;
for (var j = 0; j < cardsModel.length; j++) {
if (cardsModel[j].id === cardsDefault[i].id) {
found = true;
break;
}
}
if (!found) {
var card = cardsDefault[i];
// Auto-disable weather card if weather is disabled
if (card.id === "weather-card" && !Settings.data.location.weatherEnabled) {
card.enabled = false;
}
cardsModel.push(card);
}
}
saveCards();
}
// Clock style section
ColumnLayout {
spacing: Style.marginM
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.location.date-time-use-analog-label")
description: I18n.tr("panels.location.date-time-use-analog-description")
checked: Settings.data.location.analogClockInCalendar
onToggled: checked => Settings.data.location.analogClockInCalendar = checked
}
NToggle {
label: I18n.tr("panels.location.date-time-week-numbers-label")
description: I18n.tr("panels.location.date-time-week-numbers-description")
checked: Settings.data.location.showWeekNumberInCalendar
onToggled: checked => Settings.data.location.showWeekNumberInCalendar = checked
}
NToggle {
label: I18n.tr("panels.location.date-time-show-events-label")
description: I18n.tr("panels.location.date-time-show-events-description")
checked: Settings.data.location.showCalendarEvents
onToggled: checked => Settings.data.location.showCalendarEvents = checked
}
}
NDivider {
Layout.fillWidth: true
}
// Calendar Cards Management Section
ColumnLayout {
spacing: Style.marginXXS
Layout.fillWidth: true
Connections {
target: Settings.data.location
function onWeatherEnabledChanged() {
// Auto-disable weather card when weather is disabled
var newModel = cardsModel.slice();
for (var i = 0; i < newModel.length; i++) {
if (newModel[i].id === "weather-card") {
newModel[i] = Object.assign({}, newModel[i], {
"enabled": Settings.data.location.weatherEnabled
});
cardsModel = newModel;
saveCards();
break;
}
}
}
}
NReorderCheckboxes {
Layout.fillWidth: true
model: cardsModel
disabledIds: Settings.data.location.weatherEnabled ? [] : ["weather-card"]
onItemToggled: function (index, enabled) {
var newModel = cardsModel.slice();
newModel[index] = Object.assign({}, newModel[index], {
"enabled": enabled
});
cardsModel = newModel;
saveCards();
}
onItemsReordered: function (fromIndex, toIndex) {
var newModel = cardsModel.slice();
var item = newModel.splice(fromIndex, 1)[0];
newModel.splice(toIndex, 0, item);
cardsModel = newModel;
saveCards();
}
}
}
}
@@ -0,0 +1,46 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.location.date-time-12hour-format-label")
description: I18n.tr("panels.location.date-time-12hour-format-description")
checked: Settings.data.location.use12hourFormat
onToggled: checked => Settings.data.location.use12hourFormat = checked
}
NComboBox {
label: I18n.tr("panels.location.date-time-first-day-of-week-label")
description: I18n.tr("panels.location.date-time-first-day-of-week-description")
currentKey: Settings.data.location.firstDayOfWeek.toString()
minimumWidth: 260 * Style.uiScaleRatio
model: [
{
"key": "-1",
"name": I18n.tr("panels.location.date-time-first-day-of-week-automatic")
},
{
"key": "6",
"name": I18n.locale.dayName(6, Locale.LongFormat).trim()
} // Saturday
,
{
"key": "0",
"name": I18n.locale.dayName(0, Locale.LongFormat).trim()
} // Sunday
,
{
"key": "1",
"name": I18n.locale.dayName(1, Locale.LongFormat).trim()
} // Monday
]
onSelected: key => Settings.data.location.firstDayOfWeek = parseInt(key)
}
}
@@ -0,0 +1,157 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services.Location
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
// Language
NComboBox {
Layout.fillWidth: true
label: I18n.tr("panels.general.language-select-label")
description: I18n.tr("panels.general.language-select-description")
defaultValue: Settings.getDefaultValue("general.language")
model: [
{
"key": "",
"name": I18n.tr("panels.general.language-select-auto-detect") + " (" + I18n.systemDetectedLangCode + ")"
}
].concat(I18n.availableLanguages.map(function (langCode) {
return {
"key": langCode,
"name": langCode
};
}))
currentKey: Settings.data.general.language
settingsPath: "general.language"
onSelected: key => {
// Need to change language on next frame using "callLater" or it will pull the rug below our feet: the NComboBox would be rebuilt immediately before it can close properly.
Qt.callLater(() => {
Settings.data.general.language = key;
if (key === "") {
I18n.detectLanguage(); // Re-detect system language if "Automatic" is selected
} else {
I18n.setLanguage(key); // Set specific language
}
});
}
}
NDivider {
Layout.fillWidth: true
}
// Location
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
// Auto-locate
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NToggle {
Layout.fillWidth: true
label: I18n.tr("panels.location.auto-locate-label")
description: I18n.tr("panels.location.auto-locate-description")
checked: Settings.data.location.autoLocate
onToggled: checked => Settings.data.location.autoLocate = checked
defaultValue: Settings.getDefaultValue("location.autoLocate")
}
NButton {
text: I18n.tr("panels.location.geolocate-now-button")
icon: "current-location"
enabled: !LocationService.isFetchingWeather
onClicked: LocationService.geolocateAndApply()
}
}
NTextInput {
visible: !Settings.data.location.autoLocate
Layout.maximumWidth: root.width / 2
label: I18n.tr("panels.location.location-search-label")
description: I18n.tr("panels.location.location-search-description")
text: Settings.data.location.name
placeholderText: I18n.tr("panels.location.location-search-placeholder")
onEditingFinished: {
// Verify the location has really changed to avoid extra resets
var newLocation = text.trim();
if (newLocation != Settings.data.location.name) {
Settings.data.location.name = newLocation;
LocationService.resetWeather();
}
}
}
NText {
text: LocationService.coordinatesReady ? I18n.tr("system.location-display", {
"name": LocationService.stableName,
"coordinates": LocationService.displayCoordinates
}) : ""
pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
font.italic: true
}
}
ColumnLayout {
spacing: Style.marginL
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.location.weather-enabled-label")
description: I18n.tr("panels.location.weather-enabled-description")
checked: Settings.data.location.weatherEnabled
onToggled: checked => Settings.data.location.weatherEnabled = checked
defaultValue: Settings.getDefaultValue("location.weatherEnabled")
}
NToggle {
label: I18n.tr("panels.location.weather-fahrenheit-label")
description: I18n.tr("panels.location.weather-fahrenheit-description")
checked: Settings.data.location.useFahrenheit
onToggled: checked => Settings.data.location.useFahrenheit = checked
enabled: Settings.data.location.weatherEnabled
}
NToggle {
label: I18n.tr("panels.location.weather-show-effects-label")
description: I18n.tr("panels.location.weather-show-effects-description")
checked: Settings.data.location.weatherShowEffects
onToggled: checked => Settings.data.location.weatherShowEffects = checked
enabled: Settings.data.location.weatherEnabled
}
NToggle {
label: I18n.tr("panels.location.weather-talia-mascot-always-label")
description: I18n.tr("panels.location.weather-talia-mascot-always-description")
checked: Settings.data.location.weatherTaliaMascotAlways
onToggled: checked => Settings.data.location.weatherTaliaMascotAlways = checked
enabled: Settings.data.location.weatherEnabled
defaultValue: Settings.getDefaultValue("location.weatherTaliaMascotAlways")
}
NToggle {
label: I18n.tr("panels.location.weather-hide-city-label")
description: I18n.tr("panels.location.weather-hide-city-description")
checked: Settings.data.location.hideWeatherCityName
onToggled: checked => Settings.data.location.hideWeatherCityName = checked
enabled: Settings.data.location.weatherEnabled
}
NToggle {
label: I18n.tr("panels.location.weather-hide-timezone-label")
description: I18n.tr("panels.location.weather-hide-timezone-description")
checked: Settings.data.location.hideWeatherTimezone
onToggled: checked => Settings.data.location.hideWeatherTimezone = checked
enabled: Settings.data.location.weatherEnabled
}
}
}
@@ -0,0 +1,48 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
spacing: 0
NTabBar {
id: subTabBar
Layout.fillWidth: true
Layout.bottomMargin: Style.marginM
distributeEvenly: true
currentIndex: tabView.currentIndex
NTabButton {
text: I18n.tr("common.location")
tabIndex: 0
checked: subTabBar.currentIndex === 0
}
NTabButton {
text: I18n.tr("common.date")
tabIndex: 1
checked: subTabBar.currentIndex === 1
}
NTabButton {
text: I18n.tr("common.calendar-panel")
tabIndex: 2
checked: subTabBar.currentIndex === 2
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: Style.marginL
}
NTabView {
id: tabView
currentIndex: subTabBar.currentIndex
LocationSubTab {}
DateSubTab {}
ClockPanelSubTab {}
}
}