Warning, /frameworks/kirigami/src/controls/AboutItem.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 import QtQuick 2.1 0008 import QtQuick.Controls 2.4 as QQC2 0009 import QtQuick.Window 2.15 0010 import QtQuick.Layouts 1.3 0011 import org.kde.kirigami 2.20 as Kirigami 0012 0013 //TODO: Kf6: move somewhere else which can depend from KAboutData? 0014 /** 0015 * @brief This component is an "About" item that displays data about the application. 0016 * 0017 * It allows showing the defind copyright notice of the application together 0018 * with the contributors and some information of which platform it's running on. 0019 * 0020 * @see <a href="https://develop.kde.org/docs/getting-started/kirigami/advanced-add_about_page">About Page in Kirigami</a> 0021 * @see <a href="https://develop.kde.org/hig/components/assistance/aboutview">KDE Human Interface Guidelines on Application Information</a> 0022 * @see kirigami::AboutPage 0023 * @since KDE Frameworks 5.87 0024 * @since org.kde.kirigami 2.19 0025 */ 0026 Item { 0027 id: aboutItem 0028 /** 0029 * @brief This property holds information that this component displays. 0030 * 0031 * The stored JSON information object has the same structure as KAboutData. 0032 * 0033 * Example usage: 0034 * @code{.json} 0035 * aboutData: { 0036 * "displayName" : "KirigamiApp", 0037 * "productName" : "kirigami/app", 0038 * "componentName" : "kirigamiapp", 0039 * "shortDescription" : "A Kirigami example", 0040 * "homepage" : "", 0041 * "bugAddress" : "submit@bugs.kde.org", 0042 * "version" : "5.14.80", 0043 * "otherText" : "", 0044 * "authors" : [ 0045 * { 0046 * "name" : "...", 0047 * "task" : "", 0048 * "emailAddress" : "somebody@kde.org", 0049 * "webAddress" : "", 0050 * "ocsUsername" : "" 0051 * } 0052 * ], 0053 * "credits" : [], 0054 * "translators" : [], 0055 * "licenses" : [ 0056 * { 0057 * "name" : "GPL v2", 0058 * "text" : "long, boring, license text", 0059 * "spdx" : "GPL-2.0" 0060 * } 0061 * ], 0062 * "copyrightStatement" : "© 2010-2018 Plasma Development Team", 0063 * "desktopFileName" : "org.kde.kirigamiapp" 0064 * } 0065 * @endcode 0066 * 0067 * @see KAboutData 0068 */ 0069 property var aboutData 0070 0071 /** 0072 * @brief This property holds a link to a "Get Involved" page. 0073 * 0074 * default: `"https://community.kde.org/Get_Involved" when application id starts with "org.kde.", otherwise it is empty.` 0075 */ 0076 property url getInvolvedUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://community.kde.org/Get_Involved" : "" 0077 0078 /** 0079 * @brief This property holds a link to a "Donate" page. 0080 * 0081 * default: `"https://kde.org/community/donations" when application id starts with "org.kde.", otherwise it is empty.` 0082 */ 0083 property url donateUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://kde.org/community/donations" : "" 0084 0085 /** @internal */ 0086 property bool _usePageStack: false 0087 0088 /** 0089 * @brief This property specifies whether about item is in wide mode. 0090 * @see kirigami::FormLayout::wideMode 0091 * @property bool wideMode 0092 */ 0093 property alias wideMode: form.wideMode 0094 0095 /** @internal */ 0096 default property alias _content: form.data 0097 0098 implicitHeight: form.implicitHeight 0099 implicitWidth: form.implicitWidth 0100 0101 Component { 0102 id: personDelegate 0103 0104 RowLayout { 0105 Layout.fillWidth: true 0106 property bool hasRemoteAvatar: (typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0) 0107 0108 spacing: Kirigami.Units.smallSpacing * 2 0109 0110 Kirigami.Icon { 0111 id: avatarIcon 0112 0113 implicitWidth: Kirigami.Units.iconSizes.medium 0114 implicitHeight: implicitWidth 0115 0116 fallback: "user" 0117 source: hasRemoteAvatar && remoteAvatars.checked ? "https://store.kde.org/avatar/%1?s=%2".arg(modelData.ocsUsername).arg(width) : "user" 0118 visible: status !== Kirigami.Icon.Loading 0119 } 0120 0121 // So it's clear that something is happening while avatar images are loaded 0122 QQC2.BusyIndicator { 0123 implicitWidth: Kirigami.Units.iconSizes.medium 0124 implicitHeight: implicitWidth 0125 0126 visible: avatarIcon.status === Kirigami.Icon.Loading 0127 running: visible 0128 } 0129 0130 QQC2.Label { 0131 Layout.fillWidth: true 0132 readonly property bool withTask: typeof(modelData.task) !== "undefined" && modelData.task.length > 0 0133 text: withTask ? qsTr("%1 (%2)").arg(modelData.name).arg(modelData.task) : modelData.name 0134 wrapMode: Text.WordWrap 0135 } 0136 0137 QQC2.ToolButton { 0138 visible: typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0 0139 icon.name: "get-hot-new-stuff" 0140 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0141 QQC2.ToolTip.visible: hovered 0142 QQC2.ToolTip.text: qsTr("Visit %1's KDE Store page").arg(modelData.name) 0143 onClicked: Qt.openUrlExternally("https://store.kde.org/u/%1".arg(modelData.ocsUsername)) 0144 } 0145 0146 QQC2.ToolButton { 0147 visible: typeof(modelData.emailAddress) !== "undefined" && modelData.emailAddress.length > 0 0148 icon.name: "mail-sent" 0149 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0150 QQC2.ToolTip.visible: hovered 0151 QQC2.ToolTip.text: qsTr("Send an email to %1").arg(modelData.emailAddress) 0152 onClicked: Qt.openUrlExternally("mailto:%1".arg(modelData.emailAddress)) 0153 } 0154 0155 QQC2.ToolButton { 0156 visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0 0157 icon.name: "globe" 0158 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0159 QQC2.ToolTip.visible: hovered 0160 QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress 0161 onClicked: Qt.openUrlExternally(modelData.webAddress) 0162 } 0163 } 0164 } 0165 0166 Kirigami.FormLayout { 0167 id: form 0168 0169 anchors.fill: parent 0170 0171 GridLayout { 0172 columns: 2 0173 Layout.fillWidth: true 0174 0175 Kirigami.Icon { 0176 Layout.rowSpan: 3 0177 Layout.preferredHeight: Kirigami.Units.iconSizes.huge 0178 Layout.preferredWidth: height 0179 Layout.maximumWidth: aboutItem.width / 3; 0180 Layout.rightMargin: Kirigami.Units.largeSpacing 0181 source: Kirigami.Settings.applicationWindowIcon || aboutItem.aboutData.programLogo || aboutItem.aboutData.programIconName || aboutItem.aboutData.componentName 0182 } 0183 0184 Kirigami.Heading { 0185 Layout.fillWidth: true 0186 text: aboutItem.aboutData.displayName + " " + aboutItem.aboutData.version 0187 wrapMode: Text.WordWrap 0188 } 0189 0190 Kirigami.Heading { 0191 Layout.fillWidth: true 0192 level: 2 0193 wrapMode: Text.WordWrap 0194 text: aboutItem.aboutData.shortDescription 0195 } 0196 0197 RowLayout { 0198 spacing: Kirigami.Units.largeSpacing * 2 0199 0200 UrlButton { 0201 text: qsTr("Get Involved") 0202 url: aboutItem.getInvolvedUrl 0203 visible: url !== "" 0204 } 0205 0206 UrlButton { 0207 text: qsTr("Donate") 0208 url: aboutItem.donateUrl 0209 visible: url !== "" 0210 } 0211 0212 UrlButton { 0213 readonly property string theUrl: { 0214 if (page.aboutData.bugAddress !== "submit@bugs.kde.org") { 0215 return page.aboutData.bugAddress 0216 } 0217 const elements = page.aboutData.productName.split('/'); 0218 let url = `https://bugs.kde.org/enter_bug.cgi?format=guided&product=${elements[0]}&version=${page.aboutData.version}`; 0219 if (elements.length === 2) { 0220 url += "&component=" + elements[1]; 0221 } 0222 return url; 0223 } 0224 text: qsTr("Report a Bug") 0225 url: theUrl 0226 visible: theUrl !== "" 0227 } 0228 } 0229 } 0230 0231 Separator { 0232 Layout.fillWidth: true 0233 } 0234 0235 Kirigami.Heading { 0236 Kirigami.FormData.isSection: true 0237 text: qsTr("Copyright") 0238 } 0239 0240 QQC2.Label { 0241 Layout.leftMargin: Kirigami.Units.gridUnit 0242 text: aboutData.otherText 0243 visible: text.length > 0 0244 wrapMode: Text.WordWrap 0245 Layout.fillWidth: true 0246 } 0247 0248 QQC2.Label { 0249 Layout.leftMargin: Kirigami.Units.gridUnit 0250 text: aboutData.copyrightStatement 0251 visible: text.length > 0 0252 wrapMode: Text.WordWrap 0253 Layout.fillWidth: true 0254 } 0255 0256 UrlButton { 0257 Layout.leftMargin: Kirigami.Units.gridUnit 0258 url: aboutData.homepage 0259 visible: url.length > 0 0260 wrapMode: Text.WordWrap 0261 Layout.fillWidth: true 0262 } 0263 0264 OverlaySheet { 0265 id: licenseSheet 0266 property alias text: bodyLabel.text 0267 0268 contentItem: SelectableLabel { 0269 id: bodyLabel 0270 text: licenseSheet.text 0271 wrapMode: Text.Wrap 0272 } 0273 } 0274 0275 Component { 0276 id: licenseLinkButton 0277 0278 RowLayout { 0279 Layout.leftMargin: Kirigami.Units.smallSpacing 0280 0281 QQC2.Label { text: qsTr("License:") } 0282 0283 LinkButton { 0284 Layout.fillWidth: true 0285 wrapMode: Text.WordWrap 0286 text: modelData.name 0287 onClicked: mouse => { 0288 licenseSheet.text = modelData.text 0289 licenseSheet.title = modelData.name 0290 licenseSheet.open() 0291 } 0292 } 0293 } 0294 } 0295 0296 Component { 0297 id: licenseTextItem 0298 0299 QQC2.Label { 0300 Layout.leftMargin: Kirigami.Units.smallSpacing 0301 Layout.fillWidth: true 0302 wrapMode: Text.WordWrap 0303 text: qsTr("License: %1").arg(modelData.name) 0304 } 0305 } 0306 0307 Repeater { 0308 model: aboutData.licenses 0309 delegate: _usePageStack ? licenseLinkButton : licenseTextItem 0310 } 0311 0312 Kirigami.Heading { 0313 Kirigami.FormData.isSection: visible 0314 text: qsTr("Libraries in use") 0315 Layout.fillWidth: true 0316 wrapMode: Text.WordWrap 0317 visible: Kirigami.Settings.information 0318 } 0319 0320 Repeater { 0321 model: Kirigami.Settings.information 0322 delegate: QQC2.Label { 0323 Layout.leftMargin: Kirigami.Units.gridUnit 0324 Layout.fillWidth: true 0325 wrapMode: Text.WordWrap 0326 id: libraries 0327 text: modelData 0328 } 0329 } 0330 0331 Repeater { 0332 model: aboutData.components 0333 delegate: QQC2.Label { 0334 Layout.fillWidth: true 0335 wrapMode: Text.WordWrap 0336 Layout.leftMargin: Kirigami.Units.gridUnit 0337 text: modelData.name + (modelData.version === "" ? "" : " %1".arg(modelData.version)) 0338 } 0339 } 0340 0341 Kirigami.Heading { 0342 Layout.fillWidth: true 0343 Kirigami.FormData.isSection: visible 0344 text: qsTr("Authors") 0345 wrapMode: Text.WordWrap 0346 visible: aboutData.authors.length > 0 0347 } 0348 0349 QQC2.CheckBox { 0350 id: remoteAvatars 0351 visible: authorsRepeater.hasAnyRemoteAvatars 0352 checked: false 0353 text: qsTr("Show author photos") 0354 0355 Timer { 0356 id: remotesThrottle 0357 repeat: false 0358 interval: 1 0359 onTriggered: { 0360 let hasAnyRemotes = false; 0361 for (let i = 0; i < authorsRepeater.count; ++i) { 0362 const itm = authorsRepeater.itemAt(i); 0363 if (itm.hasRemoteAvatar) { 0364 hasAnyRemotes = true; 0365 break; 0366 } 0367 } 0368 authorsRepeater.hasAnyRemoteAvatars = hasAnyRemotes; 0369 } 0370 } 0371 } 0372 0373 Repeater { 0374 id: authorsRepeater 0375 model: aboutData.authors 0376 property bool hasAnyRemoteAvatars 0377 delegate: personDelegate 0378 onCountChanged: remotesThrottle.start() 0379 } 0380 0381 Kirigami.Heading { 0382 height: visible ? implicitHeight : 0 0383 Kirigami.FormData.isSection: visible 0384 text: qsTr("Credits") 0385 visible: repCredits.count > 0 0386 } 0387 0388 Repeater { 0389 id: repCredits 0390 model: aboutData.credits 0391 delegate: personDelegate 0392 } 0393 0394 Kirigami.Heading { 0395 height: visible ? implicitHeight : 0 0396 Kirigami.FormData.isSection: visible 0397 text: qsTr("Translators") 0398 visible: repTranslators.count > 0 0399 } 0400 0401 Repeater { 0402 id: repTranslators 0403 model: aboutData.translators 0404 delegate: personDelegate 0405 } 0406 } 0407 }