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 }