Kirigami-addons

AboutPage.qml
1// SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
2// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
3// SPDX-License-Identifier: LGPL-2.0-or-later
4
5import QtQuick 2.15
6import QtQuick.Controls 2.15 as QQC2
7import QtQuick.Window 2.15
8import QtQuick.Layouts 1.15
9import org.kde.kirigami 2.20 as Kirigami
10import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents
11import org.kde.coreaddons as Core
12
13import "private" as Private
14
15/**
16 * @brief An AboutPage that displays the about data using Form components.
17 *
18 * This component consists of an internationalized "About" page with the
19 * metadata of your program.
20 *
21 * It allows to show the copyright notice of the application together with
22 * the contributors and some information of which platform it's running on.
23 *
24 * @since KirigamiAddons 0.11.0
25 * @inherit org:kde::kirigami::ScrollablePage
26 */
28 id: page
29
30 /**
31 * @brief This property holds an object with the same shape as KAboutData.
32 *
33 * Set this property to either a KAboutData instance exposed from C++, or directly via a JSON object.
34 *
35 * Example usage:
36 * @code{json}
37 * aboutData: {
38 "displayName" : "KirigamiApp",
39 "productName" : "kirigami/app",
40 "componentName" : "kirigamiapp",
41 "shortDescription" : "A Kirigami example",
42 "homepage" : "",
43 "bugAddress" : "submit@bugs.kde.org",
44 "version" : "5.14.80",
45 "otherText" : "",
46 "authors" : [
47 {
48 "name" : "...",
49 "task" : "...",
50 "emailAddress" : "somebody@kde.org",
51 "webAddress" : "",
52 "ocsUsername" : ""
53 }
54 ],
55 "credits" : [],
56 "translators" : [],
57 "licenses" : [
58 {
59 "name" : "GPL v2",
60 "text" : "long, boring, license text",
61 "spdx" : "GPL-2.0"
62 }
63 ],
64 "copyrightStatement" : "© 2010-2018 Plasma Development Team",
65 "desktopFileName" : "org.kde.kirigamiapp"
66 }
67 @endcode
68 *
69 * @see KAboutData
70 */
71 property var aboutData: Core.AboutData
72
73 /**
74 * @brief This property holds a link to a "Get Involved" page.
75 *
76 * default: `"https://community.kde.org/Get_Involved" when the
77 * application ID starts with "org.kde.", otherwise empty.`
78 */
79 property url getInvolvedUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://community.kde.org/Get_Involved" : ""
80
81 /**
82 * @brief This property holds a link to a "Donate" page.
83 *
84 * default: `"https://www.kde.org/donate" when the application ID starts with "org.kde.", otherwise empty.`
85 */
86 property url donateUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://www.kde.org/donate" : ""
87
88 title: i18nd("kirigami-addons6", "About %1", page.aboutData.displayName)
89
90 FormCard {
91 Layout.topMargin: Kirigami.Units.largeSpacing * 4
92
94 id: generalDelegate
95 Layout.fillWidth: true
96 background: null
97 contentItem: RowLayout {
98 spacing: Kirigami.Units.smallSpacing * 2
99
100 Kirigami.Icon {
101 Layout.rowSpan: 3
102 Layout.preferredHeight: Kirigami.Units.iconSizes.huge
103 Layout.preferredWidth: height
104 Layout.maximumWidth: page.width / 3;
105 Layout.rightMargin: Kirigami.Units.largeSpacing
106 source: Kirigami.Settings.applicationWindowIcon || page.aboutData.programLogo || page.aboutData.programIconName || page.aboutData.componentName
107 }
108
109 ColumnLayout {
110 Layout.fillWidth: true
111 spacing: Kirigami.Units.smallSpacing
112
113 Kirigami.Heading {
114 Layout.fillWidth: true
115 text: page.aboutData.displayName + " " + page.aboutData.version
116 wrapMode: Text.WordWrap
117 }
118
119 Kirigami.Heading {
120 Layout.fillWidth: true
121 level: 3
122 type: Kirigami.Heading.Type.Secondary
123 wrapMode: Text.WordWrap
124 text: page.aboutData.shortDescription
125 }
126 }
127 }
128 }
129
131
133 id: copyrightDelegate
134 text: i18nd("kirigami-addons6", "Copyright")
135 descriptionItem.textFormat: Text.PlainText
136 description: aboutData.otherText + (aboutData.otherText.length > 0 ? '\n' : '')
137 + aboutData.copyrightStatement
138 }
139 }
140
141 FormHeader {
142 title: i18ndp("kirigami-addons6", "License", "Licenses", aboutData.licenses.length)
143 visible: aboutData.licenses.length
144 }
145
146 FormCard {
147 visible: aboutData.licenses.length
148
149 Repeater {
150 model: aboutData.licenses
151 delegate: FormButtonDelegate {
152 text: modelData.name
153 Layout.fillWidth: true
154 onClicked: {
155 licenseSheet.text = modelData.text;
156 licenseSheet.title = modelData.name;
157 licenseSheet.open();
158 }
159 }
160 }
161
162 data: KirigamiComponents.MessageDialog {
163 id: licenseSheet
164
165 property alias text: bodyLabel.text
166
167 parent: QQC2.Overlay.overlay
168
169 leftPadding: 0
170 rightPadding: 0
171 bottomPadding: 0
172 topPadding: 0
173
174 header: Kirigami.Heading {
175 text: licenseSheet.title
176 elide: QQC2.Label.ElideRight
177 padding: licenseSheet.padding
178 topPadding: Kirigami.Units.largeSpacing
179 bottomPadding: Kirigami.Units.largeSpacing
180
181 Kirigami.Separator {
182 anchors {
183 left: parent.left
184 right: parent.right
185 bottom: parent.bottom
186 }
187 }
188 }
189
190 contentItem: QQC2.ScrollView {
191 id: scrollView
192
193 Kirigami.SelectableLabel {
194 id: bodyLabel
195 text: licenseSheet.text
196 textMargin: Kirigami.Units.gridUnit
197 }
198 }
199
200 footer: null
201 }
202 }
203
204 FormCard {
205 Layout.topMargin: Kirigami.Units.gridUnit
206
208 id: getInvolvedDelegate
209 text: i18nd("kirigami-addons6", "Homepage")
210 onClicked: Qt.openUrlExternally(aboutData.homepage)
211 visible: aboutData.homepage.length > 0
212 }
213
215 above: getInvolvedDelegate
216 below: donateDelegate
217 visible: aboutData.homepage.length > 0
218 }
219
221 id: donateDelegate
222 text: i18nd("kirigami-addons6", "Donate")
223 onClicked: Qt.openUrlExternally(donateUrl + "?app=" + page.aboutData.componentName)
224 visible: donateUrl.toString().length > 0
225 }
226
228 above: donateDelegate
229 below: homepageDelegate
230 visible: donateUrl.toString().length > 0
231 }
232
234 id: homepageDelegate
235 text: i18nd("kirigami-addons6", "Get Involved")
236 onClicked: Qt.openUrlExternally(page.getInvolvedUrl)
237 visible: page.getInvolvedUrl != ""
238 }
239
241 above: homepageDelegate
242 below: bugDelegate
243 visible: page.getInvolvedUrl != ""
244 }
245
247 id: bugDelegate
248 readonly property string theUrl: {
249 if (aboutData.bugAddress !== "submit@bugs.kde.org") {
250 return aboutData.bugAddress
251 }
252 const elements = aboutData.productName.split('/');
253 let url = `https://bugs.kde.org/enter_bug.cgi?format=guided&product=${elements[0]}&version=${aboutData.version}`;
254 if (elements.length === 2) {
255 url += "&component=" + elements[1];
256 }
257 return url;
258 }
259
260 text: i18nd("kirigami-addons6", "Report a Bug")
261 onClicked: Qt.openUrlExternally(theUrl)
262 visible: theUrl.length > 0
263 }
264 }
265
266 FormHeader {
267 title: i18nd("kirigami-addons6", "Libraries in use")
268 visible: Kirigami.Settings.information
269 }
270
271 FormCard {
272 visible: Kirigami.Settings.information
273
274 Repeater {
275 model: Kirigami.Settings.information
276 delegate: FormTextDelegate {
277 id: libraries
278 Layout.fillWidth: true
279 text: modelData
280 }
281 }
282
283 Repeater {
284 model: aboutData.components
285 delegate: libraryDelegate
286 }
287 }
288
289 FormHeader {
290 title: i18nd("kirigami-addons6", "Authors")
291 visible: aboutData.authors !== undefined && aboutData.authors.length > 0
292 }
293
294 FormCard {
295 visible: aboutData.authors !== undefined && aboutData.authors.length > 0
296
297 Repeater {
298 id: authorsRepeater
299 model: aboutData.authors
300 delegate: personDelegate
301 }
302 }
303
304 FormHeader {
305 title: i18nd("kirigami-addons6", "Credits")
306 visible: aboutData.credits !== undefined && aboutData.credits.length > 0
307 }
308
309 FormCard {
310 visible: aboutData.credits !== undefined && aboutData.credits.length > 0
311
312 Repeater {
313 id: repCredits
314 model: aboutData.credits
315 delegate: personDelegate
316 }
317 }
318
319 FormHeader {
320 title: i18nd("kirigami-addons6", "Translators")
321 visible: aboutData.translators !== undefined && aboutData.translators.length > 0
322 }
323
324 FormCard {
325 visible: aboutData.translators !== undefined && aboutData.translators.length > 0
326
327 Repeater {
328 id: repTranslators
329 model: aboutData.translators
330 delegate: personDelegate
331 }
332 }
333
334 data: [
335 Component {
336 id: personDelegate
337
339 Layout.fillWidth: true
340 background: null
341 contentItem: RowLayout {
342 spacing: Kirigami.Units.smallSpacing * 2
343
344 KirigamiComponents.Avatar {
345 id: avatarIcon
346
347 // TODO FIXME kf6 https://phabricator.kde.org/T15993
348 property bool hasRemoteAvatar: false // (typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0)
349 implicitWidth: Kirigami.Units.iconSizes.medium
350 implicitHeight: implicitWidth
351 name: modelData.name
352 source: if (!!modelData.avatarUrl && modelData.avatarUrl.toString().startsWith('https://')) {
353 const url = new URL(modelData.avatarUrl);
354 const params = new URLSearchParams(url.search);
355 params.append("s", width);
356 url.search = params.toString();
357 return url;
358 } else {
359 return '';
360 }
361 }
362
363 ColumnLayout {
364 Layout.fillWidth: true
365 spacing: Kirigami.Units.smallSpacing
366
367 QQC2.Label {
368 Layout.fillWidth: true
369 text: modelData.name
370 elide: Text.ElideRight
371 }
372
373 QQC2.Label {
374 id: internalDescriptionItem
375 Layout.fillWidth: true
376 text: modelData.task
377 color: Kirigami.Theme.disabledTextColor
378 font: Kirigami.Theme.smallFont
379 elide: Text.ElideRight
380 visible: text.length > 0
381 }
382 }
383
384 QQC2.ToolButton {
385 visible: typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0
386 icon.name: "get-hot-new-stuff"
387 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
388 QQC2.ToolTip.visible: hovered
389 QQC2.ToolTip.text: i18nd("kirigami-addons6", "Visit %1's KDE Store page", modelData.name)
390 onClicked: Qt.openUrlExternally("https://store.kde.org/u/%1".arg(modelData.ocsUsername))
391 }
392
393 QQC2.ToolButton {
394 visible: typeof(modelData.emailAddress) !== "undefined" && modelData.emailAddress.length > 0
395 icon.name: "mail-sent"
396 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
397 QQC2.ToolTip.visible: hovered
398 QQC2.ToolTip.text: i18nd("kirigami-addons6", "Send an email to %1", modelData.emailAddress)
399 onClicked: Qt.openUrlExternally("mailto:%1".arg(modelData.emailAddress))
400 }
401
402 QQC2.ToolButton {
403 visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
404 icon.name: "globe"
405 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
406 QQC2.ToolTip.visible: hovered
407 QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
408 onClicked: Qt.openUrlExternally(modelData.webAddress)
409 }
410 }
411 }
412 },
413 Component {
414 id: libraryDelegate
415
417 id: delegate
418
419 required property var modelData
420
421 Layout.fillWidth: true
422 background: null
423 contentItem: RowLayout {
424 spacing: Kirigami.Units.smallSpacing * 2
425
426 ColumnLayout {
427 Layout.fillWidth: true
428 spacing: Kirigami.Units.smallSpacing
429
430 QQC2.Label {
431 Layout.fillWidth: true
432 text: delegate.modelData.name + ' ' + delegate.modelData.version
433 elide: Text.ElideRight
434 }
435
436 QQC2.Label {
437 id: internalDescriptionItem
438 Layout.fillWidth: true
439 text: delegate.modelData.description
440 color: Kirigami.Theme.disabledTextColor
441 font: Kirigami.Theme.smallFont
442 elide: Text.ElideRight
443 visible: text.length > 0
444 }
445 }
446
447 QQC2.ToolButton {
448 visible: modelData.licenses !== 0
449 icon.name: "license"
450
451 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
452 QQC2.ToolTip.visible: hovered
453 QQC2.ToolTip.text: !visible ? "" : delegate.modelData.licenses.name
454
455 KirigamiComponents.MessageDialog {
456 id: licenseSheet
457
458 parent: root.QQC2.Overlay.overlay
459 title: delegate.modelData.name
460
461 leftPadding: 0
462 rightPadding: 0
463 bottomPadding: 0
464 topPadding: 0
465
466 header: Kirigami.Heading {
467 text: licenseSheet.title
468 elide: QQC2.Label.ElideRight
469 padding: licenseSheet.padding
470 topPadding: Kirigami.Units.largeSpacing
471 bottomPadding: Kirigami.Units.largeSpacing
472
474 anchors {
475 left: parent.left
476 right: parent.right
477 bottom: parent.bottom
478 }
479 }
480 }
481
482 contentItem: QQC2.ScrollView {
484 id: bodyLabel
485 text: delegate.modelData.licenses.text
486 textMargin: Kirigami.Units.gridUnit
487 }
488 }
489
490 footer: null
491 }
492
493 onClicked: licenseSheet.open()
494 }
495
496 QQC2.ToolButton {
497 visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
498 icon.name: "globe"
499 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
500 QQC2.ToolTip.visible: hovered
501 QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
502 onClicked: Qt.openUrlExternally(modelData.webAddress)
503 }
504 }
505 }
506 }
507 ]
508}
A base item for delegates to be used in a FormCard.
A Form delegate that corresponds to a clickable button.
A scrollable page used as a container for one or more FormCards.
A single card that follows a form style.
Definition FormCard.qml:35
A context-aware separator.
A header item for a form card.
A Form delegate that corresponds to a text label and a description.
A dialog to show a message.
QString i18ndp(const char *domain, const char *singular, const char *plural, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
KDB_EXPORT KDbVersionInfo version()
QString name(StandardAction id)
QAction * open(const QObject *recvr, const char *slot, QObject *parent)
ElideRight
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 19 2024 11:50:50 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.