Warning, /plasma/latte-dock/plasmoid/package/contents/ui/abilities/Launchers.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 import QtQuick 2.0
0007 
0008 import org.kde.plasma.plasmoid 2.0
0009 
0010 import org.kde.latte.core 0.2 as LatteCore
0011 
0012 import "launchers" as LaunchersPart
0013 
0014 Item {
0015     id: _launchers
0016     readonly property bool isActive: bridge !== null
0017 
0018     signal launcherChanged(string launcherUrl);
0019     signal launcherRemoved(string launcherUrl);
0020 
0021     //! triggered just before action happens. They are used mostly for animation purposes
0022     signal launcherInAdding(string launcherUrl);
0023     signal launcherInRemoving(string launcherUrl);
0024     signal launcherInMoving(string launcherUrl, int pos);
0025 
0026     signal disabledIsStealingDroppedLaunchers();
0027 
0028     property bool isStealingDroppedLaunchers: false
0029     property bool isShowingAddLaunchersMessage: false
0030 
0031     property bool __isLoadedDuringViewStartup: false
0032 
0033     property string appletIndex: bridge && bridge.indexer ? String(bridge.indexer.appletIndex) : ""
0034     property int group: LatteCore.Types.UniqueLaunchers
0035     property string groupId: view && group === LatteCore.Types.UniqueLaunchers ? String(view.groupId) + "#" + appletIndex : ""
0036 
0037     property Item bridge: null
0038     property Item layout: null
0039     property Item view: null
0040     property QtObject tasksModel: null
0041 
0042     readonly property LaunchersPart.Syncer syncer: LaunchersPart.Syncer{}
0043     readonly property LaunchersPart.Validator validator: LaunchersPart.Validator{}
0044 
0045     readonly property string _NULLACTIVITYID_: "00000000-0000-0000-0000-000000000000"
0046 
0047     function inUniqueGroup() {
0048         return group === LatteCore.Types.UniqueLaunchers;
0049     }
0050 
0051     function inLayoutGroup() {
0052         return group === LatteCore.Types.LayoutLaunchers;
0053     }
0054 
0055     function inGlobalGroup() {
0056         return group === LatteCore.Types.GlobalLaunchers;
0057     }
0058 
0059     function isSeparator(launcher){
0060         return (launcher.indexOf("latte-separator")!==-1 && launcher.indexOf(".desktop")!==1);
0061     }
0062 
0063     function separatorExists(separator){
0064         return (_launchers.tasksModel.launcherPosition(separator)>=0);
0065     }
0066 
0067     function freeAvailableSeparatorName() {
0068         var available = false;
0069         var no = 1;
0070 
0071         var separatorName = "";
0072 
0073         while(!available && no<20) {
0074             separatorName = "file:///latte-separator"+no+".desktop";
0075             if (separatorExists(separatorName)) {
0076                 no = no + 1;
0077             } else {
0078                 available = true;
0079             }
0080         }
0081 
0082         if (available) {
0083             return separatorName;
0084         } else {
0085             return "";
0086         }
0087     }
0088 
0089     function hasLauncher(url) {
0090         return _launchers.tasksModel.launcherPosition(url) >= 0;
0091     }
0092 
0093     function addLauncher(launcherUrl) {
0094         if (bridge) {
0095             bridge.launchers.host.addSyncedLauncher(syncer.clientId,
0096                                                     launchers.group,
0097                                                     launchers.groupId,
0098                                                     launcherUrl);
0099         } else {
0100             _launchers.tasksModel.requestAddLauncher(launcherUrl);
0101             _launchers.launcherChanged(launcherUrl);
0102         }
0103     }
0104 
0105     function addDroppedLauncher(launcherUrl) {
0106         //workaround to protect in case the launcher contains the iconData
0107         var pos = launcherUrl.indexOf("?iconData=");
0108 
0109         if (pos>0) {
0110             launcherUrl = launcherUrl.substring( 0, launcherUrl.indexOf("?iconData=" ) );
0111         }
0112 
0113         var path = launcherUrl;
0114         var filename = path.split("/").pop();
0115         _launchers.launcherInAdding(filename);
0116 
0117         tasksModel.requestAddLauncher(launcherUrl);
0118         launchers.launcherChanged(launcherUrl);
0119         tasksModel.syncLaunchers();
0120     }
0121 
0122     function addDroppedLaunchers(urls) {
0123         //! inform synced docks for new dropped launchers
0124         if (bridge) {
0125             bridge.launchers.host.addDroppedLaunchers(syncer.clientId,
0126                                                       launchers.group,
0127                                                       launchers.groupId,
0128                                                       urls);
0129         } else {
0130             urls.forEach(function (item) {
0131                 addDroppedLauncher(item);
0132             });
0133         }
0134     }
0135 
0136     function addInternalSeparatorAtPos(pos) {
0137         var separatorName = freeAvailableSeparatorName();
0138 
0139         if (separatorName !== "") {
0140             _launchers.launcherInMoving(separatorName, Math.max(0,pos));
0141             addLauncher(separatorName);
0142         }
0143     }
0144 
0145     function removeInternalSeparatorAtPos(pos) {
0146         var item = childAtLayoutIndex(pos);
0147 
0148         if (item.isSeparator) {
0149             removeLauncher(item.launcherUrl);
0150         }
0151     }
0152 
0153     function removeLauncher(launcherUrl) {
0154         if (bridge) {
0155             bridge.launchers.host.removeSyncedLauncher(syncer.clientId,
0156                                                        launchers.group,
0157                                                        launchers.groupId,
0158                                                        launcherUrl);
0159         } else {
0160             _launchers.launcherInRemoving(launcherUrl);
0161             _launchers.tasksModel.requestRemoveLauncher(launcherUrl);
0162             _launchers.launcherRemoved(launcherUrl);
0163         }
0164     }
0165 
0166     function addLauncherToActivity(launcherUrl, activityId) {
0167         if (bridge) {
0168             bridge.launchers.host.addSyncedLauncherToActivity(syncer.clientId,
0169                                                               launchers.group,
0170                                                               launchers.groupId,
0171                                                               launcherUrl,
0172                                                               activityId);
0173         } else {
0174             if (activityId !== activityInfo.currentActivity && isOnAllActivities(launcherUrl)) {
0175                 _launchers.launcherInRemoving(launcherUrl);
0176             }
0177 
0178             _launchers.tasksModel.requestAddLauncherToActivity(launcherUrl, activityId);
0179             _launchers.launcherChanged(launcherUrl);
0180         }
0181     }
0182 
0183     function removeLauncherFromActivity(launcherUrl, activityId) {
0184         if (bridge) {
0185             bridge.launchers.host.removeSyncedLauncherFromActivity(syncer.clientId,
0186                                                                    launchers.group,
0187                                                                    launchers.groupId,
0188                                                                    launcherUrl,
0189                                                                    activityId);
0190         } else {
0191             if (activityId === activityInfo.currentActivity) {
0192                 _launchers.launcherInRemoving(launcherUrl);
0193             }
0194             _launchers.tasksModel.requestRemoveLauncherFromActivity(launcherUrl, activityId);
0195             _launchers.launcherChanged(launcherUrl);
0196         }
0197     }
0198 
0199     function validateSyncedLaunchersOrder() {
0200         if (bridge) {
0201             bridge.launchers.host.validateSyncedLaunchersOrder(syncer.clientId,
0202                                                                launchers.group,
0203                                                                launchers.groupId,
0204                                                                currentShownLauncherList());
0205         } else {
0206             /*validator.stop();
0207             validator.launchers = orderedLaunchers;
0208             validator.start();*/
0209         }
0210     }
0211 
0212     function inCurrentActivity(launcherUrl) {
0213         if (!hasLauncher(launcherUrl)) {
0214             return false;
0215         }
0216 
0217         var activities = _launchers.tasksModel.launcherActivities(launcherUrl);
0218 
0219         if (activities.length ===0
0220                 || activities.indexOf(_NULLACTIVITYID_) >= 0
0221                 || activities.indexOf(activityInfo.currentActivity) >= 0) {
0222             return true;
0223         }
0224 
0225         return false;
0226     }
0227 
0228     function isOnAllActivities(launcherUrl) {
0229         var activities = _launchers.tasksModel.launcherActivities(launcherUrl);
0230         return (activities.indexOf(_NULLACTIVITYID_) >= 0)
0231     }
0232 
0233     function childAtLayoutIndex(position) {
0234         var tasks = layout.children;
0235 
0236         if (position < 0) {
0237             return;
0238         }
0239 
0240         for(var i=0; i<tasks.length; ++i){
0241             var task = tasks[i];
0242 
0243             if (task.lastValidIndex === position
0244                     || (task.lastValidIndex === -1 && task.itemIndex === position )) {
0245                 return task;
0246             }
0247         }
0248 
0249         return undefined;
0250     }
0251 
0252     function indexOfLayoutLauncher(url) {
0253         var tasks = layout.children;
0254 
0255         for(var i=0; i<tasks.length; ++i){
0256             var task = tasks[i];
0257 
0258             if (task && (task.launcherUrl===url)) {
0259                 return task.itemIndex;
0260             }
0261         }
0262 
0263         return -1;
0264     }
0265 
0266     function currentShownLauncherList() {
0267         var launch = [];
0268 
0269         var tasks = _launchers.layout.children;
0270         for(var i=0; i<tasks.length; ++i){
0271             var task = _launchers.childAtLayoutIndex(i);
0272 
0273             if (task!==undefined && task.launcherUrl!=="" && _launchers.inCurrentActivity(task.launcherUrl)) {
0274                 launch.push(task.launcherUrl);
0275             }
0276         }
0277 
0278         return launch;
0279     }
0280 
0281 
0282     function currentStoredLauncherList() {
0283         var launch = [];
0284         var launchersList = [];
0285 
0286         if (bridge && bridge.launchers.host.isReady) {
0287             if (!_launchers.inUniqueGroup()) {
0288                 if (_launchers.inLayoutGroup()) {
0289                     launchersList = bridge.launchers.host.layoutLaunchers;
0290                 } else if (_launchers.inGlobalGroup()) {
0291                     launchersList = bridge.launchers.host.universalLaunchers;
0292                 }
0293             }
0294         } else {
0295             launchersList = plasmoid.configuration.launchers59;
0296         }
0297 
0298 
0299         for(var i=0; i<launchersList.length; ++i){
0300             var launcherRecord = launchersList[i];
0301 
0302             if (launcherRecord.indexOf("[") === -1) {
0303                 //global launcher
0304                 launch.push(launcherRecord);
0305             } else {
0306                 //launcher assigned to activities
0307                 var end = launcherRecord.indexOf("\n");
0308                 var explicitLauncher = launcherRecord.substring(end+1,launcherRecord.length);
0309                 if (explicitLauncher !== "" && launcherRecord.indexOf(activityInfo.currentActivity) > -1) {
0310                     launch.push(explicitLauncher);
0311                 }
0312             }
0313         }
0314 
0315         return launch;
0316     }
0317 
0318     function importLauncherListInModel() {
0319         if (bridge && bridge.launchers.host.isReady && !inUniqueGroup()) {
0320             if (inLayoutGroup()) {
0321                 console.log("Tasks: Applying LAYOUT Launchers List...");
0322                 tasksModel.launcherList = bridge.launchers.host.layoutLaunchers;
0323             } else if (inGlobalGroup()) {
0324                 console.log("Tasks: Applying GLOBAL Launchers List...");
0325                 tasksModel.launcherList = bridge.launchers.host.universalLaunchers;
0326             }
0327         } else {
0328             console.log("Tasks: Applying UNIQUE Launchers List...");
0329             tasksModel.launcherList = plasmoid.configuration.launchers59;
0330         }
0331     }
0332 
0333 
0334     //! Connections
0335     Component.onCompleted: {
0336         if (isActive) {
0337             bridge.launchers.client = _launchers;
0338         }
0339     }
0340 
0341     Component.onDestruction: {
0342         if (isActive) {
0343             bridge.launchers.client = null;
0344         }
0345     }
0346 
0347     onIsActiveChanged: {
0348         if (isActive) {
0349             bridge.launchers.client = _launchers;
0350         }
0351     }
0352 
0353     onGroupChanged:{
0354         if(appletAbilities.myView.isReady) {
0355             _launchers.importLauncherListInModel();
0356         }
0357     }
0358 
0359     Connections {
0360         target: appletAbilities.myView
0361         onIsReadyChanged: {
0362             if(appletAbilities.myView.isReady) {
0363                 if (!_launchers.inUniqueGroup()) {
0364                     _launchers.importLauncherListInModel();
0365                 }
0366             }
0367         }
0368     }
0369 
0370     Connections {
0371         target: bridge ? bridge.launchers.host : null
0372         onIsReadyChanged: {
0373             if (bridge && bridge.launchers.host.isReady && !_launchers.__isLoadedDuringViewStartup) {
0374                 _launchers.__isLoadedDuringViewStartup = true;
0375                 _launchers.importLauncherListInModel();
0376             }
0377         }
0378     }
0379 
0380     Connections {
0381         target: _launchers.tasksModel
0382         onLauncherListChanged: {
0383             if (bridge && bridge.launchers.host.isReady) {
0384                 if (!_launchers.inUniqueGroup()) {
0385                     if (_launchers.inLayoutGroup()) {
0386                         bridge.launchers.host.setLayoutLaunchers(_launchers.tasksModel.launcherList);
0387                     } else if (_launchers.inGlobalGroup()) {
0388                         bridge.launchers.host.setUniversalLaunchers(_launchers.tasksModel.launcherList);
0389                     }
0390                 } else {
0391                     plasmoid.configuration.launchers59 = _launchers.tasksModel.launcherList;
0392                 }
0393 
0394                 if (inDraggingPhase) {
0395                     _launchers.validateSyncedLaunchersOrder();
0396                 }
0397             } else if (!appletAbilities.myView.isReady) {
0398                 // This way we make sure that a delayed view.layout initialization does not store irrelevant launchers from different
0399                 // group to UNIQUE launchers group
0400                 plasmoid.configuration.launchers59 = _launchers.tasksModel.launcherList;
0401             }
0402         }
0403     }
0404 }