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 }