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 }