diff --git a/applets/kicker/package/contents/ui/MenuRepresentation.qml b/applets/kicker/package/contents/ui/MenuRepresentation.qml index c47f2fcb1..136d8a6e5 100644 --- a/applets/kicker/package/contents/ui/MenuRepresentation.qml +++ b/applets/kicker/package/contents/ui/MenuRepresentation.qml @@ -1,428 +1,428 @@ /*************************************************************************** * Copyright (C) 2013-2015 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents FocusScope { id: root focus: true Layout.minimumWidth: sideBar.width + mainRow.spacing + Math.max(units.gridUnit * 14, runnerColumns.width) Layout.maximumWidth: sideBar.width + mainRow.spacing + Math.max(units.gridUnit * 14, runnerColumns.width) Layout.minimumHeight: Math.max(((rootModel.count - rootModel.separatorCount) * rootList.itemHeight) + (rootModel.separatorCount * rootList.separatorHeight) + searchField.height + (2 * units.smallSpacing), sideBar.margins.top + sideBar.margins.bottom + favoriteApps.contentHeight + favoriteSystemActions.contentHeight + sidebarSeparator.height + (4 * units.smallSpacing)) Layout.maximumHeight: Math.max(((rootModel.count - rootModel.separatorCount) * rootList.itemHeight) + (rootModel.separatorCount * rootList.separatorHeight) + searchField.height + (2 * units.smallSpacing), sideBar.margins.top + sideBar.margins.bottom + favoriteApps.contentHeight + favoriteSystemActions.contentHeight + sidebarSeparator.height + (4 * units.smallSpacing)) signal appendSearchText(string text) function reset() { plasmoid.hideOnWindowDeactivate = true; rootList.currentIndex = -1; searchField.text = ""; searchField.focus = true; } Row { id: mainRow height: parent.height spacing: units.smallSpacing LayoutMirroring.enabled: ((plasmoid.location == PlasmaCore.Types.RightEdge) || (Qt.application.layoutDirection == Qt.RightToLeft)) PlasmaCore.FrameSvgItem { id: sideBar width: units.iconSizes.medium + margins.left + margins.right height: parent.height imagePath: "widgets/frame" prefix: "plain" SideBarSection { id: favoriteApps anchors.top: parent.top anchors.topMargin: sideBar.margins.top height: (sideBar.height - sideBar.margins.top - sideBar.margins.bottom - favoriteSystemActions.height - sidebarSeparator.height - (4 * units.smallSpacing)) model: globalFavorites states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteApps anchors.top: undefined anchors.bottom: parent.bottom } PropertyChanges { target: favoriteApps anchors.topMargin: undefined anchors.bottomMargin: sideBar.margins.bottom } }] Binding { target: globalFavorites property: "iconSize" value: units.iconSizes.medium } } PlasmaCore.SvgItem { id: sidebarSeparator anchors.bottom: favoriteSystemActions.top anchors.bottomMargin: (2 * units.smallSpacing) anchors.horizontalCenter: parent.horizontalCenter width: units.iconSizes.medium height: lineSvg.horLineHeight visible: favoriteApps.model.count && favoriteSystemActions.model.count svg: lineSvg elementId: "horizontal-line" states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: sidebarSeparator anchors.top: favoriteSystemActions.bottom anchors.bottom: undefined } PropertyChanges { target: sidebarSeparator anchors.topMargin: (2 * units.smallSpacing) anchors.bottomMargin: undefined } }] } SideBarSection { id: favoriteSystemActions anchors.bottom: parent.bottom anchors.bottomMargin: sideBar.margins.bottom model: systemFavorites states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteSystemActions anchors.top: parent.top anchors.bottom: undefined } PropertyChanges { target: favoriteSystemActions anchors.topMargin: sideBar.margins.top anchors.bottomMargin: undefined } }] } } ItemListView { id: rootList anchors.top: parent.top width: root.width - sideBar.width - mainRow.spacing height: ((rootModel.count - rootModel.separatorCount) * itemHeight) + (rootModel.separatorCount * separatorHeight) visible: (searchField.text == "") iconsEnabled: false model: rootModel onKeyNavigationAtListEnd: { searchField.focus = true; } states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: rootList anchors.top: undefined anchors.bottom: parent.bottom } }] Component.onCompleted: { rootList.exited.connect(root.reset); } } Row { id: runnerColumns height: parent.height signal focusChanged() visible: (searchField.text != "" && runnerModel.count > 0) Repeater { id: runnerColumnsRepeater model: runnerModel delegate: RunnerResultsList { id: runnerMatches onKeyNavigationAtListEnd: { searchField.focus = true; } onContainsMouseChanged: { if (containsMouse) { runnerMatches.focus = true; } } onFocusChanged: { if (focus) { runnerColumns.focusChanged(); } } function focusChanged() { if (!runnerMatches.focus && runnerMatches.currentIndex != -1) { runnerMatches.currentIndex = -1; } } Keys.onPressed: { var target = null; if (event.key == Qt.Key_Right) { var targets = new Array(); for (var i = index + 1; i < runnerModel.count; ++i) { targets[targets.length] = i; } for (var i = 0; i < index; ++i) { targets[targets.length] = i; } for (var i = 0; i < targets.length; ++i) { if (runnerModel.modelForRow(targets[i]).count) { target = runnerColumnsRepeater.itemAt(targets[i]); break; } } } else if (event.key == Qt.Key_Left) { var targets = new Array(); for (var i = index - 1; i >= 0; --i) { targets[targets.length] = i; } for (var i = runnerModel.count - 1; i > index; --i) { targets[targets.length] = i; } for (var i = 0; i < targets.length; ++i) { if (runnerModel.modelForRow(targets[i]).count) { target = runnerColumnsRepeater.itemAt(targets[i]); break; } } } if (target) { event.accepted = true; currentIndex = -1; target.currentIndex = 0; target.focus = true; } } Component.onCompleted: { runnerColumns.focusChanged.connect(focusChanged); } Component.onDestruction: { runnerColumns.focusChanged.disconnect(focusChanged); } } } } } PlasmaComponents.TextField { id: searchField anchors.bottom: mainRow.bottom anchors.left: parent.left anchors.leftMargin: sideBar.width + mainRow.spacing + units.smallSpacing - width: rootList.width - (2 * units.smallSpacing) + width: (units.gridUnit * 14) - (2 * units.smallSpacing) focus: true placeholderText: i18n("Search...") clearButtonShown: true onTextChanged: { runnerModel.query = text; } onFocusChanged: { if (focus) { // FIXME: Cleanup arbitration between rootList/runnerCols here and in Keys. if (rootList.visible) { rootList.currentIndex = -1; } if (runnerColumns.visible) { runnerColumnsRepeater.itemAt(0).currentIndex = -1; } } } states: [ State { name: "top" when: plasmoid.location == PlasmaCore.Types.TopEdge AnchorChanges { target: searchField anchors.top: mainRow.top anchors.bottom: undefined anchors.left: parent.left anchors.right: undefined } PropertyChanges { target: searchField anchors.leftMargin: sideBar.width + mainRow.spacing + units.smallSpacing anchors.rightMargin: undefined } }, State { name: "right" when: (plasmoid.location == PlasmaCore.Types.RightEdge || (plasmoid.location != PlasmaCore.Types.RightEdge && mainRow.LayoutMirroring.enabled)) AnchorChanges { target: searchField anchors.top: undefined anchors.bottom: mainRow.bottom anchors.left: undefined anchors.right: parent.right } PropertyChanges { target: searchField anchors.leftMargin: undefined anchors.rightMargin: sideBar.width + mainRow.spacing + units.smallSpacing } }] Keys.onPressed: { if (event.key == Qt.Key_Up) { if (rootList.visible) { rootList.showChildDialogs = false; rootList.currentIndex = rootList.model.count - 1; rootList.showChildDialogs = true; } if (runnerColumns.visible) { for (var i = 0; i < runnerModel.count; ++i) { if (runnerModel.modelForRow(i).count) { runnerColumnsRepeater.itemAt(i).currentIndex = runnerModel.modelForRow(i).count - 1; break; } } } } else if (event.key == Qt.Key_Down) { if (rootList.visible) { rootList.showChildDialogs = false; rootList.currentIndex = 0; rootList.showChildDialogs = true; } if (runnerColumns.visible) { for (var i = 0; i < runnerModel.count; ++i) { if (runnerModel.modelForRow(i).count) { runnerColumnsRepeater.itemAt(i).currentIndex = 0; break; } } } } else if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (runnerColumns.visible && runnerModel.modelForRow(0).count) { runnerModel.modelForRow(0).trigger(0, "", null); plasmoid.expanded = false; } } } function appendText(newText) { focus = true; text = text + newText; } } Keys.onPressed: { if (event.key == Qt.Key_Escape) { plasmoid.expanded = false; } } Component.onCompleted: { appendSearchText.connect(searchField.appendText); kicker.reset.connect(reset); windowSystem.hidden.connect(reset); } } diff --git a/applets/kicker/package/contents/ui/RunnerResultsList.qml b/applets/kicker/package/contents/ui/RunnerResultsList.qml index 33603f0e2..69b33fa6b 100644 --- a/applets/kicker/package/contents/ui/RunnerResultsList.qml +++ b/applets/kicker/package/contents/ui/RunnerResultsList.qml @@ -1,100 +1,101 @@ /*************************************************************************** * Copyright (C) 2013-2014 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents FocusScope { - width: rootList.width + vertLine.width + vertLine.anchors.leftMargin + width: runnerMatches.width + vertLine.width + vertLine.anchors.leftMargin + runnerMatches.anchors.leftMargin height: parent.height signal keyNavigationAtListEnd property alias currentIndex: runnerMatches.currentIndex property alias containsMouse: runnerMatches.containsMouse Accessible.name: header.text Accessible.role: Accessible.MenuItem PlasmaCore.SvgItem { id: vertLine anchors.left: parent.left - anchors.leftMargin: (index > 0 ) ? (2 * units.smallSpacing) : 0 + anchors.leftMargin: (index > 0 ) ? units.smallSpacing : 0 width: (index > 0 ) ? lineSvg.vertLineWidth : 0 height: parent.height visible: (index > 0) svg: lineSvg elementId: "vertical-line" } PlasmaComponents.Label { id: header anchors.left: vertLine.right width: runnerMatches.width height: runnerMatches.itemHeight horizontalAlignment: Text.AlignHCenter textFormat: Text.PlainText wrapMode: Text.NoWrap elide: Text.ElideRight font.weight: Font.Bold text: (runnerMatches.model != null) ? runnerMatches.model.name : "" } ItemListView { id: runnerMatches anchors.top: plasmoid.configuration.alignResultsToBottom ? undefined : header.bottom anchors.bottom: plasmoid.configuration.alignResultsToBottom ? parent.bottom : undefined anchors.bottomMargin: (index == 0 && anchors.bottom != undefined) ? searchField.height + (2 * units.smallSpacing) : undefined anchors.left: vertLine.right + anchors.leftMargin: (index > 0) ? units.smallSpacing : 0 height: Math.min(((index == 0) ? rootList.height : runnerColumns.height) - header.height, model.count * itemHeight) iconsEnabled: true keyNavigationWraps: (index != 0) resetOnExitDelay: 0 model: runnerModel.modelForRow(index) onModelChanged: { if (model == undefined || model == null) { enabled: false; visible: false; } } } Component.onCompleted: { runnerMatches.keyNavigationAtListEnd.connect(keyNavigationAtListEnd); } } diff --git a/applets/kicker/package/contents/ui/main.qml b/applets/kicker/package/contents/ui/main.qml index 689a598b0..168279faf 100644 --- a/applets/kicker/package/contents/ui/main.qml +++ b/applets/kicker/package/contents/ui/main.qml @@ -1,257 +1,257 @@ /*************************************************************************** * Copyright (C) 2014-2015 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.private.kicker 0.1 as Kicker Item { id: kicker anchors.fill: parent signal reset property bool isDash: (plasmoid.pluginName == "org.kde.plasma.kickerdash") Plasmoid.switchWidth: isDash ? undefined : Plasmoid.fullRepresentationItem.Layout.minimumWidth Plasmoid.switchHeight: isDash ? undefined : Plasmoid.fullRepresentationItem.Layout.minimumHeight // this is a bit of a hack to prevent Plasma from spawning a dialog on its own when we're Dash Plasmoid.preferredRepresentation: isDash ? Plasmoid.fullRepresentation : null Plasmoid.compactRepresentation: isDash ? null : compactRepresentation Plasmoid.fullRepresentation: isDash ? compactRepresentation : menuRepresentation property QtObject itemListDialogComponent: Qt.createComponent("ItemListDialog.qml"); property Item dragSource: null property QtObject globalFavorites: rootModel.favoritesModel property QtObject systemFavorites: rootModel.systemFavoritesModel onSystemFavoritesChanged: { systemFavorites.favorites = plasmoid.configuration.favoriteSystemActions; } function action_menuedit() { processRunner.runMenuEditor(); } function updateSvgMetrics() { lineSvg.horLineHeight = lineSvg.elementSize("horizontal-line").height; lineSvg.vertLineWidth = lineSvg.elementSize("vertical-line").width; } Component { id: compactRepresentation CompactRepresentation {} } Component { id: menuRepresentation MenuRepresentation {} } Kicker.RootModel { id: rootModel appNameFormat: plasmoid.configuration.appNameFormat flat: isDash ? true : plasmoid.configuration.limitDepth showSeparators: !isDash appletInterface: plasmoid showAllSubtree: isDash showRecentApps: plasmoid.configuration.showRecentApps showRecentDocs: plasmoid.configuration.showRecentDocs showRecentContacts: plasmoid.configuration.showRecentContacts onShowRecentAppsChanged: { plasmoid.configuration.showRecentApps = showRecentApps; } onShowRecentDocsChanged: { plasmoid.configuration.showRecentDocs = showRecentDocs; } onShowRecentContactsChanged: { plasmoid.configuration.showRecentContacts = showRecentContacts; } Component.onCompleted: { favoritesModel.favorites = plasmoid.configuration.favoriteApps; } } Connections { target: globalFavorites onFavoritesChanged: { plasmoid.configuration.favoriteApps = target.favorites; } } Connections { target: systemFavorites onFavoritesChanged: { plasmoid.configuration.favoriteSystemActions = target.favorites; } } Connections { target: plasmoid.configuration onFavoriteAppsChanged: { globalFavorites.favorites = plasmoid.configuration.favoriteApps; } onFavoriteSystemActionsChanged: { systemFavorites.favorites = plasmoid.configuration.favoriteSystemActions; } } Kicker.RunnerModel { id: runnerModel appletInterface: plasmoid favoritesModel: globalFavorites runners: { var runners = new Array("services"); if (isDash) { runners.push("desktopsessions"); } if (plasmoid.configuration.useExtraRunners) { - runners.concat(plasmoid.configuration.extraRunners); + runners = runners.concat(plasmoid.configuration.extraRunners); } return runners; } deleteWhenEmpty: isDash } Kicker.DragHelper { id: dragHelper dragIconSize: units.iconSizes.medium } Kicker.ProcessRunner { id: processRunner; } Kicker.WindowSystem { id: windowSystem; } PlasmaCore.FrameSvgItem { id : highlightItemSvg visible: false imagePath: "widgets/viewitem" prefix: "hover" } PlasmaCore.FrameSvgItem { id : listItemSvg visible: false imagePath: "widgets/listitem" prefix: "normal" } PlasmaCore.Svg { id: arrows imagePath: "widgets/arrows" size: "16x16" } PlasmaCore.Svg { id: lineSvg imagePath: "widgets/line" property int horLineHeight property int vertLineWidth } PlasmaComponents.Label { id: toolTipDelegate width: contentWidth height: contentHeight property Item toolTip text: (toolTip != null) ? toolTip.text : "" } Timer { id: justOpenedTimer repeat: false interval: 600 } Connections { target: plasmoid onExpandedChanged: { if (expanded) { windowSystem.monitorWindowVisibility(plasmoid.fullRepresentationItem); justOpenedTimer.start(); } else { kicker.reset(); } } } function resetDragSource() { dragSource = null; } function enableHideOnWindowDeactivate() { plasmoid.hideOnWindowDeactivate = true; } Component.onCompleted: { windowSystem.focusOut.connect(enableHideOnWindowDeactivate); plasmoid.hideOnWindowDeactivate = true; plasmoid.setAction("menuedit", i18n("Edit Applications...")); updateSvgMetrics(); theme.themeChanged.connect(updateSvgMetrics); rootModel.refreshed.connect(reset); dragHelper.dropped.connect(resetDragSource); } }