Warning, /system/plasma-pk-updates/src/plasma/contents/ui/Full.qml is written in an unsupported language. File is not indexed.
0001 /*************************************************************************** 0002 * Copyright (C) 2013 by Aleix Pol Gonzalez <aleixpol@blue-systems.com> * 0003 * Copyright (C) 2015 by Lukáš Tinkl <lukas@kde.org> * 0004 * Copyright (C) 2015 by Jan Grulich <jgrulich@redhat.com> * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, write to the * 0018 * Free Software Foundation, Inc., * 0019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 0020 ***************************************************************************/ 0021 0022 import QtQuick 2.15 0023 import QtQuick.Layouts 1.1 0024 import QtQuick.Controls 2.5 as QQC2 0025 import QtQuick.Dialogs 1.2 0026 import org.kde.plasma.components 3.0 as PlasmaComponents3 0027 import org.kde.plasma.extras 2.0 as PlasmaExtras 0028 import org.kde.plasma.core 2.0 as PlasmaCore 0029 import org.kde.plasma.PackageKit 1.0 0030 0031 Item { 0032 id: fullRepresentation 0033 0034 property bool anySelected: false 0035 property bool allSelected: false 0036 property bool populatePreSelected: true 0037 0038 width: units.gridUnit * 20 0039 height: units.gridUnit * 20 0040 0041 Binding { 0042 target: timestampLabel 0043 property: "text" 0044 value: PkUpdates.timestamp 0045 when: !plasmoid.expanded 0046 } 0047 0048 Connections { 0049 target: PkUpdates 0050 onUpdatesChanged: populateModel() 0051 onUpdateDetail: updateDetails(packageID, updateText, urls) 0052 onUpdatesInstalled: plasmoid.expanded = false 0053 onEulaRequired: eulaDialog.showPrompt(eulaID, packageID, vendor, licenseAgreement) 0054 } 0055 0056 Component.onCompleted: populateModel() 0057 0058 Dialog { 0059 property string eulaID: "" 0060 property string packageName: "" 0061 property string vendor: "" 0062 property string licenseText: "" 0063 0064 property bool buttonClicked: false 0065 0066 id: eulaDialog 0067 title: i18n("License Agreement for %1").arg(packageName) 0068 standardButtons: StandardButton.Yes | StandardButton.No 0069 0070 ColumnLayout { 0071 anchors.fill: parent 0072 0073 QQC2.Label { 0074 text: i18n("License agreement required for %1 (from %2):").arg(eulaDialog.packageName).arg(eulaDialog.vendor) 0075 } 0076 0077 QQC2.ScrollView { 0078 Layout.fillWidth: true 0079 Layout.fillHeight: true 0080 // The Dialog uses the implicit size as minimum, 0081 // so this doesn't have much effect... 0082 Layout.minimumWidth: 400 0083 Layout.minimumHeight: 200 0084 0085 Layout.preferredWidth: 600 0086 Layout.preferredHeight: 500 0087 0088 // Work around that TextArea does not redraw 0089 // when the visible area changes after resizing. 0090 onHeightChanged: licenseArea.update() 0091 onWidthChanged: licenseArea.update() 0092 0093 QQC2.TextArea { 0094 id: licenseArea 0095 text: eulaDialog.licenseText 0096 readOnly: true 0097 } 0098 } 0099 0100 QQC2.Label { 0101 text: i18n("Do you accept?") 0102 } 0103 } 0104 0105 onVisibleChanged: { 0106 // onRejected does not fire on dialog closing, so implement that ourselves 0107 if(!visible && !buttonClicked) 0108 onNo(); 0109 } 0110 onNo: { 0111 buttonClicked = true; 0112 PkUpdates.eulaAgreementResult(this.eulaID, false); 0113 } 0114 onYes: { 0115 buttonClicked = true; 0116 PkUpdates.eulaAgreementResult(this.eulaID, true); 0117 } 0118 0119 function showPrompt(eulaID, packageID, vendor, licenseAgreement) { 0120 this.eulaID = eulaID; 0121 this.packageName = PkUpdates.packageName(packageID); 0122 this.vendor = vendor; 0123 this.licenseText = licenseAgreement; 0124 0125 this.visible = true; 0126 } 0127 } 0128 0129 ListModel { 0130 id: updatesModel 0131 } 0132 0133 0134 ColumnLayout { 0135 id: statusbar 0136 0137 anchors.fill: parent 0138 0139 spacing: units.smallSpacing 0140 0141 PlasmaExtras.Heading { 0142 Layout.fillWidth: true 0143 level: 4 0144 wrapMode: Text.WordWrap 0145 text: !PkUpdates.isNetworkOnline ? i18n("Network is offline") : PkUpdates.message 0146 } 0147 0148 PlasmaComponents3.Label { 0149 visible: PkUpdates.isActive || PkUpdates.count === 0 0150 font.pointSize: theme.smallestFont.pointSize; 0151 opacity: 0.6; 0152 text: { 0153 if (PkUpdates.isActive) 0154 return PkUpdates.statusMessage 0155 else if (PkUpdates.isNetworkOnline) 0156 return i18n("Updates are automatically checked %1.", 0157 updateInterval(plasmoid.configuration.daily, 0158 plasmoid.configuration.weekly, 0159 plasmoid.configuration.monthly)); 0160 return "" 0161 } 0162 Layout.fillWidth: true 0163 wrapMode: Text.WordWrap 0164 } 0165 0166 PlasmaComponents3.Label { 0167 id: timestampLabel 0168 Layout.fillWidth: true 0169 visible: !PkUpdates.isActive 0170 wrapMode: Text.WordWrap 0171 font.italic: true 0172 font.pointSize: theme.smallestFont.pointSize; 0173 opacity: 0.6; 0174 text: PkUpdates.timestamp 0175 } 0176 0177 PlasmaComponents3.ProgressBar { 0178 Layout.fillWidth: true 0179 visible: PkUpdates.isActive 0180 from: 0 0181 to: 101 // BUG workaround a bug in ProgressBar! if the value is > max, it's set to max and never changes below 0182 value: PkUpdates.percentage 0183 indeterminate: PkUpdates.percentage > 100 0184 } 0185 0186 PlasmaExtras.ScrollArea { 0187 id: listViewScrollArea 0188 0189 Layout.fillWidth: true 0190 Layout.fillHeight: true 0191 0192 visible: PkUpdates.count && PkUpdates.isNetworkOnline && !PkUpdates.isActive 0193 0194 ListView { 0195 id: updatesView 0196 0197 reuseItems: true 0198 clip: true 0199 model: PlasmaCore.SortFilterModel { 0200 sourceModel: updatesModel 0201 filterRole: "name" 0202 } 0203 anchors.fill: parent 0204 currentIndex: -1 0205 property int lastIndex: -1 0206 boundsBehavior: Flickable.StopAtBounds 0207 delegate: PackageDelegate { 0208 onClicked: { 0209 if (updatesView.lastIndex == updatesView.currentIndex) { 0210 // Unselect as current 0211 updatesView.currentIndex = -1 0212 } else { 0213 // Expand, load details 0214 PkUpdates.getUpdateDetails(id) 0215 } 0216 updatesView.lastIndex = updatesView.currentIndex 0217 } 0218 onCheckStateChanged: updateSelectionState(); 0219 } 0220 } 0221 } 0222 0223 // Container for other items that can be shown when the main scroll 0224 // view is not visible 0225 Item { 0226 Layout.fillWidth: true 0227 Layout.fillHeight: true 0228 0229 visible: !listViewScrollArea.visible 0230 0231 PlasmaComponents3.BusyIndicator { 0232 running: PkUpdates.isActive && PkUpdates.count == 0 0233 visible: running 0234 anchors.centerIn: parent 0235 } 0236 0237 PlasmaExtras.PlaceholderMessage { 0238 anchors.centerIn: parent 0239 width: parent.width - (units.largeSpacing * 4) 0240 0241 visible: PkUpdates.count === 0 && PkUpdates.isNetworkOnline && !PkUpdates.isActive 0242 0243 text: PkUpdates.lastCheckSuccessful ? i18n("No updates available") : "" 0244 0245 helpfulAction: QQC2.Action { 0246 icon.name: "view-refresh" 0247 text: i18n("Check for Updates") 0248 onTriggered: { 0249 PkUpdates.checkUpdates(true /* manual */) // circumvent the checks, the user knows what they're doing ;) 0250 } 0251 } 0252 } 0253 } 0254 0255 PlasmaComponents3.CheckBox { 0256 Layout.fillWidth: true 0257 Layout.leftMargin: units.smallSpacing 0258 0259 visible: PkUpdates.count !== 0 && PkUpdates.isNetworkOnline && !PkUpdates.isActive 0260 0261 tristate: true 0262 0263 checkState: fullRepresentation.allSelected ? Qt.Checked : 0264 (fullRepresentation.anySelected ? Qt.PartiallyChecked 0265 : Qt.Unchecked) 0266 0267 text: i18n("Select all packages") 0268 0269 onClicked: { 0270 populatePreSelected = !fullRepresentation.anySelected; 0271 populateModel(); 0272 } 0273 } 0274 0275 PlasmaComponents3.Button { 0276 visible: PkUpdates.count !== 0 && PkUpdates.isNetworkOnline && !PkUpdates.isActive 0277 icon.name: "install" 0278 enabled: fullRepresentation.anySelected 0279 Layout.alignment: Qt.AlignHCenter 0280 text: i18n("Install Updates") 0281 onClicked: PkUpdates.installUpdates(selectedPackages()) 0282 0283 PlasmaComponents3.ToolTip { 0284 text: i18n("Performs the software update") 0285 } 0286 } 0287 } 0288 0289 function updateSelectionState() { 0290 console.log("Updating state of selection"); 0291 var anySelected = false; 0292 var allSelected = true; 0293 for (var i = 0; i < updatesModel.count; i++) { 0294 var pkg = updatesModel.get(i) 0295 if (pkg.selected) 0296 anySelected = true; 0297 else 0298 allSelected = false; 0299 0300 if (anySelected && !allSelected) 0301 break; // Can't change anymore 0302 } 0303 fullRepresentation.anySelected = anySelected; 0304 fullRepresentation.allSelected = allSelected; 0305 } 0306 0307 function selectedPackages() { 0308 var result = [] 0309 for (var i = 0; i < updatesModel.count; i++) { 0310 var pkg = updatesModel.get(i) 0311 if (pkg.selected) { 0312 print("Package " + pkg.id + " selected for update") 0313 result.push(pkg.id) 0314 } 0315 } 0316 return result 0317 } 0318 0319 function populateModel() { 0320 print("Populating model") 0321 updatesModel.clear() 0322 var packages = PkUpdates.packages 0323 for (var id in packages) { 0324 if (packages.hasOwnProperty(id)) { 0325 var desc = packages[id] 0326 updatesModel.append({"selected": populatePreSelected, "id": id, "name": PkUpdates.packageName(id), "desc": desc, "version": PkUpdates.packageVersion(id)}) 0327 } 0328 } 0329 updateSelectionState(); 0330 } 0331 0332 function updateDetails(packageID, updateText, urls) { 0333 //print("Got update details for: " + packageID) 0334 print("Update text: " + updateText) 0335 print("URLs: " + urls) 0336 updatesView.currentItem.updateText = updateText 0337 updatesView.currentItem.updateUrls = urls 0338 } 0339 0340 function updateInterval(daily, weekly, monthly) { 0341 if (weekly) 0342 return i18n("weekly"); 0343 else if (monthly) 0344 return i18n("monthly"); 0345 0346 return i18n("daily"); 0347 } 0348 }