Changeset View
Changeset View
Standalone View
Standalone View
src/qtquick/qml/NewStuffPage.qml
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright (C) 2019 Dan Leinir Turthra Jensen <admin@leinir.dk> | ||||
3 | * | ||||
4 | * This library is free software; you can redistribute it and/or | ||||
5 | * modify it under the terms of the GNU Lesser General Public | ||||
6 | * License as published by the Free Software Foundation; either | ||||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | * later version accepted by the membership of KDE e.V. (or its | ||||
9 | * successor approved by the membership of KDE e.V.), which shall | ||||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | * | ||||
12 | * This library is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | * Lesser General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU Lesser General Public | ||||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | * | ||||
20 | */ | ||||
21 | | ||||
22 | /** | ||||
23 | * @brief A Kirigami.Page component used for managing KNS entries | ||||
24 | * | ||||
25 | * This component is functionally equivalent to the old DownloadDialog | ||||
26 | * @see KNewStuff::DownloadDialog | ||||
27 | */ | ||||
28 | | ||||
29 | import QtQuick 2.7 | ||||
30 | import QtQuick.Controls 2.5 as QtControls | ||||
31 | import QtQuick.Layouts 1.12 as QtLayouts | ||||
32 | import QtGraphicalEffects 1.12 as QtEffects | ||||
33 | import org.kde.kcm 1.2 as KCM | ||||
34 | import org.kde.kirigami 2.7 as Kirigami | ||||
35 | import org.kde.newstuff 1.1 as NewStuff | ||||
36 | | ||||
37 | KCM.GridViewKCM { | ||||
38 | id: root; | ||||
39 | /** | ||||
40 | * @brief The configuration file which describes the application (knsrc) | ||||
41 | * | ||||
42 | * The format and location of this file is found in the documentation for | ||||
43 | * KNS3::DownloadDialog | ||||
44 | */ | ||||
45 | property alias configFile: newStuffEngine.configFile; | ||||
46 | readonly property alias engine: newStuffEngine; | ||||
47 | signal message(string message); | ||||
48 | signal idleMessage(string message); | ||||
49 | signal busyMessage(string message); | ||||
50 | signal errorMessage(string message); | ||||
51 | | ||||
52 | property string uninstallLabel: i18nc("Request uninstallation of this item", "Uninstall"); | ||||
53 | property string useLabel: i18nc("If a knsrc file defines an adoption command, the option to run this command and 'use' an item becomes available. This is the text for an action to do so.", "Use"); | ||||
54 | | ||||
55 | property int viewMode: NewStuffPage.ViewMode.Tiles | ||||
56 | enum ViewMode { | ||||
57 | Tiles, | ||||
58 | Icons, | ||||
59 | Preview | ||||
60 | } | ||||
61 | | ||||
62 | title: newStuffEngine.name | ||||
63 | NewStuff.Engine { | ||||
64 | id: newStuffEngine; | ||||
65 | onMessage: root.message(message); | ||||
66 | onIdleMessage: root.idleMessage(message); | ||||
67 | onBusyMessage: root.busyMessage(message); | ||||
68 | onErrorMessage: root.errorMessage(message); | ||||
69 | } | ||||
70 | NewStuffQuestionAsker {} | ||||
71 | | ||||
72 | titleDelegate: QtLayouts.RowLayout { | ||||
73 | Kirigami.Heading { | ||||
74 | id: title | ||||
75 | level: 1 | ||||
76 | | ||||
77 | QtLayouts.Layout.fillWidth: true; | ||||
78 | QtLayouts.Layout.preferredWidth: titleTextMetrics.width | ||||
79 | QtLayouts.Layout.minimumWidth: titleTextMetrics.width | ||||
80 | opacity: root.isCurrentPage ? 1 : 0.4 | ||||
81 | maximumLineCount: 1 | ||||
82 | elide: Text.ElideRight | ||||
83 | text: root.title | ||||
84 | TextMetrics { | ||||
85 | id: titleTextMetrics | ||||
86 | text: root.title | ||||
87 | font: title.font | ||||
88 | } | ||||
89 | } | ||||
90 | QtControls.ButtonGroup { | ||||
91 | id: displayModeGroup | ||||
92 | buttons: [displayModeTiles, displayModeIcons] | ||||
93 | } | ||||
94 | QtControls.ToolButton { | ||||
95 | id: displayModeTiles | ||||
96 | icon.name: "view-list-details" | ||||
97 | onClicked: { root.viewMode = NewStuffPage.ViewMode.Tiles; } | ||||
98 | checked: root.viewMode == NewStuffPage.ViewMode.Tiles | ||||
99 | } | ||||
100 | QtControls.ToolButton { | ||||
101 | id: displayModeIcons | ||||
102 | icon.name: "view-list-icons" | ||||
103 | onClicked: { root.viewMode = NewStuffPage.ViewMode.Icons; } | ||||
104 | checked: root.viewMode == NewStuffPage.ViewMode.Icons | ||||
105 | } | ||||
106 | QtControls.ToolButton { | ||||
107 | id: displayPreview | ||||
108 | icon.name: "view-preview" | ||||
109 | onClicked: { root.viewMode = NewStuffPage.ViewMode.Preview; } | ||||
110 | checked: root.viewMode == NewStuffPage.ViewMode.Preview | ||||
111 | } | ||||
112 | Kirigami.ActionTextField { | ||||
113 | id: searchField | ||||
114 | placeholderText: i18n("Search...") | ||||
115 | focusSequence: "Ctrl+F" | ||||
116 | rightActions: [ | ||||
117 | Kirigami.Action { | ||||
118 | iconName: "edit-clear" | ||||
119 | visible: searchField.text !== "" | ||||
120 | onTriggered: { | ||||
121 | searchField.text = ""; | ||||
122 | searchField.accepted(); | ||||
123 | } | ||||
124 | } | ||||
125 | ] | ||||
126 | onAccepted: { | ||||
127 | newStuffEngine.searchTerm = searchField.text; | ||||
128 | } | ||||
129 | } | ||||
130 | } | ||||
131 | | ||||
132 | footer: QtLayouts.RowLayout { | ||||
133 | QtControls.ComboBox { | ||||
134 | id: categoriesCombo | ||||
135 | QtLayouts.Layout.fillWidth: true | ||||
136 | model: newStuffEngine.categories | ||||
137 | textRole: "displayName" | ||||
138 | onCurrentIndexChanged: { | ||||
139 | newStuffEngine.categoriesFilter = model.data(currentIndex, NewStuff.CategoriesModel.NameRole); | ||||
140 | } | ||||
141 | } | ||||
142 | QtControls.ComboBox { | ||||
143 | id: filterCombo | ||||
144 | QtLayouts.Layout.fillWidth: true | ||||
145 | model: ListModel {} | ||||
146 | Component.onCompleted: { | ||||
147 | filterCombo.model.append({ text: i18nc("List option which will set the filter to show everything", "Show Everything") }); | ||||
148 | filterCombo.model.append({ text: i18nc("List option which will set the filter so only installed items are shown", "Installed Only") }); | ||||
149 | filterCombo.model.append({ text: i18nc("List option which will set the filter so only installed items with updates available are shown", "Updateable Only") }); | ||||
150 | filterCombo.currentIndex = newStuffEngine.filter; | ||||
151 | } | ||||
152 | onCurrentIndexChanged: { | ||||
153 | newStuffEngine.filter = currentIndex; | ||||
154 | } | ||||
155 | } | ||||
156 | QtControls.ComboBox { | ||||
157 | id: sortCombo | ||||
158 | QtLayouts.Layout.fillWidth: true | ||||
159 | model: ListModel { } | ||||
160 | Component.onCompleted: { | ||||
161 | sortCombo.model.append({ text: i18nc("List option which will set the sort order to based on when items were most recently updated", "Show most recent first") }); | ||||
162 | sortCombo.model.append({ text: i18nc("List option which will set the sort order to be alphabetical based on the name", "Sort alphabetically") }); | ||||
163 | sortCombo.model.append({ text: i18nc("List option which will set the sort order to based on user ratings", "Show highest rated first") }); | ||||
164 | sortCombo.model.append({ text: i18nc("List option which will set the sort order to based on number of downloads", "Show most downloaded first") }); | ||||
165 | sortCombo.currentIndex = newStuffEngine.sortOrder; | ||||
166 | } | ||||
167 | onCurrentIndexChanged: { | ||||
168 | newStuffEngine.sortOrder = currentIndex; | ||||
169 | } | ||||
170 | } | ||||
171 | } | ||||
172 | | ||||
173 | view.model: NewStuff.ItemsModel { | ||||
174 | id: newStuffModel; | ||||
175 | engine: newStuffEngine; | ||||
176 | } | ||||
177 | NewStuffDownloadItemsSheet { | ||||
178 | id: downloadItemsSheet | ||||
179 | onItemPicked: { | ||||
180 | var entryName = newStuffModel.data(entryId, NewStuff.ItemsModel.NameRole); | ||||
181 | applicationWindow().showPassiveNotification(i18nc("A passive notification shown when installation of an item is initiated", "Installing %1 from %2").arg(downloadName).arg(entryName), 1500); | ||||
182 | newStuffModel.installItem(entryId, downloadItemId); | ||||
183 | } | ||||
184 | } | ||||
185 | | ||||
186 | view.implicitCellWidth: root.viewMode == NewStuffPage.ViewMode.Tiles ? Kirigami.Units.gridUnit * 30 : (root.viewMode == NewStuffPage.ViewMode.Preview ? Kirigami.Units.gridUnit * 25 : Kirigami.Units.gridUnit * 10) | ||||
187 | view.implicitCellHeight: root.viewMode == NewStuffPage.ViewMode.Tiles ? Math.round(view.implicitCellWidth / 3) : (root.viewMode == NewStuffPage.ViewMode.Preview ? Kirigami.Units.gridUnit * 25 : Math.round(view.implicitCellWidth / 1.6) + Kirigami.Units.gridUnit*2) | ||||
188 | view.delegate: root.viewMode == NewStuffPage.ViewMode.Tiles ? tileDelegate : (root.viewMode == NewStuffPage.ViewMode.Preview ? bigPreviewDelegate : thumbDelegate) | ||||
189 | | ||||
190 | Component { | ||||
191 | id: bigPreviewDelegate | ||||
192 | GridTileDelegate { | ||||
193 | id: bigPreviewDelegateRoot | ||||
194 | actionsAnchors.topMargin: bigPreview.height + Kirigami.Units.smallSpacing * 2 | ||||
195 | function showDetails() { | ||||
196 | pageStack.push(detailsPage, { | ||||
197 | newStuffModel: root.view.model, | ||||
198 | index: model.index, | ||||
199 | name: model.name, | ||||
200 | author: model.author, | ||||
201 | previews: model.previews, | ||||
202 | shortSummary: model.shortSummary, | ||||
203 | summary: model.summary, | ||||
204 | homepage: model.homepage, | ||||
205 | donationLink: model.donationLink, | ||||
206 | status: model.status, | ||||
207 | commentsCount: model.numberOfComments, | ||||
208 | rating: model.rating, | ||||
209 | downloadCount: model.downloadCount | ||||
210 | }); | ||||
211 | } | ||||
212 | actions: [ | ||||
213 | Kirigami.Action { | ||||
214 | text: root.useLabel | ||||
215 | iconName: "dialog-ok-apply" | ||||
216 | onTriggered: { model.adopt(model.index); } | ||||
217 | enabled: (model.status == NewStuff.ItemsModel.InstalledStatus || model.status == NewStuff.ItemsModel.UpdateableStatus) && newStuffEngine.hasAdoptionCommand | ||||
218 | visible: enabled | ||||
219 | }, | ||||
220 | Kirigami.Action { | ||||
221 | text: model.downloadCount == 1 ? i18nc("Request installation of this item, available when there is exactly one downloadable item", "Install") : i18nc("Show installation options, where there is more than one downloadable item", "Install..."); | ||||
222 | iconName: "install" | ||||
223 | onTriggered: { | ||||
224 | if (model.downloadCount == 1) { | ||||
225 | newStuffModel.installItem(model.index, 1); | ||||
226 | } else { | ||||
227 | downloadItemsSheet.downloadLinks = model.downloadLinks; | ||||
228 | downloadItemsSheet.entryId = model.index; | ||||
229 | downloadItemsSheet.open(); | ||||
230 | } | ||||
231 | } | ||||
232 | enabled: model.status == NewStuff.ItemsModel.DownloadableStatus || model.status == NewStuff.ItemsModel.DeletedStatus; | ||||
233 | visible: enabled; | ||||
234 | }, | ||||
235 | Kirigami.Action { | ||||
236 | text: i18nc("Request updating of this item", "Update"); | ||||
237 | iconName: "update" | ||||
238 | onTriggered: { newStuffModel.installItem(model.index); } | ||||
239 | enabled: model.status == NewStuff.ItemsModel.UpdateableStatus; | ||||
240 | visible: enabled; | ||||
241 | }, | ||||
242 | Kirigami.Action { | ||||
243 | text: root.uninstallLabel | ||||
244 | iconName: "uninstall" | ||||
245 | onTriggered: { newStuffModel.uninstallItem(model.index); } | ||||
246 | enabled: model.status == NewStuff.ItemsModel.InstalledStatus | ||||
247 | visible: enabled; | ||||
248 | } | ||||
249 | ] | ||||
250 | thumbnailAvailable: model.previewsSmall.length > 0 | ||||
251 | tile: Item { | ||||
252 | anchors { | ||||
253 | fill: parent | ||||
254 | margins: Kirigami.Units.smallSpacing | ||||
255 | } | ||||
256 | QtLayouts.ColumnLayout { | ||||
257 | anchors.fill: parent; | ||||
258 | Item { | ||||
259 | QtLayouts.Layout.fillWidth: true | ||||
260 | QtLayouts.Layout.minimumHeight: width / 1.8 | ||||
261 | QtLayouts.Layout.maximumHeight: width / 1.8 | ||||
262 | Image { | ||||
263 | id: bigPreview | ||||
264 | asynchronous: true; | ||||
265 | fillMode: Image.PreserveAspectCrop; | ||||
266 | source: thumbnailAvailable ? model.previews[0] : ""; | ||||
267 | anchors.fill: parent | ||||
268 | } | ||||
269 | QtEffects.DropShadow { | ||||
270 | anchors.fill: bigPreview | ||||
271 | horizontalOffset: 0 | ||||
272 | verticalOffset: 0 | ||||
273 | radius: Kirigami.Units.largeSpacing | ||||
274 | samples: radius * 2 | ||||
275 | color: "#80000000" | ||||
276 | source: bigPreview | ||||
277 | } | ||||
278 | Kirigami.Icon { | ||||
279 | id: updateAvailableBadge; | ||||
280 | opacity: (model.status == NewStuff.ItemsModel.UpdateableStatus) ? 1 : 0; | ||||
281 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
282 | anchors { | ||||
283 | top: parent.top; | ||||
284 | left: parent.left; | ||||
285 | margins: -Kirigami.Units.smallSpacing; | ||||
286 | } | ||||
287 | height: Kirigami.Units.iconSizes.medium; | ||||
288 | width: height; | ||||
289 | source: "package-installed-outdated"; | ||||
290 | } | ||||
291 | Kirigami.Icon { | ||||
292 | id: installedBadge; | ||||
293 | opacity: (model.status == NewStuff.ItemsModel.InstalledStatus) ? 1 : 0; | ||||
294 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
295 | anchors { | ||||
296 | top: parent.top; | ||||
297 | left: parent.left; | ||||
298 | } | ||||
299 | height: Kirigami.Units.iconSizes.medium; | ||||
300 | width: height; | ||||
301 | source: "package-installed-updated"; | ||||
302 | } | ||||
303 | Item { | ||||
304 | anchors { | ||||
305 | top: parent.top; | ||||
306 | right: parent.right; | ||||
307 | } | ||||
308 | height: Kirigami.Units.iconSizes.large; | ||||
309 | width: height; | ||||
310 | Kirigami.Icon { | ||||
311 | id: infoIcon | ||||
312 | source: "documentinfo" | ||||
313 | anchors.fill: parent | ||||
314 | } | ||||
315 | MouseArea { | ||||
316 | anchors.fill: parent | ||||
317 | onClicked: { bigPreviewDelegateRoot.showDetails(); } | ||||
318 | } | ||||
319 | QtEffects.Glow { | ||||
320 | anchors.fill: infoIcon | ||||
321 | radius: 1 | ||||
322 | samples: 2 | ||||
323 | spread: 0.3 | ||||
324 | color: "white" | ||||
325 | source: infoIcon | ||||
326 | } | ||||
327 | } | ||||
328 | } | ||||
329 | Rating { | ||||
330 | QtLayouts.Layout.fillWidth: true | ||||
331 | rating: model.rating / 10 | ||||
332 | } | ||||
333 | Kirigami.Heading { | ||||
334 | QtLayouts.Layout.fillWidth: true | ||||
335 | level: 5 | ||||
336 | elide: Text.ElideRight | ||||
337 | text: i18nc("The number of times the item has been downloaded", "%1 downloads").arg(model.downloadCount) | ||||
338 | } | ||||
339 | Kirigami.Heading { | ||||
340 | QtLayouts.Layout.fillWidth: true | ||||
341 | elide: Text.ElideRight | ||||
342 | level: 3 | ||||
343 | text: model.name | ||||
344 | } | ||||
345 | Kirigami.Heading { | ||||
346 | QtLayouts.Layout.fillWidth: true | ||||
347 | elide: Text.ElideRight | ||||
348 | level: 4 | ||||
349 | textFormat: Text.StyledText | ||||
350 | text: i18nc("Subheading for the tile view, located immediately underneath the name of the item", "By <i>%1</i>").arg(model.author.name) | ||||
351 | } | ||||
352 | QtControls.Label { | ||||
353 | QtLayouts.Layout.fillWidth: true | ||||
354 | QtLayouts.Layout.fillHeight: true | ||||
355 | wrapMode: Text.Wrap | ||||
356 | text: model.shortSummary.length > 0 ? model.shortSummary : model.summary | ||||
357 | elide: Text.ElideRight | ||||
358 | } | ||||
359 | } | ||||
360 | Item { | ||||
361 | anchors.fill: parent | ||||
362 | opacity: (model.status == NewStuff.ItemsModel.InstallingStatus || model.status == NewStuff.ItemsModel.UpdatingStatus) ? 1 : 0 | ||||
363 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; } } | ||||
364 | Rectangle { | ||||
365 | anchors.fill: parent | ||||
366 | color: Kirigami.Theme.backgroundColor | ||||
367 | opacity: 0.5; | ||||
368 | } | ||||
369 | QtControls.BusyIndicator { | ||||
370 | anchors.centerIn: parent | ||||
371 | running: parent.opacity > 0 | ||||
372 | } | ||||
373 | } | ||||
374 | MouseArea { | ||||
375 | anchors.fill: parent; | ||||
376 | onClicked: bigPreviewDelegateRoot.showDetails(); | ||||
377 | } | ||||
378 | } | ||||
379 | } | ||||
380 | } | ||||
381 | Component { | ||||
382 | id: tileDelegate | ||||
383 | GridTileDelegate { | ||||
384 | id: tileDelegateRoot | ||||
385 | function showDetails() { | ||||
386 | pageStack.push(detailsPage, { | ||||
387 | newStuffModel: root.view.model, | ||||
388 | index: model.index, | ||||
389 | name: model.name, | ||||
390 | author: model.author, | ||||
391 | previews: model.previews, | ||||
392 | shortSummary: model.shortSummary, | ||||
393 | summary: model.summary, | ||||
394 | homepage: model.homepage, | ||||
395 | donationLink: model.donationLink, | ||||
396 | status: model.status, | ||||
397 | commentsCount: model.numberOfComments, | ||||
398 | rating: model.rating, | ||||
399 | downloadCount: model.downloadCount | ||||
400 | }); | ||||
401 | } | ||||
402 | actions: [ | ||||
403 | Kirigami.Action { | ||||
404 | text: root.useLabel | ||||
405 | iconName: "dialog-ok-apply" | ||||
406 | onTriggered: { model.adopt(model.index); } | ||||
407 | enabled: (model.status == NewStuff.ItemsModel.InstalledStatus || model.status == NewStuff.ItemsModel.UpdateableStatus) && newStuffEngine.hasAdoptionCommand | ||||
408 | visible: enabled | ||||
409 | }, | ||||
410 | Kirigami.Action { | ||||
411 | text: model.downloadCount == 1 ? i18nc("Request installation of this item, available when there is exactly one downloadable item", "Install") : i18nc("Show installation options, where there is more than one downloadable item", "Install..."); | ||||
412 | iconName: "install" | ||||
413 | onTriggered: { | ||||
414 | if (model.downloadCount == 1) { | ||||
415 | newStuffModel.installItem(model.index, 1); | ||||
416 | } else { | ||||
417 | downloadItemsSheet.downloadLinks = model.downloadLinks; | ||||
418 | downloadItemsSheet.entryId = model.index; | ||||
419 | downloadItemsSheet.open(); | ||||
420 | } | ||||
421 | } | ||||
422 | enabled: model.status == NewStuff.ItemsModel.DownloadableStatus || model.status == NewStuff.ItemsModel.DeletedStatus; | ||||
423 | visible: enabled; | ||||
424 | }, | ||||
425 | Kirigami.Action { | ||||
426 | text: i18nc("Request updating of this item", "Update"); | ||||
427 | iconName: "update" | ||||
428 | onTriggered: { newStuffModel.installItem(model.index); } | ||||
429 | enabled: model.status == NewStuff.ItemsModel.UpdateableStatus; | ||||
430 | visible: enabled; | ||||
431 | }, | ||||
432 | Kirigami.Action { | ||||
433 | text: root.uninstallLabel | ||||
434 | iconName: "uninstall" | ||||
435 | onTriggered: { newStuffModel.uninstallItem(model.index); } | ||||
436 | enabled: model.status == NewStuff.ItemsModel.InstalledStatus | ||||
437 | visible: enabled; | ||||
438 | }, | ||||
439 | Kirigami.Action { | ||||
440 | text: i18nc("Show a page with details for this item", "Details...") | ||||
441 | iconName: "documentinfo" | ||||
442 | onTriggered: { tileDelegateRoot.showDetails(); } | ||||
443 | } | ||||
444 | ] | ||||
445 | thumbnailAvailable: model.previewsSmall.length > 0 | ||||
446 | tile: Item { | ||||
447 | anchors { | ||||
448 | fill: parent | ||||
449 | margins: Kirigami.Units.smallSpacing | ||||
450 | } | ||||
451 | QtLayouts.GridLayout { | ||||
452 | anchors.fill: parent; | ||||
453 | columns: 2 | ||||
454 | QtLayouts.ColumnLayout { | ||||
455 | QtLayouts.Layout.minimumWidth: view.implicitCellWidth / 5 | ||||
456 | QtLayouts.Layout.maximumWidth: view.implicitCellWidth / 5 | ||||
457 | Item { | ||||
458 | QtLayouts.Layout.fillWidth: true | ||||
459 | QtLayouts.Layout.minimumHeight: width | ||||
460 | QtLayouts.Layout.maximumHeight: width | ||||
461 | Image { | ||||
462 | id: tilePreview | ||||
463 | asynchronous: true; | ||||
464 | fillMode: Image.PreserveAspectFit; | ||||
465 | source: thumbnailAvailable ? model.previewsSmall[0] : ""; | ||||
466 | anchors { | ||||
467 | fill: parent | ||||
468 | margins: Kirigami.Units.smallSpacing | ||||
469 | } | ||||
470 | verticalAlignment: Image.AlignTop | ||||
471 | } | ||||
472 | QtEffects.DropShadow { | ||||
473 | anchors.fill: tilePreview | ||||
474 | horizontalOffset: 0 | ||||
475 | verticalOffset: 0 | ||||
476 | radius: Kirigami.Units.largeSpacing | ||||
477 | samples: radius * 2 | ||||
478 | color: "#80000000" | ||||
479 | source: tilePreview | ||||
480 | } | ||||
481 | Kirigami.Icon { | ||||
482 | id: updateAvailableBadge; | ||||
483 | opacity: (model.status == NewStuff.ItemsModel.UpdateableStatus) ? 1 : 0; | ||||
484 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
485 | anchors { | ||||
486 | top: parent.top; | ||||
487 | left: parent.left; | ||||
488 | margins: -Kirigami.Units.smallSpacing; | ||||
489 | } | ||||
490 | height: Kirigami.Units.iconSizes.smallMedium; | ||||
491 | width: height; | ||||
492 | source: "package-installed-outdated"; | ||||
493 | } | ||||
494 | Kirigami.Icon { | ||||
495 | id: installedBadge; | ||||
496 | opacity: (model.status == NewStuff.ItemsModel.InstalledStatus) ? 1 : 0; | ||||
497 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
498 | anchors { | ||||
499 | top: parent.top; | ||||
500 | left: parent.left; | ||||
501 | margins: -Kirigami.Units.smallSpacing; | ||||
502 | } | ||||
503 | height: Kirigami.Units.iconSizes.smallMedium; | ||||
504 | width: height; | ||||
505 | source: "package-installed-updated"; | ||||
506 | } | ||||
507 | } | ||||
508 | Item { | ||||
509 | QtLayouts.Layout.fillHeight: true | ||||
510 | } | ||||
511 | } | ||||
512 | QtLayouts.ColumnLayout { | ||||
513 | QtLayouts.Layout.fillWidth: true | ||||
514 | QtLayouts.Layout.fillHeight: true | ||||
515 | Kirigami.Heading { | ||||
516 | QtLayouts.Layout.fillWidth: true | ||||
517 | elide: Text.ElideRight | ||||
518 | level: 3 | ||||
519 | text: model.name | ||||
520 | } | ||||
521 | Kirigami.Heading { | ||||
522 | QtLayouts.Layout.fillWidth: true | ||||
523 | elide: Text.ElideRight | ||||
524 | level: 4 | ||||
525 | textFormat: Text.StyledText | ||||
526 | text: i18nc("Subheading for the tile view, located immediately underneath the name of the item", "By <i>%1</i>").arg(model.author.name) | ||||
527 | } | ||||
528 | QtControls.Label { | ||||
529 | QtLayouts.Layout.fillWidth: true | ||||
530 | QtLayouts.Layout.fillHeight: true | ||||
531 | wrapMode: Text.Wrap | ||||
532 | text: model.shortSummary.length > 0 ? model.shortSummary : model.summary | ||||
533 | elide: Text.ElideRight | ||||
534 | } | ||||
535 | } | ||||
536 | Rating { | ||||
537 | QtLayouts.Layout.fillWidth: true | ||||
538 | rating: model.rating / 10 | ||||
539 | } | ||||
540 | Kirigami.Heading { | ||||
541 | QtLayouts.Layout.fillWidth: true | ||||
542 | level: 5 | ||||
543 | elide: Text.ElideRight | ||||
544 | text: i18nc("The number of times the item has been downloaded", "%1 downloads").arg(model.downloadCount) | ||||
545 | } | ||||
546 | } | ||||
547 | Item { | ||||
548 | anchors.fill: parent | ||||
549 | opacity: (model.status == NewStuff.ItemsModel.InstallingStatus || model.status == NewStuff.ItemsModel.UpdatingStatus) ? 1 : 0 | ||||
550 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; } } | ||||
551 | Rectangle { | ||||
552 | anchors.fill: parent | ||||
553 | color: Kirigami.Theme.backgroundColor | ||||
554 | opacity: 0.5; | ||||
555 | } | ||||
556 | QtControls.BusyIndicator { | ||||
557 | anchors.centerIn: parent | ||||
558 | running: parent.opacity > 0 | ||||
559 | } | ||||
560 | } | ||||
561 | MouseArea { | ||||
562 | anchors.fill: parent; | ||||
563 | onClicked: tileDelegateRoot.showDetails(); | ||||
564 | } | ||||
565 | } | ||||
566 | } | ||||
567 | } | ||||
568 | Component { | ||||
569 | id: thumbDelegate | ||||
570 | KCM.GridDelegate { | ||||
571 | text: model.name | ||||
572 | // onClicked: pageStack.push(detailsPage, { | ||||
573 | // name: model.name, | ||||
574 | // author: model.author, | ||||
575 | // previews: model.previews, | ||||
576 | // shortSummary: model.shortSummary, | ||||
577 | // summary: model.summary, | ||||
578 | // homepage: model.homepage, | ||||
579 | // donationLink: model.donationLink | ||||
580 | // }); | ||||
581 | actions: [ | ||||
582 | Kirigami.Action { | ||||
583 | text: root.useLabel | ||||
584 | iconName: "dialog-ok-apply" | ||||
585 | onTriggered: { model.adopt(model.index); } | ||||
586 | enabled: (model.status == NewStuff.ItemsModel.InstalledStatus || model.status == NewStuff.ItemsModel.UpdateableStatus) && newStuffEngine.hasAdoptionCommand | ||||
587 | visible: enabled | ||||
588 | }, | ||||
589 | Kirigami.Action { | ||||
590 | text: model.downloadCount == 1 ? i18nc("Request installation of this item, available when there is exactly one downloadable item", "Install") : i18nc("Show installation options, where there is more than one downloadable item", "Install..."); | ||||
591 | iconName: "install" | ||||
592 | onTriggered: { | ||||
593 | if (model.downloadCount == 1) { | ||||
594 | newStuffModel.installItem(model.index); | ||||
595 | } else { | ||||
596 | downloadItemsSheet.downloadLinks = model.downloadLinks; | ||||
597 | downloadItemsSheet.entryId = model.index; | ||||
598 | downloadItemsSheet.open(); | ||||
599 | } | ||||
600 | } | ||||
601 | enabled: model.status == NewStuff.ItemsModel.DownloadableStatus || model.status == NewStuff.ItemsModel.DeletedStatus; | ||||
602 | visible: enabled; | ||||
603 | }, | ||||
604 | Kirigami.Action { | ||||
605 | text: i18nc("Request updating of this item", "Update"); | ||||
606 | iconName: "update" | ||||
607 | onTriggered: { newStuffModel.installItem(model.index); } | ||||
608 | enabled: model.status == NewStuff.ItemsModel.UpdateableStatus; | ||||
609 | visible: enabled; | ||||
610 | }, | ||||
611 | Kirigami.Action { | ||||
612 | text: root.uninstallLabel | ||||
613 | iconName: "uninstall" | ||||
614 | onTriggered: { newStuffModel.uninstallItem(model.index); } | ||||
615 | enabled: model.status == NewStuff.ItemsModel.InstalledStatus | ||||
616 | visible: enabled; | ||||
617 | } | ||||
618 | ] | ||||
619 | thumbnailAvailable: model.previewsSmall.length > 0 | ||||
620 | thumbnail: Image { | ||||
621 | anchors { | ||||
622 | fill: parent; | ||||
623 | margins: Kirigami.Units.smallSpacing; | ||||
624 | } | ||||
625 | asynchronous: true; | ||||
626 | fillMode: Image.PreserveAspectFit; | ||||
627 | source: thumbnailAvailable ? model.previewsSmall[0] : ""; | ||||
628 | Kirigami.Icon { | ||||
629 | id: updateAvailableBadge; | ||||
630 | opacity: (model.status == NewStuff.ItemsModel.UpdateableStatus) ? 1 : 0; | ||||
631 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
632 | anchors { | ||||
633 | top: parent.top; | ||||
634 | right: parent.right; | ||||
635 | margins: -Kirigami.Units.smallSpacing; | ||||
636 | } | ||||
637 | height: Kirigami.Units.iconSizes.smallMedium; | ||||
638 | width: height; | ||||
639 | source: "package-installed-outdated"; | ||||
640 | } | ||||
641 | Kirigami.Icon { | ||||
642 | id: installedBadge; | ||||
643 | opacity: (model.status == NewStuff.ItemsModel.InstalledStatus) ? 1 : 0; | ||||
644 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } } | ||||
645 | anchors { | ||||
646 | top: parent.top; | ||||
647 | right: parent.right; | ||||
648 | margins: -Kirigami.Units.smallSpacing; | ||||
649 | } | ||||
650 | height: Kirigami.Units.iconSizes.smallMedium; | ||||
651 | width: height; | ||||
652 | source: "package-installed-updated"; | ||||
653 | } | ||||
654 | Item { | ||||
655 | anchors.fill: parent | ||||
656 | opacity: (model.status == NewStuff.ItemsModel.InstallingStatus || model.status == NewStuff.ItemsModel.UpdatingStatus) ? 1 : 0 | ||||
657 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; } } | ||||
658 | Rectangle { | ||||
659 | anchors.fill: parent | ||||
660 | color: Kirigami.Theme.backgroundColor | ||||
661 | opacity: 0.5; | ||||
662 | } | ||||
663 | QtControls.BusyIndicator { | ||||
664 | anchors.centerIn: parent | ||||
665 | running: parent.opacity > 0 | ||||
666 | } | ||||
667 | } | ||||
668 | MouseArea { | ||||
669 | anchors.fill: parent; | ||||
670 | onClicked: pageStack.push(detailsPage, { | ||||
671 | newStuffModel: root.view.model, | ||||
672 | index: model.index, | ||||
673 | name: model.name, | ||||
674 | author: model.author, | ||||
675 | previews: model.previews, | ||||
676 | shortSummary: model.shortSummary, | ||||
677 | summary: model.summary, | ||||
678 | homepage: model.homepage, | ||||
679 | donationLink: model.donationLink, | ||||
680 | status: model.status, | ||||
681 | commentsCount: model.numberOfComments, | ||||
682 | rating: model.rating, | ||||
683 | downloadCount: model.downloadCount | ||||
684 | }); | ||||
685 | } | ||||
686 | } | ||||
687 | } | ||||
688 | } | ||||
689 | | ||||
690 | Component { | ||||
691 | id: detailsPage; | ||||
692 | NewStuffEntryDetails { } | ||||
693 | } | ||||
694 | } |