Warning, /plasma/plasma-sdk/plasmoidviewer/qmlpackages/shell/contents/configuration/AppletConfiguration.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
0004 SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
0005 SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
0006
0007 SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009
0010 import QtQuick 2.15
0011 import QtQuick.Controls 2.15 as QQC2
0012 import QtQuick.Layouts 1.15
0013
0014 import org.kde.kirigami 2.20 as Kirigami
0015 import org.kde.kitemmodels 1.0 as KItemModels
0016 import org.kde.plasma.configuration 2.0
0017
0018 Rectangle {
0019 id: root
0020
0021 implicitWidth: Kirigami.Units.gridUnit * 40
0022 implicitHeight: Kirigami.Units.gridUnit * 30
0023
0024 Layout.minimumWidth: Kirigami.Units.gridUnit * 30
0025 Layout.minimumHeight: Kirigami.Units.gridUnit * 21
0026
0027 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
0028 LayoutMirroring.childrenInherit: true
0029
0030 color: Kirigami.Theme.backgroundColor
0031
0032 property bool isContainment: false
0033
0034 property ConfigModel globalConfigModel: globalAppletConfigModel
0035
0036 function closing() {
0037 if (applyButton.enabled) {
0038 messageDialog.item = null;
0039 messageDialog.open();
0040 return false;
0041 }
0042 return true;
0043 }
0044
0045 Connections {
0046 target: configDialog
0047 function onClosing(event) {
0048 event.accepted = closing();
0049 }
0050 }
0051
0052 ConfigModel {
0053 id: globalAppletConfigModel
0054 ConfigCategory {
0055 name: i18nd("plasma_shell_org.kde.plasma.desktop", "Keyboard Shortcuts")
0056 icon: "preferences-desktop-keyboard"
0057 source: "ConfigurationShortcuts.qml"
0058 }
0059 }
0060
0061 KItemModels.KSortFilterProxyModel {
0062 id: configDialogFilterModel
0063 sourceModel: configDialog.configModel
0064 filterRowCallback: (row, parent) => {
0065 return sourceModel.data(sourceModel.index(row, 0), ConfigModel.VisibleRole);
0066 }
0067 }
0068
0069 function settingValueChanged() {
0070 applyButton.enabled = true;
0071 }
0072
0073 function pushReplace(item, config) {
0074 let page;
0075 if (app.pageStack.depth === 0) {
0076 page = app.pageStack.push(item, config);
0077 } else {
0078 page = app.pageStack.replace(item, config);
0079 }
0080 app.currentConfigPage = page;
0081 }
0082 Component {
0083 id: configurationKcmPageComponent
0084 ConfigurationKcmPage {
0085 }
0086 }
0087
0088 function open(item) {
0089 app.isAboutPage = false;
0090 if (item.source) {
0091 app.isAboutPage = item.source === "AboutPlugin.qml";
0092 pushReplace(Qt.resolvedUrl("ConfigurationAppletPage.qml"), {configItem: item, title: item.name});
0093 } else if (item.kcm) {
0094 pushReplace(configurationKcmPageComponent, {kcm: item.kcm, internalPage: item.kcm.mainUi});
0095 } else {
0096 app.pageStack.pop();
0097 }
0098
0099 applyButton.enabled = false
0100 }
0101
0102 Connections {
0103 target: app.currentConfigPage
0104
0105 function onSettingValueChanged() {
0106 applyButton.enabled = true;
0107 }
0108 }
0109
0110 Component.onCompleted: {
0111 // if we are a containment then the first item will be ConfigurationContainmentAppearance
0112 // if the applet does not have own configs then the first item will be Shortcuts
0113 if (isContainment || !configDialog.configModel || configDialog.configModel.count === 0) {
0114 open(root.globalConfigModel.get(0))
0115 } else {
0116 open(configDialog.configModel.get(0))
0117 }
0118 }
0119
0120 function applicationWindow() {
0121 return app;
0122 }
0123
0124
0125 QQC2.ScrollView {
0126 id: categoriesScroll
0127 anchors {
0128 left: parent.left
0129 top: parent.top
0130 bottom: parent.bottom
0131 }
0132 width: Kirigami.Units.gridUnit * 7
0133 Kirigami.Theme.colorSet: Kirigami.Theme.View
0134 Kirigami.Theme.inherit: false
0135 leftPadding: 0
0136 rightPadding: 0
0137 topPadding: 0
0138 bottomPadding: 0
0139 activeFocusOnTab: true
0140 focus: true
0141 Accessible.role: Accessible.MenuBar
0142 background: Rectangle {
0143 color: Kirigami.Theme.backgroundColor
0144 }
0145
0146 Keys.onUpPressed: {
0147 const buttons = categories.children
0148
0149 let foundPrevious = false
0150 for (let i = buttons.length - 1; i >= 0; --i) {
0151 const button = buttons[i];
0152 if (!button.hasOwnProperty("highlighted")) {
0153 // not a ConfigCategoryDelegate
0154 continue;
0155 }
0156
0157 if (foundPrevious) {
0158 categories.openCategory(button.item)
0159 categoriesScroll.forceActiveFocus(Qt.TabFocusReason)
0160 return
0161 } else if (button.highlighted) {
0162 foundPrevious = true
0163 }
0164 }
0165
0166 event.accepted = false
0167 }
0168
0169 Keys.onDownPressed: {
0170 const buttons = categories.children
0171
0172 let foundNext = false
0173 for (let i = 0, length = buttons.length; i < length; ++i) {
0174 const button = buttons[i];
0175 if (!button.hasOwnProperty("highlighted")) {
0176 continue;
0177 }
0178
0179 if (foundNext) {
0180 categories.openCategory(button.item)
0181 categoriesScroll.forceActiveFocus(Qt.TabFocusReason)
0182 return
0183 } else if (button.highlighted) {
0184 foundNext = true
0185 }
0186 }
0187
0188 event.accepted = false
0189 }
0190
0191 ColumnLayout {
0192 id: categories
0193
0194 spacing: 0
0195 width: categoriesScroll.width
0196 focus: true
0197
0198 function openCategory(item) {
0199 if (applyButton.enabled) {
0200 messageDialog.item = item;
0201 messageDialog.open();
0202 return;
0203 }
0204 open(item)
0205 }
0206
0207 Component {
0208 id: categoryDelegate
0209 ConfigCategoryDelegate {
0210 id: delegate
0211 onActivated: categories.openCategory(model);
0212 highlighted: {
0213 if (app.pageStack.currentItem) {
0214 if (model.kcm && app.pageStack.currentItem.kcm) {
0215 return model.kcm == app.pageStack.currentItem.kcm
0216 } else if (app.pageStack.currentItem.configItem) {
0217 return model.source == app.pageStack.currentItem.configItem.source
0218 } else {
0219 return app.pageStack.currentItem.source == Qt.resolvedUrl(model.source)
0220 }
0221 }
0222 return false
0223 }
0224 item: model
0225 }
0226 }
0227
0228 Repeater {
0229 Layout.fillWidth: true
0230 model: root.isContainment ? globalConfigModel : undefined
0231 delegate: categoryDelegate
0232 }
0233 Repeater {
0234 Layout.fillWidth: true
0235 model: configDialogFilterModel
0236 delegate: categoryDelegate
0237 }
0238 Repeater {
0239 Layout.fillWidth: true
0240 model: !root.isContainment ? globalConfigModel : undefined
0241 delegate: categoryDelegate
0242 }
0243 Repeater {
0244 Layout.fillWidth: true
0245 model: ConfigModel {
0246 ConfigCategory{
0247 name: i18nd("plasma_shell_org.kde.plasma.desktop", "About")
0248 icon: "help-about"
0249 source: "AboutPlugin.qml"
0250 }
0251 }
0252 delegate: categoryDelegate
0253 }
0254 }
0255 }
0256
0257 Kirigami.Separator {
0258 anchors {
0259 left: parent.left
0260 right: parent.right
0261 top: parent.top
0262 }
0263 z: 1
0264 }
0265 Kirigami.Separator {
0266 anchors {
0267 right: categoriesScroll.right
0268 top: parent.top
0269 bottom: parent.bottom
0270 }
0271 z: 1
0272 }
0273
0274 Kirigami.ApplicationItem {
0275 id: app
0276 anchors {
0277 left: categoriesScroll.right
0278 top: parent.top
0279 right: parent.right
0280 bottom: parent.bottom
0281 }
0282
0283 pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.Breadcrumb
0284 wideScreen: true
0285 pageStack.globalToolBar.separatorVisible: bottomSeparator.visible
0286 pageStack.globalToolBar.colorSet: Kirigami.Theme.Window
0287
0288 property var currentConfigPage: null
0289 property bool isAboutPage: false
0290
0291 QQC2.Dialog {
0292 id: messageDialog
0293 property var item
0294 title: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply Settings")
0295 QQC2.Label {
0296 anchors.fill:parent
0297 text: i18nd("plasma_shell_org.kde.plasma.desktop", "The settings of the current module have changed. Do you want to apply the changes or discard them?")
0298 }
0299 standardButtons: QQC2.Dialog.Apply | QQC2.Dialog.Discard | QQC2.Dialog.Cancel
0300 onAccepted: {
0301 applyAction.trigger()
0302 discard();
0303 }
0304 onRejected: {
0305 if (item) {
0306 root.open(item);
0307 } else {
0308 applyButton.enabled = false;
0309 configDialog.close();
0310 }
0311 }
0312 }
0313
0314 footer: QQC2.Pane {
0315
0316 padding: Kirigami.Units.largeSpacing
0317
0318 contentItem: RowLayout {
0319 id: buttonsRow
0320 spacing: Kirigami.Units.smallSpacing
0321
0322 Item {
0323 Layout.fillWidth: true
0324 }
0325
0326 QQC2.Button {
0327 icon.name: "dialog-ok"
0328 text: i18nd("plasma_shell_org.kde.plasma.desktop", "OK")
0329 onClicked: acceptAction.trigger()
0330 KeyNavigation.tab: categories
0331 }
0332 QQC2.Button {
0333 id: applyButton
0334 enabled: false
0335 icon.name: "dialog-ok-apply"
0336 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Apply")
0337 visible: !app.isAboutPage && app.pageStack.currentItem && (!app.pageStack.currentItem.kcm || app.pageStack.currentItem.kcm.buttons & 4) // 4 = Apply button
0338 onClicked: applyAction.trigger()
0339 }
0340 QQC2.Button {
0341 icon.name: "dialog-cancel"
0342 text: i18nd("plasma_shell_org.kde.plasma.desktop", "Cancel")
0343 onClicked: cancelAction.trigger()
0344 visible: !app.isAboutPage
0345 }
0346 }
0347 background: Item {
0348 Kirigami.Separator {
0349 id: bottomSeparator
0350 visible: app.pageStack.currentItem
0351 && app.pageStack.currentItem.flickable
0352 && !(app.pageStack.currentItem.flickable.atYBeginning
0353 && app.pageStack.currentItem.flickable.atYEnd)
0354 anchors {
0355 left: parent.left
0356 right: parent.right
0357 top: parent.top
0358 }
0359 }
0360 }
0361 }
0362
0363 QQC2.Action {
0364 id: acceptAction
0365 onTriggered: {
0366 applyAction.trigger();
0367 configDialog.close();
0368 }
0369 }
0370
0371 QQC2.Action {
0372 id: applyAction
0373 onTriggered: {
0374 app.pageStack.get(0).saveConfig()
0375
0376 applyButton.enabled = false;
0377 }
0378 }
0379
0380 QQC2.Action {
0381 id: cancelAction
0382 onTriggered: {
0383 if (root.closing()) {
0384 configDialog.close();
0385 }
0386 }
0387 }
0388
0389 Keys.onReturnPressed: acceptAction.trigger();
0390 Keys.onEscapePressed: cancelAction.trigger();
0391 }
0392 }