Warning, /plasma/plasma-desktop/applets/kickoff/package/contents/ui/Header.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2014 Sebastian Kügler <sebas@kde.org>
0003     SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
0004     SPDX-FileCopyrightText: 2021 Mikel Johnson <mikel5764@gmail.com>
0005     SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 import QtQuick 2.15
0011 import QtQml 2.15
0012 import QtQuick.Layouts 1.15
0013 import QtQuick.Templates 2.15 as T
0014 import Qt5Compat.GraphicalEffects
0015 import org.kde.plasma.components 3.0 as PC3
0016 import org.kde.plasma.extras 2.0 as PlasmaExtras
0017 import org.kde.kirigami 2.20 as Kirigami
0018 import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents
0019 import org.kde.coreaddons 1.0 as KCoreAddons
0020 import org.kde.kcmutils as KCM
0021 import org.kde.config as KConfig
0022 import org.kde.plasma.plasmoid 2.0
0023 
0024 PlasmaExtras.PlasmoidHeading {
0025     id: root
0026 
0027     property alias searchText: searchField.text
0028     property Item configureButton: configureButton
0029     property Item pinButton: pinButton
0030     property Item avatar: avatar
0031     property real preferredNameAndIconWidth: 0
0032 
0033     contentHeight: Math.max(searchField.implicitHeight, configureButton.implicitHeight)
0034 
0035     leftPadding: 0
0036     rightPadding: 0
0037     topPadding: Math.round((background.margins.top - background.inset.top) / 2.0)
0038     bottomPadding: background.margins.bottom + Math.round((background.margins.bottom - background.inset.bottom) / 2.0)
0039 
0040     leftInset: -kickoff.backgroundMetrics.leftPadding
0041     rightInset: -kickoff.backgroundMetrics.rightPadding
0042     topInset: -background.margins.top
0043     bottomInset: 0
0044 
0045     KCoreAddons.KUser {
0046         id: kuser
0047     }
0048 
0049     spacing: kickoff.backgroundMetrics.spacing
0050 
0051     function tabSetFocus(event, invertedTarget, normalTarget) {
0052         // Set input focus depending on whether layout order matches focus chain order
0053         // normalTarget is optional
0054         const reason = event.key == Qt.Key_Tab ? Qt.TabFocusReason : Qt.BacktabFocusReason
0055         if (kickoff.paneSwap) {
0056             invertedTarget.forceActiveFocus(reason)
0057         } else if (normalTarget !== undefined) {
0058             normalTarget.forceActiveFocus(reason)
0059         } else {
0060             event.accepted = false
0061         }
0062     }
0063 
0064     RowLayout {
0065         id: nameAndIcon
0066         spacing: root.spacing
0067         anchors.left: parent.left
0068         LayoutMirroring.enabled: kickoff.sideBarOnRight
0069         height: parent.height
0070         width: root.preferredNameAndIconWidth
0071 
0072         KirigamiComponents.AvatarButton {
0073             id: avatar
0074             visible: KConfig.KAuthorized.authorizeControlModule("kcm_users")
0075 
0076             Layout.fillHeight: true
0077             Layout.minimumWidth: height
0078             Layout.maximumWidth: height
0079 
0080             text: i18n("Open user settings")
0081             name: kuser.fullName
0082             source: kuser.faceIconUrl + "?timestamp=" + Date.now()
0083 
0084             Keys.onTabPressed: event => {
0085                 tabSetFocus(event, kickoff.firstCentralPane);
0086             }
0087             Keys.onBacktabPressed: event => {
0088                 tabSetFocus(event, nextItemInFocusChain());
0089             }
0090             Keys.onLeftPressed: event => {
0091                 if (kickoff.sideBarOnRight) {
0092                     searchField.forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)
0093                 }
0094             }
0095             Keys.onRightPressed: event => {
0096                 if (!kickoff.sideBarOnRight) {
0097                     searchField.forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)
0098                 }
0099             }
0100             Keys.onDownPressed: event => {
0101                 if (kickoff.sideBar) {
0102                     kickoff.sideBar.forceActiveFocus(Qt.TabFocusReason)
0103                 } else {
0104                     kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason)
0105                 }
0106             }
0107 
0108             onClicked: KCM.KCMLauncher.openSystemSettings("kcm_users")
0109         }
0110 
0111         MouseArea {
0112             id: nameAndInfoMouseArea
0113             hoverEnabled: true
0114 
0115             Layout.fillHeight: true
0116             Layout.fillWidth: true
0117 
0118             Kirigami.Heading {
0119                 id: nameLabel
0120                 anchors.fill: parent
0121                 opacity: parent.containsMouse ? 0 : 1
0122                 color: Kirigami.Theme.textColor
0123                 level: 4
0124                 text: kuser.fullName
0125                 textFormat: Text.PlainText
0126                 elide: Text.ElideRight
0127                 horizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeft
0128                 verticalAlignment: Text.AlignVCenter
0129 
0130                 Behavior on opacity {
0131                     NumberAnimation {
0132                         duration: Kirigami.Units.longDuration
0133                         easing.type: Easing.InOutQuad
0134                     }
0135                 }
0136             }
0137 
0138             Kirigami.Heading {
0139                 id: infoLabel
0140                 anchors.fill: parent
0141                 level: 5
0142                 opacity: parent.containsMouse ? 1 : 0
0143                 color: Kirigami.Theme.textColor
0144                 text: kuser.os !== "" ? `${kuser.loginName}@${kuser.host} (${kuser.os})` : `${kuser.loginName}@${kuser.host}`
0145                 textFormat: Text.PlainText
0146                 elide: Text.ElideRight
0147                 horizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeft
0148                 verticalAlignment: Text.AlignVCenter
0149 
0150                 Behavior on opacity {
0151                     NumberAnimation {
0152                         duration: Kirigami.Units.longDuration
0153                         easing.type: Easing.InOutQuad
0154                     }
0155                 }
0156             }
0157 
0158             PC3.ToolTip.text: infoLabel.text
0159             PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0160             PC3.ToolTip.visible: infoLabel.truncated && containsMouse
0161         }
0162     }
0163     RowLayout {
0164         id: rowLayout
0165         spacing: root.spacing
0166         height: parent.height
0167         anchors {
0168             left: nameAndIcon.right
0169             right: parent.right
0170         }
0171         LayoutMirroring.enabled: kickoff.sideBarOnRight
0172         Keys.onDownPressed: event => {
0173             kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason);
0174         }
0175 
0176         PlasmaExtras.SearchField {
0177             id: searchField
0178             Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
0179             Layout.fillWidth: true
0180             Layout.leftMargin: kickoff.backgroundMetrics.leftPadding
0181             focus: true
0182 
0183             Binding {
0184                 target: kickoff
0185                 property: "searchField"
0186                 value: searchField
0187                 // there's only one header ever, so don't waste resources
0188                 restoreMode: Binding.RestoreNone
0189             }
0190             Connections {
0191                 target: kickoff
0192                 function onExpandedChanged() {
0193                     if (kickoff.expanded) {
0194                         searchField.clear()
0195                     }
0196                 }
0197             }
0198             onTextEdited: {
0199                 searchField.forceActiveFocus(Qt.ShortcutFocusReason)
0200             }
0201             onAccepted: {
0202                 kickoff.contentArea.currentItem.action.triggered()
0203                 kickoff.contentArea.currentItem.forceActiveFocus(Qt.ShortcutFocusReason)
0204             }
0205             Keys.priority: Keys.AfterItem
0206             Keys.forwardTo: kickoff.contentArea !== null ? kickoff.contentArea.view : []
0207             Keys.onTabPressed: event => {
0208                 tabSetFocus(event, nextItemInFocusChain(false));
0209             }
0210             Keys.onBacktabPressed: event => {
0211                 tabSetFocus(event, nextItemInFocusChain());
0212             }
0213             Keys.onLeftPressed: event => {
0214                 if (activeFocus) {
0215                     nextItemInFocusChain(kickoff.sideBarOnRight).forceActiveFocus(
0216                         Qt.application.layoutDirection === Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)
0217                 }
0218             }
0219             Keys.onRightPressed: event => {
0220                 if (activeFocus) {
0221                     nextItemInFocusChain(!kickoff.sideBarOnRight).forceActiveFocus(
0222                         Qt.application.layoutDirection === Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)
0223                 }
0224             }
0225         }
0226 
0227         PC3.ToolButton {
0228             id: configureButton
0229             Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
0230             visible: Plasmoid.internalAction("configure").enabled
0231             icon.name: "configure"
0232             text: Plasmoid.internalAction("configure").text
0233             display: PC3.ToolButton.IconOnly
0234 
0235             PC3.ToolTip.text: text
0236             PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0237             PC3.ToolTip.visible: hovered
0238             Keys.onTabPressed: event => {
0239                 tabSetFocus(event, nextItemInFocusChain(false));
0240             }
0241             Keys.onBacktabPressed: event => {
0242                 tabSetFocus(event, nextItemInFocusChain());
0243             }
0244             Keys.onLeftPressed: event => {
0245                 nextItemInFocusChain(kickoff.sideBarOnRight).forceActiveFocus(
0246                     Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)
0247             }
0248             Keys.onRightPressed: event => {
0249                 nextItemInFocusChain(!kickoff.sideBarOnRight).forceActiveFocus(
0250                     Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)
0251             }
0252             onClicked: plasmoid.internalAction("configure").trigger()
0253         }
0254         PC3.ToolButton {
0255             id: pinButton
0256             checkable: true
0257             checked: Plasmoid.configuration.pin
0258             icon.name: "window-pin"
0259             text: i18n("Keep Open")
0260             display: PC3.ToolButton.IconOnly
0261             PC3.ToolTip.text: text
0262             PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0263             PC3.ToolTip.visible: hovered
0264             Binding {
0265                 target: kickoff
0266                 property: "hideOnWindowDeactivate"
0267                 value: !Plasmoid.configuration.pin
0268                 // there should be no other bindings, so don't waste resources
0269                 restoreMode: Binding.RestoreNone
0270             }
0271             Keys.onTabPressed: event => {
0272                 tabSetFocus(event, nextItemInFocusChain(false), kickoff.firstCentralPane || nextItemInFocusChain());
0273             }
0274             Keys.onBacktabPressed: event => {
0275                 tabSetFocus(event, nameAndIcon.nextItemInFocusChain(false), nextItemInFocusChain(false));
0276             }
0277             Keys.onLeftPressed: event => {
0278                 if (!kickoff.sideBarOnRight) {
0279                     nextItemInFocusChain(false).forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)
0280                 }
0281             }
0282             Keys.onRightPressed: event => {
0283                 if (kickoff.sideBarOnRight) {
0284                     nextItemInFocusChain(false).forceActiveFocus(Qt.application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)
0285                 }
0286             }
0287             onToggled: Plasmoid.configuration.pin = checked
0288         }
0289     }
0290 }