Changeset View
Changeset View
Standalone View
Standalone View
src/qtquick/qml/EntryDetails.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 displaying the details for a single entry | ||||
24 | * | ||||
25 | * This component is equivalent to the details view in the old DownloadDialog | ||||
26 | * @see KNewStuff::DownloadDialog | ||||
27 | * @since 5.63 | ||||
28 | */ | ||||
29 | | ||||
30 | import QtQuick 2.11 | ||||
31 | import QtQuick.Controls 2.11 as QtControls | ||||
32 | import QtQuick.Layouts 1.11 as QtLayouts | ||||
33 | | ||||
34 | import org.kde.kirigami 2.7 as Kirigami | ||||
35 | import org.kde.kcm 1.2 as KCM | ||||
36 | | ||||
37 | import org.kde.newstuff 1.62 as NewStuff | ||||
38 | | ||||
39 | import "private" as Private | ||||
40 | | ||||
41 | KCM.SimpleKCM { | ||||
42 | id: component | ||||
43 | property QtObject newStuffModel | ||||
44 | property int index | ||||
45 | property string name | ||||
46 | property var author | ||||
47 | property alias shortSummary: shortSummaryItem.text | ||||
48 | property alias summary: summaryItem.text; | ||||
49 | property alias previews: screenshotsItem.screenshotsModel | ||||
50 | property string homepage | ||||
51 | property string donationLink | ||||
52 | property int status | ||||
53 | property int commentsCount | ||||
54 | property int rating | ||||
55 | property int downloadCount | ||||
56 | property var downloadLinks | ||||
57 | property string providerId | ||||
58 | | ||||
59 | NewStuff.DownloadItemsSheet { | ||||
60 | id: downloadItemsSheet | ||||
61 | onItemPicked: { | ||||
62 | var entryName = newStuffModel.data(newStuffModel.index(entryId, 0), NewStuff.ItemsModel.NameRole); | ||||
63 | applicationWindow().showPassiveNotification(i18nc("A passive notification shown when installation of an item is initiated", "Installing %1 from %2").arg(downloadName).arg(entryName), 1500); | ||||
64 | newStuffModel.installItem(entryId, downloadItemId); | ||||
65 | } | ||||
66 | } | ||||
67 | | ||||
68 | Connections { | ||||
69 | target: newStuffModel | ||||
70 | onEntryChanged: { | ||||
71 | var status = newStuffModel.data(newStuffModel.index(index, 0), NewStuff.ItemsModel.StatusRole); | ||||
72 | if (status == NewStuff.ItemsModel.DownloadableStatus | ||||
73 | || status == NewStuff.ItemsModel.InstalledStatus | ||||
74 | || status == NewStuff.ItemsModel.UpdateableStatus | ||||
75 | || status == NewStuff.ItemsModel.DeletedStatus) { | ||||
76 | statusCard.message = ""; | ||||
77 | } else if (status == NewStuff.ItemsModel.InstallingStatus) { | ||||
78 | statusCard.message = i18nc("Status message to be shown when the entry is in the process of being installed", "Currently installing the item %1 by %2. Please wait...").arg(component.name).arg(entryAuthor.name); | ||||
79 | } else if (status == NewStuff.ItemsModel.UpdatingStatus) { | ||||
80 | statusCard.message = i18nc("Status message to be shown when the entry is in the process of being updated", "Currently updating the item %1 by %2. Please wait...").arg(component.name).arg(entryAuthor.name); | ||||
81 | } else { | ||||
82 | statusCard.message = i18nc("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. Please report this to the KDE Community in a bug report."); | ||||
83 | } | ||||
84 | } | ||||
85 | } | ||||
86 | | ||||
87 | NewStuff.Author { | ||||
88 | id: entryAuthor | ||||
89 | engine: component.newStuffModel.engine | ||||
90 | providerId: component.providerId | ||||
91 | username: author.name | ||||
92 | } | ||||
93 | title: i18nc("Combined title for the entry details page made of the name of the entry, and the author's name", "%1 by %2").arg(component.name).arg(entryAuthor.name) | ||||
94 | titleDelegate: QtLayouts.RowLayout { | ||||
95 | implicitHeight: title.height | ||||
96 | Kirigami.Heading { | ||||
97 | id: title | ||||
98 | level: 1 | ||||
99 | | ||||
100 | QtLayouts.Layout.fillWidth: true; | ||||
101 | QtLayouts.Layout.preferredWidth: titleTextMetrics.width | ||||
102 | QtLayouts.Layout.minimumWidth: titleTextMetrics.width | ||||
103 | opacity: component.isCurrentPage ? 1 : 0.4 | ||||
104 | maximumLineCount: 1 | ||||
105 | elide: Text.ElideRight | ||||
106 | text: component.title | ||||
107 | TextMetrics { | ||||
108 | id: titleTextMetrics | ||||
109 | text: component.title | ||||
110 | font: title.font | ||||
111 | } | ||||
112 | } | ||||
113 | QtControls.ToolButton { | ||||
114 | text: component.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..."); | ||||
115 | icon.name: "install" | ||||
116 | onClicked: { | ||||
117 | if (component.downloadCount == 1) { | ||||
118 | newStuffModel.installItem(component.index); | ||||
119 | } else { | ||||
120 | downloadItemsSheet.downloadLinks = component.downloadLinks; | ||||
121 | downloadItemsSheet.entryId = component.index; | ||||
122 | downloadItemsSheet.open(); | ||||
123 | } | ||||
124 | } | ||||
125 | enabled: component.status == NewStuff.ItemsModel.DownloadableStatus || component.status == NewStuff.ItemsModel.DeletedStatus; | ||||
126 | visible: enabled; | ||||
127 | } | ||||
128 | QtControls.ToolButton { | ||||
129 | text: i18nc("Request updating of this item", "Update"); | ||||
130 | icon.name: "update" | ||||
131 | onClicked: { newStuffModel.installItem(component.index); } | ||||
132 | enabled: component.status == NewStuff.ItemsModel.UpdateableStatus; | ||||
133 | visible: enabled; | ||||
134 | } | ||||
135 | QtControls.ToolButton { | ||||
136 | text: i18nc("Request uninstallation of this item", "Uninstall"); | ||||
137 | icon.name: "uninstall" | ||||
138 | onClicked: { newStuffModel.uninstallItem(component.index); } | ||||
139 | enabled: component.status == NewStuff.ItemsModel.InstalledStatus | ||||
140 | visible: enabled; | ||||
141 | } | ||||
142 | } | ||||
143 | QtLayouts.ColumnLayout { | ||||
144 | spacing: Kirigami.Units.smallSpacing | ||||
145 | Item { width: parent.width; height: Kirigami.Units.gridUnit * 3; } | ||||
146 | Kirigami.AbstractCard { | ||||
147 | id: statusCard | ||||
148 | property string message; | ||||
149 | visible: opacity > 0 | ||||
150 | opacity: message.length > 0 ? 1 : 0 | ||||
151 | Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; } } | ||||
152 | QtLayouts.Layout.fillWidth: true | ||||
153 | QtLayouts.Layout.margins: Kirigami.Units.largeSpacing | ||||
154 | Item { | ||||
155 | id: statusContent | ||||
156 | implicitHeight: statusCard.message.length > 0 ? Math.max(statusBusy.height, statusLabel.height) + Kirigami.Units.largeSpacing * 4 : 0 | ||||
157 | implicitWidth: statusCard.width | ||||
158 | QtControls.BusyIndicator { | ||||
159 | id: statusBusy | ||||
160 | anchors { | ||||
161 | top: parent.top | ||||
162 | left: parent.left | ||||
163 | } | ||||
164 | running: statusCard.opacity > 0 | ||||
165 | Rectangle { anchors.fill: parent; color: "red"; opacity: 0.3; } | ||||
166 | } | ||||
167 | QtControls.Label { | ||||
168 | id: statusLabel | ||||
169 | anchors { | ||||
170 | top: parent.top | ||||
171 | left: statusBusy.right | ||||
172 | leftMargin: Kirigami.Units.largeSpacing | ||||
173 | right: parent.right | ||||
174 | } | ||||
175 | text: statusCard.message | ||||
176 | wrapMode: Text.Wrap | ||||
177 | Rectangle { anchors.fill: parent; color: "blue"; opacity: 0.3; } | ||||
178 | } | ||||
179 | } | ||||
180 | } | ||||
181 | Private.EntryScreenshots { | ||||
182 | id: screenshotsItem | ||||
183 | QtLayouts.Layout.fillWidth: true | ||||
184 | } | ||||
185 | Kirigami.Heading { | ||||
186 | id: shortSummaryItem | ||||
187 | QtLayouts.Layout.fillWidth: true | ||||
188 | } | ||||
189 | Kirigami.FormLayout { | ||||
190 | QtLayouts.Layout.fillWidth: true | ||||
191 | Kirigami.LinkButton { | ||||
192 | Kirigami.FormData.label: i18n("Comments and Reviews:") | ||||
193 | enabled: component.commentsCount > 0 | ||||
194 | text: i18nc("A link which, when clicked, opens a new sub page with reviews (comments) for this entry", "%1 Reviews").arg(component.commentsCount) | ||||
195 | onClicked: pageStack.push(commentsPage) | ||||
196 | } | ||||
197 | Private.Rating { | ||||
198 | id: ratingsItem | ||||
199 | Kirigami.FormData.label: i18n("Rating:") | ||||
200 | rating: Math.floor(component.rating / 10) | ||||
201 | } | ||||
202 | Kirigami.LinkButton { | ||||
203 | Kirigami.FormData.label: i18n("Homepage:") | ||||
204 | text: i18nc("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 %2").arg(component.name) | ||||
205 | onClicked: Qt.openUrlExternally(component.homepage) | ||||
206 | } | ||||
207 | Kirigami.LinkButton { | ||||
208 | Kirigami.FormData.label: i18n("How To Donate:") | ||||
209 | text: i18nc("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") | ||||
210 | onClicked: Qt.openUrlExternally(component.donationLink) | ||||
211 | } | ||||
212 | } | ||||
213 | QtControls.Label { | ||||
214 | id: summaryItem | ||||
215 | QtLayouts.Layout.fillWidth: true | ||||
216 | QtLayouts.Layout.margins: Kirigami.Units.largeSpacing | ||||
217 | wrapMode: Text.Wrap | ||||
218 | } | ||||
219 | } | ||||
220 | | ||||
221 | Component { | ||||
222 | id: commentsPage | ||||
223 | Private.EntryCommentsPage { | ||||
224 | itemsModel: component.newStuffModel | ||||
225 | entryIndex: component.index | ||||
226 | entryName: component.name | ||||
227 | entryAuthorId: component.author.name | ||||
228 | entryProviderId: component.providerId | ||||
229 | } | ||||
230 | } | ||||
231 | } |