Warning, /plasma/plasma-systemmonitor/src/page/EditablePage.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 import QtQuick 0008 import QtQuick.Controls 0009 import QtQuick.Layouts 0010 0011 import org.kde.kirigami as Kirigami 0012 0013 import org.kde.ksysguard.page 0014 0015 Kirigami.ScrollablePage { 0016 id: page 0017 0018 property PageDataObject pageData 0019 property bool edit: false 0020 0021 title: pageData.title 0022 0023 leftPadding: pageData.margin * Kirigami.Units.largeSpacing 0024 rightPadding: pageData.margin * Kirigami.Units.largeSpacing 0025 topPadding: pageData.margin * Kirigami.Units.largeSpacing 0026 bottomPadding: pageData.margin * Kirigami.Units.largeSpacing 0027 0028 Kirigami.ColumnView.fillWidth: true 0029 Kirigami.ColumnView.reservedSpace: edit ? applicationWindow().pageStack.columnView.columnWidth : 0 0030 0031 Binding { 0032 target: globalToolBarItem 0033 property: "enabled" 0034 value: contentLoader.status != Loader.Loading 0035 } 0036 0037 readonly property real heightForContent: (parent?.height ?? 0) - topPadding - bottomPadding - (globalToolBarItem?.height ?? 0) 0038 0039 readonly property var actionsFace: contentLoader.item && contentLoader.item.actionsFace ? contentLoader.item.actionsFace : null 0040 onActionsFaceChanged: Qt.callLater(updateActions) 0041 Connections { 0042 target: page.actionsFace 0043 function onActionsChanged() { Qt.callLater(page.updateActions) } 0044 } 0045 0046 function updateActions() { 0047 actions = [] 0048 0049 if (!actionsFace || page.edit) { 0050 actions = defaultActions 0051 return 0052 } 0053 0054 actions = actions.concat(page.actionsFace.actions).concat(defaultActions) 0055 } 0056 0057 // Scroll the contents of the page based on the position of a rect (in scene 0058 // coordinates). If any part of the rect is above the visible area, contents 0059 // will be scrolled down. If any part of the rect is below the visible area, 0060 // contents will be scrolled up instead. This mimics dragging behaviour of 0061 // file managers and similar things. 0062 function scrollContents(rect) { 0063 let visibleRect = page.flickable.mapToItem(null, Qt.rect(page.flickable.x, page.flickable.y, page.flickable.width, page.flickable.height - page.bottomPadding)) 0064 0065 let minY = rect.y 0066 let maxY = rect.y + rect.height 0067 0068 let visibleTop = visibleRect.y 0069 let visibleBottom = visibleRect.y + visibleRect.height 0070 0071 if (minY >= visibleTop && maxY <= visibleBottom) { 0072 return 0073 } 0074 0075 if (maxY > visibleBottom && !page.flickable.atYEnd) { 0076 page.flickable.contentY += (maxY - visibleBottom) 0077 } else if (minY < visibleTop && !page.flickable.atYBeginning) { 0078 page.flickable.contentY += (minY - visibleTop) 0079 } 0080 page.flickable.returnToBounds() 0081 } 0082 0083 Kirigami.Action { 0084 id: editAction 0085 0086 text: i18nc("@action", "Edit Page") 0087 icon.name: "document-edit" 0088 visible: !page.edit 0089 0090 displayHint: page.actionsFace ? Kirigami.DisplayHint.AlwaysHide : Kirigami.DisplayHint.NoPreference 0091 0092 onTriggered: page.edit = !page.edit 0093 } 0094 Kirigami.Action { 0095 id: saveAction 0096 text: i18nc("@action", "Save Changes") 0097 icon.name: "document-save" 0098 visible: page.edit 0099 onTriggered: { 0100 page.edit = false 0101 page.pageData.savePage() 0102 } 0103 } 0104 Kirigami.Action { 0105 id: discardAction 0106 text: i18nc("@action", "Discard Changes") 0107 icon.name: "edit-delete-remove" 0108 visible: page.edit 0109 onTriggered: { 0110 page.edit = false 0111 page.pageData.resetPage() 0112 } 0113 } 0114 Kirigami.Action { 0115 id: configureAction 0116 0117 text: i18nc("@action", "Configure Pageā¦") 0118 icon.name: "configure" 0119 visible: page.edit 0120 0121 onTriggered: pageDialog.open() 0122 } 0123 Kirigami.Action { 0124 id: addRowAction 0125 0126 text: i18nc("@action", "Add Row") 0127 icon.name: "edit-table-insert-row-under" 0128 visible: page.edit 0129 0130 onTriggered: contentLoader.item.addRow(-1) 0131 } 0132 0133 Kirigami.Action { 0134 id: addTitleAction 0135 text: i18nc("@action", "Add Title") 0136 icon.name: "insert-text-frame" 0137 visible: page.edit 0138 0139 onTriggered: contentLoader.item.addTitle(-1) 0140 } 0141 0142 readonly property var defaultActions: [editAction, saveAction, discardAction, addRowAction, addTitleAction, configureAction] 0143 0144 Component { 0145 id: pageEditor 0146 0147 PageEditor { 0148 parentPage: page 0149 pageData: page.pageData 0150 } 0151 } 0152 0153 Component { 0154 id: pageContents 0155 0156 PageContents { 0157 pageData: page.pageData 0158 } 0159 } 0160 0161 data: [ 0162 DialogLoader { 0163 id: pageDialog 0164 sourceComponent: PageDialog { 0165 title: i18nc("@title:window %1 is page title", "Configure Page \"%1\"", page.pageData.title) 0166 0167 acceptText: i18nc("@action:button", "Save") 0168 acceptIcon: "document-save" 0169 0170 onAboutToShow: { 0171 name = page.pageData.title 0172 iconName = page.pageData.icon 0173 margin = page.pageData.margin 0174 pageData = page.pageData 0175 actionsFace = page.pageData.actionsFace ? page.pageData.actionsFace : "" 0176 loadType = page.pageData.loadType ? page.pageData.loadType : "ondemand" 0177 } 0178 0179 onAccepted: { 0180 pageData.title = name 0181 pageData.icon = iconName 0182 pageData.margin = margin 0183 pageData.actionsFace = actionsFace 0184 pageData.loadType = loadType 0185 } 0186 } 0187 }, 0188 DialogLoader { 0189 id: missingSensorsDialog 0190 0191 sourceComponent: MissingSensorsDialog { 0192 missingSensors: contentLoader.item ? contentLoader.item.missingSensors : [] 0193 0194 onSensorReplacementChanged: { 0195 contentLoader.item.replaceSensors(sensorReplacement) 0196 } 0197 } 0198 } 0199 ] 0200 0201 Rectangle { 0202 id: loadOverlay 0203 0204 parent: page.overlay 0205 anchors.fill: parent 0206 anchors.margins: -pageData.margin * Kirigami.Units.largeSpacing 0207 color: Kirigami.Theme.backgroundColor 0208 0209 opacity: 1 0210 visible: opacity > 0 0211 Behavior on opacity { OpacityAnimator { duration: Kirigami.Units.shortDuration } } 0212 0213 BusyIndicator { 0214 anchors.centerIn: parent 0215 running: loadOverlay.visible 0216 } 0217 } 0218 0219 Loader { 0220 id: contentLoader 0221 0222 width: page.width 0223 height: item ? Math.max(item.Layout.minimumHeight, page.heightForContent) : page.heightForContent 0224 0225 property real availableHeight: page.heightForContent 0226 property real rowSpacing: page.pageData.margin * Kirigami.Units.smallSpacing 0227 0228 sourceComponent: page.edit ? pageEditor : pageContents 0229 asynchronous: true 0230 0231 onStatusChanged: { 0232 if (status == Loader.Loading) { 0233 loadOverlay.opacity = 1 0234 if (!edit && applicationWindow().pageStack.columnView.containsItem(page)) { 0235 // Pop any pages that might have been opened during editing 0236 applicationWindow().pageStack.pop(page) 0237 } 0238 } else { 0239 Qt.callLater(updateActions) 0240 page.flickable.returnToBounds() 0241 loadOverlay.opacity = 0 0242 } 0243 } 0244 0245 Connections { 0246 target: contentLoader.item 0247 0248 function onShowMissingSensors() { 0249 missingSensorsDialog.open() 0250 } 0251 } 0252 } 0253 }