~ubuntu-branches/ubuntu/maverick/cairo-dock/maverick

1.1.10 by Matthieu Baerts (matttbe)
Import upstream version 2.2.0~0beta4
1
/**
2
* This file is a part of the Cairo-Dock project
3
*
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail    : see the 'copyright' file.
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include <math.h>
21
#include <string.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
25
#include <gtk/gtk.h>
26
#include <glib/gstdio.h>
27
28
#include <cairo.h>
29
30
#ifdef HAVE_GLITZ
31
#include <gdk/gdkx.h>
32
#include <glitz-glx.h>
33
#include <cairo-glitz.h>
34
#endif
35
36
#include "cairo-dock-draw.h"
37
#include "cairo-dock-draw-opengl.h"
38
#include "cairo-dock-animations.h"
39
#include "cairo-dock-config.h"
40
#include "cairo-dock-modules.h"
41
#include "cairo-dock-callbacks.h"
42
#include "cairo-dock-dock-factory.h"
43
#include "cairo-dock-dock-facility.h"
44
#include "cairo-dock-dialog-manager.h"
45
#include "cairo-dock-applications-manager.h"
46
#include "cairo-dock-application-facility.h"
47
#include "cairo-dock-separator-factory.h"
48
#include "cairo-dock-log.h"
49
#include "cairo-dock-dock-manager.h"
50
#include "cairo-dock-file-manager.h"
51
#include "cairo-dock-class-manager.h"
52
#include "cairo-dock-internal-icons.h"
53
#include "cairo-dock-internal-labels.h"
54
#include "cairo-dock-internal-background.h"
55
#include "cairo-dock-internal-indicators.h"
56
#include "cairo-dock-notifications.h"
57
#include "cairo-dock-load.h"
58
#include "cairo-dock-container.h"
59
#include "cairo-dock-emblem.h"
60
#include "cairo-dock-desktop-file-factory.h"
61
#include "cairo-dock-gui-manager.h"
62
#include "cairo-dock-X-manager.h"
63
#include "cairo-dock-icons.h"
64
65
int g_iNbNonStickyLaunchers = 0;
66
67
extern CairoDockDesktopGeometry g_desktopGeometry;
68
extern gchar *g_cCurrentLaunchersPath;
69
extern gboolean g_bUseOpenGL;
70
71
static GList *s_DetachedLaunchersList = NULL;
72
73
74
static void _cairo_dock_free_icon_buffers (Icon *icon)
75
{
76
	if (icon == NULL)
77
		return ;
78
	
79
	g_free (icon->cDesktopFileName);
80
	g_free (icon->cFileName);
81
	g_free (icon->cName);
82
	g_free (icon->cInitialName);
83
	g_free (icon->cCommand);
84
	g_free (icon->cWorkingDirectory);
85
	g_free (icon->cBaseURI);
86
	g_free (icon->cParentDockName);  // on ne liberera pas le sous-dock ici sous peine de se mordre la queue, donc il faut l'avoir fait avant.
87
	g_free (icon->cClass);
88
	g_free (icon->cQuickInfo);
89
	g_free (icon->cLastAttentionDemand);
90
	
91
	cairo_surface_destroy (icon->pIconBuffer);
92
	cairo_surface_destroy (icon->pReflectionBuffer);
93
	cairo_surface_destroy (icon->pTextBuffer);
94
	cairo_surface_destroy (icon->pQuickInfoBuffer);
95
	
96
	if (icon->iIconTexture != 0)
97
		_cairo_dock_delete_texture (icon->iIconTexture);
98
	if (icon->iLabelTexture != 0)
99
		_cairo_dock_delete_texture (icon->iLabelTexture);
100
	if (icon->iQuickInfoTexture != 0)
101
		_cairo_dock_delete_texture (icon->iQuickInfoTexture);
102
}
103
void cairo_dock_free_icon (Icon *icon)
104
{
105
	if (icon == NULL)
106
		return ;
107
	cd_debug ("%s (%s , %s)", __func__, icon->cName, icon->cClass);
108
	
109
	cairo_dock_remove_dialog_if_any (icon);
110
	if (icon->iSidRedrawSubdockContent != 0)
111
		g_source_remove (icon->iSidRedrawSubdockContent);
112
	if (icon->iSidLoadImage != 0)
113
		g_source_remove (icon->iSidLoadImage);
114
	if (icon->cBaseURI != NULL)
115
		cairo_dock_fm_remove_monitor_full (icon->cBaseURI, (icon->pSubDock != NULL), (icon->iVolumeID != 0 ? icon->cCommand : NULL));
116
	if (CAIRO_DOCK_IS_NORMAL_APPLI (icon))
117
		cairo_dock_unregister_appli (icon);
118
	else if (icon->cClass != NULL)  // c'est un inhibiteur.
119
		cairo_dock_deinhibate_class (icon->cClass, icon);
120
	if (icon->pModuleInstance != NULL)
121
		cairo_dock_deinstanciate_module (icon->pModuleInstance);
122
	cairo_dock_notify (CAIRO_DOCK_STOP_ICON, icon);
123
	cairo_dock_remove_transition_on_icon (icon);
124
	
125
	if (icon->iSpecificDesktop != 0)
126
	{
127
		g_iNbNonStickyLaunchers --;
128
		s_DetachedLaunchersList = g_list_remove(s_DetachedLaunchersList, icon);
129
	}
130
	
131
	cairo_dock_free_notification_table (icon->pNotificationsTab);
132
	_cairo_dock_free_icon_buffers (icon);
133
	cd_debug ("icon freeed");
134
	g_free (icon);
135
}
136
137
CairoDockIconType cairo_dock_get_icon_type (Icon *icon)
138
{
139
	int iType;
140
	if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
141
		iType = CAIRO_DOCK_SEPARATOR12;
142
	else
143
		iType = (icon->iType < CAIRO_DOCK_NB_TYPES ? icon->iType : icon->iType & 1);
144
	
145
	return iType;
146
	/**if (CAIRO_DOCK_IS_APPLI (icon))
147
		return CAIRO_DOCK_APPLI;
148
	else if (CAIRO_DOCK_IS_APPLET (icon))
149
		return CAIRO_DOCK_APPLET;
150
	else if (CAIRO_DOCK_IS_SEPARATOR (icon))
151
		return CAIRO_DOCK_SEPARATOR12;
152
	else
153
		return CAIRO_DOCK_LAUNCHER;*/
154
}
155
156
157
int cairo_dock_compare_icons_order (Icon *icon1, Icon *icon2)
158
{
159
	int iOrder1 = cairo_dock_get_icon_order (icon1);
160
	int iOrder2 = cairo_dock_get_icon_order (icon2);
161
	if (iOrder1 < iOrder2)
162
		return -1;
163
	else if (iOrder1 > iOrder2)
164
		return 1;
165
	else
166
	{
167
		if (icon1->fOrder < icon2->fOrder)
168
			return -1;
169
		else if (icon1->fOrder > icon2->fOrder)
170
			return 1;
171
		else
172
			return 0;
173
	}
174
}
175
int cairo_dock_compare_icons_name (Icon *icon1, Icon *icon2)
176
{
177
	int iOrder1 = cairo_dock_get_icon_order (icon1);
178
	int iOrder2 = cairo_dock_get_icon_order (icon2);
179
	if (iOrder1 < iOrder2)
180
		return -1;
181
	else if (iOrder1 > iOrder2)
182
		return 1;
183
	
184
	if (icon1->cName == NULL)
185
		return -1;
186
	if (icon2->cName == NULL)
187
		return 1;
188
	gchar *cURI_1 = g_ascii_strdown (icon1->cName, -1);
189
	gchar *cURI_2 = g_ascii_strdown (icon2->cName, -1);
190
	int iOrder = strcmp (cURI_1, cURI_2);
191
	g_free (cURI_1);
192
	g_free (cURI_2);
193
	return iOrder;
194
}
195
196
int cairo_dock_compare_icons_extension (Icon *icon1, Icon *icon2)
197
{
198
	int iOrder1 = cairo_dock_get_icon_order (icon1);
199
	int iOrder2 = cairo_dock_get_icon_order (icon2);
200
	if (iOrder1 < iOrder2)
201
		return -1;
202
	else if (iOrder1 > iOrder2)
203
		return 1;
204
	
205
	if (icon1->cBaseURI == NULL)
206
		return -1;
207
	if (icon2->cBaseURI == NULL)
208
		return 1;
209
	
210
	gchar *ext1 = strrchr (icon1->cBaseURI, '.');
211
	gchar *ext2 = strrchr (icon2->cBaseURI, '.');
212
	if (ext1 == NULL)
213
		return -1;
214
	if (ext2 == NULL)
215
		return 1;
216
	
217
	ext1 = g_ascii_strdown (ext1+1, -1);
218
	ext2 = g_ascii_strdown (ext2+1, -1);
219
	
220
	int iOrder = strcmp (ext1, ext2);
221
	g_free (ext1);
222
	g_free (ext2);
223
	return iOrder;
224
}
225
226
GList *cairo_dock_sort_icons_by_order (GList *pIconList)
227
{
228
	return g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_order);
229
}
230
231
GList *cairo_dock_sort_icons_by_name (GList *pIconList)
232
{
233
	GList *pSortedIconList = g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_name);
234
	int iOrder = 0;
235
	Icon *icon;
236
	GList *ic;
237
	for (ic = pIconList; ic != NULL; ic = ic->next)
238
	{
239
		icon = ic->data;
240
		icon->fOrder = iOrder ++;
241
	}
242
	return pSortedIconList;
243
}
244
245
246
247
Icon* cairo_dock_get_first_icon (GList *pIconList)
248
{
249
	GList *pListHead = g_list_first(pIconList);
250
	return (pListHead != NULL ? pListHead->data : NULL);
251
}
252
253
Icon* cairo_dock_get_last_icon (GList *pIconList)
254
{
255
	GList *pListTail = g_list_last(pIconList);
256
	return (pListTail != NULL ? pListTail->data : NULL);
257
}
258
259
Icon *cairo_dock_get_first_drawn_icon (CairoDock *pDock)
260
{
261
	if (pDock->pFirstDrawnElement != NULL)
262
		return pDock->pFirstDrawnElement->data;
263
	else
264
		return cairo_dock_get_first_icon (pDock->icons);
265
}
266
267
Icon *cairo_dock_get_last_drawn_icon (CairoDock *pDock)
268
{
269
	if (pDock->pFirstDrawnElement != NULL)
270
	{
271
		if (pDock->pFirstDrawnElement->prev != NULL)
272
			return pDock->pFirstDrawnElement->prev->data;
273
		else
274
			return cairo_dock_get_last_icon (pDock->icons);
275
	}
276
	else
277
		return cairo_dock_get_last_icon (pDock->icons);;
278
}
279
280
Icon* cairo_dock_get_first_icon_of_group (GList *pIconList, CairoDockIconType iType)
281
{
282
	GList* ic;
283
	Icon *icon;
284
	for (ic = pIconList; ic != NULL; ic = ic->next)
285
	{
286
		icon = ic->data;
287
		if (icon->iType == iType)
288
			return icon;
289
	}
290
	return NULL;
291
}
292
Icon* cairo_dock_get_last_icon_of_group (GList *pIconList, CairoDockIconType iType)
293
{
294
	GList* ic;
295
	Icon *icon;
296
	for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
297
	{
298
		icon = ic->data;
299
		if (icon->iType == iType)
300
			return icon;
301
	}
302
	return NULL;
303
}
304
Icon* cairo_dock_get_first_icon_of_order (GList *pIconList, CairoDockIconType iType)
305
{
306
	CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
307
	GList* ic;
308
	Icon *icon;
309
	for (ic = pIconList; ic != NULL; ic = ic->next)
310
	{
311
		icon = ic->data;
312
		if (cairo_dock_get_icon_order (icon) == iGroupOrder)
313
			return icon;
314
	}
315
	return NULL;
316
}
317
Icon* cairo_dock_get_last_icon_of_order (GList *pIconList, CairoDockIconType iType)
318
{
319
	CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
320
	GList* ic;
321
	Icon *icon;
322
	for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
323
	{
324
		icon = ic->data;
325
		if (cairo_dock_get_icon_order (icon) == iGroupOrder)
326
			return icon;
327
	}
328
	return NULL;
329
}
330
Icon* cairo_dock_get_last_icon_until_order (GList *pIconList, CairoDockIconType iType)
331
{
332
	CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
333
	GList* ic;
334
	Icon *icon = NULL;
335
	for (ic = pIconList; ic != NULL; ic = ic->next)
336
	{
337
		icon = ic->data;
338
		if (cairo_dock_get_icon_order (icon) > iGroupOrder)
339
		{
340
			if (ic->prev != NULL)
341
				icon = ic->prev->data;
342
			else
343
				icon = NULL;
344
			break;
345
		}
346
	}
347
	return icon;
348
}
349
350
Icon* cairo_dock_get_pointed_icon (GList *pIconList)
351
{
352
	GList* ic;
353
	Icon *icon;
354
	for (ic = pIconList; ic != NULL; ic = ic->next)
355
	{
356
		icon = ic->data;
357
		if (icon->bPointed)
358
			return icon;
359
	}
360
	return NULL;
361
}
362
363
364
Icon *cairo_dock_get_next_icon (GList *pIconList, Icon *pIcon)
365
{
366
	GList* ic;
367
	Icon *icon;
368
	for (ic = pIconList; ic != NULL; ic = ic->next)
369
	{
370
		icon = ic->data;
371
		if (icon == pIcon)
372
		{
373
			if (ic->next != NULL)
374
				return ic->next->data;
375
			else
376
				return NULL;
377
		}
378
	}
379
	return NULL;
380
}
381
382
Icon *cairo_dock_get_previous_icon (GList *pIconList, Icon *pIcon)
383
{
384
	GList* ic;
385
	Icon *icon;
386
	for (ic = pIconList; ic != NULL; ic = ic->next)
387
	{
388
		icon = ic->data;
389
		if (icon == pIcon)
390
		{
391
			if (ic->prev != NULL)
392
				return ic->prev->data;
393
			else
394
				return NULL;
395
		}
396
	}
397
	return NULL;
398
}
399
400
Icon *cairo_dock_get_icon_with_command (GList *pIconList, const gchar *cCommand)
401
{
402
	g_return_val_if_fail (cCommand != NULL, NULL);
403
	GList* ic;
404
	Icon *icon;
405
	for (ic = pIconList; ic != NULL; ic = ic->next)
406
	{
407
		icon = ic->data;
408
		if (icon->cCommand != NULL && strncmp (icon->cCommand, cCommand, MIN (strlen (icon->cCommand), strlen (cCommand))) == 0)
409
			return icon;
410
	}
411
	return NULL;
412
}
413
414
Icon *cairo_dock_get_icon_with_base_uri (GList *pIconList, const gchar *cBaseURI)
415
{
416
	g_return_val_if_fail (cBaseURI != NULL, NULL);
417
	GList* ic;
418
	Icon *icon;
419
	for (ic = pIconList; ic != NULL; ic = ic->next)
420
	{
421
		icon = ic->data;
422
		//cd_message ("  icon->cBaseURI : %s\n", icon->cBaseURI);
423
		if (icon->cBaseURI != NULL && strcmp (icon->cBaseURI, cBaseURI) == 0)
424
			return icon;
425
	}
426
	return NULL;
427
}
428
429
Icon *cairo_dock_get_icon_with_name (GList *pIconList, const gchar *cName)
430
{
431
	g_return_val_if_fail (cName != NULL, NULL);
432
	GList* ic;
433
	Icon *icon;
434
	for (ic = pIconList; ic != NULL; ic = ic->next)
435
	{
436
		icon = ic->data;
437
		//cd_message ("  icon->cName : %s\n", icon->cName);
438
		if (icon->cName != NULL && strcmp (icon->cName, cName) == 0)
439
			return icon;
440
	}
441
	return NULL;
442
}
443
444
Icon *cairo_dock_get_icon_with_subdock (GList *pIconList, CairoDock *pSubDock)
445
{
446
	GList* ic;
447
	Icon *icon;
448
	for (ic = pIconList; ic != NULL; ic = ic->next)
449
	{
450
		icon = ic->data;
451
		if (icon->pSubDock == pSubDock)
452
			return icon;
453
	}
454
	return NULL;
455
}
456
457
Icon *cairo_dock_get_icon_with_module (GList *pIconList, CairoDockModule *pModule)
458
{
459
	GList* ic;
460
	Icon *icon;
461
	for (ic = pIconList; ic != NULL; ic = ic->next)
462
	{
463
		icon = ic->data;
464
		if (icon->pModuleInstance->pModule == pModule)
465
			return icon;
466
	}
467
	return NULL;
468
}
469
470
void cairo_dock_get_icon_extent (Icon *pIcon, CairoContainer *pContainer, int *iWidth, int *iHeight)
471
{
472
	/**double fMaxScale = cairo_dock_get_max_scale (pContainer);
473
	double fRatio = (CAIRO_DOCK_IS_DOCK (pContainer) ? pContainer->fRatio : 1.);  // on ne tient pas compte de l'effet de zoom initial du desklet.
474
	if (!pContainer || pContainer->bIsHorizontal)
475
	{
476
		*iWidth = (int) (pIcon->fWidth / fRatio * fMaxScale);
477
		*iHeight = (int) (pIcon->fHeight / fRatio * fMaxScale);
478
	}
479
	else
480
	{
481
		*iHeight = (int) (pIcon->fWidth / fRatio * fMaxScale);
482
		*iWidth = (int) (pIcon->fHeight / fRatio * fMaxScale);
483
	}*/
484
	*iWidth = pIcon->iImageWidth;
485
	*iHeight = pIcon->iImageHeight;
486
}
487
488
void cairo_dock_get_current_icon_size (Icon *pIcon, CairoContainer *pContainer, double *fSizeX, double *fSizeY)
489
{
490
	if (pContainer->bIsHorizontal)
491
	{
492
		if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon))
493
		{
494
			*fSizeX = pIcon->fWidth;
495
			*fSizeY = pIcon->fHeight;
496
		}
497
		else
498
		{
499
			*fSizeX = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
500
			*fSizeY = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
501
		}
502
	}
503
	else
504
	{
505
		if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon))
506
		{
507
			*fSizeX = pIcon->fHeight;
508
			*fSizeY = pIcon->fWidth;
509
		}
510
		else
511
		{
512
			*fSizeX = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
513
			*fSizeY = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
514
		}
515
	}
516
}
517
518
void cairo_dock_compute_icon_area (Icon *icon, CairoContainer *pContainer, GdkRectangle *pArea)
519
{
520
	double fReflectSize = 0;
521
	if (pContainer->bUseReflect)
522
	{
523
		fReflectSize = myIcons.fReflectSize * icon->fScale * fabs (icon->fHeightFactor) + icon->fDeltaYReflection + myBackground.iFrameMargin;  // un peu moyen le iFrameMargin mais bon ...
524
	}
525
	if (! myIndicators.bIndicatorOnIcon)
526
		fReflectSize = MAX (fReflectSize, myIndicators.fIndicatorDeltaY * icon->fHeight);
527
	
528
	double fX = icon->fDrawX;
529
	fX += icon->fWidth * icon->fScale * (1 - fabs (icon->fWidthFactor))/2 + icon->fGlideOffset * icon->fWidth * icon->fScale;
530
	
531
	double fY = icon->fDrawY;
532
	fY += (pContainer->bDirectionUp ? icon->fHeight * icon->fScale * (1 - icon->fHeightFactor)/2 : - fReflectSize);
533
	if (fY < 0)
534
		fY = 0;
535
	
536
	if (pContainer->bIsHorizontal)
537
	{
538
		pArea->x = (int) floor (fX) - 1;
539
		pArea->y = (int) floor (fY);
540
		pArea->width = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
541
		pArea->height = (int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize);
542
	}
543
	else
544
	{
545
		pArea->x = (int) floor (fY);
546
		pArea->y = (int) floor (fX) - 1;
547
		pArea->width = ((int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize));
548
		pArea->height = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
549
	}
550
	//g_print ("redraw : %d;%d %dx%d\n", pArea->x, pArea->y, pArea->width,pArea->height);
551
}
552
553
554
555
void cairo_dock_normalize_icons_order (GList *pIconList, CairoDockIconType iType)
556
{
557
	cd_message ("%s (%d)", __func__, iType);
558
	int iOrder = 1;
559
	CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
560
	GString *sDesktopFilePath = g_string_new ("");
561
	GList* ic;
562
	Icon *icon;
563
	for (ic = pIconList; ic != NULL; ic = ic->next)
564
	{
565
		icon = ic->data;
566
		if (cairo_dock_get_icon_order (icon) != iGroupOrder)
567
			continue;
568
		
569
		icon->fOrder = iOrder ++;
570
		if (icon->cDesktopFileName != NULL)
571
		{
572
			g_string_printf (sDesktopFilePath, "%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
573
			cairo_dock_update_conf_file (sDesktopFilePath->str,
574
				G_TYPE_DOUBLE, "Desktop Entry", "Order", icon->fOrder,
575
				G_TYPE_INVALID);
576
		}
577
		else if (CAIRO_DOCK_IS_APPLET (icon))
578
		{
579
			cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
580
				G_TYPE_DOUBLE, "Icon", "order", icon->fOrder,
581
				G_TYPE_INVALID);
582
		}
583
	}
584
	g_string_free (sDesktopFilePath, TRUE);
585
	cairo_dock_trigger_refresh_launcher_gui ();
586
}
587
588
void cairo_dock_move_icon_after_icon (CairoDock *pDock, Icon *icon1, Icon *icon2)
589
{
590
	//g_print ("%s (%s, %.2f, %x)\n", __func__, icon1->cName, icon1->fOrder, icon2);
591
	if ((icon2 != NULL) && fabs (cairo_dock_get_icon_order (icon1) - cairo_dock_get_icon_order (icon2)) > 1)
592
		return ;
593
	//\_________________ On change l'ordre de l'icone.
594
	gboolean bForceUpdate = FALSE;
595
	if (icon2 != NULL)
596
	{
597
		Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon2);
598
		if (pNextIcon != NULL && fabs (pNextIcon->fOrder - icon2->fOrder) < 1e-2)
599
		{
600
			bForceUpdate = TRUE;
601
		}
602
		if (pNextIcon == NULL || cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (icon2))
603
			icon1->fOrder = icon2->fOrder + 1;
604
		else
605
			icon1->fOrder = (pNextIcon->fOrder - icon2->fOrder > 1 ? icon2->fOrder + 1 : (pNextIcon->fOrder + icon2->fOrder) / 2);
606
	}
607
	else
608
	{
609
		Icon *pFirstIcon = cairo_dock_get_first_icon_of_order (pDock->icons, icon1->iType);
610
		if (pFirstIcon != NULL)
611
			icon1->fOrder = pFirstIcon->fOrder - 1;
612
		else
613
			icon1->fOrder = 1;
614
	}
615
	//g_print ("icon1->fOrder:%.2f\n", icon1->fOrder);
616
	
617
	//\_________________ On change l'ordre dans le fichier du lanceur 1.
618
	cairo_dock_write_order_in_conf_file (icon1, icon1->fOrder);
619
	
620
	//\_________________ On change sa place dans la liste.
621
	pDock->pFirstDrawnElement = NULL;
622
	pDock->icons = g_list_remove (pDock->icons, icon1);
623
	pDock->icons = g_list_insert_sorted (pDock->icons,
624
		icon1,
625
		(GCompareFunc) cairo_dock_compare_icons_order);
626
627
	//\_________________ On recalcule la largeur max, qui peut avoir ete influencee par le changement d'ordre.
628
	cairo_dock_update_dock_size (pDock);
629
	
630
	if (icon1->pSubDock != NULL && icon1->cClass != NULL)
631
	{
632
		cairo_dock_trigger_set_WM_icons_geometry (icon1->pSubDock);
633
	}
634
	
635
	if (pDock->iRefCount != 0)
636
	{
637
		cairo_dock_redraw_subdock_content (pDock);
638
	}
639
	
640
	if (bForceUpdate)
641
		cairo_dock_normalize_icons_order (pDock->icons, icon1->iType);
642
	if (CAIRO_DOCK_IS_STORED_LAUNCHER (icon1) || CAIRO_DOCK_IS_USER_SEPARATOR (icon1) || CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon1))
643
		cairo_dock_trigger_refresh_launcher_gui ();
644
}
645
646
647
Icon *cairo_dock_foreach_icons_of_type (GList *pIconList, CairoDockIconType iType, CairoDockForeachIconFunc pFuntion, gpointer data)
648
{
649
	//g_print ("%s (%d)\n", __func__, iType);
650
	if (pIconList == NULL)
651
		return NULL;
652
653
	Icon *icon;
654
	GList *ic = pIconList, *next_ic;
655
	gboolean bOneIconFound = FALSE;
656
	Icon *pSeparatorIcon = NULL;
657
	while (ic != NULL)  // on parcourt tout, inutile de complexifier la chose pour gagner 3ns.
658
	{
659
		icon = ic->data;
660
		next_ic = ic->next;
661
		if (icon->iType == iType)
662
		{
663
			bOneIconFound = TRUE;
664
			pFuntion (icon, NULL, data);
665
		}
666
		else
667
		{
668
			if (CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (icon))
669
			{
670
				if ( (bOneIconFound && pSeparatorIcon == NULL) || (! bOneIconFound) )
671
					pSeparatorIcon = icon;
672
			}
673
		}
674
		ic = next_ic;
675
	}
676
677
	if (bOneIconFound)
678
		return pSeparatorIcon;
679
	else
680
		return NULL;
681
}
682
683
684
685
void cairo_dock_update_icon_s_container_name (Icon *icon, const gchar *cNewParentDockName)
686
{
687
	g_free (icon->cParentDockName);
688
	icon->cParentDockName = g_strdup (cNewParentDockName);
689
	
690
	cairo_dock_write_container_name_in_conf_file (icon, cNewParentDockName);
691
}
692
693
694
void cairo_dock_set_icon_name (const gchar *cIconName, Icon *pIcon, CairoContainer *pContainer)  // fonction proposee par Necropotame.
695
{
696
	g_return_if_fail (pIcon != NULL && pContainer != NULL);  // le contexte sera verifie plus loin.
697
	gchar *cUniqueName = NULL;
698
	
699
	if (pIcon->pSubDock != NULL)
700
	{
701
		cUniqueName = cairo_dock_get_unique_dock_name (cIconName);
702
		cIconName = cUniqueName;
703
		cairo_dock_rename_dock (pIcon->cName, pIcon->pSubDock, cUniqueName);
704
	}
705
	if (pIcon->cName != cIconName)
706
	{
707
		g_free (pIcon->cName);
708
		pIcon->cName = g_strdup (cIconName);
709
	}
710
	
711
	g_free (cUniqueName);
712
	
713
	cairo_dock_load_icon_text (pIcon, &myLabels.iconTextDescription);
714
}
715
716
void cairo_dock_set_icon_name_printf (Icon *pIcon, CairoContainer *pContainer, const gchar *cIconNameFormat, ...)
717
{
718
	va_list args;
719
	va_start (args, cIconNameFormat);
720
	gchar *cFullText = g_strdup_vprintf (cIconNameFormat, args);
721
	cairo_dock_set_icon_name (cFullText, pIcon, pContainer);
722
	g_free (cFullText);
723
	va_end (args);
724
}
725
726
void cairo_dock_set_quick_info (Icon *pIcon, CairoContainer *pContainer, const gchar *cQuickInfo)
727
{
728
	g_return_if_fail (pIcon != NULL);  // le contexte sera verifie plus loin.
729
730
	if (pIcon->cQuickInfo != cQuickInfo)
731
	{
732
		g_free (pIcon->cQuickInfo);
733
		pIcon->cQuickInfo = g_strdup (cQuickInfo);
734
	}
735
	
736
	double fMaxScale = cairo_dock_get_max_scale (pContainer);
737
	cairo_dock_load_icon_quickinfo (pIcon,
738
		&myLabels.quickInfoTextDescription,
739
		fMaxScale);
740
}
741
742
void cairo_dock_set_quick_info_printf (Icon *pIcon, CairoContainer *pContainer, const gchar *cQuickInfoFormat, ...)
743
{
744
	va_list args;
745
	va_start (args, cQuickInfoFormat);
746
	gchar *cFullText = g_strdup_vprintf (cQuickInfoFormat, args);
747
	cairo_dock_set_quick_info (pIcon, pContainer, cFullText);
748
	g_free (cFullText);
749
	va_end (args);
750
}
751
752
753
754
static CairoDock *_cairo_dock_insert_launcher_in_dock (Icon *icon, CairoDock *pMainDock, gboolean bUpdateSize, gboolean bAnimate)
755
{
756
	cd_message ("%s (%s)", __func__, icon->cName);
757
	g_return_val_if_fail (pMainDock != NULL, NULL);
758
	
759
	cairo_dock_reserve_one_icon_geometry_for_window_manager (&icon->Xid, icon, pMainDock);
760
	
761
	//\_________________ On determine dans quel dock l'inserer.
762
	CairoDock *pParentDock = pMainDock;
763
	g_return_val_if_fail (pParentDock != NULL, NULL);
764
765
	//\_________________ On l'insere dans son dock parent en animant ce dernier eventuellement.
766
	cairo_dock_insert_icon_in_dock (icon, pParentDock, bUpdateSize, bAnimate);
767
	cd_message (" insertion de %s complete (%.2f %.2fx%.2f) dans %s", icon->cName, icon->fInsertRemoveFactor, icon->fWidth, icon->fHeight, icon->cParentDockName);
768
769
	if (bAnimate && cairo_dock_animation_will_be_visible (pParentDock))
770
	{
771
		cairo_dock_launch_animation (CAIRO_CONTAINER (pParentDock));
772
	}
773
	else
774
	{
775
		icon->fInsertRemoveFactor = 0;
776
		icon->fScale = 1.;
777
	}
778
779
	return pParentDock;
780
}
781
static CairoDock * _cairo_dock_detach_launcher(Icon *pIcon)
782
{
783
	cd_debug ("%s (%s, parent dock=%s)", __func__, pIcon->cName, pIcon->cParentDockName);
784
	CairoDock *pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
785
	if (pParentDock == NULL)
786
		return NULL;
787
788
	gchar *cParentDockName = g_strdup(pIcon->cParentDockName);
789
	cairo_dock_detach_icon_from_dock (pIcon, pParentDock, TRUE); // this will set cParentDockName to NULL
790
	
791
	pIcon->cParentDockName = cParentDockName; // put it back !
792
793
	cairo_dock_update_dock_size (pParentDock);
794
	return pParentDock;
795
}
796
static void _cairo_dock_hide_show_launchers_on_other_desktops (Icon *icon, CairoContainer *pContainer, CairoDock *pMainDock)
797
{
798
	if (CAIRO_DOCK_IS_LAUNCHER(icon))
799
	{
800
		cd_debug ("%s (%s, iNumViewport=%d)", __func__, icon->cName, icon->iSpecificDesktop);
801
		CairoDock *pParentDock = NULL;
802
		// a specific desktop/viewport has been selected for this icon
803
804
		int iCurrentDesktop = 0, iCurrentViewportX = 0, iCurrentViewportY = 0;
805
		cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
806
		int index = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY + 1;  // +1 car on commence a compter a partir de 1.
807
		
808
		if (icon->iSpecificDesktop == 0 || icon->iSpecificDesktop == index || icon->iSpecificDesktop > g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY)
809
		/**if( icon->iSpecificDesktop <= 0 ||
810
		// metacity case: metacity uses desktop instead of viewport.
811
		    (g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY==1 &&
812
		    (icon->iSpecificDesktop-1 == iCurrentDesktop || 
813
		     icon->iSpecificDesktop >= g_desktopGeometry.iNbDesktops)) ||
814
		// compiz case: viewports are used within a desktop
815
				(g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY>1 &&
816
		    (icon->iSpecificDesktop-1 == iCurrentViewportX + g_desktopGeometry.iNbViewportX*iCurrentViewportY ||
817
		     icon->iSpecificDesktop >= g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY)) )*/
818
		{
819
			cd_debug (" => est visible sur ce viewport (iSpecificDesktop = %d).",icon->iSpecificDesktop);
820
			// check that it is in the detached list
821
			if( g_list_find(s_DetachedLaunchersList, icon) != NULL )
822
			{
823
				pParentDock = _cairo_dock_insert_launcher_in_dock (icon, pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
824
				s_DetachedLaunchersList = g_list_remove(s_DetachedLaunchersList, icon);
825
			}
826
		}
827
		else
828
		{
829
			cd_debug (" Viewport actuel = %d => n'est pas sur le viewport actuel.", iCurrentViewportX + g_desktopGeometry.iNbViewportX*iCurrentViewportY);
830
			if( g_list_find(s_DetachedLaunchersList, icon) == NULL ) // only if not yet detached
831
			{
832
				cd_debug( "Detach launcher %s", icon->cName);
833
				pParentDock = _cairo_dock_detach_launcher(icon);
834
				s_DetachedLaunchersList = g_list_prepend(s_DetachedLaunchersList, icon);
835
			}
836
		}
837
		if (pParentDock != NULL)
838
			gtk_widget_queue_draw (pParentDock->container.pWidget);
839
	}
840
}
841
842
void cairo_dock_hide_show_launchers_on_other_desktops (CairoDock *pDock)
843
{
844
	if (g_iNbNonStickyLaunchers <= 0)
845
		return ;
846
	// first we detach what shouldn't be show on this viewport
847
	cairo_dock_foreach_icons_of_type (pDock->icons, CAIRO_DOCK_LAUNCHER, (CairoDockForeachIconFunc)_cairo_dock_hide_show_launchers_on_other_desktops, pDock);
848
	// then we reattach what was eventually missing
849
	cairo_dock_foreach_icons_of_type (s_DetachedLaunchersList, CAIRO_DOCK_LAUNCHER, (CairoDockForeachIconFunc)_cairo_dock_hide_show_launchers_on_other_desktops, pDock);
850
}