Warning, /plasma/plasma-systemmonitor/src/Main.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 import QtCore 0008 import QtQml 0009 import QtQuick 0010 import QtQuick.Controls 0011 import QtQuick.Dialogs 0012 import QtQuick.Layouts 0013 import QtQuick.Window 0014 0015 import org.kde.kirigami as Kirigami 0016 import org.kde.newstuff as NewStuff 0017 0018 import org.kde.systemmonitor 0019 import org.kde.ksysguard.page as Page 0020 0021 Kirigami.ApplicationWindow { 0022 id: app 0023 0024 minimumWidth: Kirigami.Units.gridUnit * 34 0025 minimumHeight: Kirigami.Units.gridUnit* 27 0026 0027 title: pageStack.currentItem?.title ?? "" 0028 0029 header: contentItem.GraphicsInfo.api === GraphicsInfo.Software ? degradedWarning.createObject(app) : null 0030 0031 Loader { 0032 active: !Kirigami.Settings.isMobile 0033 sourceComponent: GlobalMenu { } 0034 } 0035 0036 Kirigami.PagePool { 0037 id: pagePoolObject 0038 } 0039 0040 globalDrawer: Kirigami.GlobalDrawer { 0041 id: globalDrawer 0042 0043 handleVisible: false 0044 modal: false 0045 width: collapsed ? globalToolBar.Layout.minimumWidth + Kirigami.Units.smallSpacing : Math.max(globalToolBar.implicitWidth + globalToolBar.Layout.minimumWidth + Kirigami.Units.smallSpacing * 3, Kirigami.Units.gridUnit * 10) 0046 Behavior on width { NumberAnimation {id: collapseAnimation; duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad } } 0047 showHeaderWhenCollapsed: true 0048 0049 Kirigami.Theme.colorSet: Kirigami.Theme.View 0050 0051 header: ToolBar { 0052 implicitHeight: app.pageStack.globalToolBar.height 0053 0054 leftPadding: globalDrawer.collapsed ? 0 : Kirigami.Units.smallSpacing 0055 rightPadding: globalDrawer.collapsed ? Kirigami.Units.smallSpacing / 2 : Kirigami.Units.smallSpacing 0056 topPadding: 0 0057 bottomPadding: 0 0058 0059 Kirigami.ActionToolBar { 0060 id: globalToolBar 0061 0062 anchors.fill: parent 0063 0064 overflowIconName: "application-menu" 0065 0066 actions: [ 0067 Kirigami.Action { 0068 id: toolsAction 0069 text: i18nc("@action", "Tools") 0070 icon.name: "tools-symbolic" 0071 }, 0072 Kirigami.Action { 0073 id: editPagesAction 0074 icon.name: "handle-sort" 0075 text: i18nc("@action", "Edit or Remove pages…") 0076 displayHint: Kirigami.DisplayHint.AlwaysHide 0077 onTriggered: pageSortDialog.open() 0078 }, 0079 Kirigami.Action { 0080 id: exportAction 0081 text: i18nc("@action", "Export Current Page…") 0082 icon.name: "document-export" 0083 displayHint: Kirigami.DisplayHint.AlwaysHide 0084 enabled: !app.pageStack.currentItem?.edit ?? false 0085 onTriggered: exportDialog.open() 0086 }, 0087 Kirigami.Action { 0088 icon.name: "document-import" 0089 text: i18nc("@action", "Import Page…") 0090 displayHint: Kirigami.DisplayHint.AlwaysHide 0091 onTriggered: importDialog.open() 0092 }, 0093 NewStuff.Action { 0094 id: ghnsAction 0095 text: i18nc("@action:inmenu", "Get New Pages…") 0096 configFile: "plasma-systemmonitor.knsrc" 0097 pageStack: app.pageStack.layers 0098 displayHint: Kirigami.DisplayHint.AlwaysHide 0099 onEntryEvent: { 0100 if (event === NewStuff.Engine.StatusChangedEvent) { 0101 pagesModel.ghnsEntryStatusChanged(entry) 0102 } 0103 } 0104 }, 0105 Kirigami.Action { 0106 id: collapseAction 0107 icon.name: app.globalDrawer.collapsed ? "view-split-left-right" : "view-left-close" 0108 text: app.globalDrawer.collapsed ? i18nc("@action", "Expand Sidebar") : i18nc("@action", "Collapse Sidebar") 0109 onTriggered: app.globalDrawer.collapsed = !app.globalDrawer.collapsed 0110 displayHint: Kirigami.DisplayHint.AlwaysHide 0111 }, 0112 Kirigami.Action { 0113 separator: true 0114 displayHint: Kirigami.DisplayHint.AlwaysHide 0115 }, 0116 Kirigami.Action { 0117 icon.name: "tools-report-bug"; 0118 text: i18nc("@action", "Report Bug…"); 0119 displayHint: Kirigami.DisplayHint.AlwaysHide 0120 onTriggered: Qt.openUrlExternally(CommandLineArguments.aboutData.bugAddress); 0121 }, 0122 Kirigami.Action { 0123 icon.name: "help-about-symbolic"; 0124 text: i18nc("@action", "About System Monitor"); 0125 displayHint: Kirigami.DisplayHint.AlwaysHide 0126 onTriggered: app.pageStack.layers.push("AboutPage.qml") 0127 enabled: app.pageStack.layers.depth <= 1 0128 } 0129 ] 0130 Component.onCompleted: { 0131 app.quitAction.displayHint = Kirigami.DisplayHint.AlwaysHide 0132 actions.push(app.quitAction) 0133 } 0134 } 0135 0136 Instantiator { 0137 model: ToolsModel { id: toolsModel } 0138 0139 Kirigami.Action { 0140 text: model.name 0141 icon.name: model.icon 0142 shortcut: model.shortcut 0143 onTriggered: toolsModel.trigger(model.id) 0144 } 0145 0146 onObjectAdded: (index, object) => { 0147 toolsAction.children.push(object) 0148 } 0149 } 0150 } 0151 0152 actions: [ 0153 Kirigami.Action { 0154 text: i18nc("@action", "Add New Page…") 0155 icon.name: "list-add" 0156 onTriggered: pageDialog.open() 0157 } 0158 ] 0159 0160 Instantiator { 0161 model: Page.PagesModel { id: pagesModel } 0162 0163 Page.EditablePageAction { 0164 text: model.title 0165 icon.name: model.icon 0166 pagePool: pagePoolObject 0167 pageData: model.data 0168 visible: !model.hidden 0169 onTriggered: { 0170 config.lastVisitedPage = model.fileName 0171 0172 if (app.pageStack.layers.depth > 0) { 0173 app.pageStack.layers.clear() 0174 } 0175 } 0176 0177 Component.onCompleted: { 0178 if (CommandLineArguments.pageId && model.fileName == CommandLineArguments.pageId) { 0179 trigger() 0180 } else if (CommandLineArguments.pageName && model.title == CommandLineArguments.pageName) { 0181 trigger() 0182 } else if (config.startPage == model.fileName) { 0183 trigger() 0184 } else if (config.startPage == "" && config.lastVisitedPage == model.fileName) { 0185 trigger() 0186 } 0187 } 0188 } 0189 0190 onObjectAdded: (index, object) => { 0191 var actions = Array.prototype.map.call(globalDrawer.actions, i => i) 0192 actions.splice(index, 0, object) 0193 globalDrawer.actions = actions 0194 } 0195 0196 onObjectRemoved: (index, object) => { 0197 var actions = Array.prototype.map.call(globalDrawer.actions, i => i) 0198 var actionIndex = actions.indexOf(object) 0199 actions.splice(actionIndex, 1) 0200 globalDrawer.actions = actions 0201 } 0202 } 0203 0204 contentData: [ 0205 TapHandler { 0206 acceptedButtons: Qt.RightButton 0207 onTapped: globalContextMenu.popup(eventPoint.scenePosition.x, eventPoint.scenePosition.y, globalDrawer) 0208 }, 0209 Menu { 0210 id: globalContextMenu 0211 0212 MenuItem { action: editPagesAction } 0213 MenuItem { action: ghnsAction } 0214 MenuItem { action: collapseAction } 0215 } 0216 ] 0217 } 0218 0219 Page.DialogLoader { 0220 id: pageDialog 0221 0222 sourceComponent: Page.PageDialog { 0223 title: i18nc("@window:title", "Add New Page") 0224 0225 onAccepted: { 0226 var fileName = name.toLowerCase().replace(" ", "_"); 0227 var newPage = pagesModel.addPage(fileName, {title: name, icon: iconName, margin: margin}) 0228 var row = newPage.insertChild(0, {name: "row-0", isTitle: false, title: "", heightMode: "balanced"}) 0229 var column = row.insertChild(0, {name: "column-0", showBackground: true}) 0230 column.insertChild(0, {name: "section-0", isSeparator: false}) 0231 newPage.savePage() 0232 0233 const pageAction = Array.from(globalDrawer.actions).find(action => action.pageData.fileName == newPage.fileName) 0234 pageAction.trigger() 0235 app.pageStack.currentItem.edit = true 0236 } 0237 } 0238 } 0239 0240 Page.DialogLoader { 0241 id: pageSortDialog 0242 0243 sourceComponent: Page.PageSortDialog { 0244 title: i18nc("@window:title", "Edit Pages") 0245 model: pagesModel 0246 startPage: config.startPage 0247 onAccepted: { 0248 config.startPage = startPage 0249 const currentPage = pageStack.currentItem.pageData.fileName 0250 const indices = pagesModel.match(pagesModel.index(0, 0), Page.PagesModel.FileNameRole, currentPage, 1, Qt.MatchExactly) 0251 if (indices.length == 0 || pagesModel.data(indices[0], Page.PagesModel.HiddenRole)) { 0252 if (config.lastVisitedPage == currentPage) { 0253 config.lastVisitedPage = "overview.page" 0254 } 0255 const startPage = config.startPage || config.lastVisitedPage 0256 Array.prototype.find.call(globalDrawer.actions, action => action.pageData.fileName == startPage).trigger() 0257 } 0258 } 0259 } 0260 } 0261 0262 Page.DialogLoader { 0263 id: exportDialog 0264 sourceComponent: FileDialog { 0265 fileMode: FileDialog.SaveFile 0266 currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] 0267 title: i18nc("@title:window %1 is the name of the page that is being exported", "Export %1", app.pageStack.currentItem.title) 0268 defaultSuffix: "page" 0269 nameFilters: [i18nc("Name filter in file dialog", "System Monitor page (*.page)")] 0270 onAccepted: app.pageStack.currentItem.pageData.saveAs(selectedFile) 0271 } 0272 } 0273 Page.DialogLoader { 0274 id: importDialog 0275 sourceComponent: FileDialog { 0276 currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] 0277 title: i18nc("@title:window", "Import Page") 0278 defaultSuffix: "page" 0279 nameFilters: [i18nc("Name filter in file dialog", "System Monitor page (*.page)")] 0280 onAccepted: { 0281 const newPage = pagesModel.importPage(selectedFile) 0282 if (!newPage) { 0283 return; 0284 } 0285 const pageAction = Array.from(globalDrawer.actions).find(action => action.pageData.fileName == newPage.fileName) 0286 pageAction.trigger() 0287 } 0288 } 0289 } 0290 0291 Configuration { 0292 id: config 0293 property alias sidebarCollapsed: globalDrawer.collapsed 0294 property alias pageOrder: pagesModel.pageOrder 0295 property alias hiddenPages: pagesModel.hiddenPages 0296 property string startPage 0297 property string lastVisitedPage 0298 0299 property real width 0300 Binding on width { 0301 when: app.visibility == Window.Windowed 0302 delayed: true 0303 value: app.width 0304 restoreMode: Binding.RestoreNone 0305 } 0306 0307 property real height 0308 Binding on height { 0309 when: app.visibility == Window.Windowed 0310 delayed: true 0311 value: app.height 0312 restoreMode: Binding.RestoreNone 0313 } 0314 0315 property bool maximized 0316 0317 Binding on maximized { 0318 when: app.visibility != Window.Hidden 0319 // This is delayed otherwise it still writes to the config property even though when is false 0320 delayed: true 0321 value: app.visibility == Window.Maximized 0322 restoreMode: Binding.RestoreNone 0323 } 0324 } 0325 0326 onVisibilityChanged: (visibility) => { 0327 if (visibility == Window.Windowed) { 0328 width = config.width 0329 height = config.height 0330 } 0331 } 0332 0333 Component { 0334 id: degradedWarning 0335 0336 ToolBar { 0337 Kirigami.InlineMessage { 0338 anchors.fill: parent 0339 visible: true 0340 type: Kirigami.MessageType.Warning 0341 text: i18n("System Monitor has fallen back to software rendering because hardware acceleration is not available, and visual glitches may appear. Please check your graphics drivers.") 0342 } 0343 } 0344 } 0345 0346 pageStack.columnView.columnWidth: Kirigami.Units.gridUnit * 22 0347 }