This commit is contained in:
2026-03-31 20:13:15 +08:00
parent 48044e957d
commit 08c513b995
1155 changed files with 79920 additions and 0 deletions

View File

@ -0,0 +1,730 @@
/*
SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
SPDX-License-Identifier: MIT
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Controls
import org.kde.ksvg
import org.kde.kcmutils
import org.kde.iconthemes
import org.kde.kquickcontrolsaddons
import org.kde.kirigami as Kirigami
import org.kde.plasma.core as PlasmaCore
import "../../tools/tools.js" as JS
SimpleKCM {
property alias cfg_relevantIcon: relevantIcon.value
property string cfg_selectedIcon: plasmoid.configuration.selectedIcon
property alias cfg_indicatorStop: indicatorStop.checked
property alias cfg_counterEnabled: counterEnabled.checked
property alias cfg_counterOnLeft: counterOnLeft.checked
property string cfg_counterColor: plasmoid.configuration.counterColor
property alias cfg_counterSize: counterSize.value
property alias cfg_counterRadius: counterRadius.value
property alias cfg_counterOpacity: counterOpacity.value
property alias cfg_counterShadow: counterShadow.checked
property string cfg_counterFontFamily: plasmoid.configuration.counterFontFamily
property alias cfg_counterFontBold: counterFontBold.checked
property alias cfg_counterFontSize: counterFontSize.value
property alias cfg_counterSpacing: counterSpacing.value
property alias cfg_counterMargins: counterMargins.value
property alias cfg_counterOffsetX: counterOffsetX.value
property alias cfg_counterOffsetY: counterOffsetY.value
property alias cfg_counterCenter: counterCenter.checked
property bool cfg_counterTop: plasmoid.configuration.counterTop
property bool cfg_counterBottom: plasmoid.configuration.counterBottom
property bool cfg_counterRight: plasmoid.configuration.counterRight
property bool cfg_counterLeft: plasmoid.configuration.counterLeft
property alias cfg_ownIconsUI: ownIconsUI.checked
property int cfg_defaultTab: plasmoid.configuration.defaultTab
property alias cfg_switchDefaultTab: switchDefaultTab.checked
property alias cfg_spacing: spacing.value
property alias cfg_sorting: sorting.checked
property alias cfg_showStatusText: showStatusText.checked
property alias cfg_showToolBar: showToolBar.checked
property alias cfg_searchButton: searchButton.checked
property alias cfg_intervalButton: intervalButton.checked
property alias cfg_sortButton: sortButton.checked
property alias cfg_managementButton: managementButton.checked
property alias cfg_upgradeButton: upgradeButton.checked
property alias cfg_checkButton: checkButton.checked
property alias cfg_tabBarVisible: tabBarVisible.checked
property alias cfg_tabBarTexts: tabBarTexts.checked
property bool inTray: (plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentDrawsPlasmoidHeading)
property bool horizontal: plasmoid.location === 3 || plasmoid.location === 4
property bool counterOverlay: inTray || !horizontal
property bool counterRow: !inTray && horizontal
property int currentTab
signal tabChanged(currentTab: int)
onCurrentTabChanged: tabChanged(currentTab)
header: Kirigami.NavigationTabBar {
actions: [
Kirigami.Action {
icon.name: "view-list-icons"
text: i18n("Panel Icon View")
checked: currentTab === 0
onTriggered: currentTab = 0
},
Kirigami.Action {
icon.name: "view-split-left-right"
text: i18n("List View")
checked: currentTab === 1
onTriggered: currentTab = 1
}
]
}
Kirigami.FormLayout {
id: iconViewTab
visible: currentTab === 0
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Shown when")
enabled: counterOverlay
SpinBox {
id: relevantIcon
from: 0
to: 999
stepSize: 1
value: relevantIcon.value
}
Label {
text: i18np("update is pending ", "updates are pending ", relevantIcon.value)
}
}
Button {
id: iconButton
implicitWidth: iconFrame.width + Kirigami.Units.smallSpacing
implicitHeight: implicitWidth
hoverEnabled: true
FrameSvgItem {
id: iconFrame
anchors.centerIn: parent
width: Kirigami.Units.iconSizes.large + fixedMargins.left + fixedMargins.right
height: width
imagePath: "widgets/background"
Kirigami.Icon {
anchors.centerIn: parent
width: Kirigami.Units.iconSizes.large
height: width
source: JS.setIcon(cfg_selectedIcon)
}
}
IconDialog {
id: iconDialog
onIconNameChanged: cfg_selectedIcon = iconName || JS.defaultIcon
}
onClicked: menu.opened ? menu.close() : menu.open()
Menu {
id: menu
y: +parent.height
MenuItem {
text: i18n("Default") + " 1"
icon.name: "apdatifier-plasmoid"
enabled: cfg_selectedIcon !== JS.defaultIcon
onClicked: cfg_selectedIcon = JS.defaultIcon
}
MenuItem {
text: i18n("Default") + " 2"
icon.name: "apdatifier-packages"
enabled: cfg_selectedIcon !== icon.name
onClicked: cfg_selectedIcon = icon.name
}
MenuItem {
text: i18n("Default") + " 3"
icon.name: "apdatifier-package"
enabled: cfg_selectedIcon !== icon.name
onClicked: cfg_selectedIcon = icon.name
}
MenuItem {
text: i18n("Default") + " 4"
icon.name: "apdatifier-flatpak"
enabled: cfg_selectedIcon !== icon.name
onClicked: cfg_selectedIcon = icon.name
}
MenuItem {
text: i18n("Select...")
icon.name: "document-open-folder"
onClicked: iconDialog.open()
}
}
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
ToolTip {
text: cfg_selectedIcon === JS.defaultIcon ? i18n("Default icon") : cfg_selectedIcon
delay: Kirigami.Units.toolTipDelay
visible: iconButton.hovered
}
}
Item {
Kirigami.FormData.isSection: true
}
CheckBox {
Kirigami.FormData.label: i18n("Stopped interval") + ":"
id: indicatorStop
text: i18n("Enable")
}
Item {
Kirigami.FormData.isSection: true
}
CheckBox {
Kirigami.FormData.label: i18n("Counter") + ":"
id: counterEnabled
text: i18n("Enable")
}
CheckBox {
Kirigami.FormData.label: "On left" + ":"
id: counterOnLeft
text: i18n("Enable")
visible: counterRow
enabled: counterEnabled.checked
}
Button {
Kirigami.FormData.label: i18n("Color") + ":"
id: counterColor
Layout.leftMargin: Kirigami.Units.gridUnit
implicitWidth: Kirigami.Units.gridUnit
implicitHeight: implicitWidth
visible: counterOverlay
enabled: counterEnabled.checked
background: Rectangle {
radius: counterRadius.value
border.width: 1
border.color: "black"
color: cfg_counterColor ? cfg_counterColor : Kirigami.Theme.backgroundColor
}
onPressed: menuColor.opened ? menuColor.close() : menuColor.open()
Menu {
id: menuColor
y: +parent.height
MenuItem {
text: i18n("Default color")
icon.name: "edit-clear"
enabled: cfg_counterColor && cfg_counterColor !== Kirigami.Theme.backgroundColor
onClicked: cfg_counterColor = ""
}
MenuItem {
text: i18n("Select...")
icon.name: "document-open-folder"
onClicked: colorDialog.open()
}
}
ColorDialog {
id: colorDialog
visible: false
title: i18n("Select counter background color")
selectedColor: cfg_counterColor
onAccepted: {
cfg_counterColor = selectedColor
}
}
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
ToolTip {
text: cfg_counterColor ? cfg_counterColor : i18n("Default background color from current theme")
delay: Kirigami.Units.toolTipDelay
visible: counterColor.hovered
}
}
RowLayout {
Kirigami.FormData.label: i18n("Size") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
Slider {
id: counterSize
from: -5
to: 10
stepSize: 1
value: counterSize.value
onValueChanged: plasmoid.configuration.counterSize = counterSize.value
}
Label {
text: counterSize.value
}
}
RowLayout {
Kirigami.FormData.label: i18n("Radius") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
Slider {
id: counterRadius
from: 0
to: 100
stepSize: 1
value: counterRadius.value
onValueChanged: plasmoid.configuration.counterRadius = counterRadius.value
}
Label {
text: counterRadius.value
}
}
RowLayout {
Kirigami.FormData.label: i18n("Opacity") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
Slider {
id: counterOpacity
from: 0
to: 10
stepSize: 1
value: counterOpacity.value
onValueChanged: plasmoid.configuration.counterOpacity = counterOpacity.value
}
Label {
text: counterOpacity.value / 10
}
}
CheckBox {
Kirigami.FormData.label: i18n("Shadow") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
id: counterShadow
text: i18n("Enable")
}
ComboBox {
Kirigami.FormData.label: i18n("Font") + ":"
enabled: counterEnabled.checked
implicitWidth: 250
editable: true
textRole: "name"
model: {
let fonts = Qt.fontFamilies()
let arr = []
arr.push({"name": i18n("Default system font"), "value": ""})
for (let i = 0; i < fonts.length; i++) {
arr.push({"name": fonts[i], "value": fonts[i]})
}
return arr
}
onCurrentIndexChanged: cfg_counterFontFamily = model[currentIndex]["value"]
Component.onCompleted: currentIndex = JS.setIndex(plasmoid.configuration.counterFontFamily, model)
}
CheckBox {
Kirigami.FormData.label: i18n("Font bold") + ":"
enabled: counterEnabled.checked
id: counterFontBold
text: i18n("Enable")
}
Slider {
Kirigami.FormData.label: i18n("Font size") + ":"
visible: counterRow
enabled: counterEnabled.checked
id: counterFontSize
from: 4
to: 8
stepSize: 1
value: counterFontSize.value
onValueChanged: plasmoid.configuration.counterFontSize = counterFontSize.value
}
SpinBox {
Kirigami.FormData.label: i18n("Left spacing") + ":"
visible: counterRow
enabled: counterEnabled.checked
id: counterSpacing
from: 0
to: 99
stepSize: 1
value: counterSpacing.value
onValueChanged: plasmoid.configuration.counterSpacing = counterSpacing.value
}
SpinBox {
Kirigami.FormData.label: i18n("Side margins") + ":"
visible: counterRow
id: counterMargins
from: 0
to: 99
stepSize: 1
value: counterMargins.value
onValueChanged: plasmoid.configuration.counterMargins = counterMargins.value
}
RowLayout {
Kirigami.FormData.label: i18n("Offset") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
Label { text: "X:" }
SpinBox {
id: counterOffsetX
from: -10
to: 10
stepSize: 1
value: counterOffsetX.value
onValueChanged: plasmoid.configuration.counterOffsetX = counterOffsetX.value
}
Label { text: "Y:" }
SpinBox {
id: counterOffsetY
from: -10
to: 10
stepSize: 1
value: counterOffsetY.value
onValueChanged: plasmoid.configuration.counterOffsetY = counterOffsetY.value
}
}
Item {
Kirigami.FormData.isSection: true
}
CheckBox {
Kirigami.FormData.label: i18n("Position") + ":"
visible: counterOverlay
enabled: counterEnabled.checked
id: counterCenter
text: i18n("Center")
}
GridLayout {
Layout.fillWidth: true
visible: counterOverlay
enabled: counterEnabled.checked
columns: 4
rowSpacing: 0
columnSpacing: 0
ButtonGroup {
id: position
}
Label {
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Layout.rightMargin: Kirigami.Units.smallSpacing * 2.5
text: i18n("Top-Left")
MouseArea {
anchors.fill: parent
onClicked: {
topleft.checked = true
}
}
}
RadioButton {
id: topleft
ButtonGroup.group: position
checked: cfg_counterTop && cfg_counterLeft
onCheckedChanged: {
if (checked) {
cfg_counterTop = true
cfg_counterBottom = false
cfg_counterRight = false
cfg_counterLeft = true
}
}
}
RadioButton {
id: topright
ButtonGroup.group: position
checked: cfg_counterTop && cfg_counterRight
onCheckedChanged: {
if (checked) {
cfg_counterTop = true
cfg_counterBottom = false
cfg_counterRight = true
cfg_counterLeft = false
}
}
}
Label {
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft
text: i18n("Top-Right")
MouseArea {
anchors.fill: parent
onClicked: {
topright.checked = true
}
}
}
Label {
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
Layout.rightMargin: Kirigami.Units.smallSpacing * 2.5
text: i18n("Bottom-Left")
MouseArea {
anchors.fill: parent
onClicked: {
bottomleft.checked = true
}
}
}
RadioButton {
id: bottomleft
ButtonGroup.group: position
checked: cfg_counterBottom && cfg_counterLeft
onCheckedChanged: {
if (checked) {
cfg_counterTop = false
cfg_counterBottom = true
cfg_counterRight = false
cfg_counterLeft = true
}
}
}
RadioButton {
id: bottomright
ButtonGroup.group: position
checked: cfg_counterBottom && cfg_counterRight
onCheckedChanged: {
if (checked) {
cfg_counterTop = false
cfg_counterBottom = true
cfg_counterRight = true
cfg_counterLeft = false
}
}
}
Label {
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft
text: i18n("Bottom-Right")
MouseArea {
anchors.fill: parent
onClicked: {
bottomright.checked = true
}
}
}
}
Item {
Kirigami.FormData.isSection: true
}
}
Kirigami.FormLayout {
id: listViewTab
visible: currentTab === 1
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: "UI:"
CheckBox {
id: ownIconsUI
text: i18n("Use built-in icons")
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Override custom icon theme and use default Apdatifier icons instead.")
}
}
Item {
Kirigami.FormData.isSection: true
}
ButtonGroup {
id: viewGroup
}
RadioButton {
Kirigami.FormData.label: i18n("Default tab") + ":"
id: compactView
ButtonGroup.group: viewGroup
text: i18n("Compact")
Component.onCompleted: checked = !plasmoid.configuration.defaultTab
}
RadioButton {
ButtonGroup.group: viewGroup
text: i18n("Extended")
onCheckedChanged: cfg_defaultTab = checked
Component.onCompleted: checked = plasmoid.configuration.defaultTab
}
CheckBox {
Kirigami.FormData.label: i18n("Behavior") + ":"
id: switchDefaultTab
text: i18n("Always switch to default tab")
}
RowLayout {
Kirigami.FormData.label: i18n("Item spacing (Compact)") + ":"
Slider {
id: spacing
from: 0
to: 12
stepSize: 1
value: spacing.value
onValueChanged: plasmoid.configuration.spacing = spacing.value
}
Label {
text: spacing.value
}
}
Item {
Kirigami.FormData.isSection: true
}
ButtonGroup {
id: sortGroup
}
RadioButton {
id: sorting
Kirigami.FormData.label: i18n("Sorting") + ":"
text: i18n("By repository")
checked: true
Component.onCompleted: checked = plasmoid.configuration.sorting
ButtonGroup.group: sortGroup
}
RadioButton {
text: i18n("By name")
Component.onCompleted: checked = !plasmoid.configuration.sorting
ButtonGroup.group: sortGroup
}
Item {
Kirigami.FormData.isSection: true
}
CheckBox {
id: showStatusText
Kirigami.FormData.label: i18n("Header") + ":"
text: i18n("Show status")
}
CheckBox {
id: showToolBar
text: i18n("Show tool bar")
}
RowLayout {
enabled: showToolBar.checked
CheckBox {
id: searchButton
icon.name: "search"
}
CheckBox {
id: intervalButton
icon.name: "media-playback-paused"
}
CheckBox {
id: sortButton
icon.name: "sort-name"
}
}
RowLayout {
enabled: showToolBar.checked
CheckBox {
id: managementButton
icon.name: "tools"
}
CheckBox {
id: upgradeButton
icon.name: "akonadiconsole"
}
CheckBox {
id: checkButton
icon.name: "view-refresh"
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Footer") + ":"
CheckBox {
id: tabBarVisible
text: i18n("Show tab bar")
}
}
CheckBox {
id: tabBarTexts
text: i18n("Show tab texts")
enabled: tabBarVisible.checked
}
Item {
Kirigami.FormData.isSection: true
}
}
}

View File

@ -0,0 +1,514 @@
/*
SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
SPDX-License-Identifier: MIT
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import org.kde.kcmutils
import org.kde.kirigami as Kirigami
import "../components" as QQC
import "../../tools/tools.js" as JS
SimpleKCM {
property alias cfg_interval: interval.checked
property alias cfg_time: time.value
property alias cfg_checkOnStartup: checkOnStartup.checked
property alias cfg_arch: arch.checked
property alias cfg_aur: aur.checked
property alias cfg_flatpak: flatpak.checked
property alias cfg_widgets: widgets.checked
property alias cfg_newsArch: newsArch.checked
property alias cfg_newsKDE: newsKDE.checked
property alias cfg_newsTWIK: newsTWIK.checked
property alias cfg_newsTWIKA: newsTWIKA.checked
property alias cfg_newsKeep: newsKeep.value
property string cfg_middleAction: plasmoid.configuration.middleAction
property string cfg_rightAction: plasmoid.configuration.rightAction
property string cfg_scrollUpAction: plasmoid.configuration.scrollUpAction
property string cfg_scrollDownAction: plasmoid.configuration.scrollDownAction
property alias cfg_notifyUpdates: notifyUpdates.checked
property alias cfg_notifyUpdatesAction: notifyUpdatesAction.checked
property alias cfg_notifyEveryBump: notifyEveryBump.checked
property alias cfg_notifyNews: notifyNews.checked
property alias cfg_notifyNewsAction: notifyNewsAction.checked
property alias cfg_notifyErrors: notifyErrors.checked
property alias cfg_notifySound: notifySound.checked
property alias cfg_notifyPersistent: notifyPersistent.checked
property var cfg: plasmoid.configuration
property var pkg: plasmoid.configuration.packages
property var terminals: plasmoid.configuration.terminals
property var packageLink: "https://archlinux.org/packages/extra/x86_64/pacman-contrib"
property int installButton
property var dialogTitles: {
"0": i18n("Install Development version"),
"1": i18n("Install Stable version"),
"2": i18n("Uninstall widget")
}
property var dialogSubtitles: {
"0": i18n("Note: version with the latest commits may be unstable."),
"1": i18n("Note: if you haven't installed the Devel version before, there's no need to install the Stable version."),
"2": i18n("Removal of the widget and all related files, including the directory with its configuration.")
}
property int currentTab
signal tabChanged(currentTab: int)
onCurrentTabChanged: tabChanged(currentTab)
Component.onCompleted: {
JS.checkDependencies()
}
header: Kirigami.NavigationTabBar {
actions: [
Kirigami.Action {
icon.name: "search"
text: i18n("Search")
checked: currentTab === 0
onTriggered: currentTab = 0
},
Kirigami.Action {
icon.name: "notification-active"
text: i18n("Notifications")
checked: currentTab === 1
onTriggered: currentTab = 1
},
Kirigami.Action {
icon.name: "followmouse-symbolic"
text: i18n("Mouse actions")
checked: currentTab === 2
onTriggered: currentTab = 2
},
Kirigami.Action {
icon.name: "documentinfo"
text: i18n("Misc")
checked: currentTab === 3
onTriggered: currentTab = 3
}
]
}
ColumnLayout {
Kirigami.InlineMessage {
id: configMsg
Layout.fillWidth: true
icon.source: "document-save"
text: "<b>" + i18n("Configuration is automatically saved in a config file and loaded at every startup, ensuring you never lose your settings. The config file is stored in ") + "~/.config/apdatifier" + "</b>"
type: Kirigami.MessageType.Positive
visible: plasmoid.configuration.configMsg
actions: [
Kirigami.Action {
text: "OK"
icon.name: "checkmark"
onTriggered: plasmoid.configuration.configMsg = false
}
]
}
Kirigami.InlineMessage {
Layout.fillWidth: true
icon.source: "apdatifier-package"
text: "<b>" + "<a href=\"" + packageLink + "\">checkupdates</a>" + i18n(" not installed! Highly recommended to install it for getting the latest updates without the need to download fresh package databases.") + "</b>"
type: Kirigami.MessageType.Error
onLinkActivated: Qt.openUrlExternally(packageLink)
visible: !pkg.checkupdates
}
Kirigami.FormLayout {
id: searchTab
visible: currentTab === 0
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Interval") + ":"
CheckBox {
id: interval
}
SpinBox {
id: time
from: 15
to: 1440
stepSize: 5
value: time
enabled: interval.checked
}
Label {
text: i18n("minutes")
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("The current timer is reset when either of these settings is changed.")
}
}
RowLayout {
CheckBox {
id: checkOnStartup
text: i18n("Check on start up")
enabled: interval.checked
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("If the option is <b>enabled</b>, update checking will begin immediately upon widget startup.<br><br>If the option is <b>disabled</b>, update checking will be initiated after a specified time interval has passed since the widget was started. <b>Recommended.</b>")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Updates") + ":"
CheckBox {
id: arch
text: i18n("Arch Official Repositories")
enabled: pkg.pacman
onCheckedChanged: if (!checked) aur.checked = false
}
}
RowLayout {
spacing: Kirigami.Units.gridUnit
visible: pkg.pacman
CheckBox {
id: aur
text: i18n("Arch User Repository") + " (AUR)"
enabled: arch.checked && (pkg.paru || pkg.yay)
}
Kirigami.UrlButton {
url: "https://github.com/exequtic/apdatifier#supported-pacman-wrappers"
text: instTip.text
font.pointSize: instTip.font.pointSize
color: instTip.color
visible: !pkg.paru && !pkg.yay
}
}
RowLayout {
spacing: Kirigami.Units.gridUnit
CheckBox {
id: flatpak
text: i18n("Flatpak applications")
enabled: pkg.flatpak
}
Kirigami.UrlButton {
id: instTip
url: "https://flathub.org/setup"
text: i18n("Not installed")
font.pointSize: Kirigami.Theme.smallFont.pointSize
color: Kirigami.Theme.neutralTextColor
visible: !pkg.flatpak
}
}
RowLayout {
CheckBox {
id: widgets
text: i18n("Plasma Widgets")
enabled: pkg.jq
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Required installed") + " jq." + i18n("<br><br>For widget developers:<br>Don't forget to update the metadata.json and specify the name of the applet and its version <b>exactly</b> as they appear on the KDE Store.")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("News") + ":"
CheckBox {
id: newsArch
text: i18n("Arch Linux News")
enabled: pkg.jq
}
}
CheckBox {
id: newsKDE
text: "KDE Announcements"
enabled: pkg.jq
}
CheckBox {
id: newsTWIK
text: "This Week in KDE"
enabled: pkg.jq
}
CheckBox {
id: newsTWIKA
text: "This Week in KDE Apps"
enabled: pkg.jq
}
RowLayout {
Label {
text: i18n("Keep")
}
SpinBox {
id: newsKeep
from: 1
to: 10
stepSize: 1
value: newsKeep
enabled: newsArch.checked || newsKDE.checked || newsTWIK.checked || newsTWIKA.checked
}
Label {
text: i18np("news item from the feed", "news items from the feed", newsKeep.value)
}
}
}
Kirigami.FormLayout {
id: notificationsTab
visible: currentTab === 1
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
spacing: Kirigami.Units.largeSpacing * 2
CheckBox {
Kirigami.FormData.label: i18n("Notifications") + ":"
id: notifyUpdates
text: i18n("For new updates")
}
CheckBox {
id: notifyUpdatesAction
text: i18n("Action button")
enabled: notifyUpdates.checked
}
}
RowLayout {
CheckBox {
id: notifyEveryBump
text: i18n("For every version bump")
enabled: notifyUpdates.checked
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("If the option is <b>enabled</b>, notifications will be sent when a new version of the package is bumped, even if the package is already on the list. <b>More notifications.</b> <br><br>If the option is <b>disabled</b>, notifications will only be sent for packages that are not yet on the list. <b>Less notifications.</b>")
}
}
RowLayout {
spacing: Kirigami.Units.largeSpacing * 2
CheckBox {
id: notifyNews
text: i18n("For news")
}
CheckBox {
id: notifyNewsAction
text: i18n("Action button")
enabled: notifyNews.checked
}
}
CheckBox {
id: notifyErrors
text: i18n("For errors")
}
CheckBox {
id: notifySound
text: i18n("With sound")
enabled: notifyUpdates.checked || notifyNews.checked || notifyErrors.checked
}
CheckBox {
id: notifyPersistent
text: i18n("Persistent")
enabled: notifyUpdates.checked || notifyNews.checked || notifyErrors.checked
}
Item {
Kirigami.FormData.isSection: true
}
Kirigami.Separator {
Layout.fillWidth: true
}
RowLayout {
id: notifyTip
Label {
horizontalAlignment: Text.AlignHCenter
Layout.maximumWidth: 250
font.pointSize: instTip.font.pointSize
text: i18n("To further configure, click the button below -> Application Settings -> Apdatifier")
wrapMode: Text.WordWrap
}
}
Item {
Kirigami.FormData.isSection: true
}
Button {
anchors.horizontalCenter: notifyTip.horizontalCenter
enabled: notifyUpdates.checked || notifyNews.checked || notifyErrors.checked
icon.name: "settings-configure"
text: i18n("Configure...")
onClicked: KCMLauncher.openSystemSettings("kcm_notifications")
}
Item {
Kirigami.FormData.isSection: true
}
}
Kirigami.FormLayout {
id: mouseActionsTab
visible: currentTab === 2
Item {
Kirigami.FormData.isSection: true
}
QQC.ComboBox {
Kirigami.FormData.label: i18n("Middle click") + ":"
type: "middle"
}
QQC.ComboBox {
Kirigami.FormData.label: i18n("Right click") + ":"
type: "right"
Kirigami.ContextualHelpButton {
toolTipText: i18n("Do not enable this option if the widget is not used in the system tray; otherwise, you will not be able to open the settings by right-clicking.")
}
}
QQC.ComboBox {
Kirigami.FormData.label: i18n("Scroll up") + ":"
type: "scrollUp"
}
QQC.ComboBox {
Kirigami.FormData.label: i18n("Scroll down") + ":"
type: "scrollDown"
}
Item {
Kirigami.FormData.isSection: true
}
}
Kirigami.FormLayout {
id: miscTab
visible: currentTab === 3
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Layout.preferredWidth: miscTab.width - Kirigami.Units.largeSpacing * 10
Button {
Layout.fillWidth: true
Layout.maximumWidth: 500
icon.name: "backup"
text: i18n("Restore hidden tooltips")
onClicked: {
plasmoid.configuration.configMsg = true
plasmoid.configuration.rulesMsg = true
plasmoid.configuration.newsMsg = true
plasmoid.configuration.version = "v0"
}
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Layout.preferredWidth: miscTab.width - Kirigami.Units.largeSpacing * 10
Button {
Layout.fillWidth: true
Layout.maximumWidth: 500
icon.name: "folder-git-symbolic"
text: i18n("Install Development version")
onClicked: {
installButton = 0
installDialog.open()
}
}
}
RowLayout {
Layout.preferredWidth: miscTab.width - Kirigami.Units.largeSpacing * 10
Button {
Layout.fillWidth: true
Layout.maximumWidth: 500
icon.name: "run-build"
text: i18n("Install Stable version")
onClicked: {
installButton = 1
installDialog.open()
}
}
}
RowLayout {
Layout.preferredWidth: miscTab.width - Kirigami.Units.largeSpacing * 10
Button {
Layout.fillWidth: true
Layout.maximumWidth: 500
icon.name: "delete"
text: i18n("Uninstall widget")
onClicked: {
installButton = 2
installDialog.open()
}
}
}
Kirigami.PromptDialog {
id: installDialog
title: dialogTitles[installButton]
subtitle: dialogSubtitles[installButton]
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: {
if (installButton === 0) {
JS.execute(JS.runInTerminal("utils", "installDev"))
} else if (installButton === 1) {
JS.execute(JS.runInTerminal("utils", "installStable"))
} else {
JS.execute(JS.runInTerminal("utils", "uninstall"))
}
}
}
}
}
}

View File

@ -0,0 +1,212 @@
/*
SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
SPDX-License-Identifier: MIT
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import org.kde.iconthemes
import org.kde.kirigami as Kirigami
import "../../tools/tools.js" as JS
ColumnLayout {
ListModel {
id: rulesModel
Component.onCompleted: {
JS.execute(JS.readFile(JS.rulesFile), (cmd, out, err, code) => {
if (JS.Error(code, err)) return
if (out && JS.validJSON(out, JS.rulesFile)) {
JSON.parse(out).forEach(el =>
rulesModel.append({
type: el.type,
value: el.value,
icon: el.icon,
excluded: el.excluded,
important: ('important' in el) ? el.important : false
})
)
}
})
}
}
ListModel {
id: typesModel
Component.onCompleted: {
let types = [
{name: i18n("Unimportant"), type: "all", tip: "---"},
{name: i18n("Repository"), type: "repo", tip: i18n("Exact repository match")},
{name: i18n("Group"), type: "group", tip: i18n("Substring group match")},
{name: i18n("Substring"), type: "match", tip: i18n("Substring name match")},
{name: i18n("Name"), type: "name", tip: i18n("Exact name match")}
]
for (var i = 0; i < types.length; ++i) {
typesModel.append({name: types[i].name, type: types[i].type, tip: types[i].tip})
}
}
}
Kirigami.InlineMessage {
id: rulesMsg
Layout.fillWidth: true
Layout.leftMargin: Kirigami.Units.smallSpacing * 2
Layout.rightMargin: Kirigami.Units.smallSpacing * 2
icon.source: "showinfo"
text: i18n("Here you can override the default package icons and exclude them from the list. Each rule overwrites the previous one, so the list of rules should be in this order: ")+i18n("Unimportant")+", "+i18n("Repository")+", "+i18n("Group")+", "+i18n("Substring")+", "+i18n("Name")
visible: plasmoid.configuration.rulesMsg
actions: [
Kirigami.Action {
text: "OK"
icon.name: "checkmark"
onTriggered: plasmoid.configuration.rulesMsg = false
}
]
}
Component {
id: rule
ItemDelegate {
width: rulesList.width - Kirigami.Units.largeSpacing * 2
contentItem: RowLayout {
ComboBox {
implicitWidth: 200
id: type
model: typesModel
textRole: "name"
currentIndex: -1
onCurrentIndexChanged: {
if (currentIndex === 0) valueField.text = ""
rulesList.model.set(index, {"type": model.get(currentIndex).type})
}
Component.onCompleted: {
var currentType = rulesList.model.get(index).type
for (var i = 0; i < model.count; ++i) {
if (model.get(i).type === currentType) {
currentIndex = i
break
}
}
}
}
TextField {
id: valueField
Layout.fillWidth: true
text: model.value
placeholderText: type.model.get(type.currentIndex).tip
enabled: type.currentIndex !== 0
onTextChanged: {
var allow = /^[a-z0-9_\-+.]*$/
var filtered = valueField.text.replace(/[^a-z0-9_\-+.]/g, "")
if (valueField.text !== filtered) {
valueField.text = filtered
return
}
if (model.value !== valueField.text) {
model.value = valueField.text
}
}
}
ToolButton {
ToolTip { text: model.icon }
icon.name: model.icon
onClicked: iconDialog.open()
IconDialog {
id: iconDialog
onIconNameChanged: model.icon = iconName
}
}
ToolButton {
ToolTip { text: i18n("Mark as important") }
icon.name: model.important ? "flag-red" : "flag"
onClicked: model.important = !model.important
}
ToolButton {
ToolTip { text: model.excluded ? i18n("Show in the list") : i18n("Exclude from the list") }
icon.name: model.excluded ? "view-visible" : "hint"
onClicked: model.excluded = !model.excluded
}
ToolButton {
icon.name: 'arrow-up'
enabled: index > 0
onClicked: rulesList.model.move(index, index - 1, 1)
}
ToolButton {
icon.name: 'arrow-down'
enabled: index > -1 && index < rulesList.model.count - 1
onClicked: rulesList.model.move(index, index + 1, 1)
}
ToolButton {
ToolTip { text: i18n("Remove") }
icon.name: 'delete'
onClicked: rulesList.model.remove(index)
}
}
}
}
ListView {
Layout.fillHeight: true
Layout.fillWidth: true
id: rulesList
model: rulesModel
delegate: rule
clip: true
boundsBehavior: Flickable.StopAtBounds
add: Transition { NumberAnimation { properties: "x"; from: 100; duration: 300 } }
moveDisplaced: Transition { NumberAnimation { properties: "x,y"; duration: 300 } }
move: Transition { NumberAnimation { properties: "x,y"; duration: 300 } }
removeDisplaced: Transition { NumberAnimation { properties: "x,y"; duration: 300 } }
remove: Transition { ParallelAnimation {
NumberAnimation { property: "opacity"; to: 0; duration: 300 }
NumberAnimation { properties: "x"; to: 100; duration: 300 } } }
ScrollBar.vertical: ScrollBar { active: true }
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
Button {
text: i18n("Add rule")
icon.name: "list-add"
onClicked: {
rulesModel.append({
type: "name",
value: "",
icon: plasmoid.configuration.ownIconsUI ? "apdatifier-package" : "server-database",
excluded: false,
important: false
})
}
}
Button {
text: i18n("Apply")
icon.name: "dialog-ok-apply"
onClicked: {
var array = []
for (var i = rulesModel.count - 1; i >= 0; --i) {
if (rulesModel.get(i).type !== "all" && rulesModel.get(i).value.trim() === "") rulesModel.remove(i, 1);
}
for (var i = 0; i < rulesModel.count; i++) {
array.push(rulesModel.get(i))
}
var rules = JS.toFileFormat(array)
plasmoid.configuration.rules = rules
JS.execute(JS.writeFile(rules, '>', JS.rulesFile))
}
}
}
}

View File

@ -0,0 +1,94 @@
/*
SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
SPDX-License-Identifier: MIT
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import org.kde.kirigami as Kirigami
Kirigami.Page {
id: supportPage
leftPadding: Kirigami.Units.gridUnit
rightPadding: Kirigami.Units.gridUnit
header: Item {
height: layout.implicitHeight + (Kirigami.Units.gridUnit * 2)
ColumnLayout {
id: layout
width: parent.width - (Kirigami.Units.gridUnit * 2)
anchors.centerIn: parent
Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: i18n("Thanks for using my widget! If you appreciate my work, you can support me by starring the GitHub repository or buying me a coffee ;)")
wrapMode: Text.WordWrap
}
}
}
RowLayout {
anchors.centerIn: parent
Layout.fillWidth: true
Layout.fillHeight: true
Kirigami.UrlButton {
id: buymeacoffee
url: "https://buymeacoffee.com/evgk"
visible: false
}
Kirigami.UrlButton {
id: github
url: "https://github.com/exequtic/apdatifier"
visible: false
}
Image {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
source: "../assets/art/apdatifier-donate.png"
sourceSize.width: supportPage.width / 2
sourceSize.height: supportPage.height
HoverHandler {
id: handlerCoffee
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: Qt.openUrlExternally(buymeacoffee.url)
}
ToolTip {
visible: handlerCoffee.hovered
text: i18n("Visit %1", buymeacoffee.url)
}
}
Image {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
source: "../assets/art/apdatifier-githubstar.png"
sourceSize.width: supportPage.width / 2
sourceSize.height: supportPage.height
HoverHandler {
id: handlerGithub
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: Qt.openUrlExternally(github.url)
}
ToolTip {
visible: handlerGithub.hovered
text: i18n("Visit %1", github.url)
}
}
}
}

View File

@ -0,0 +1,712 @@
/*
SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
SPDX-License-Identifier: MIT
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Dialogs
import org.kde.kcmutils
import org.kde.kirigami as Kirigami
import "../../tools/tools.js" as JS
SimpleKCM {
property string cfg_terminal: plasmoid.configuration.terminal
property alias cfg_tmuxSession: tmuxSession.checked
property alias cfg_idleInhibit: idleInhibit.checked
property alias cfg_termFont: termFont.checked
property string cfg_wrapper: plasmoid.configuration.wrapper
property alias cfg_archFlags: archFlags.text
property alias cfg_sudoBin: sudoBin.text
property alias cfg_rebootSystem: rebootSystem.checked
property string cfg_mirrors: plasmoid.configuration.mirrors
property alias cfg_mirrorsAge: mirrorsAge.value
property alias cfg_mirrorCount: mirrorCount.value
property var countryList: []
property string cfg_dynamicUrl: plasmoid.configuration.dynamicUrl
property alias cfg_flatpakRemoveUnused: flatpakRemoveUnused.checked
property string cfg_flatpakFlags: plasmoid.configuration.flatpakFlags
property alias cfg_widgetConfirmation: widgetConfirmation.checked
property alias cfg_restartShell: restartShell.checked
property alias cfg_restartCommand: restartCommand.text
property alias cfg_trayEnabledByDefault: trayEnabledByDefault.checked
property var pkg: plasmoid.configuration.packages
property var terminals: plasmoid.configuration.terminals
property alias cfg_preExec: preExec.text
property alias cfg_postExec: postExec.text
property int currentTab
signal tabChanged(currentTab: int)
onCurrentTabChanged: tabChanged(currentTab)
header: Kirigami.NavigationTabBar {
actions: [
Kirigami.Action {
icon.name: "akonadiconsole"
text: i18n("General")
checked: currentTab === 0
onTriggered: currentTab = 0
},
Kirigami.Action {
icon.name: "apdatifier-package"
text: "Arch"
checked: currentTab === 1
onTriggered: currentTab = 1
},
Kirigami.Action {
icon.name: "apdatifier-flatpak"
text: "Flatpak"
checked: currentTab === 2
onTriggered: currentTab = 2
},
Kirigami.Action {
icon.name: "start-here-kde-plasma-symbolic"
text: i18n("Widgets")
checked: currentTab === 3
onTriggered: currentTab = 3
}
]
}
Kirigami.FormLayout {
id: terminalTab
visible: currentTab === 0
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Terminal") + ":"
ComboBox {
model: terminals
textRole: "name"
enabled: terminals
onCurrentIndexChanged: cfg_terminal = model[currentIndex]["value"]
Component.onCompleted: {
if (terminals) {
currentIndex = JS.setIndex(plasmoid.configuration.terminal, terminals)
if (!plasmoid.configuration.terminal) {
plasmoid.configuration.terminal = model[0]["value"]
}
}
}
}
Kirigami.UrlButton {
url: "https://github.com/exequtic/apdatifier#supported-terminals"
text: i18n("Not installed")
font.pointSize: Kirigami.Theme.smallFont.pointSize
color: Kirigami.Theme.neutralTextColor
visible: !terminals
}
}
RowLayout {
CheckBox {
id: termFont
text: i18n("Use NerdFont icons")
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("If your terminal utilizes any <b>Nerd Font</b>, icons from that font will be used.")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
CheckBox {
id: tmuxSession
text: i18n("tmux session")
enabled: pkg.tmux
}
}
RowLayout {
CheckBox {
id: idleInhibit
text: "Idle Inhibit"
}
Kirigami.ContextualHelpButton {
toolTipText: "Disables automatic sleep and screen lock while upgrading."
}
}
Kirigami.Separator {
Kirigami.FormData.label: i18n("Pre/post upgrade scripts")
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Pre-exec") + ":"
TextField {
id: preExec
placeholderText: i18n("Command or script path")
placeholderTextColor: "grey"
}
Button {
icon.name: "document-open"
onClicked: fileDialogPreExec.open()
}
FileDialog {
id: fileDialogPreExec
fileMode: FileDialog.OpenFile
onAccepted: preExec.text = selectedFile.toString().substring(7)
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Running your command or script BEFORE the upgrade.<br>For example, you can specify your command to update the mirrorlist if you have unofficial repositories.")
}
}
RowLayout {
Kirigami.FormData.label: i18n("Post-exec") + ":"
TextField {
id: postExec
placeholderText: i18n("Command or script path")
placeholderTextColor: "grey"
}
Button {
icon.name: "document-open"
onClicked: fileDialogPostExec.open()
}
FileDialog {
id: fileDialogPostExec
fileMode: FileDialog.OpenFile
onAccepted: postExec.text = selectedFile.toString().substring(7)
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Running your command or script AFTER the upgrade.<br>For example, you can specify your command to upgrade something else.")
}
}
}
Kirigami.FormLayout {
id: archTab
visible: currentTab === 1
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
enabled: plasmoid.configuration.aur
Kirigami.FormData.label: i18n("Wrapper") + ":"
spacing: Kirigami.Units.largeSpacing * 2
ButtonGroup {
id: wrappersGroup
}
RadioButton {
ButtonGroup.group: wrappersGroup
text: "paru"
enabled: pkg.paru
onCheckedChanged: cfg_wrapper = checked ? "paru" : "yay"
Component.onCompleted: checked = plasmoid.configuration.wrapper === text
}
RadioButton {
ButtonGroup.group: wrappersGroup
text: "yay"
enabled: pkg.yay
Component.onCompleted: checked = plasmoid.configuration.wrapper === text
}
}
RowLayout {
visible: !plasmoid.configuration.aur
Label {
horizontalAlignment: Text.AlignHCenter
font.pointSize: Kirigami.Theme.smallFont.pointSize
font.bold: true
color: Kirigami.Theme.negativeTextColor
text: i18n("AUR disabled in search settings")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Upgrade options") + ":"
Label {
text: plasmoid.configuration.aur ? cfg_wrapper+" "+"-Syu" : cfg_sudoBin+" "+"pacman -Syu"
}
TextField {
id: archFlags
onTextChanged: {
var allow = /^[a-z\- ]*$/
if (!allow.test(archFlags.text))
archFlags.text = archFlags.text.replace(/[^a-z\- ]/g, "")
}
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: "sudobin:"
spacing: 0
enabled: pkg.pacman
TextField {
id: sudoBin
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Reboot system") + ":"
CheckBox {
id: rebootSystem
text: i18n("Suggest after upgrading")
}
Kirigami.ContextualHelpButton {
toolTipText: "This option suggests restarting the system after upgrading critical packages.<br><br><b>Note that not all critical packages require a full system restart; some may only need a session restart or no action at all, such as when an updated package is not currently running (e.g., an alternative kernel) or not in use (e.g., an alternative driver).</b>"
}
}
Kirigami.Separator {
Kirigami.FormData.label: i18n("Pacman Mirrorlist Generator")
Kirigami.FormData.isSection: true
}
RowLayout {
height: 30
Label {
horizontalAlignment: Text.AlignHCenter
font.pointSize: Kirigami.Theme.smallFont.pointSize
font.bold: true
color: Kirigami.Theme.negativeTextColor
text: i18n("Only for official repositories")
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Required installed") + " pacman-contrib." + i18n("<br><br>Also see https://archlinux.org/mirrorlist (click button to open link)")
onClicked: Qt.openUrlExternally("https://archlinux.org/mirrorlist")
}
}
Item {
Layout.preferredHeight: Kirigami.Units.smallSpacing * 2
}
ButtonGroup {
id: generator
}
RowLayout{
Kirigami.FormData.label: i18n("Generator") + ":"
RadioButton {
ButtonGroup.group: generator
id: mirrors
text: i18n("Disabled")
enabled: pkg.pacman && pkg.checkupdates
checked: {
plasmoid.configuration.mirrors === "false"
}
onCheckedChanged: {
if (checked) cfg_mirrors = "false"
}
Component.onCompleted: {
if (!checked && !enabled) {
checked = true
plasmoid.configuration.mirrors = "false"
}
}
}
}
RadioButton {
ButtonGroup.group: generator
text: i18n("Always ask")
enabled: mirrors.enabled
checked: plasmoid.configuration.mirrors === "alwaysAsk"
onCheckedChanged: {
if (checked) cfg_mirrors = "alwaysAsk"
}
}
RowLayout{
enabled: mirrors.enabled
RadioButton {
ButtonGroup.group: generator
text: i18n("Ask if older than")
checked: plasmoid.configuration.mirrors === "age"
onCheckedChanged: {
if (checked) cfg_mirrors = "age"
}
}
SpinBox {
id: mirrorsAge
from: 1
to: 999
stepSize: 1
value: mirrorsAge
}
Label {
text: i18np("day", "days", mirrorsAge.value)
}
}
RadioButton {
ButtonGroup.group: generator
text: i18n("No ask, force refresh")
enabled: mirrors.enabled
checked: plasmoid.configuration.mirrors === "force"
onCheckedChanged: {
if (checked) cfg_mirrors = "force"
}
}
Item {
Layout.preferredHeight: Kirigami.Units.smallSpacing * 2
}
RowLayout {
Kirigami.FormData.label: i18n("Protocol") + ":"
CheckBox {
id: http
text: "http"
onClicked: updateUrl()
enabled: mirrors.enabled
}
CheckBox {
id: https
text: "https"
onClicked: updateUrl()
enabled: mirrors.enabled
}
}
RowLayout {
Kirigami.FormData.label: i18n("IP version") + ":"
CheckBox {
id: ipv4
text: "IPv4"
onClicked: updateUrl()
enabled: mirrors.enabled
}
CheckBox {
id: ipv6
text: "IPv6"
onClicked: updateUrl()
enabled: mirrors.enabled
}
}
CheckBox {
Kirigami.FormData.label: i18n("Mirror status") + ":"
id: mirrorstatus
text: i18n("Enable")
onClicked: updateUrl()
enabled: mirrors.enabled
}
RowLayout {
Kirigami.FormData.label: i18n("Number output") + ":"
SpinBox {
id: mirrorCount
from: 0
to: 10
stepSize: 1
value: mirrorCount
enabled: mirrors.enabled
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("Number of servers to write to mirrorlist file. 0 for all.")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Country") + ":"
Label {
textFormat: Text.RichText
text: {
var matchResult = cfg_dynamicUrl.match(/country=([A-Z]+)/g)
if (matchResult !== null) {
var countries = matchResult.map(str => str.split("=")[1]).join(", ")
return countries
} else {
return '<a style="color: ' + Kirigami.Theme.negativeTextColor + '">' + i18n("Select at least one!") + '</a>'
}
}
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("You must select at least one country, otherwise all will be chosen by default. <br><br><b>The more countries you select, the longer it will take to generate the mirrors!</b> <br><br>It is optimal to choose <b>1-2</b> countries closest to you.")
}
}
ColumnLayout {
Layout.maximumWidth: archTab.width / 2.5
Layout.maximumHeight: 200
enabled: mirrors.enabled
ScrollView {
Layout.preferredWidth: archTab.width / 2.5
Layout.preferredHeight: 200
GridLayout {
columns: 1
Repeater {
model: countryListModel
delegate: CheckBox {
text: model.text
checked: model.checked
onClicked: {
model.checked = checked
checked ? countryList.push(model.code) : countryList.splice(countryList.indexOf(model.code), 1)
updateUrl()
}
}
}
}
}
}
Item {
Kirigami.FormData.isSection: true
}
}
Kirigami.FormLayout {
id: flatpakTab
visible: currentTab === 2
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Uninstall unused") + ":"
CheckBox {
id: flatpakRemoveUnused
text: i18n("Enable")
}
}
Item {
Kirigami.FormData.isSection: true
}
ButtonGroup {
id: flatpakFlags
}
RowLayout{
Kirigami.FormData.label: i18n("Upgrade options") + ":"
RadioButton {
ButtonGroup.group: flatpakFlags
text: i18n("Normal")
checked: plasmoid.configuration.flatpakFlags === ""
onCheckedChanged: {
if (checked) cfg_flatpakFlags = ""
}
}
}
RadioButton {
ButtonGroup.group: flatpakFlags
text: i18n("Normal, skip questions")
checked: plasmoid.configuration.flatpakFlags === "--assumeyes"
onCheckedChanged: {
if (checked) cfg_flatpakFlags = "--assumeyes"
}
}
RadioButton {
ButtonGroup.group: flatpakFlags
text: i18n("Non interactive, skip questions")
checked: plasmoid.configuration.flatpakFlags === "--noninteractive"
onCheckedChanged: {
if (checked) cfg_flatpakFlags = "--noninteractive"
}
}
RadioButton {
ButtonGroup.group: flatpakFlags
text: i18n("Verbose")
checked: plasmoid.configuration.flatpakFlags === "--verbose"
onCheckedChanged: {
if (checked) cfg_flatpakFlags = "--verbose"
}
}
}
Kirigami.FormLayout {
id: widgetsTab
visible: currentTab === 3
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Upgrade confirmation") + ":"
CheckBox {
id: widgetConfirmation
text: i18n("Enable")
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Restart plasmashell") + ":"
CheckBox {
id: restartShell
text: i18n("Suggest after upgrading")
}
Kirigami.ContextualHelpButton {
toolTipText: i18n("After upgrading widget, the old version will still remain in memory until you restart plasmashell. To avoid doing this manually, enable this option.")
}
}
RowLayout {
Kirigami.FormData.label: i18n("Command") + ":"
TextField {
id: restartCommand
enabled: restartShell.checked
}
}
Item {
Kirigami.FormData.isSection: true
}
RowLayout {
Kirigami.FormData.label: i18n("Apdatifier tray icon") + ":"
CheckBox {
id: trayEnabledByDefault
text: i18n("Enabled by default")
}
}
}
Component.onCompleted: {
if (tmuxSession.checked && !pkg.tmux) tmuxSession.checked = plasmoid.configuration.tmuxSession = false
if(cfg_dynamicUrl) {
var urlParams = plasmoid.configuration.dynamicUrl.split("?")[1].split("&")
for (var i = 0; i < urlParams.length; i++) {
var param = urlParams[i]
if (param.includes("use_mirror_status=on")) mirrorstatus.checked = true
if (/protocol=http\b/.test(param)) http.checked = true
if (param.includes("protocol=https")) https.checked = true
if (param.includes("ip_version=4")) ipv4.checked = true
if (param.includes("ip_version=6")) ipv6.checked = true
if (param.includes("country=")) {
var country = decodeURIComponent(param.split("=")[1])
countryList.push(country)
for (var j = 0; j < countryListModel.count; ++j) {
if (countryListModel.get(j).code === country) {
countryListModel.get(j).checked = true
}
}
}
}
}
}
function updateUrl() {
var params = ""
if (http.checked) params += "&protocol=http"
if (https.checked) params += "&protocol=https"
if (ipv4.checked) params += "&ip_version=4"
if (ipv6.checked) params += "&ip_version=6"
if (mirrorstatus.checked) params += "&use_mirror_status=on"
for (var i = 0; i < countryList.length; i++) {
params += "&country=" + countryList[i]
}
var baseUrl = "https://archlinux.org/mirrorlist/?"
cfg_dynamicUrl = baseUrl + params.substring(1)
}
ListModel {
id: countryListModel
function createCountryList() {
let countries =
"Australia:AU, Austria:AT, Azerbaijan:AZ, Bangladesh:BD, Belarus:BY, Belgium:BE, " +
"Bosnia and Herzegovina:BA, Brazil:BR, Bulgaria:BG, Cambodia:KH, Canada:CA, Chile:CL, " +
"China:CN, Colombia:CO, Croatia:HR, Czech Republic:CZ, Denmark:DK, Ecuador:EC, " +
"Estonia:EE, Finland:FI, France:FR, Georgia:GE, Germany:DE, Greece:GR, Hong Kong:HK, " +
"Hungary:HU, Iceland:IS, India:IN, Indonesia:ID, Iran:IR, Israel:IL, Italy:IT, Japan:JP, " +
"Kazakhstan:KZ, Kenya:KE, Latvia:LV, Lithuania:LT, Luxembourg:LU, Mauritius:MU, Mexico:MX, " +
"Moldova:MD, Monaco:MC, Netherlands:NL, New Caledonia:NC, New Zealand:NZ, North Macedonia:MK, " +
"Norway:NO, Paraguay:PY, Poland:PL, Portugal:PT, Romania:RO, Russia:RU, Réunion:RE, " +
"Serbia:RS, Singapore:SG, Slovakia:SK, Slovenia:SI, South Africa:ZA, South Korea:KR, Spain:ES, " +
"Sweden:SE, Switzerland:CH, Taiwan:TW, Thailand:TH, Turkey:TR, Ukraine:UA, United Kingdom:GB, " +
"United States:US, Uzbekistan:UZ, Vietnam:VN"
countries.split(", ").map(item => {
let [country, code] = item.split(":")
countryListModel.append({text: country, code: code, checked: false})
})
}
Component.onCompleted: createCountryList()
}
}