Warning, /plasma/kdeplasma-addons/applets/quicklaunch/package/contents/ui/main.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 David Rosca <nowrep@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 import QtQuick 2.2
0008 import QtQuick.Layouts 1.0
0009 import org.kde.plasma.plasmoid 2.0
0010 import org.kde.plasma.core as PlasmaCore
0011 import org.kde.kirigami 2.20 as Kirigami
0012 import org.kde.plasma.components 3.0 as PlasmaComponents3
0013 import org.kde.draganddrop 2.0 as DragAndDrop
0014 import org.kde.plasma.private.quicklaunch 1.0
0015 
0016 import "layout.js" as LayoutManager
0017 
0018 PlasmoidItem {
0019     id: root
0020 
0021     readonly property int maxSectionCount: plasmoid.configuration.maxSectionCount
0022     readonly property bool showLauncherNames : plasmoid.configuration.showLauncherNames
0023     readonly property bool enablePopup : plasmoid.configuration.enablePopup
0024     readonly property string title : plasmoid.formFactor == PlasmaCore.Types.Planar ? plasmoid.configuration.title : ""
0025     readonly property bool vertical : plasmoid.formFactor == PlasmaCore.Types.Vertical || (plasmoid.formFactor == PlasmaCore.Types.Planar && height > width)
0026     readonly property bool horizontal : plasmoid.formFactor == PlasmaCore.Types.Horizontal
0027     property bool dragging : false
0028 
0029     Layout.minimumWidth: LayoutManager.minimumWidth()
0030     Layout.minimumHeight: LayoutManager.minimumHeight()
0031     Layout.preferredWidth: LayoutManager.preferredWidth()
0032     Layout.preferredHeight: LayoutManager.preferredHeight()
0033 
0034     preferredRepresentation: fullRepresentation
0035     Plasmoid.backgroundHints: PlasmaCore.Types.DefaultBackground | PlasmaCore.Types.ConfigurableBackground
0036 
0037     Item {
0038         anchors.fill: parent
0039 
0040         DragAndDrop.DropArea {
0041             anchors.fill: parent
0042             preventStealing: true
0043             enabled: !plasmoid.immutable
0044 
0045             onDragEnter: {
0046                 if (event.mimeData.hasUrls) {
0047                     dragging = true;
0048                 } else {
0049                     event.ignore();
0050                 }
0051             }
0052 
0053             onDragMove: {
0054                 var index = grid.indexAt(event.x, event.y);
0055 
0056                 if (isInternalDrop(event)) {
0057                     launcherModel.moveUrl(event.mimeData.source.itemIndex, index);
0058                 } else {
0059                     launcherModel.showDropMarker(index);
0060                 }
0061 
0062                 popup.visible = root.childAt(event.x, event.y) == popupArrow;
0063             }
0064 
0065             onDragLeave: {
0066                 dragging = false;
0067                 launcherModel.clearDropMarker();
0068             }
0069 
0070             onDrop: {
0071                 dragging = false;
0072                 launcherModel.clearDropMarker();
0073 
0074                 if (isInternalDrop(event)) {
0075                     event.accept(Qt.IgnoreAction);
0076                     saveConfiguration();
0077                 } else {
0078                     var index = grid.indexAt(event.x, event.y);
0079                     launcherModel.insertUrls(index == -1 ? launcherModel.count : index, event.mimeData.urls);
0080                     event.accept(event.proposedAction);
0081                 }
0082             }
0083         }
0084 
0085         PlasmaComponents3.Label {
0086             id: titleLabel
0087 
0088             anchors {
0089                 top: parent.top
0090                 left: parent.left
0091                 right: parent.right
0092             }
0093 
0094             height: Kirigami.Units.iconSizes.sizeForLabels
0095             horizontalAlignment: Text.AlignHCenter
0096             verticalAlignment: Text.AlignTop
0097             elide: Text.ElideMiddle
0098             text: title
0099             textFormat: Text.PlainText
0100         }
0101 
0102         Item {
0103             id: launcher
0104 
0105             anchors {
0106                 top: title.length ? titleLabel.bottom : parent.top
0107                 left: parent.left
0108                 right: !vertical && popupArrow.visible ? popupArrow.left : parent.right
0109                 bottom: vertical && popupArrow.visible ? popupArrow.top : parent.bottom
0110             }
0111 
0112             GridView {
0113                 id: grid
0114                 anchors.fill: parent
0115                 interactive: false
0116                 flow: horizontal ? GridView.FlowTopToBottom : GridView.FlowLeftToRight
0117                 cellWidth: LayoutManager.preferredCellWidth()
0118                 cellHeight: LayoutManager.preferredCellHeight()
0119                 visible: count
0120 
0121                 model: UrlModel {
0122                     id: launcherModel
0123                 }
0124 
0125                 delegate: IconItem { }
0126 
0127                 function moveItemToPopup(iconItem, url) {
0128                     if (!popupArrow.visible) {
0129                         return;
0130                     }
0131 
0132                     popup.visible = true;
0133                     popup.mainItem.popupModel.insertUrl(popup.mainItem.popupModel.count, url);
0134                     popup.mainItem.listView.currentIndex = popup.mainItem.popupModel.count - 1;
0135                     iconItem.removeLauncher();
0136                 }
0137             }
0138 
0139             Kirigami.Icon {
0140                 id: defaultIcon
0141                 anchors.fill: parent
0142                 source: "fork"
0143                 visible: !grid.visible
0144 
0145                 PlasmaCore.ToolTipArea {
0146                     anchors.fill: parent
0147                     mainText: i18n("Quicklaunch")
0148                     subText: i18nc("@info", "Add launchers by Drag and Drop or by using the context menu.")
0149                     location: Plasmoid.location
0150                 }
0151             }
0152         }
0153 
0154         PlasmaCore.Dialog {
0155             id: popup
0156             type: PlasmaCore.Dialog.PopupMenu
0157             flags: Qt.WindowStaysOnTopHint
0158             hideOnWindowDeactivate: true
0159             location: plasmoid.location
0160             visualParent: vertical ? popupArrow : root
0161 
0162             mainItem: Popup {
0163                 Keys.onEscapePressed: popup.visible = false
0164             }
0165         }
0166 
0167         PlasmaCore.ToolTipArea {
0168             id: popupArrow
0169             visible: enablePopup
0170             location: Plasmoid.location
0171 
0172             anchors {
0173                 top: vertical ? undefined : parent.top
0174                 right: parent.right
0175                 bottom: parent.bottom
0176             }
0177 
0178             subText: popup.visible ? i18n("Hide icons") : i18n("Show hidden icons")
0179 
0180             MouseArea {
0181                 id: arrowMouseArea
0182                 anchors.fill: parent
0183 
0184                 activeFocusOnTab: parent.visible
0185 
0186                 Keys.onPressed: {
0187                     switch (event.key) {
0188                     case Qt.Key_Space:
0189                     case Qt.Key_Enter:
0190                     case Qt.Key_Return:
0191                     case Qt.Key_Select:
0192                         arrowMouseArea.clicked(null);
0193                         break;
0194                     }
0195                 }
0196                 Accessible.name: parent.subText
0197                 Accessible.role: Accessible.Button
0198 
0199                 onClicked: {
0200                     popup.visible = !popup.visible
0201                 }
0202 
0203                 Kirigami.Icon {
0204                     anchors.fill: parent
0205 
0206                     rotation: popup.visible ? 180 : 0
0207                     Behavior on rotation {
0208                         RotationAnimation {
0209                             duration: Kirigami.Units.shortDuration * 3
0210                         }
0211                     }
0212 
0213                     source: {
0214                         if (plasmoid.location == PlasmaCore.Types.TopEdge) {
0215                             return "arrow-down";
0216                         } else if (plasmoid.location == PlasmaCore.Types.LeftEdge) {
0217                             return "arrow-right";
0218                         } else if (plasmoid.location == PlasmaCore.Types.RightEdge) {
0219                             return "arrow-left";
0220                         } else if (vertical) {
0221                             return "arrow-right";
0222                         } else {
0223                             return "arrow-up";
0224                         }
0225                     }
0226                 }
0227             }
0228         }
0229     }
0230 
0231     Logic {
0232         id: logic
0233 
0234         onLauncherAdded: {
0235             var m = isPopup ? popup.mainItem.popupModel : launcherModel;
0236             m.appendUrl(url);
0237         }
0238 
0239         onLauncherEdited: {
0240             var m = isPopup ? popup.mainItem.popupModel : launcherModel;
0241             m.changeUrl(index, url);
0242         }
0243     }
0244 
0245     // States to fix binding loop with enabled popup
0246     states: [
0247         State {
0248             name: "normal"
0249             when: !vertical
0250 
0251             PropertyChanges {
0252                 target: popupArrow
0253                 width: Kirigami.Units.iconSizes.smallMedium
0254                 height: root.height
0255             }
0256         },
0257 
0258         State {
0259             name: "vertical"
0260             when: vertical
0261 
0262             PropertyChanges {
0263                 target: popupArrow
0264                 width: root.width
0265                 height: Kirigami.Units.iconSizes.smallMedium
0266             }
0267         }
0268     ]
0269 
0270     Connections {
0271         target: plasmoid.configuration
0272        function onLauncherUrlsChanged() {
0273             launcherModel.urlsChanged.disconnect(saveConfiguration);
0274             launcherModel.setUrls(plasmoid.configuration.launcherUrls);
0275             launcherModel.urlsChanged.connect(saveConfiguration);
0276         }
0277     }
0278 
0279     Plasmoid.contextualActions: [
0280         PlasmaCore.Action {
0281             text: i18nc("@action", "Add Launcher…")
0282             icon.name: "list-add"
0283             onTriggered: logic.addLauncher()
0284         }
0285     ]
0286 
0287     Component.onCompleted: {
0288         launcherModel.setUrls(plasmoid.configuration.launcherUrls);
0289         launcherModel.urlsChanged.connect(saveConfiguration);
0290     }
0291 
0292     function saveConfiguration()
0293     {
0294         if (!dragging) {
0295             plasmoid.configuration.launcherUrls = launcherModel.urls();
0296         }
0297     }
0298 
0299     function isInternalDrop(event)
0300     {
0301         return event.mimeData.source
0302             && event.mimeData.source.GridView
0303             && event.mimeData.source.GridView.view == grid;
0304     }
0305 }