Warning, /libraries/kirigami-addons/src/formcard/AboutPage.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0002 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0003 // SPDX-License-Identifier: LGPL-2.0-or-later
0004 
0005 import QtQuick 2.15
0006 import QtQuick.Controls 2.15 as QQC2
0007 import QtQuick.Window 2.15
0008 import QtQuick.Layouts 1.15
0009 import org.kde.kirigami 2.20 as Kirigami
0010 import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents
0011 
0012 import "private" as Private
0013 
0014 /**
0015  * @brief An AboutPage that displays the about data using Form components.
0016  *
0017  * This component consists of an internationalized "About" page with the
0018  * metadata of your program.
0019  *
0020  * It allows to show the copyright notice of the application together with
0021  * the contributors and some information of which platform it's running on.
0022  *
0023  * @since KirigamiAddons 0.11.0
0024  * @inherit org:kde::kirigami::ScrollablePage
0025  */
0026 FormCardPage {
0027     id: page
0028 
0029     /**
0030      * @brief This property holds an object with the same shape as KAboutData.
0031      *
0032      * Set this property to either a KAboutData instance exposed from C++, or directly via a JSON object.
0033      *
0034      * Example usage:
0035      * @code{json}
0036      * aboutData: {
0037           "displayName" : "KirigamiApp",
0038           "productName" : "kirigami/app",
0039           "componentName" : "kirigamiapp",
0040           "shortDescription" : "A Kirigami example",
0041           "homepage" : "",
0042           "bugAddress" : "submit@bugs.kde.org",
0043           "version" : "5.14.80",
0044           "otherText" : "",
0045           "authors" : [
0046               {
0047                   "name" : "...",
0048                   "task" : "...",
0049                   "emailAddress" : "somebody@kde.org",
0050                   "webAddress" : "",
0051                   "ocsUsername" : ""
0052               }
0053           ],
0054           "credits" : [],
0055           "translators" : [],
0056           "licenses" : [
0057               {
0058                   "name" : "GPL v2",
0059                   "text" : "long, boring, license text",
0060                   "spdx" : "GPL-2.0"
0061               }
0062           ],
0063           "copyrightStatement" : "© 2010-2018 Plasma Development Team",
0064           "desktopFileName" : "org.kde.kirigamiapp"
0065        }
0066        @endcode
0067      *
0068      * @see KAboutData
0069      */
0070     property var aboutData
0071 
0072     /**
0073      * @brief This property holds a link to a "Get Involved" page.
0074      *
0075      * default: `"https://community.kde.org/Get_Involved" when the
0076      * application ID starts with "org.kde.", otherwise empty.`
0077      */
0078     property url getInvolvedUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://community.kde.org/Get_Involved" : ""
0079 
0080     /**
0081      * @brief This property holds a link to a "Donate" page.
0082      *
0083      * default: `"https://www.kde.org/donate" when the application ID starts with "org.kde.", otherwise empty.`
0084      */
0085     property url donateUrl: aboutData.desktopFileName.startsWith("org.kde.") ? "https://www.kde.org/donate" : ""
0086 
0087     title: i18nd("kirigami-addons", "About %1", page.aboutData.displayName)
0088 
0089     FormCard {
0090         Layout.topMargin: Kirigami.Units.gridUnit
0091 
0092         AbstractFormDelegate {
0093             id: generalDelegate
0094             Layout.fillWidth: true
0095             background: null
0096             contentItem: RowLayout {
0097                 spacing: Kirigami.Units.smallSpacing * 2
0098 
0099                 Kirigami.Icon {
0100                     Layout.rowSpan: 3
0101                     Layout.preferredHeight: Kirigami.Units.iconSizes.huge
0102                     Layout.preferredWidth: height
0103                     Layout.maximumWidth: page.width / 3;
0104                     Layout.rightMargin: Kirigami.Units.largeSpacing
0105                     source: Kirigami.Settings.applicationWindowIcon || page.aboutData.programLogo || page.aboutData.programIconName || page.aboutData.componentName
0106                 }
0107 
0108                 ColumnLayout {
0109                     Layout.fillWidth: true
0110                     spacing: Kirigami.Units.smallSpacing
0111 
0112                     Kirigami.Heading {
0113                         Layout.fillWidth: true
0114                         text: page.aboutData.displayName + " " + page.aboutData.version
0115                         wrapMode: Text.WordWrap
0116                     }
0117 
0118                     Kirigami.Heading {
0119                         Layout.fillWidth: true
0120                         level: 3
0121                         type: Kirigami.Heading.Type.Secondary
0122                         wrapMode: Text.WordWrap
0123                         text: page.aboutData.shortDescription
0124                     }
0125                 }
0126             }
0127         }
0128 
0129         FormDelegateSeparator {}
0130 
0131         FormTextDelegate {
0132             id: copyrightDelegate
0133             text: i18nd("kirigami-addons", "Copyright")
0134             descriptionItem.textFormat: Text.PlainText
0135             description: aboutData.otherText + (aboutData.otherText.length > 0 ? '</br>' : '')
0136                 + aboutData.copyrightStatement
0137         }
0138     }
0139 
0140     FormHeader {
0141         title: i18ndp("kirigami-addons", "License", "Licenses", aboutData.licenses.length)
0142         visible: aboutData.licenses.length
0143     }
0144 
0145     FormCard {
0146         visible: aboutData.licenses.length
0147 
0148         Repeater {
0149             model: aboutData.licenses
0150             delegate: FormButtonDelegate {
0151                 text: modelData.name
0152                 Layout.fillWidth: true
0153                 onClicked: {
0154                     licenseSheet.text = modelData.text;
0155                     licenseSheet.title = modelData.name;
0156                     licenseSheet.open();
0157                 }
0158             }
0159         }
0160 
0161         data: Kirigami.OverlaySheet {
0162             id: licenseSheet
0163             property alias text: bodyLabel.text
0164             parent: applicationWindow().overlay
0165 
0166             contentItem: Kirigami.SelectableLabel {
0167                 id: bodyLabel
0168                 text: licenseSheet.text
0169                 Layout.preferredWidth: Kirigami.Units.gridUnit * 15
0170             }
0171         }
0172     }
0173 
0174     FormCard {
0175         Layout.topMargin: Kirigami.Units.gridUnit
0176 
0177         FormButtonDelegate {
0178             id: getInvolvedDelegate
0179             text: i18nd("kirigami-addons", "Homepage")
0180             onClicked: Qt.openUrlExternally(aboutData.homepage)
0181             visible: aboutData.homepage.length > 0
0182         }
0183 
0184         FormDelegateSeparator {
0185             above: getInvolvedDelegate
0186             below: donateDelegate
0187             visible: aboutData.homepage.length > 0
0188         }
0189 
0190         FormButtonDelegate {
0191             id: donateDelegate
0192             text: i18nd("kirigami-addons", "Donate")
0193             onClicked: Qt.openUrlExternally(donateUrl + "?app=" + page.aboutData.componentName)
0194             visible: donateUrl.toString().length > 0
0195         }
0196 
0197         FormDelegateSeparator {
0198             above: donateDelegate
0199             below: homepageDelegate
0200             visible: donateUrl.toString().length > 0
0201         }
0202 
0203         FormButtonDelegate {
0204             id: homepageDelegate
0205             text: i18nd("kirigami-addons", "Get Involved")
0206             onClicked: Qt.openUrlExternally(page.getInvolvedUrl)
0207             visible: page.getInvolvedUrl != ""
0208         }
0209 
0210         FormDelegateSeparator {
0211             above: homepageDelegate
0212             below: bugDelegate
0213             visible: page.getInvolvedUrl != ""
0214         }
0215 
0216         FormButtonDelegate {
0217             id: bugDelegate
0218             readonly property string theUrl: {
0219                 if (aboutData.bugAddress !== "submit@bugs.kde.org") {
0220                     return aboutData.bugAddress
0221                 }
0222                 const elements = aboutData.productName.split('/');
0223                 let url = `https://bugs.kde.org/enter_bug.cgi?format=guided&product=${elements[0]}&version=${aboutData.version}`;
0224                 if (elements.length === 2) {
0225                     url += "&component=" + elements[1];
0226                 }
0227                 return url;
0228             }
0229 
0230             text: i18nd("kirigami-addons", "Report a bug")
0231             onClicked: Qt.openUrlExternally(theUrl)
0232             visible: theUrl.length > 0
0233         }
0234     }
0235 
0236     FormHeader {
0237         title: i18nd("kirigami-addons", "Libraries in use")
0238         visible: Kirigami.Settings.information
0239     }
0240 
0241     FormCard {
0242         visible: Kirigami.Settings.information
0243 
0244         Repeater {
0245             model: Kirigami.Settings.information
0246             delegate: FormTextDelegate {
0247                 id: libraries
0248                 Layout.fillWidth: true
0249                 text: modelData
0250             }
0251         }
0252 
0253         Repeater {
0254             model: aboutData.components
0255             delegate: libraryDelegate
0256         }
0257     }
0258 
0259     FormHeader {
0260         title: i18nd("kirigami-addons", "Authors")
0261         visible: aboutData.authors !== undefined && aboutData.authors.length > 0
0262     }
0263 
0264     FormCard {
0265         visible: aboutData.authors !== undefined && aboutData.authors.length > 0
0266 
0267         Repeater {
0268             id: authorsRepeater
0269             model: aboutData.authors
0270             delegate: personDelegate
0271         }
0272     }
0273 
0274     FormHeader {
0275         title: i18nd("kirigami-addons", "Credits")
0276         visible: aboutData.credits !== undefined && aboutData.credits.length > 0
0277     }
0278 
0279     FormCard {
0280         visible: aboutData.credits !== undefined && aboutData.credits.length > 0
0281 
0282         Repeater {
0283             id: repCredits
0284             model: aboutData.credits
0285             delegate: personDelegate
0286         }
0287     }
0288 
0289     FormHeader {
0290         title: i18nd("kirigami-addons", "Translators")
0291         visible: aboutData.translators !== undefined && aboutData.translators.length > 0
0292     }
0293 
0294     FormCard {
0295         visible: aboutData.translators !== undefined && aboutData.translators.length > 0
0296 
0297         Repeater {
0298             id: repTranslators
0299             model: aboutData.translators
0300             delegate: personDelegate
0301         }
0302     }
0303 
0304     data: [
0305         Component {
0306             id: personDelegate
0307 
0308             AbstractFormDelegate {
0309                 Layout.fillWidth: true
0310                 background: null
0311                 contentItem: RowLayout {
0312                     spacing: Kirigami.Units.smallSpacing * 2
0313 
0314                     KirigamiComponents.Avatar {
0315                         id: avatarIcon
0316 
0317                         // TODO FIXME kf6 https://phabricator.kde.org/T15993
0318                         property bool hasRemoteAvatar: false // (typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0)
0319                         implicitWidth: Kirigami.Units.iconSizes.medium
0320                         implicitHeight: implicitWidth
0321                         name: modelData.name
0322                         source: if (!!modelData.avatarUrl && modelData.avatarUrl.toString().startsWith('https://')) {
0323                             const url = new URL(modelData.avatarUrl);
0324                             const params = new URLSearchParams(url.search);
0325                             params.append("s", width);
0326                             url.search = params.toString();
0327                             return url;
0328                         } else {
0329                             return '';
0330                         }
0331                     }
0332 
0333                     ColumnLayout {
0334                         Layout.fillWidth: true
0335                         spacing: Kirigami.Units.smallSpacing
0336 
0337                         QQC2.Label {
0338                             Layout.fillWidth: true
0339                             text: modelData.name
0340                             elide: Text.ElideRight
0341                         }
0342 
0343                         QQC2.Label {
0344                             id: internalDescriptionItem
0345                             Layout.fillWidth: true
0346                             text: modelData.task
0347                             color: Kirigami.Theme.disabledTextColor
0348                             font: Kirigami.Theme.smallFont
0349                             elide: Text.ElideRight
0350                             visible: text.length > 0
0351                         }
0352                     }
0353 
0354                     QQC2.ToolButton {
0355                         visible: typeof(modelData.ocsUsername) !== "undefined" && modelData.ocsUsername.length > 0
0356                         icon.name: "get-hot-new-stuff"
0357                         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0358                         QQC2.ToolTip.visible: hovered
0359                         QQC2.ToolTip.text: i18nd("kirigami-addons", "Visit %1's KDE Store page", modelData.name)
0360                         onClicked: Qt.openUrlExternally("https://store.kde.org/u/%1".arg(modelData.ocsUsername))
0361                     }
0362 
0363                     QQC2.ToolButton {
0364                         visible: typeof(modelData.emailAddress) !== "undefined" && modelData.emailAddress.length > 0
0365                         icon.name: "mail-sent"
0366                         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0367                         QQC2.ToolTip.visible: hovered
0368                         QQC2.ToolTip.text: i18nd("kirigami-addons", "Send an email to %1", modelData.emailAddress)
0369                         onClicked: Qt.openUrlExternally("mailto:%1".arg(modelData.emailAddress))
0370                     }
0371 
0372                     QQC2.ToolButton {
0373                         visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
0374                         icon.name: "globe"
0375                         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0376                         QQC2.ToolTip.visible: hovered
0377                         QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
0378                         onClicked: Qt.openUrlExternally(modelData.webAddress)
0379                     }
0380                 }
0381             }
0382         },
0383         Component {
0384             id: libraryDelegate
0385 
0386             AbstractFormDelegate {
0387                 id: delegate
0388 
0389                 required property var modelData
0390 
0391                 Layout.fillWidth: true
0392                 background: null
0393                 contentItem: RowLayout {
0394                     spacing: Kirigami.Units.smallSpacing * 2
0395 
0396                     ColumnLayout {
0397                         Layout.fillWidth: true
0398                         spacing: Kirigami.Units.smallSpacing
0399 
0400                         QQC2.Label {
0401                             Layout.fillWidth: true
0402                             text: delegate.modelData.name + ' ' + delegate.modelData.version
0403                             elide: Text.ElideRight
0404                         }
0405 
0406                         QQC2.Label {
0407                             id: internalDescriptionItem
0408                             Layout.fillWidth: true
0409                             text: delegate.modelData.description
0410                             color: Kirigami.Theme.disabledTextColor
0411                             font: Kirigami.Theme.smallFont
0412                             elide: Text.ElideRight
0413                             visible: text.length > 0
0414                         }
0415                     }
0416 
0417                     QQC2.ToolButton {
0418                         visible: modelData.licenses !== 0
0419                         icon.name: "license"
0420                         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0421                         QQC2.ToolTip.visible: hovered
0422                         QQC2.ToolTip.text: !visible ? "" : delegate.modelData.licenses.name
0423 
0424                         Kirigami.OverlaySheet {
0425                             id: licenseSheet
0426 
0427                             title: delegate.modelData.licenses.name
0428 
0429                             contentItem: Kirigami.SelectableLabel {
0430                                 id: bodyLabel
0431                                 text: delegate.modelData.licenses.text
0432                                 Layout.preferredWidth: Kirigami.Units.gridUnit * 15
0433                             }
0434                         }
0435 
0436                         onClicked: licenseSheet.open()
0437                     }
0438 
0439                     QQC2.ToolButton {
0440                         visible: typeof(modelData.webAddress) !== "undefined" && modelData.webAddress.length > 0
0441                         icon.name: "globe"
0442                         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0443                         QQC2.ToolTip.visible: hovered
0444                         QQC2.ToolTip.text: (typeof(modelData.webAddress) === "undefined" && modelData.webAddress.length > 0) ? "" : modelData.webAddress
0445                         onClicked: Qt.openUrlExternally(modelData.webAddress)
0446                     }
0447                 }
0448             }
0449         }
0450     ]
0451 }