~cairo-dock-team/ubuntu/precise/cairo-dock/3.0.0.0beta1

« back to all changes in this revision

Viewing changes to src/cairo-dock-file-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Lavergne
  • Date: 2008-09-14 16:26:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080914162612-t6aa8pr2o0qry48o
Tags: 1.6.2.3-0ubuntu1
* New upstream release.
* debian/control
 - Update to 3.8.0 (no change needed).
 - Add libxtst-dev as Build-Depends.
* debian/cairo-dock-data.install
 - Add usr/share/cairo-dock/emblems directory.
* debian/watch
 - Update location.
* debian/rules
 - Add a get-orig-source rule.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
#include "cairo-dock-dialogs.h"
16
16
#include "cairo-dock-log.h"
17
17
#include "cairo-dock-dock-manager.h"
 
18
#include "cairo-dock-desklet.h"
 
19
#include "cairo-dock-desktop-file-factory.h"
18
20
#include "cairo-dock-file-manager.h"
19
21
 
20
22
extern CairoDockDesktopEnv g_iDesktopEnv;
67
69
                return FALSE;
68
70
}
69
71
 
 
72
static gpointer _cairo_dock_fm_launch_uri_threaded (gchar *cURI)
 
73
{
 
74
        s_pVFSBackend->launch_uri (cURI);
 
75
}
70
76
gboolean cairo_dock_fm_launch_uri (const gchar *cURI)
71
77
{
72
78
        if (s_pVFSBackend != NULL && s_pVFSBackend->launch_uri != NULL)
73
79
        {
74
 
                s_pVFSBackend->launch_uri (cURI);
 
80
                //s_pVFSBackend->launch_uri (cURI);
 
81
                GError *erreur = NULL;
 
82
                GThread* pThread = g_thread_create ((GThreadFunc) _cairo_dock_fm_launch_uri_threaded, (gpointer) cURI, FALSE, &erreur);
 
83
                if (erreur != NULL)
 
84
                {
 
85
                        cd_warning ("Attention : %s", erreur->message);
 
86
                        g_error_free (erreur);
 
87
                }
75
88
                return TRUE;
76
89
        }
77
90
        else
117
130
 
118
131
 
119
132
 
120
 
gboolean cairo_dock_fm_mount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, Icon *icon, CairoDock *pDock)
 
133
gboolean cairo_dock_fm_mount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, Icon *icon, CairoContainer *pContainer)
121
134
{
122
135
        if (s_pVFSBackend != NULL && s_pVFSBackend->mount != NULL && iVolumeID > 0)
123
136
        {
124
 
                s_pVFSBackend->mount (cURI, iVolumeID, pCallback, icon, pDock);
 
137
                s_pVFSBackend->mount (cURI, iVolumeID, pCallback, icon, pContainer);
125
138
                return TRUE;
126
139
        }
127
140
        else
128
141
                return FALSE;
129
142
}
130
143
 
131
 
gboolean cairo_dock_fm_unmount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, Icon *icon, CairoDock *pDock)
 
144
gboolean cairo_dock_fm_unmount_full (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, Icon *icon, CairoContainer *pContainer)
132
145
{
133
146
        if (s_pVFSBackend != NULL && s_pVFSBackend->unmount != NULL && iVolumeID > 0)
134
147
        {
135
 
                s_pVFSBackend->unmount (cURI, iVolumeID, pCallback, icon, pDock);
 
148
                s_pVFSBackend->unmount (cURI, iVolumeID, pCallback, icon, pContainer);
136
149
                return TRUE;
137
150
        }
138
151
        else
147
160
                return NULL;
148
161
}
149
162
 
 
163
gboolean cairo_dock_fm_can_eject (const gchar *cURI)
 
164
{
 
165
        if (s_pVFSBackend != NULL && s_pVFSBackend->can_eject != NULL)
 
166
                return s_pVFSBackend->can_eject (cURI);
 
167
        else
 
168
                return FALSE;
 
169
}
 
170
 
 
171
gboolean cairo_dock_fm_eject_drive (const gchar *cURI)
 
172
{
 
173
        if (s_pVFSBackend != NULL && s_pVFSBackend->eject != NULL)
 
174
                return s_pVFSBackend->eject (cURI);
 
175
        else
 
176
                return FALSE;
 
177
}
 
178
 
 
179
 
150
180
gboolean cairo_dock_fm_delete_file (const gchar *cURI)
151
181
{
152
 
        if (s_pVFSBackend != NULL && s_pVFSBackend->delete != NULL)
 
182
        if (s_pVFSBackend != NULL && s_pVFSBackend->delete_file != NULL)
153
183
        {
154
 
                return s_pVFSBackend->delete (cURI);
 
184
                return s_pVFSBackend->delete_file (cURI);
155
185
        }
156
186
        else
157
187
                return FALSE;
178
208
}
179
209
 
180
210
 
181
 
gchar *cairo_dock_fm_get_trash_path (const gchar *cNearURI, gboolean bCreateIfNecessary)
 
211
gchar *cairo_dock_fm_get_trash_path (const gchar *cNearURI, gchar **cFileInfoPath)
182
212
{
183
213
        if (s_pVFSBackend != NULL && s_pVFSBackend->get_trash_path != NULL)
184
214
        {
185
 
                return s_pVFSBackend->get_trash_path (cNearURI, bCreateIfNecessary);
 
215
                return s_pVFSBackend->get_trash_path (cNearURI, cFileInfoPath);
186
216
        }
187
217
        else
188
218
                return NULL;
220
250
                return FALSE;
221
251
}
222
252
 
223
 
Icon *cairo_dock_fm_create_icon_from_URI (const gchar *cURI, CairoDock *pDock)
 
253
Icon *cairo_dock_fm_create_icon_from_URI (const gchar *cURI, CairoContainer *pContainer)
224
254
{
225
255
        if (s_pVFSBackend == NULL || s_pVFSBackend->get_file_info == NULL)
226
256
                return NULL;
242
272
 
243
273
        if (g_iFileSortType == CAIRO_DOCK_FM_SORT_BY_NAME)
244
274
        {
 
275
                GList *pList = (CAIRO_DOCK_IS_DOCK (pContainer) ? CAIRO_DOCK (pContainer)->icons : CAIRO_DESKLET (pContainer)->icons);
245
276
                GList *ic;
246
277
                Icon *icon;
247
 
                for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
278
                for (ic = pList; ic != NULL; ic = ic->next)
248
279
                {
249
280
                        icon = ic->data;
250
 
                        if (strcmp (pNewIcon->acName, icon->acName) < 0)
 
281
                        if (icon->acName != NULL && strcmp (pNewIcon->acName, icon->acName) < 0)
251
282
                        {
252
283
                                if (ic->prev != NULL)
253
284
                                {
264
295
                        }
265
296
                }
266
297
        }
267
 
        cairo_dock_load_one_icon_from_scratch (pNewIcon, CAIRO_CONTAINER (pDock));
 
298
        cairo_dock_load_one_icon_from_scratch (pNewIcon, pContainer);
268
299
 
269
300
        return pNewIcon;
270
301
}
271
302
 
272
 
void cairo_dock_fm_create_dock_from_directory (Icon *pIcon)
 
303
void cairo_dock_fm_create_dock_from_directory (Icon *pIcon, CairoDock *pParentDock)
273
304
{
274
305
        if (s_pVFSBackend == NULL)
275
306
                return;
276
307
        cd_message ("");
277
308
        g_free (pIcon->acCommand);
278
309
        GList *pIconList = cairo_dock_fm_list_directory (pIcon->cBaseURI, g_iFileSortType, CAIRO_DOCK_LAUNCHER, g_bShowHiddenFiles, &pIcon->acCommand);
279
 
        pIcon->pSubDock = cairo_dock_create_subdock_from_scratch (pIconList, pIcon->acName);
 
310
        pIcon->pSubDock = cairo_dock_create_subdock_from_scratch (pIconList, pIcon->acName, pParentDock);
280
311
 
281
312
        cairo_dock_update_dock_size (pIcon->pSubDock);  // le 'load_buffer' ne le fait pas.
282
313
 
285
316
 
286
317
 
287
318
 
288
 
static Icon *cairo_dock_fm_alter_icon_if_necessary (Icon *pIcon, CairoDock *pDock)
 
319
static Icon *cairo_dock_fm_alter_icon_if_necessary (Icon *pIcon, CairoContainer *pContainer)
289
320
{
290
321
        if (s_pVFSBackend == NULL)
291
322
                return NULL;
292
 
        Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (pIcon->cBaseURI, pDock);
 
323
        cd_debug ("%s (%s)", __func__, pIcon->cBaseURI);
 
324
        Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (pIcon->cBaseURI, pContainer);
293
325
        g_return_val_if_fail (pNewIcon != NULL && pNewIcon->acName != NULL, NULL);
294
326
 
295
 
        if (strcmp (pIcon->acName, pNewIcon->acName) != 0 || strcmp (pIcon->acFileName, pNewIcon->acFileName) != 0 || pIcon->fOrder != pNewIcon->fOrder)
 
327
        //g_print ("%s <-> %s (%s <-> <%s)\n", pIcon->acName, pNewIcon->acName, pIcon->acFileName, pNewIcon->acFileName);
 
328
        if (pIcon->acName == NULL || strcmp (pIcon->acName, pNewIcon->acName) != 0 || pNewIcon->acFileName == NULL || strcmp (pIcon->acFileName, pNewIcon->acFileName) != 0 || pIcon->fOrder != pNewIcon->fOrder)
296
329
        {
297
330
                cd_message ("  on remplace %s", pIcon->acName);
298
 
                cairo_dock_remove_one_icon_from_dock (pDock, pIcon);
 
331
                if (CAIRO_DOCK_IS_DOCK (pContainer))
 
332
                        cairo_dock_remove_one_icon_from_dock (CAIRO_DOCK (pContainer), pIcon);
 
333
                else
 
334
                {
 
335
                        CAIRO_DESKLET (pContainer)->icons = g_list_remove (CAIRO_DESKLET (pContainer)->icons, pIcon);
 
336
                }
299
337
                if (pIcon->acDesktopFileName != NULL)
300
338
                        cairo_dock_fm_remove_monitor (pIcon);
301
339
 
315
353
                pNewIcon->fXAtRest = pIcon->fXAtRest;
316
354
                pNewIcon->fDrawX = pIcon->fDrawX;
317
355
 
318
 
                cairo_dock_insert_icon_in_dock (pNewIcon, pDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, ! CAIRO_DOCK_INSERT_SEPARATOR);  // on met a jour la taille du dock pour le fXMin/fXMax, et eventuellement la taille de l'icone peut aussi avoir change.
319
 
 
320
 
                cairo_dock_redraw_my_icon (pNewIcon, CAIRO_CONTAINER (pDock));
 
356
                if (CAIRO_DOCK_IS_DOCK (pContainer))
 
357
                        cairo_dock_insert_icon_in_dock (pNewIcon, CAIRO_DOCK (pContainer), CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, ! CAIRO_DOCK_INSERT_SEPARATOR);  // on met a jour la taille du dock pour le fXMin/fXMax, et eventuellement la taille de l'icone peut aussi avoir change.
 
358
                else
 
359
                        CAIRO_DESKLET (pContainer)->icons = g_list_insert_sorted (CAIRO_DESKLET (pContainer)->icons,
 
360
                                pIcon,
 
361
                                (GCompareFunc) cairo_dock_compare_icons_order);  // on n'utilise pas le pDesklet->pRenderer->load_icons, car on remplace juste une icone par une autre quasi identique, et on ne sait pas si load_icons a ete utilisee.
 
362
                cairo_dock_redraw_my_icon (pNewIcon, pContainer);
321
363
 
322
364
                if (pNewIcon->acDesktopFileName != NULL)
323
365
                        cairo_dock_fm_add_monitor (pNewIcon);
331
373
                return pIcon;
332
374
        }
333
375
}
334
 
void cairo_dock_fm_manage_event_on_file (CairoDockFMEventType iEventType, const gchar *cURI, Icon *pIcon, CairoDockIconType iTypeOnCreation)
 
376
void cairo_dock_fm_manage_event_on_file (CairoDockFMEventType iEventType, const gchar *cBaseURI, Icon *pIcon, CairoDockIconType iTypeOnCreation)
335
377
{
336
 
        g_return_if_fail (cURI != NULL && pIcon != NULL);
 
378
        g_return_if_fail (cBaseURI != NULL && pIcon != NULL);
 
379
        gchar *cURI = (g_strdup (cBaseURI));
 
380
        cairo_dock_remove_html_spaces (cURI);
337
381
        cd_message ("%s (%d sur %s)", __func__, iEventType, cURI);
338
382
 
339
383
        switch (iEventType)
341
385
                case CAIRO_DOCK_FILE_DELETED :
342
386
                {
343
387
                        Icon *pConcernedIcon;
344
 
                        CairoDock *pParentDock;
 
388
                        CairoContainer *pParentContainer;
345
389
                        if (pIcon->cBaseURI != NULL && strcmp (cURI, pIcon->cBaseURI) == 0)
346
390
                        {
347
391
                                pConcernedIcon = pIcon;
348
 
                                pParentDock = cairo_dock_search_container_from_icon (pIcon);
 
392
                                pParentContainer = cairo_dock_search_container_from_icon (pIcon);
349
393
                        }
350
394
                        else if (pIcon->pSubDock != NULL)
351
395
                        {
356
400
                                }
357
401
                                if (pConcernedIcon == NULL)
358
402
                                        return ;
359
 
                                pParentDock = pIcon->pSubDock;
 
403
                                pParentContainer = CAIRO_CONTAINER (pIcon->pSubDock);
360
404
                        }
361
405
                        else
362
406
                        {
365
409
                        }
366
410
                        cd_message ("  %s sera supprimee", pConcernedIcon->acName);
367
411
                        
368
 
                        if (CAIRO_DOCK_IS_DOCK (pParentDock))
 
412
                        if (CAIRO_DOCK_IS_DOCK (pParentContainer))
369
413
                        {
370
 
                                cairo_dock_remove_one_icon_from_dock (pParentDock, pConcernedIcon);  // enleve aussi son moniteur.
371
 
                                cairo_dock_update_dock_size (pParentDock);
 
414
                                cairo_dock_remove_one_icon_from_dock (CAIRO_DOCK (pParentContainer), pConcernedIcon);  // enleve aussi son moniteur.
 
415
                                cairo_dock_update_dock_size (CAIRO_DOCK (pParentContainer));
372
416
                        }
373
417
                        else if (pConcernedIcon->acDesktopFileName != NULL)  // alors elle a un moniteur.
374
418
                                cairo_dock_fm_remove_monitor (pConcernedIcon);
381
425
                {
382
426
                        if ((pIcon->cBaseURI == NULL || strcmp (cURI, pIcon->cBaseURI) != 0) && pIcon->pSubDock != NULL)  // dans des cas foirreux, il se peut que le fichier soit cree alors qu'il existait deja dans le dock.
383
427
                        {
384
 
                                Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (cURI, pIcon->pSubDock);
 
428
                                CairoContainer *pParentContainer = cairo_dock_search_container_from_icon (pIcon);
 
429
                                Icon *pNewIcon = cairo_dock_fm_create_icon_from_URI (cURI, (CAIRO_DOCK_IS_DOCK (pParentContainer) ? CAIRO_CONTAINER (pIcon->pSubDock) : pParentContainer));
385
430
                                if (pNewIcon == NULL)
386
431
                                        return ;
387
432
                                pNewIcon->iType = iTypeOnCreation;
388
433
 
389
 
                                cairo_dock_insert_icon_in_dock (pNewIcon, pIcon->pSubDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, ! CAIRO_DOCK_INSERT_SEPARATOR);
 
434
                                if (CAIRO_DOCK_IS_DOCK (pParentContainer))
 
435
                                        cairo_dock_insert_icon_in_dock (pNewIcon, pIcon->pSubDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, ! CAIRO_DOCK_INSERT_SEPARATOR);
 
436
                                else
 
437
                                        CAIRO_DESKLET (pParentContainer)->icons = g_list_insert_sorted (CAIRO_DESKLET (pParentContainer)->icons,
 
438
                                                pIcon,
 
439
                                                (GCompareFunc) cairo_dock_compare_icons_order);
390
440
                                cd_message ("  %s a ete insere(e)", (pNewIcon != NULL ? pNewIcon->acName : "aucune icone n'"));
391
441
                                
392
442
                                if (pNewIcon->iVolumeID > 0)
397
447
                                        
398
448
                                        cd_message (" c'est un volume, on considere qu'il vient de se faire (de)monter");
399
449
                                        gchar *cMessage = g_strdup_printf (_("%s is now %s"), pNewIcon->acName, (bIsMounted ? _("mounted") : _("unmounted")));
400
 
                                        cairo_dock_show_temporary_dialog (cMessage, pNewIcon, pIcon->pSubDock, 4000);
 
450
                                        cairo_dock_show_temporary_dialog (cMessage, pNewIcon, CAIRO_DOCK_IS_DOCK (pParentContainer) ? CAIRO_CONTAINER (pIcon->pSubDock) : pParentContainer, 4000);
401
451
                                        g_free (cMessage);
402
452
                                }
403
453
                        }
407
457
                case CAIRO_DOCK_FILE_MODIFIED :
408
458
                {
409
459
                        Icon *pConcernedIcon;
410
 
                        CairoDock *pParentDock;
 
460
                        CairoContainer *pParentContainer;
411
461
                        if (pIcon->cBaseURI != NULL && strcmp (pIcon->cBaseURI, cURI) == 0)  // c'est l'icone elle-meme.
412
462
                        {
413
463
                                pConcernedIcon = pIcon;
414
 
                                pParentDock = cairo_dock_search_container_from_icon (pIcon);
415
 
                                g_return_if_fail (pParentDock != NULL);
 
464
                                pParentContainer = cairo_dock_search_container_from_icon (pIcon);
 
465
                                g_return_if_fail (pParentContainer != NULL);
416
466
                        }
417
467
                        else if (pIcon->pSubDock != NULL)  // c'est a l'interieur du repertoire qu'elle represente.
418
468
                        {
423
473
                                        pConcernedIcon = cairo_dock_get_icon_with_name (pIcon->pSubDock->icons, cURI);
424
474
                                }
425
475
                                g_return_if_fail (pConcernedIcon != NULL);
426
 
                                pParentDock = pIcon->pSubDock;
 
476
                                pParentContainer = CAIRO_CONTAINER (pIcon->pSubDock);
427
477
                        }
428
478
                        else
429
479
                        {
430
480
                                cd_warning ("  on n'aurait pas du arriver la !");
431
481
                                return ;
432
482
                        }
433
 
                        cd_message ("  %s est modifiee (iRefCount:%d)", pConcernedIcon->acName, pParentDock->iRefCount);
434
 
                        
435
 
                        Icon *pNewIcon = cairo_dock_fm_alter_icon_if_necessary (pConcernedIcon, pParentDock);
436
 
                        
437
 
                        if (pNewIcon != NULL && pNewIcon != pConcernedIcon && pNewIcon->iVolumeID > 0)
 
483
                        cd_message ("  %s est modifiee", pConcernedIcon->acName);
 
484
                        
 
485
                        Icon *pNewIcon = cairo_dock_fm_alter_icon_if_necessary (pConcernedIcon, pParentContainer);
 
486
                        
 
487
                        if (pNewIcon != NULL && pNewIcon->iVolumeID > 0)  // && pNewIcon != pConcernedIcon
438
488
                        {
439
 
                                cd_message ("ce volume a change\n");
 
489
                                cd_message ("ce volume a change");
440
490
                                gboolean bIsMounted = FALSE;
441
491
                                if (s_pVFSBackend->is_mounted != NULL)
442
492
                                {
445
495
                                }
446
496
                                gchar *cMessage = g_strdup_printf (_("%s is now %s"), pNewIcon->acName, (bIsMounted ? _("mounted") : _("unmounted")));
447
497
                                
448
 
                                cairo_dock_show_temporary_dialog (cMessage, pNewIcon, pParentDock, 4000);
 
498
                                cairo_dock_show_temporary_dialog (cMessage, pNewIcon, pParentContainer, 4000);
449
499
                                g_free (cMessage);
450
500
                        }
451
501
                }
452
502
                break ;
453
503
        }
 
504
        g_free (cURI);
454
505
}
455
506
 
456
507
void cairo_dock_fm_action_on_file_event (CairoDockFMEventType iEventType, const gchar *cURI, Icon *pIcon)
458
509
        cairo_dock_fm_manage_event_on_file (iEventType, cURI, pIcon, CAIRO_DOCK_LAUNCHER);
459
510
}
460
511
 
461
 
void cairo_dock_fm_action_after_mounting (gboolean bMounting, gboolean bSuccess, const gchar *cName, Icon *icon, CairoDock *pDock)
 
512
void cairo_dock_fm_action_after_mounting (gboolean bMounting, gboolean bSuccess, const gchar *cName, Icon *icon, CairoContainer *pContainer)
462
513
{
463
514
        cd_message ("%s (%s) : %d\n", __func__, (bMounting ? "mount" : "unmount"), bSuccess);  // en cas de demontage effectif, l'icone n'est plus valide !
464
 
        if ((! bSuccess && pDock != NULL) || icon == NULL)  // dans l'autre cas (succes), l'icone peut ne plus etre valide ! mais on s'en fout, puisqu'en cas de succes, il y'aura rechargement de l'icone, et donc on pourra balancer le message a ce moment-la.
 
515
        if ((! bSuccess && pContainer != NULL) || icon == NULL)  // dans l'autre cas (succes), l'icone peut ne plus etre valide ! mais on s'en fout, puisqu'en cas de succes, il y'aura rechargement de l'icone, et donc on pourra balancer le message a ce moment-la.
465
516
        {
466
517
                gchar *cMessage = g_strdup_printf (_("failed to %s %s"), (bMounting ? _("mount") : _("unmount")), cName);
467
518
                if (icon != NULL)
468
 
                        cairo_dock_show_temporary_dialog (cMessage, icon, pDock, 4000);
 
519
                        cairo_dock_show_temporary_dialog (cMessage, icon, pContainer, 4000);
469
520
                else
470
521
                {
471
522
                        cairo_dock_show_general_message (cMessage, 4000);
472
523
                }
473
 
 
474
524
                g_free (cMessage);
475
525
        }
476
526
}
477
527
 
478
528
 
479
529
 
480
 
gboolean cairo_dock_fm_move_into_directory (const gchar *cURI, Icon *icon, CairoDock *pDock)
 
530
gboolean cairo_dock_fm_move_into_directory (const gchar *cURI, Icon *icon, CairoContainer *pContainer)
481
531
{
482
532
        g_return_val_if_fail (cURI != NULL && icon != NULL, FALSE);
483
533
        cd_message (" -> copie de %s dans %s", cURI, icon->cBaseURI);
486
536
        {
487
537
                cd_warning ("Attention : couldn't copy this file.\nCheck that you have writing rights, and that the new does not already exist.");
488
538
                gchar *cMessage = g_strdup_printf ("Attention : couldn't copy %s into %s.\nCheck that you have writing rights, and that the name does not already exist.", cURI, icon->cBaseURI);
489
 
                cairo_dock_show_temporary_dialog (cMessage, icon, pDock, 4000);
 
539
                cairo_dock_show_temporary_dialog (cMessage, icon, pContainer, 4000);
490
540
                g_free (cMessage);
491
541
        }
492
542
        return bSuccess;