Warning, /plasma/plasma-desktop/kcms/componentchooser/ui/ComponentOverlay.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2022 Méven Car <meven@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick
0008 import QtQuick.Layouts
0009 import QtQuick.Controls as QQC2
0010 import org.kde.kirigami as Kirigami
0011 import org.kde.kcmutils as KCM
0012 
0013 Kirigami.OverlaySheet {
0014     id: root
0015 
0016     property QtObject componentChooser
0017 
0018     // type: list<string>
0019     property var unsupportedMimeTypes: componentChooser?.unsupportedMimeTypes ?? []
0020     // type: list<{ first, second }>
0021     property var mimeTypesNotAssociated: componentChooser?.mimeTypesNotAssociated ?? []
0022 
0023     function sanitize(input: string): string {
0024         // Based on QQuickStyledTextPrivate::parseEntity
0025         const table = {
0026             '>': '&gt;',
0027             '<': '&lt;',
0028             '&': '&amp;',
0029             "'": '&apos;',
0030             '"': '&quot;',
0031             '\u00a0': '&nbsp;',
0032         };
0033         return input.replace(/[<>&'"\u00a0]/g, c => table[c]);
0034     }
0035 
0036     function formatListItem(item: string): string {
0037         return "<li>" + sanitize(item) + "</li>";
0038     }
0039 
0040     function formatHtmlUnorderedStringList(list: list<string>): string {
0041         return "<ul>" + list.map(formatListItem).join("\n") + "</ul>";
0042     }
0043 
0044     onOpened: {
0045         focus = true;
0046     }
0047 
0048     onClosed: {
0049         componentChooser = null;
0050     }
0051 
0052     title: i18n("Details")
0053 
0054     modal: true
0055     QQC2.Overlay.modal: KcmPopupModal {}
0056 
0057     ColumnLayout {
0058         enabled: root.componentChooser !== null
0059         spacing: Kirigami.Units.smallSpacing
0060         Layout.preferredWidth: Kirigami.Units.gridUnit * 25
0061 
0062         RowLayout {
0063             Layout.fillWidth: true
0064             spacing: Kirigami.Units.largeSpacing
0065 
0066             Kirigami.Icon {
0067                 Layout.preferredWidth: Kirigami.Units.iconSizes.large
0068                 Layout.preferredHeight: Kirigami.Units.iconSizes.large
0069                 source: root.componentChooser?.applicationIcon()
0070             }
0071 
0072             Kirigami.Heading {
0073                 text: root.componentChooser?.applicationName() ?? ""
0074                 textFormat: Text.PlainText
0075                 level: 1
0076                 wrapMode: Text.Wrap
0077                 Layout.fillWidth: true
0078                 Layout.alignment: Qt.AlignVCenter
0079             }
0080         }
0081 
0082         Kirigami.Heading {
0083             text: i18n("This application can also open these file types:")
0084             textFormat: Text.PlainText
0085             visible: root.mimeTypesNotAssociated.length > 0
0086             level: 3
0087             wrapMode: Text.Wrap
0088             Layout.fillWidth: true
0089             Layout.bottomMargin: Kirigami.Units.largeSpacing
0090         }
0091         Kirigami.SelectableLabel {
0092             visible: root.mimeTypesNotAssociated.length > 0
0093             text: root.formatHtmlUnorderedStringList(
0094                 root.mimeTypesNotAssociated.map(
0095                     ({first, second}) => i18nc(
0096                         "@label %1 is a MIME type and %2 is an application name",
0097                         "%1 (Currently opens in %2)",
0098                         second,
0099                         first,
0100                     )
0101                 )
0102             )
0103             Layout.fillWidth: true
0104         }
0105         QQC2.Button {
0106             visible: root.mimeTypesNotAssociated.length > 0
0107             icon.name: root.componentChooser?.applicationIcon() ?? ""
0108             text: i18nc(
0109                 "@action:button %1 is an application name",
0110                 "Open All in %1",
0111                 root.componentChooser?.applicationName() ?? ""
0112             )
0113             Layout.topMargin: Kirigami.Units.largeSpacing
0114             onClicked: {
0115                 root.close();
0116                 root.componentChooser.saveMimeTypesNotAssociated();
0117             }
0118         }
0119 
0120         Kirigami.Separator {
0121             // extra double-spacing
0122             Layout.fillWidth: true
0123             Layout.margins: Kirigami.Units.largeSpacing
0124             visible: root.unsupportedMimeTypes.length > 0
0125                 && root.mimeTypesNotAssociated.length > 0
0126         }
0127 
0128         Kirigami.Heading {
0129             text: i18n("This application does not advertise support for the following file types, but may be able to open them anyway:")
0130             textFormat: Text.PlainText
0131             visible: root.unsupportedMimeTypes.length > 0
0132             level: 3
0133             wrapMode: Text.Wrap
0134             Layout.fillWidth: true
0135             Layout.bottomMargin: Kirigami.Units.largeSpacing
0136         }
0137         Kirigami.SelectableLabel {
0138             visible: root.unsupportedMimeTypes.length > 0
0139             text: root.formatHtmlUnorderedStringList(root.unsupportedMimeTypes)
0140             Layout.fillWidth: true
0141         }
0142         QQC2.Button {
0143             visible: root.unsupportedMimeTypes.length > 0
0144             icon.name: root.componentChooser?.applicationIcon() ?? ""
0145             text: root.componentChooser
0146                 ? i18nc("@action:button", "Force All to Open in %1", root.componentChooser.applicationName())
0147                 : ""
0148             Layout.topMargin: Kirigami.Units.largeSpacing
0149             onClicked: {
0150                 root.close();
0151                 root.componentChooser.saveAssociationUnsuportedMimeTypes();
0152             }
0153         }
0154 
0155         QQC2.Button {
0156             Layout.topMargin: Kirigami.Units.largeSpacing
0157             icon.name: "configure-symbolic"
0158             text: i18n("Configure Manually…")
0159             visible: root.componentChooser !== null
0160             onClicked: {
0161                 root.close();
0162                 KCM.KCMLauncher.openSystemSettings("kcm_filetypes");
0163             }
0164         }
0165     }
0166 }