/*SPDX-FileCopyrightText: 2014 Sebastian KΓΌgler <sebas@kde.org>SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>SPDX-FileCopyrightText: 2021 Mikel Johnson <mikel5764@gmail.com>SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>SPDX-License-Identifier: GPL-2.0-or-later*/pragma ComponentBehavior: Boundimport QtQuickimport QtQuick.Layoutsimport org.kde.plasma.components as PC3import org.kde.plasma.extras as PlasmaExtrasimport org.kde.kirigami as Kirigamiimport org.kde.kirigamiaddons.components as KirigamiComponentsimport org.kde.coreaddons as KCoreAddonsimport org.kde.kcmutils as KCMimport org.kde.config as KConfigimport org.kde.plasma.plasmoidPlasmaExtras.PlasmoidHeading {id: rootproperty alias searchText: searchField.textproperty Item configureButton: configureButtonproperty Item pinButton: pinButtonproperty Item avatar: avatarproperty real preferredNameAndIconWidth: 0contentHeight: layoutContainer.height+ kickoff.backgroundMetrics.topPadding+ kickoff.backgroundMetrics.bottomPaddingKCoreAddons.KUser {id: kuser}spacing: kickoff.backgroundMetrics.spacingfunction tabSetFocus(event, invertedTarget, normalTarget) {// Set input focus depending on whether layout order matches focus chain order// normalTarget is optionalconst reason = event.key == Qt.Key_Tab ? Qt.TabFocusReason : Qt.BacktabFocusReasonif (kickoff.paneSwap) {invertedTarget.forceActiveFocus(reason)} else if (normalTarget !== undefined) {normalTarget.forceActiveFocus(reason)} else {event.accepted = false}}contentItem: Item {Item {id: layoutContainerheight: Math.max(searchField.implicitHeight, configureButton.implicitHeight)anchors {verticalCenter: parent.verticalCenterleft: parent.leftleftMargin: kickoff.backgroundMetrics.leftPaddingright: parent.rightrightMargin: kickoff.backgroundMetrics.rightPadding}Keys.forwardTo: searchField.activeFocus ? null : searchFieldRowLayout {id: nameAndIconspacing: root.spacinganchors.left: parent.leftLayoutMirroring.enabled: kickoff.sideBarOnRightheight: parent.heightwidth: root.preferredNameAndIconWidth - layoutContainer.anchors.leftMarginKirigamiComponents.AvatarButton {id: avatarvisible: KConfig.KAuthorized.authorizeControlModule("kcm_users")Layout.fillHeight: trueLayout.minimumWidth: heightLayout.maximumWidth: heighttext: i18nc("@action:button icon-only, for tooltip/Accessible", "Open user settings")name: kuser.fullName// The icon property emits two signals in a row during which it// changes to an empty URL and probably back to the same// static file path, so we need QtQuick.Image not to cache it.cache: falsesource: kuser.faceIconUrlKeys.onTabPressed: event => {root.tabSetFocus(event, kickoff.firstCentralPane);}Keys.onBacktabPressed: event => {root.tabSetFocus(event, nextItemInFocusChain());}Keys.onLeftPressed: event => {if (kickoff.sideBarOnRight) {searchField.forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)}}Keys.onRightPressed: event => {if (!kickoff.sideBarOnRight) {searchField.forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)}}Keys.onDownPressed: event => {if (kickoff.sideBar) {kickoff.sideBar.forceActiveFocus(Qt.TabFocusReason)} else {kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason)}}onClicked: KCM.KCMLauncher.openSystemSettings("kcm_users")}MouseArea {id: nameAndInfoMouseAreahoverEnabled: trueLayout.fillHeight: trueLayout.fillWidth: trueKirigami.Heading {id: nameLabelanchors.fill: parentopacity: parent.containsMouse ? 0 : 1color: Kirigami.Theme.textColorlevel: 4text: kuser.fullNametextFormat: Text.PlainTextelide: Text.ElideRighthorizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeftverticalAlignment: Text.AlignVCenterBehavior on opacity {NumberAnimation {duration: Kirigami.Units.longDurationeasing.type: Easing.InOutQuad}}}Kirigami.Heading {id: infoLabelanchors.fill: parentlevel: 5opacity: parent.containsMouse ? 1 : 0color: Kirigami.Theme.textColortext: kuser.os !== "" ? `${kuser.loginName}@${kuser.host} (${kuser.os})` : `${kuser.loginName}@${kuser.host}`textFormat: Text.PlainTextelide: Text.ElideRighthorizontalAlignment: kickoff.paneSwap ? Text.AlignRight : Text.AlignLeftverticalAlignment: Text.AlignVCenterBehavior on opacity {NumberAnimation {duration: Kirigami.Units.longDurationeasing.type: Easing.InOutQuad}}}PC3.ToolTip.text: infoLabel.textPC3.ToolTip.delay: Kirigami.Units.toolTipDelayPC3.ToolTip.visible: infoLabel.truncated && containsMouse}}RowLayout {id: rowLayoutspacing: root.spacingheight: parent.heightanchors {left: nameAndIcon.rightright: parent.right}LayoutMirroring.enabled: kickoff.sideBarOnRightKeys.onDownPressed: event => {kickoff.contentArea.forceActiveFocus(Qt.TabFocusReason);}PlasmaExtras.SearchField {id: searchFieldLayout.alignment: Qt.AlignLeft | Qt.AlignVCenterLayout.fillWidth: trueLayout.leftMargin: kickoff.backgroundMetrics.leftPaddingfocus: trueBinding {target: kickoffproperty: "searchField"value: searchField// there's only one header ever, so don't waste resourcesrestoreMode: Binding.RestoreNone}Connections {target: kickofffunction onExpandedChanged() {if (!kickoff.expanded) {searchField.clear()}}}onTextEdited: {searchField.forceActiveFocus(Qt.ShortcutFocusReason)}Keys.priority: Keys.AfterItemKeys.forwardTo: {if (kickoff.contentArea === null) {return []}if (kickoff.contentArea instanceof ListOfGridsView) {// forward to grid inside of list, or down will skip the whole grid'return [kickoff.contentArea.view.currentItem?.view, kickoff.contentArea.view]}return kickoff.contentArea.view}Keys.onTabPressed: event => {tabSetFocus(event, nextItemInFocusChain(false));}Keys.onBacktabPressed: event => {tabSetFocus(event, nextItemInFocusChain());}Keys.onLeftPressed: event => {if (activeFocus) {(sideBarOnRight ? configureButton : avatar).forceActiveFocus(Application.layoutDirection === Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)}}Keys.onRightPressed: event => {if (activeFocus) {(sideBarOnRight ? avatar : configureButton).forceActiveFocus(Application.layoutDirection === Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)}}}PC3.ToolButton {id: configureButtonLayout.alignment: Qt.AlignRight | Qt.AlignVCentervisible: Plasmoid.internalAction("configure").enabledicon.name: "configure"text: Plasmoid.internalAction("configure").textdisplay: PC3.ToolButton.IconOnlyPC3.ToolTip.text: textPC3.ToolTip.delay: Kirigami.Units.toolTipDelayPC3.ToolTip.visible: hoveredKeys.onTabPressed: event => {tabSetFocus(event, nextItemInFocusChain(false));}Keys.onBacktabPressed: event => {tabSetFocus(event, nextItemInFocusChain());}Keys.onLeftPressed: event => {(kickoff.sideBarOnRight ? pinButton : searchField).forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)}Keys.onRightPressed: event => {(kickoff.sideBarOnRight ? searchField : pinButton).forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)}onClicked: plasmoid.internalAction("configure").trigger()}PC3.ToolButton {id: pinButtoncheckable: truechecked: Plasmoid.configuration.pinicon.name: "window-pin"text: i18nc("@action:button Pin widget open if it loses focus, icon-only button, for tooltip/Accessible", "Keep Open")display: PC3.ToolButton.IconOnlyPC3.ToolTip.text: textPC3.ToolTip.delay: Kirigami.Units.toolTipDelayPC3.ToolTip.visible: hoveredBinding {target: kickoffproperty: "hideOnWindowDeactivate"value: !Plasmoid.configuration.pin// there should be no other bindings, so don't waste resourcesrestoreMode: Binding.RestoreNone}Keys.onTabPressed: event => {tabSetFocus(event, nextItemInFocusChain(false), kickoff.firstCentralPane || nextItemInFocusChain());}Keys.onBacktabPressed: event => {tabSetFocus(event, nameAndIcon.nextItemInFocusChain(false), nextItemInFocusChain(false));}Keys.onLeftPressed: event => {if (!kickoff.sideBarOnRight) {nextItemInFocusChain(false).forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.TabFocusReason : Qt.BacktabFocusReason)}}Keys.onRightPressed: event => {if (kickoff.sideBarOnRight) {nextItemInFocusChain(false).forceActiveFocus(Application.layoutDirection == Qt.RightToLeft ? Qt.BacktabFocusReason : Qt.TabFocusReason)}}onToggled: Plasmoid.configuration.pin = checked}}}}}