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
6import QtQuick.Controls as QQC2
7import QtQuick.Window
8import QtQuick.Layouts
9import org.kde.kirigami as Kirigami
10import org.kde.kirigamiaddons.components as KirigamiComponents
11import org.kde.kirigamiaddons.formcard as FormCardModule
12import org.kde.coreaddons as Core
13
14import "private" as Private
15
16/**
17 * @brief An AboutPage that displays the about data using Form components.
18 *
19 * This component consists of an internationalized "About" page with the
20 * metadata of your program.
21 *
22 * It allows to show the copyright notice of the application together with
23 * the contributors and some information of which platform it's running on.
24 *
25 * @since KirigamiAddons 0.11.0
26 * @inherit org:kde::kirigami::ScrollablePage
27 */
29 id: page
30
31 /**
32 * @brief This property holds an object with the same shape as KAboutData.
33 *
34 * Set this property to either a KAboutData instance exposed from C++, or directly via a JSON object.
35 *
36 * Example usage:
37 * @code{json}
38 * aboutData: {
39 "displayName" : "KirigamiApp",
40 "productName" : "kirigami/app",
41 "componentName" : "kirigamiapp",
42 "shortDescription" : "A Kirigami example",
43 "homepage" : "",
44 "bugAddress" : "submit@bugs.kde.org",
45 "version" : "5.14.80",
46 "otherText" : "",
47 "authors" : [
48 {
49 "name" : "...",
50 "task" : "...",
51 "emailAddress" : "somebody@kde.org",
52 "webAddress" : "",
53 "ocsUsername" : ""
54 }
55 ],
56 "credits" : [],
57 "translators" : [],
58 "licenses" : [
59 {
60 "name" : "GPL v2",
61 "text" : "long, boring, license text",
62 "spdx" : "GPL-2.0"
63 }
64 ],
65 "copyrightStatement" : "© 2010-2018 Plasma Development Team",
66 "desktopFileName" : "org.kde.kirigamiapp"
67 }
68 @endcode
69 *
70 * @see KAboutData
71 */
72 property var aboutData: Core.AboutData
73
74 /**
75 * @brief This property holds a link to a "Get Involved" page.
76 *
77 * default: `"https://community.kde.org/Get_Involved" when the
78 * application ID starts with "org.kde.", otherwise empty.`
79 */
80 property url getInvolvedUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://community.kde.org/Get_Involved" : ""
81
82 /**
83 * @brief This property holds a link to a "Donate" page.
84 *
85 * default: `"https://www.kde.org/donate" when the application ID starts with "org.kde.", otherwise empty.`
86 */
87 property url donateUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://www.kde.org/donate" : ""
88
89 title: i18nd("kirigami-addons6", "About %1", page.aboutData.displayName)
90
91 FormCard {
92 Layout.topMargin: Kirigami.Units.largeSpacing * 4
93
94 AbstractFormDelegate {
95 id: generalDelegate
96 Layout.fillWidth: true
97 background: null
98 contentItem: RowLayout {
99 spacing: Kirigami.Units.smallSpacing * 2
100
101 Kirigami.Icon {
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.copyrightStatement
137 }
138 }
139
140 FormHeader {
141 visible: aboutData.otherText.length > 0
142 title: i18nd("kirigami-addons6", "Description")
143 }
144
145 FormCard {
146 visible: aboutData.otherText.length > 0
148 Layout.fillWidth: true
149 textItem.wrapMode: Text.WordWrap
150 text: aboutData.otherText
151 }
152 }
153
154 FormHeader {
155 title: i18ndp("kirigami-addons6", "License", "Licenses", aboutData.licenses.length)
156 visible: aboutData.licenses.length
157 }
158
159 FormCard {
160 visible: aboutData.licenses.length
161
162 Repeater {
163 model: aboutData.licenses
164 delegate: FormButtonDelegate {
165 text: modelData.name
166 Layout.fillWidth: true
167 onClicked: {
168 licenseSheet.text = modelData.text;
169 licenseSheet.title = modelData.name;
170 licenseSheet.open();
171 }
172 }
173 }
174
175 data: KirigamiComponents.MessageDialog {
176 id: licenseSheet
177
178 property alias text: bodyLabel.text
179
180 parent: QQC2.Overlay.overlay
181
182 leftPadding: 0
183 rightPadding: 0
184 bottomPadding: 0
185 topPadding: 0
186
187 header: Kirigami.Heading {
188 text: licenseSheet.title
189 elide: QQC2.Label.ElideRight
190 padding: licenseSheet.padding
191 topPadding: Kirigami.Units.largeSpacing
192 bottomPadding: Kirigami.Units.largeSpacing
193
194 Kirigami.Separator {
195 anchors {
196 left: parent.left
197 right: parent.right
198 bottom: parent.bottom
199 }
200 }
201 }
202
203 contentItem: QQC2.ScrollView {
204 id: scrollView
205
206 Kirigami.SelectableLabel {
207 id: bodyLabel
208 text: licenseSheet.text
209 textMargin: Kirigami.Units.gridUnit
210 }
211 }
212
213 footer: null
214 }
215 }
216
217 FormCard {
218 Layout.topMargin: Kirigami.Units.gridUnit
219
221 id: getInvolvedDelegate
222 icon.name: "globe-symbolic"
223 text: i18nd("kirigami-addons6", "Homepage")
224 url: aboutData.homepage
225 visible: aboutData.homepage.length > 0
226 }
227
229 above: getInvolvedDelegate
230 below: donateDelegate
231 visible: aboutData.homepage.length > 0
232 }
233
235 id: donateDelegate
236 icon.name: "donate-symbolic"
237 text: i18nd("kirigami-addons6", "Donate")
238 url: donateUrl + "?app=" + page.aboutData.componentName
239 visible: donateUrl.toString().length > 0
240 }
241
243 above: donateDelegate
244 below: homepageDelegate
245 visible: donateUrl.toString().length > 0
246 }
247
249 id: homepageDelegate
250 icon.name: "applications-development-symbolic"
251 text: i18nd("kirigami-addons6", "Get Involved")
252 url: page.getInvolvedUrl
253 visible: page.getInvolvedUrl != ""
254 }
255
257 above: homepageDelegate
258 below: bugDelegate
259 visible: page.getInvolvedUrl != ""
260 }
261
263 id: bugDelegate
264 url: {
265 if (aboutData.bugAddress !== "submit@bugs.kde.org") {
266 return aboutData.bugAddress
267 }
268 const elements = aboutData.productName.split('/');
269 let url = `https://bugs.kde.org/enter_bug.cgi?format=guided&product=${elements[0]}&version=${aboutData.version}`;
270 if (elements.length === 2) {
271 url += "&component=" + elements[1];
272 }
273 return url;
274 }
275
276 icon.name: "tools-report-bug-symbolic"
277 text: i18nd("kirigami-addons6", "Report a Bug")
278 visible: url.length > 0
279 }
280 }
281
282 FormHeader {
283 title: i18nd("kirigami-addons6", "Libraries in use")
284
285 actions: QQC2.Action {
286 text: i18ndc("kirigami-addons6", "@action:button", "Copy to Clipboard")
287 icon.name: 'edit-copy-symbolic'
288 onTriggered: {
289 FormCardModule.AboutComponent.copyToClipboard();
290 page.QQC2.ApplicationWindow.window.showPassiveNotification(i18ndc("kirigami-addons6", "@info", "System information copied to clipboard."), 'short');
291 }
292 }
293 }
294
295 FormCard {
296 Repeater {
297 model: FormCardModule.AboutComponent.components
298 delegate: libraryDelegate
299 }
300 }
301
302 FormHeader {
303 title: i18nd("kirigami-addons6", "Authors")
304 visible: aboutData.authors !== undefined && aboutData.authors.length > 0
305 }
306
307 FormCard {
308 visible: aboutData.authors !== undefined && aboutData.authors.length > 0
309
310 Repeater {
311 id: authorsRepeater
312 model: aboutData.authors
313 delegate: personDelegate
314 }
315 }
316
317 FormHeader {
318 title: i18nd("kirigami-addons6", "Credits")
319 visible: aboutData.credits !== undefined && aboutData.credits.length > 0
320 }
321
322 FormCard {
323 visible: aboutData.credits !== undefined && aboutData.credits.length > 0
324
325 Repeater {
326 id: repCredits
327 model: aboutData.credits
328 delegate: personDelegate
329 }
330 }
331
332 FormHeader {
333 title: i18nd("kirigami-addons6", "Translators")
334 visible: aboutData.translators !== undefined && aboutData.translators.length > 0
335 }
336
337 FormCard {
338 visible: aboutData.translators !== undefined && aboutData.translators.length > 0
339
340 Repeater {
341 id: repTranslators
342 model: aboutData.translators
343 delegate: personDelegate
344 }
345 }
346
347 data: [
348 Component {
349 id: personDelegate
350
352 Layout.fillWidth: true
353 background: null
354 contentItem: RowLayout {
355 spacing: Private.FormCardUnits.horizontalSpacing
356
357 KirigamiComponents.Avatar {
358 id: avatarIcon
359
360 implicitWidth: Kirigami.Units.iconSizes.medium
361 implicitHeight: implicitWidth
362 name: modelData.name
363 source: if (!!modelData.avatarUrl && modelData.avatarUrl.toString().startsWith('https://')) {
364 const url = new URL(modelData.avatarUrl);
365 const params = new URLSearchParams(url.search);
366 params.append("s", width);
367 url.search = params.toString();
368 return url;
369 } else {
370 return '';
371 }
372
373 Layout.rightMargin: Private.FormCardUnits.horizontalSpacing
374 }
375
376 ColumnLayout {
377 Layout.fillWidth: true
378 spacing: Private.FormCardUnits.verticalSpacing
379
380 QQC2.Label {
381 Layout.fillWidth: true
382 text: modelData.name
383 elide: Text.ElideRight
384 }
385
386 QQC2.Label {
387 id: internalDescriptionItem
388 Layout.fillWidth: true
389 text: modelData.task
390 color: Kirigami.Theme.disabledTextColor
391 font: Kirigami.Theme.smallFont
392 elide: Text.ElideRight
393 visible: text.length > 0
394 }
395 }
396
397 QQC2.ToolButton {
398 visible: typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0
399 icon.name: "get-hot-new-stuff-symbolic"
400 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
401 QQC2.ToolTip.visible: hovered
402 QQC2.ToolTip.text: i18nd("kirigami-addons6", "Visit %1's KDE Store page", modelData.name)
403 onClicked: Qt.openUrlExternally("https://store.kde.org/u/%1".arg(modelData.ocsUsername))
404 }
405
406 QQC2.ToolButton {
407 visible: typeof(modelData.emailAddress) !== "undefined" && modelData.emailAddress.length > 0
408 icon.name: "mail-sent-symbolic"
409 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
410 QQC2.ToolTip.visible: hovered
411 QQC2.ToolTip.text: i18nd("kirigami-addons6", "Send an email to %1", modelData.emailAddress)
412 onClicked: Qt.openUrlExternally("mailto:%1".arg(modelData.emailAddress))
413 }
414
415 QQC2.ToolButton {
416 visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
417 icon.name: "globe-symbolic"
418 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
419 QQC2.ToolTip.visible: hovered
420 QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
421 onClicked: Qt.openUrlExternally(modelData.webAddress)
422 }
423 }
424 }
425 },
426 Component {
427 id: libraryDelegate
428
430 id: delegate
431
432 required property var modelData
433
434 Layout.fillWidth: true
435 background: null
436 contentItem: RowLayout {
437 spacing: Private.FormCardUnits.horizontalSpacing
438
439 ColumnLayout {
440 Layout.fillWidth: true
441 spacing: Private.FormCardUnits.verticalSpacing
442
443 QQC2.Label {
444 Layout.fillWidth: true
445 text: delegate.modelData.name + ' ' + delegate.modelData.version
446 elide: Text.ElideRight
447 }
448
449 QQC2.Label {
450 id: internalDescriptionItem
451 Layout.fillWidth: true
452 text: delegate.modelData.description
453 color: Kirigami.Theme.disabledTextColor
454 font: Kirigami.Theme.smallFont
455 elide: Text.ElideRight
456 visible: text.length > 0
457 }
458 }
459
460 QQC2.ToolButton {
461 id: licenseButton
462 visible: modelData.licenses !== 0
463 icon.name: "license-symbolic"
464
465 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
466 QQC2.ToolTip.visible: hovered
467 QQC2.ToolTip.text: !visible ? "" : delegate.modelData.licenses.name
468
469 KirigamiComponents.MessageDialog {
470 id: licenseSheet
471
472 title: delegate.modelData.name
473
474 parent: licenseButton.QQC2.Overlay.overlay
475 implicitWidth: Math.min(parent.width - Kirigami.Units.gridUnit * 2, implicitContentWidth)
476
477 leftPadding: 0
478 rightPadding: 0
479 bottomPadding: 0
480 topPadding: 0
481
482 header: QQC2.Control {
483 padding: licenseSheet.padding
484 topPadding: Kirigami.Units.largeSpacing
485 bottomPadding: Kirigami.Units.largeSpacing
486
487 contentItem: RowLayout {
488 spacing: Kirigami.Units.largeSpacing
489
491 text: licenseSheet.title
492 elide: QQC2.Label.ElideRight
493 padding: 0
494 leftPadding: Kirigami.Units.largeSpacing
495 Layout.fillWidth: true
496 }
497
498 QQC2.ToolButton {
499 icon.name: hovered ? "window-close" : "window-close-symbolic"
500 text: i18ndc("kirigami-addons6", "@action:button", "Close")
501 display: QQC2.ToolButton.IconOnly
502 onClicked: licenseSheet.close()
503 }
504 }
505
507 anchors {
508 left: parent.left
509 right: parent.right
510 bottom: parent.bottom
511 }
512 }
513 }
514
515 contentItem: QQC2.ScrollView {
517 id: bodyLabel
518 text: delegate.modelData.licenses.text
519 textMargin: Kirigami.Units.gridUnit
520 }
521 }
522
523 footer: null
524 }
525
526 onClicked: licenseSheet.open()
527 }
528
529 QQC2.ToolButton {
530 visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
531 icon.name: "globe"
532 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
533 QQC2.ToolTip.visible: hovered
534 QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
535 onClicked: Qt.openUrlExternally(modelData.webAddress)
536 }
537 }
538 }
539 }
540 ]
541}
url getInvolvedUrl
This property holds a link to a "Get Involved" page.
Definition AboutPage.qml:74
url donateUrl
This property holds a link to a "Donate" page.
Definition AboutPage.qml:80
var aboutData
This property holds an object with the same shape as KAboutData.
Definition AboutPage.qml:67
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 contains a URL.
A Form delegate that corresponds to a text label and a description.
A dialog to show a message.
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
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...)
QString name(StandardAction id)
KGuiItem open()
KGuiItem close()
NETWORKMANAGERQT_EXPORT QString version()
ElideRight
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.