KNewStuff

EntryDetails.qml
1/*
2 SPDX-FileCopyrightText: 2019 Dan Leinir Turthra Jensen <admin@leinir.dk>
3 SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8/**
9 * @brief A Kirigami.Page component used for displaying the details for a single entry
10 *
11 * This component is equivalent to the details view in the old DownloadDialog
12 * @see KNewStuff::DownloadDialog
13 * @since 5.63
14 */
15
16import QtQuick
17import QtQuick.Controls as QQC2
18import QtQuick.Layouts
19
20import org.kde.kirigami 2 as Kirigami
21import org.kde.kcmutils as KCM
22import org.kde.newstuff as NewStuff
23
24import "private" as Private
25
26KCM.SimpleKCM {
27 id: component
28
29 property QtObject newStuffModel
30 property var entry
31
32 property string name
33 property var author
34 property alias shortSummary: shortSummaryItem.text
35 property alias summary: summaryItem.text
36 property alias previews: screenshotsItem.screenshotsModel
37 property string homepage
38 property string donationLink
39 property int status
40 property int commentsCount
41 property int rating
42 property int downloadCount
43 property var downloadLinks
44 property string providerId
45 property int entryType
46
47 Component.onCompleted: {
48 updateContents();
49 newStuffModel.engine.updateEntryContents(component.entry);
50 }
51
52 Connections {
53 target: newStuffModel
55 if (entry === changedEntry) {
56 updateContents();
57 }
58 }
59 }
60
61 function updateContents() {
62 component.providerId = entry.providerId;
63 component.status = entry.status;
64
65 component.author = entry.author;
66 component.name = entry.name;
67 component.shortSummary = entry.shortSummary;
68 component.summary = entry.summary;
69 component.homepage = entry.homepage;
70 component.donationLink = entry.donationLink;
71 component.status = entry.status;
72 component.commentsCount = entry.numberOfComments;
73 component.rating = entry.rating;
74 component.downloadCount = entry.downloadCount;
75
76 const modelIndex = newStuffModel.index(newStuffModel.indexOfEntry(entry), 0);
77 component.previews = newStuffModel.data(modelIndex, NewStuff.ItemsModel.PreviewsRole);
78 component.downloadLinks = newStuffModel.data(modelIndex, NewStuff.ItemsModel.DownloadLinksRole);
79
80 }
81
82 NewStuff.DownloadItemsSheet {
83 id: downloadItemsSheet
84
86 const entryName = newStuffModel.data(newStuffModel.index(entryId, 0), NewStuff.ItemsModel.NameRole);
87 applicationWindow().showPassiveNotification(i18ndc("knewstuff6", "A passive notification shown when installation of an item is initiated", "Installing %1 from %2", downloadName, entryName), 1500);
88 newStuffModel.engine.install(component.entry, downloadItemId);
89 }
90 }
91
92 Private.ErrorDisplayer {
93 engine: component.newStuffModel.engine
94 active: component.isCurrentPage
95 }
96
97 NewStuff.Author {
98 id: entryAuthor
99 engine: component.newStuffModel.engine
100 providerId: component.providerId
101 username: author.name
102 }
103
104 title: i18ndc("knewstuff6", "Combined title for the entry details page made of the name of the entry, and the author's name", "%1 by %2", component.name, entryAuthor.name)
105
106 actions: [
107 Kirigami.Action {
108 text: component.downloadLinks.length == 1 ? i18ndc("knewstuff6", "Request installation of this item, available when there is exactly one downloadable item", "Install") : i18ndc("knewstuff6", "Show installation options, where there is more than one downloadable item", "Install…")
109 icon.name: "install"
110 onTriggered: {
111 if (component.downloadLinks.length == 1) {
112 newStuffModel.engine.install(component.entry, NewStuff.ItemsModel.FirstLinkId);
113 } else {
114 downloadItemsSheet.downloadLinks = component.downloadLinks;
115 downloadItemsSheet.entry = component.index;
116 downloadItemsSheet.open();
117 }
118 }
119 enabled: component.status == NewStuff.Entry.Downloadable || component.status == NewStuff.Entry.Deleted
120 visible: enabled
121 },
122 Kirigami.Action {
123 text: i18ndc("knewstuff6", "Request updating of this item", "Update")
124 icon.name: "update-none"
125 onTriggered: newStuffModel.update(component.entry, NewStuff.ItemsModel.AutoDetectLinkId)
126 enabled: component.status == NewStuff.Entry.Updateable
127 visible: enabled
128 },
129 Kirigami.Action {
130 text: i18ndc("knewstuff6", "Request uninstallation of this item", "Uninstall")
131 icon.name: "edit-delete"
132 onTriggered: newStuffModel.engine.uninstall(component.entry)
133 enabled: component.status == NewStuff.Entry.Installed || component.status == NewStuff.Entry.Updateable
134 visible: enabled
135 }
136 ]
137
138 ColumnLayout {
139 spacing: Kirigami.Units.smallSpacing
140
141 Kirigami.AbstractCard {
142 id: statusCard
143
144 readonly property string message: {
145 switch (component.status) {
146 case NewStuff.Entry.Downloadable:
147 case NewStuff.Entry.Installed:
148 case NewStuff.Entry.Updateable:
149 case NewStuff.Entry.Deleted:
150 return "";
151 case NewStuff.Entry.Installing:
152 return i18ndc("knewstuff6", "Status message to be shown when the entry is in the process of being installed OR uninstalled", "Currently working on the item %1 by %2. Please wait…", component.name, entryAuthor.name);
153 case NewStuff.Entry.Updating:
154 return i18ndc("knewstuff6", "Status message to be shown when the entry is in the process of being updated", "Currently updating the item %1 by %2. Please wait…", component.name, entryAuthor.name);
155 default:
156 return i18ndc("knewstuff6", "Status message which should only be shown when the entry has been given some unknown or invalid status.", "This item is currently in an invalid or unknown state. <a href=\"https://bugs.kde.org/enter_bug.cgi?product=frameworks-knewstuff\">Please report this to the KDE Community in a bug report</a>.");
157 }
158 }
159
160 visible: opacity > 0
161 opacity: message.length > 0 ? 1 : 0
162
163 Behavior on opacity {
165 duration: Kirigami.Units.longDuration
166 }
167 }
168
169 Layout.fillWidth: true
170 Layout.margins: Kirigami.Units.largeSpacing
171
172 contentItem: RowLayout {
173 Layout.fillWidth: true
174 spacing: Kirigami.Units.smallSpacing
175
176 QQC2.Label {
177 Layout.fillWidth: true
178 text: statusCard.message
179 wrapMode: Text.Wrap
180 onLinkActivated: Qt.openUrlExternally(link);
181 }
182
183 QQC2.BusyIndicator {
184 running: statusCard.opacity > 0
185 }
186 }
187 }
188
189 Item {
190 Layout.fillWidth: true
191 height: Kirigami.Units.gridUnit * 3
192 }
193
194 Private.EntryScreenshots {
196 Layout.fillWidth: true
197 }
198
199 Kirigami.Heading {
201 wrapMode: Text.Wrap
202 Layout.fillWidth: true
203 }
204
205 Kirigami.FormLayout {
206 Layout.fillWidth: true
207
208 Kirigami.LinkButton {
209 Kirigami.FormData.label: i18nd("knewstuff6", "Comments and Reviews:")
210 enabled: component.commentsCount > 0
211 text: i18ndc("knewstuff6", "A link which, when clicked, opens a new sub page with comments (comments with or without ratings) for this entry", "%1 Reviews and Comments", component.commentsCount)
212 onClicked: pageStack.push(commentsPage)
213 }
214
215 Private.Rating {
216 id: ratingsItem
217 Kirigami.FormData.label: i18nd("knewstuff6", "Rating:")
218 rating: component.rating
219 }
220
221 Kirigami.UrlButton {
222 Kirigami.FormData.label: i18nd("knewstuff6", "Homepage:")
223 text: i18ndc("knewstuff6", "A link which, when clicked, opens the website associated with the entry (this could be either one specific to the project, the author's homepage, or any other website they have chosen for the purpose)", "Open the homepage for %1", component.name)
224 url: component.homepage
225 visible: component.homepage
226 }
227
228 Kirigami.UrlButton {
229 Kirigami.FormData.label: i18nd("knewstuff6", "How To Donate:")
230 text: i18ndc("knewstuff6", "A link which, when clicked, opens a website with information on donation in support of the entry", "Find out how to donate to this project")
231 url: component.donationLink
232 visible: component.donationLink
233 }
234 }
235
236 Kirigami.SelectableLabel {
237 id: summaryItem
238
239 Layout.fillWidth: true
240 Layout.margins: Kirigami.Units.largeSpacing
241
242 textFormat: Text.RichText
243 }
244
245 Component {
246 id: commentsPage
247
248 Private.EntryCommentsPage {
249 itemsModel: component.newStuffModel
250 entry: component.entry
251 entryName: component.name
252 entryAuthorId: component.author.name
253 entryProviderId: component.providerId
254 }
255 }
256 }
257}
Q_SCRIPTABLE CaptureState status()
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
T * data() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:35 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.