2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
20
// If Gio is not detected, do not try to compile this file.
21
// Note: Gio is present from GLib >= 2.16
22
#include "cairo-dock-gio-vfs.h"
30
#define G_VFS_DBUS_DAEMON_NAME "org.gtk.vfs.Daemon"
32
#include <cairo-dock.h>
34
static void _cairo_dock_gio_vfs_empty_dir (const gchar *cBaseURI);
36
static GHashTable *s_hMonitorHandleTable = NULL;
38
static void _gio_vfs_free_monitor_data (gpointer *data)
42
GFileMonitor *pHandle = data[2];
43
g_file_monitor_cancel (pHandle);
44
g_object_unref (pHandle);
49
gboolean cairo_dock_gio_vfs_init (void)
51
// first, check that the session has gvfs on DBus
52
if( !cairo_dock_dbus_is_enabled() ||
53
!cairo_dock_dbus_detect_application (G_VFS_DBUS_DAEMON_NAME) )
55
cd_warning("VFS Deamon NOT found on DBus !");
58
cd_message("VFS Deamon found on DBus.");
61
if (s_hMonitorHandleTable != NULL)
62
g_hash_table_destroy (s_hMonitorHandleTable);
64
s_hMonitorHandleTable = g_hash_table_new_full (g_str_hash,
67
(GDestroyNotify) _gio_vfs_free_monitor_data);
69
GVfs *vfs = g_vfs_get_default ();
70
return (vfs != NULL && g_vfs_is_active (vfs)); // utile ?
74
static void cairo_dock_gio_vfs_stop (void)
76
if (s_hMonitorHandleTable != NULL)
78
g_hash_table_destroy (s_hMonitorHandleTable);
79
s_hMonitorHandleTable = NULL;
84
static gchar *_cd_get_icon_path (GIcon *pIcon, const gchar *cTargetURI) // cTargetURI est l'URI que represente l'icone, pour les cas ou l'icone est contenue dans le repertoire lui-meme (CD ou DVD de jeux notamment)
86
//g_print ("%s ()\n", __func__);
87
gchar *cIconPath = NULL;
88
if (G_IS_THEMED_ICON (pIcon))
90
const gchar * const *cFileNames = g_themed_icon_get_names (G_THEMED_ICON (pIcon));
91
//cd_message ("icones possibles : %s", g_strjoinv (":", (gchar **) cFileNames));
93
for (i = 0; cFileNames[i] != NULL && cIconPath == NULL; i ++)
95
//g_print (" une icone possible est : %s\n", cFileNames[i]);
97
gchar *path = cairo_dock_search_icon_s_path (cFileNames[i], CAIRO_DOCK_DEFAULT_ICON_SIZE);
101
cIconPath = g_strdup (cFileNames[i]);
104
//g_print (" chemin trouve : %s\n", cIconPath);
107
else if (G_IS_FILE_ICON (pIcon))
109
GFile *pFile = g_file_icon_get_file (G_FILE_ICON (pIcon));
110
cIconPath = g_file_get_basename (pFile);
111
//g_print (" file_icon => %s\n", cIconPath);
113
if (cTargetURI && cIconPath && g_str_has_suffix (cIconPath, ".ico")) // cas des montages de CD ou d'iso
115
gchar *tmp = cIconPath;
116
cIconPath = g_strdup_printf ("%s/%s", cTargetURI, tmp);
118
if (strncmp (cIconPath, "file://", 7) == 0)
121
cIconPath = g_filename_from_uri (tmp, NULL, NULL);
130
static void _cd_find_mount_from_volume_name (const gchar *cVolumeName, GMount **pFoundMount, gchar **cURI, gchar **cIconName)
132
g_return_if_fail (cVolumeName != NULL);
133
cd_message ("%s (%s)", __func__, cVolumeName);
134
GFile *pFile = g_file_new_for_uri ("computer://");
135
GError *erreur = NULL;
136
const gchar *cAttributes = G_FILE_ATTRIBUTE_STANDARD_TYPE","
137
G_FILE_ATTRIBUTE_STANDARD_NAME","
138
///G_FILE_ATTRIBUTE_STANDARD_ICON","
139
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI;
140
GFileEnumerator *pFileEnum = g_file_enumerate_children (pFile,
142
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
147
cd_warning ("gvfs-integration : %s", erreur->message);
148
g_error_free (erreur);
149
g_object_unref (pFile);
153
GFileInfo *pFileInfo;
156
pFileInfo = g_file_enumerator_next_file (pFileEnum, NULL, &erreur);
159
cd_warning ("gvfs-integration : %s", erreur->message);
160
g_error_free (erreur);
165
if (pFileInfo == NULL)
167
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
168
if (iFileType == G_FILE_TYPE_MOUNTABLE)
170
const gchar *cFileName = g_file_info_get_name (pFileInfo);
171
cd_debug (" test of %s...", cFileName);
172
const gchar *cTargetURI = g_file_info_get_attribute_string (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
174
GMount *pMount = NULL;
175
if (cTargetURI != NULL)
177
GFile *file = g_file_new_for_uri (cTargetURI);
178
pMount = g_file_find_enclosing_mount (file, NULL, NULL);
179
g_object_unref (file);
183
gchar *cName = g_mount_get_name (pMount);
184
cd_message (" mount : %s", cName);
185
if (cName != NULL && strcmp (cName, cVolumeName) == 0)
188
*pFoundMount = pMount;
189
*cURI = g_strconcat ("computer:///", cFileName, NULL);
190
GIcon *pSystemIcon = g_mount_get_icon (pMount);
191
*cIconName = _cd_get_icon_path (pSystemIcon, NULL);
192
g_object_unref (pSystemIcon);
199
g_object_unref (pFileInfo);
202
g_object_unref (pFileEnum);
203
g_object_unref (pFile);
206
static GDrive *_cd_find_drive_from_name (const gchar *cName)
208
g_return_val_if_fail (cName != NULL, NULL);
209
cd_message ("%s (%s)", __func__, cName);
210
GVolumeMonitor *pVolumeMonitor = g_volume_monitor_get ();
211
GDrive *pFoundDrive = NULL;
213
gchar *str = strrchr (cName, '-');
217
//\___________________ On chope les disques connectes (lecteur de CD/disquette/etc) et on liste leurs volumes.
218
GList *pDrivesList = g_volume_monitor_get_connected_drives (pVolumeMonitor);
222
for (dl = pDrivesList; dl != NULL; dl = dl->next)
225
if (pFoundDrive == NULL)
227
cDriveName = g_drive_get_name (pDrive);
228
cd_message (" drive '%s'", cDriveName);
229
if (cDriveName != NULL && strcmp (cDriveName, cName) == 0)
230
pFoundDrive = pDrive;
232
g_object_unref (pDrive);
236
g_object_unref (pDrive);
238
g_list_free (pDrivesList);
243
static gchar *_cd_find_volume_name_from_drive_name (const gchar *cName)
245
g_return_val_if_fail (cName != NULL, NULL);
246
cd_message ("%s (%s)", __func__, cName);
247
GDrive *pDrive = _cd_find_drive_from_name (cName);
248
g_return_val_if_fail (pDrive != NULL, NULL);
250
gchar *cVolumeName = NULL;
251
GList *pAssociatedVolumes = g_drive_get_volumes (pDrive);
252
g_object_unref (pDrive);
253
if (pAssociatedVolumes == NULL)
257
gchar *str = strrchr (cName, '-');
260
iNumVolume = atoi (str+1);
265
GVolume *pVolume = g_list_nth_data (pAssociatedVolumes, iNumVolume);
268
cVolumeName = g_volume_get_name (pVolume);
270
cd_debug ("%dth volume -> cVolumeName : %s", iNumVolume, cVolumeName);
272
/* cd_debug ("List of unavailable volumes on this disc:");
275
for (av = pAssociatedVolumes; av != NULL; av = av->next)
278
cLog = g_volume_get_name (pVolume);
279
cd_debug (" - %s", cLog);
283
g_list_foreach (pAssociatedVolumes, (GFunc)g_object_unref, NULL);
284
g_list_free (pAssociatedVolumes);
288
static gboolean _cd_find_can_eject_from_drive_name (const gchar *cName)
290
cd_debug ("%s (%s)", __func__, cName);
291
GDrive *pDrive = _cd_find_drive_from_name (cName);
292
g_return_val_if_fail (pDrive != NULL, FALSE);
294
gboolean bCanEject = g_drive_can_eject (pDrive);
295
g_object_unref (pDrive);
299
static void cairo_dock_gio_vfs_get_file_info (const gchar *cBaseURI, gchar **cName, gchar **cURI, gchar **cIconName, gboolean *bIsDirectory, int *iVolumeID, double *fOrder, CairoDockFMSortType iSortType)
304
g_return_if_fail (cBaseURI != NULL);
305
GError *erreur = NULL;
306
cd_message ("%s (%s)", __func__, cBaseURI);
308
// make it a valid URI.
310
if (strncmp (cBaseURI, "x-nautilus-desktop://", 21) == 0) // shortcut on the desktop (nautilus)
312
gchar *cNautilusFile = g_strdup (cBaseURI+14);
313
memcpy (cNautilusFile, "file", 4);
314
if (g_str_has_suffix (cBaseURI, ".volume"))
316
cNautilusFile[strlen(cNautilusFile)-7] = '\0';
318
else if (g_str_has_suffix (cBaseURI, ".drive"))
320
cNautilusFile[strlen(cNautilusFile)-6] = '\0';
322
cValidUri = g_filename_from_uri (cNautilusFile, NULL, &erreur);
325
cd_warning ("gvfs-integration : %s", erreur->message);
326
g_error_free (erreur);
329
gchar *cVolumeName = cValidUri + 1; // we drop the '/'.
330
cd_message ("cVolumeName : %s", cVolumeName);
332
GMount *pMount = NULL;
333
gchar *uri=NULL, *iconname=NULL;
334
_cd_find_mount_from_volume_name (cVolumeName, &pMount, &uri, &iconname);
335
g_return_if_fail (pMount != NULL);
342
*cIconName = iconname;
346
*cName = g_strdup (cVolumeName);
348
*bIsDirectory = TRUE;
354
g_object_unref (pMount);
356
g_free (cNautilusFile);
361
if (*cBaseURI == '/')
362
cValidUri = g_filename_to_uri (cBaseURI, NULL, NULL);
364
cValidUri = g_strdup (cBaseURI);
365
// strange case when unmounting a FTP bookmark when it's not available: crash with DBus
366
if (*cBaseURI == ':' || *cValidUri == ':')
368
cd_warning ("invalid URI (%s ; %s), skip it", cBaseURI, cValidUri);
374
// get its attributes.
375
GFile *pFile = g_file_new_for_uri (cValidUri);
376
g_return_if_fail (pFile);
377
const gchar *cQuery = G_FILE_ATTRIBUTE_STANDARD_TYPE","
378
G_FILE_ATTRIBUTE_STANDARD_SIZE","
379
G_FILE_ATTRIBUTE_TIME_MODIFIED","
380
G_FILE_ATTRIBUTE_TIME_ACCESS","
381
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
382
G_FILE_ATTRIBUTE_STANDARD_NAME","
383
G_FILE_ATTRIBUTE_STANDARD_ICON","
384
G_FILE_ATTRIBUTE_THUMBNAIL_PATH","
385
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 20)
386
///G_FILE_ATTRIBUTE_PREVIEW_ICON","
388
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI;
389
GFileInfo *pFileInfo = g_file_query_info (pFile,
391
G_FILE_QUERY_INFO_NONE, /// G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS
394
if (erreur != NULL) // peut arriver si l'emplacement n'est pas monte.
396
cd_debug ("gvfs-integration : %s", erreur->message); // inutile d'en faire un warning.
397
g_error_free (erreur);
399
g_object_unref (pFile);
403
const gchar *cFileName = g_file_info_get_name (pFileInfo);
404
const gchar *cMimeType = g_file_info_get_content_type (pFileInfo);
405
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
406
const gchar *cTargetURI = g_file_info_get_attribute_string (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
408
// find the order of the file
411
if (iSortType == CAIRO_DOCK_FM_SORT_BY_DATE)
414
g_file_info_get_modification_time (pFileInfo, &t);
417
else if (iSortType == CAIRO_DOCK_FM_SORT_BY_ACCESS)
418
*fOrder = g_file_info_get_attribute_uint64 (pFileInfo, G_FILE_ATTRIBUTE_TIME_ACCESS);
419
else if (iSortType == CAIRO_DOCK_FM_SORT_BY_SIZE)
420
*fOrder = g_file_info_get_size (pFileInfo);
421
else if (iSortType == CAIRO_DOCK_FM_SORT_BY_TYPE)
422
*fOrder = (cMimeType != NULL ? *((int *) cMimeType) : 0);
428
*bIsDirectory = (iFileType == G_FILE_TYPE_DIRECTORY);
431
// find a readable name if it's a mount point.
432
if (iFileType == G_FILE_TYPE_MOUNTABLE)
441
cd_message (" cTargetURI:%s", cTargetURI);
442
GMount *pMount = NULL;
443
if (cTargetURI != NULL)
445
GFile *file = g_file_new_for_uri (cTargetURI);
446
pMount = g_file_find_enclosing_mount (file, NULL, NULL);
447
g_object_unref (file);
451
*cName = g_mount_get_name (pMount);
452
cd_message ("un GMount existe (%s)",* cName);
453
g_object_unref (pMount);
457
gchar *cMountName = g_strdup (cFileName);
458
gchar *str = strrchr (cMountName, '.'); // on vire l'extension ".volume" ou ".drive".
462
if (strcmp (str+1, "link") == 0) // pour les liens, on prend le nom du lien.
464
if (strcmp (cMountName, "root") == 0) // on remplace 'root' par un nom plus parlant, sinon on prendra le nom du lien.
466
*cName = g_strdup (D_("File System"));
469
else if (strcmp (str+1, "drive") == 0) // on cherche un nom plus parlant si possible.
471
gchar *cVolumeName = _cd_find_volume_name_from_drive_name (cMountName);
472
if (cVolumeName != NULL)
474
*cName = cVolumeName;
484
*cName = g_strdup (cFileName);
487
else // for an normal file, just re-use the filename
492
*cName = g_strdup (cFileName);
495
// find the target URI if it's a mount point
500
*cURI = g_strdup (cTargetURI);
512
// first use an available thumbnail.
513
*cIconName = g_strdup (g_file_info_get_attribute_byte_string (pFileInfo, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
514
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 20)
515
/**if (*cIconName == NULL)
517
GIcon *pPreviewIcon = (GIcon *)g_file_info_get_attribute_object (pFileInfo, G_FILE_ATTRIBUTE_PREVIEW_ICON);
518
if (pPreviewIcon != NULL)
520
*cIconName = _cd_get_icon_path (pPreviewIcon, NULL);
521
//g_print ("got preview icon '%s'\n", *cIconName);
525
// if no thumbnail available and the file is an image, use it directly.
526
if (*cIconName == NULL && cMimeType != NULL && strncmp (cMimeType, "image", 5) == 0)
528
gchar *cHostname = NULL;
529
GError *erreur = NULL;
530
gchar *cFilePath = g_filename_from_uri (cBaseURI, &cHostname, &erreur);
533
g_error_free (erreur);
535
else if (cHostname == NULL || strcmp (cHostname, "localhost") == 0) // on ne recupere la vignette que sur les fichiers locaux.
537
*cIconName = g_strdup (cFilePath);
538
cairo_dock_remove_html_spaces (*cIconName);
542
// else, get the icon for the mime-types.
543
if (*cIconName == NULL)
545
GIcon *pSystemIcon = g_file_info_get_icon (pFileInfo);
546
if (pSystemIcon != NULL)
548
*cIconName = _cd_get_icon_path (pSystemIcon, cTargetURI ? cTargetURI : *cURI);
551
cd_message ("cIconName : %s", *cIconName);
554
g_object_unref (pFileInfo);
555
g_object_unref (pFile);
559
static Icon *_cd_get_icon_for_volume (GVolume *pVolume, GMount *pMount)
563
gchar *cName, *cCommand, *cFileName;
565
pMount = g_volume_get_mount (pVolume);
566
else if (pMount == NULL)
569
if (pMount != NULL) // ce volume est monte.
571
cName = g_mount_get_name (pMount);
573
pRootDir = g_mount_get_root (pMount);
574
cCommand = g_file_get_uri (pRootDir);
576
pIcon = g_mount_get_icon (pMount);
577
cFileName = _cd_get_icon_path (pIcon, NULL);
579
g_object_unref (pRootDir);
580
g_object_unref (pIcon);
581
g_object_unref (pMount);
583
else // ce volume est demonte, on le montre quand meme (l'automount peut etre off).
585
cName = g_volume_get_name (pVolume);
587
pIcon = g_volume_get_icon (pVolume);
588
cFileName = _cd_get_icon_path (pIcon, NULL);
590
cCommand = g_strdup (cName);
592
g_object_unref (pIcon);
595
Icon *pNewIcon = cairo_dock_create_dummy_launcher (cName,
600
pNewIcon->iVolumeID = 1;
601
pNewIcon->cBaseURI = g_strdup (pNewIcon->cCommand);
602
cd_message (" => %s", pNewIcon->cCommand);
607
static GList *cairo_dock_gio_vfs_list_volumes (void)
609
GVolumeMonitor *pVolumeMonitor = g_volume_monitor_get ();
610
GList *pIconsList = NULL;
613
//\___________________ On chope les disques connectes (lecteur de CD/disquette/etc) et on liste leurs volumes.
614
GList *pDrivesList = g_volume_monitor_get_connected_drives (pVolumeMonitor);
615
GList *pAssociatedVolumes;
620
for (dl = pDrivesList; dl != NULL; dl = dl->next)
624
pAssociatedVolumes = g_drive_get_volumes (pDrive);
625
if (pAssociatedVolumes != NULL)
627
for (av = pAssociatedVolumes; av != NULL; av = av->next)
630
pNewIcon = _cd_get_icon_for_volume (pVolume, NULL);
631
if (pNewIcon != NULL)
632
pIconsList = g_list_prepend (pIconsList, pNewIcon);
633
g_object_unref (pVolume);
635
g_list_free (pAssociatedVolumes);
637
else // le disque n'a aucun volume montable
639
cd_message (" le disque n'a aucun volume montable");
640
*if (g_drive_is_media_removable (pDrive) && ! g_drive_is_media_check_automatic (pDrive))
642
g_drive_get_icon (pDrive);
643
g_drive_get_name (pDrive);
646
//g_object_unref (pDrive);
648
g_list_free (pDrivesList);
652
//\___________________ On chope les volumes qui ne sont pas associes a un disque.
653
GList *pVolumesList = g_volume_monitor_get_volumes (pVolumeMonitor);
655
for (v = pVolumesList; v != NULL; v = v->next)
658
cLog = g_volume_get_name (pVolume);
659
cd_message ("volume '%s'", cLog);
660
pDrive = g_volume_get_drive (pVolume);
661
if (pDrive != NULL) // on l'a deja liste dans la 1ere boucle.
664
cLog = g_drive_get_name (pDrive);
665
cd_message (" drive '%s' est deja liste", cLog);
666
g_object_unref (pDrive);
670
cd_message (" + volume '%s'", cLog);
671
if (pNewIcon != NULL)
672
pNewIcon = _cd_get_icon_for_volume (pVolume, NULL);
673
pIconsList = g_list_prepend (pIconsList, pNewIcon);
676
g_object_unref (pVolume);
678
g_list_free (pVolumesList);
680
//\___________________ On chope les points de montage qui n'ont pas de volumes. (montage de mtab, ftp, etc)
681
GList *pMountsList = g_volume_monitor_get_mounts (pVolumeMonitor);
684
for (m = pMountsList; m != NULL; m = m->next)
687
cLog = g_mount_get_name (pMount);
688
cd_message ("mount '%s'", cLog);
690
pVolume = g_mount_get_volume (pMount);
691
if (pVolume != NULL) // on l'a deja liste precedemment.
693
cLog = g_volume_get_name (pVolume);
694
cd_message ("volume '%s' est deja liste", cLog);
696
g_object_unref (pVolume);
700
cd_message ("volume 'NULL'");
701
if (pNewIcon != NULL)
702
pNewIcon = _cd_get_icon_for_volume (NULL, pMount);
703
pIconsList = g_list_prepend (pIconsList, pNewIcon);
705
g_object_unref (pMount);
707
g_list_free (pMountsList);
712
static GList *cairo_dock_gio_vfs_list_directory (const gchar *cBaseURI, CairoDockFMSortType iSortType, int iNewIconsGroup, gboolean bListHiddenFiles, int iNbMaxFiles, gchar **cValidUri)
714
g_return_val_if_fail (cBaseURI != NULL, NULL);
715
cd_message ("%s (%s)", __func__, cBaseURI);
718
if (strcmp (cBaseURI, CAIRO_DOCK_FM_VFS_ROOT) == 0)
719
cURI = g_strdup ("computer://");
720
else if (strcmp (cBaseURI, CAIRO_DOCK_FM_NETWORK) == 0)
721
cURI = g_strdup ("network://");
723
cURI = (*cBaseURI == '/' ? g_strconcat ("file://", cBaseURI, NULL) : g_strdup (cBaseURI));
726
GFile *pFile = g_file_new_for_uri (cURI);
727
GError *erreur = NULL;
728
const gchar *cAttributes = G_FILE_ATTRIBUTE_STANDARD_TYPE","
729
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
730
G_FILE_ATTRIBUTE_STANDARD_NAME","
731
G_FILE_ATTRIBUTE_STANDARD_ICON","
732
G_FILE_ATTRIBUTE_THUMBNAIL_PATH","
733
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN","
734
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 20)
735
///G_FILE_ATTRIBUTE_PREVIEW_ICON","
737
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI;
738
GFileEnumerator *pFileEnum = g_file_enumerate_children (pFile,
740
G_FILE_QUERY_INFO_NONE, /// G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS
745
cd_warning ("gvfs-integration : %s", erreur->message);
746
g_error_free (erreur);
747
g_object_unref (pFile);
753
GList *pIconList = NULL;
755
GFileInfo *pFileInfo;
758
pFileInfo = g_file_enumerator_next_file (pFileEnum, NULL, &erreur);
761
cd_warning ("gvfs-integration : %s", erreur->message);
762
g_error_free (erreur);
766
if (pFileInfo == NULL)
769
gboolean bIsHidden = g_file_info_get_is_hidden (pFileInfo);
770
if (bListHiddenFiles || ! bIsHidden)
772
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
773
GIcon *pFileIcon = g_file_info_get_icon (pFileInfo);
774
if (pFileIcon == NULL)
776
cd_message ("No ICON");
779
const gchar *cFileName = g_file_info_get_name (pFileInfo);
780
const gchar *cMimeType = g_file_info_get_content_type (pFileInfo);
783
icon = cairo_dock_create_dummy_launcher (NULL, NULL, NULL, NULL, 0);
784
icon->iGroup = iNewIconsGroup;
785
icon->cBaseURI = g_strconcat (*cValidUri, "/", cFileName, NULL);
786
//g_print ("+ %s (mime:%s)n", icon->cBaseURI, cMimeType);
788
if (iFileType == G_FILE_TYPE_MOUNTABLE)
790
const gchar *cTargetURI = g_file_info_get_attribute_string (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
791
cd_message ("It's a mount point: %s (%s)", cTargetURI, cFileName);
793
GMount *pMount = NULL;
794
if (cTargetURI != NULL)
796
icon->cCommand = g_strdup (cTargetURI);
797
GFile *file = g_file_new_for_uri (cTargetURI);
798
pMount = g_file_find_enclosing_mount (file, NULL, NULL);
799
g_object_unref (file);
803
cName = g_mount_get_name (pMount);
804
cd_message ("GMount exists (%s)", cName);
805
g_object_unref (pMount);
807
/* GVolume *volume = g_mount_get_volume (pMount);
809
cd_message (" volume associe : %s", g_volume_get_name (volume));
810
GDrive *drive = g_mount_get_drive (pMount);
812
cd_message (" disque associe : %s", g_drive_get_name (drive));*/
814
///pFileIcon = g_mount_get_icon (pMount);
818
cName = g_strdup (cFileName);
819
gchar *str = strrchr (cName, '.'); // we remove the extension ".volume" or ".drive".
823
if (strcmp (str+1, "link") == 0)
825
if (strcmp (cName, "root") == 0)
828
cName = g_strdup (D_("File System"));
831
else if (strcmp (str+1, "drive") == 0) // on cherche un nom plus parlant si possible.
833
gchar *cVolumeName = _cd_find_volume_name_from_drive_name (cName);
834
if (cVolumeName != NULL)
838
//g_free (cVolumeName);
839
//continue; /// apparemment il n'est plus necessaire d'afficher les .drives qui ont 1 (ou plusieurs ?) volumes, car ces derniers sont dans la liste, donc ca fait redondant.
840
/**if (strcmp (cVolumeName, "discard") == 0)
843
cName = cVolumeName;*/
849
cd_message ("The name of this volume is: %s", cName);
853
if (iFileType == G_FILE_TYPE_DIRECTORY)
854
icon->iVolumeID = -1;
855
cName = g_strdup (cFileName);
858
if (icon->cCommand == NULL)
859
icon->cCommand = g_strdup (icon->cBaseURI);
861
icon->cFileName = g_strdup (g_file_info_get_attribute_byte_string (pFileInfo, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
862
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 20)
863
/**if (icon->cFileName == NULL)
865
GIcon *pPreviewIcon = (GIcon *)g_file_info_get_attribute_object (pFileInfo, G_FILE_ATTRIBUTE_PREVIEW_ICON);
866
if (pPreviewIcon != NULL)
868
icon->cFileName = _cd_get_icon_path (pPreviewIcon, NULL);
869
// g_print ("got preview icon '%s'\n", icon->cFileName);
873
if (cMimeType != NULL && strncmp (cMimeType, "image", 5) == 0)
875
gchar *cHostname = NULL;
876
gchar *cFilePath = g_filename_from_uri (icon->cBaseURI, &cHostname, &erreur);
879
g_error_free (erreur);
882
else if (cHostname == NULL || strcmp (cHostname, "localhost") == 0) // on ne recupere la vignette que sur les fichiers locaux.
884
icon->cFileName = g_strdup (cFilePath);
885
cairo_dock_remove_html_spaces (icon->cFileName);
891
if (icon->cFileName == NULL)
893
icon->cFileName = _cd_get_icon_path (pFileIcon, icon->cCommand);
894
//g_print ("icon->cFileName : %s\n", icon->cFileName);
897
if (iSortType == CAIRO_DOCK_FM_SORT_BY_SIZE)
898
icon->fOrder = g_file_info_get_size (pFileInfo);
899
else if (iSortType == CAIRO_DOCK_FM_SORT_BY_DATE)
902
g_file_info_get_modification_time (pFileInfo, &t);
903
icon->fOrder = t.tv_sec;
905
else if (iSortType == CAIRO_DOCK_FM_SORT_BY_TYPE)
906
icon->fOrder = (cMimeType != NULL ? *((int *) cMimeType) : 0);
907
if (icon->fOrder == 0) // un peu moyen mais mieux que rien non ?
908
icon->fOrder = iOrder;
909
/*pIconList = g_list_insert_sorted (pIconList,
911
(GCompareFunc) cairo_dock_compare_icons_order);*/
912
pIconList = g_list_prepend (pIconList, icon);
913
cd_debug (" + %s (%s)", icon->cName, icon->cFileName);
917
g_object_unref (pFileInfo);
918
} while (iNbFiles < iNbMaxFiles);
920
g_object_unref (pFileEnum);
921
g_object_unref (pFile);
923
if (iSortType == CAIRO_DOCK_FM_SORT_BY_NAME)
924
pIconList = cairo_dock_sort_icons_by_name (pIconList);
926
pIconList = cairo_dock_sort_icons_by_order (pIconList);
931
static gsize cairo_dock_gio_vfs_measure_directory (const gchar *cBaseURI, gint iCountType, gboolean bRecursive, gint *pCancel)
933
g_return_val_if_fail (cBaseURI != NULL, 0);
934
//cd_debug ("%s (%s)", __func__, cBaseURI);
936
gchar *cURI = (*cBaseURI == '/' ? g_strconcat ("file://", cBaseURI, NULL) : (gchar*)cBaseURI); // on le libere a la fin si necessaire.
938
GFile *pFile = g_file_new_for_uri (cURI);
939
GError *erreur = NULL;
940
const gchar *cAttributes = G_FILE_ATTRIBUTE_STANDARD_TYPE","
941
G_FILE_ATTRIBUTE_STANDARD_SIZE","
942
G_FILE_ATTRIBUTE_STANDARD_NAME","
943
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI;
944
GFileEnumerator *pFileEnum = g_file_enumerate_children (pFile,
946
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
951
cd_warning ("gvfs-integration: %s (%s)", erreur->message, cURI);
952
g_error_free (erreur);
953
g_object_unref (pFile);
954
if (cURI != cBaseURI)
956
g_atomic_int_set (pCancel, TRUE);
961
GFileInfo *pFileInfo;
962
GString *sFilePath = g_string_new ("");
965
pFileInfo = g_file_enumerator_next_file (pFileEnum, NULL, &erreur);
968
cd_warning ("gvfs-integration : %s (%s [%s]: %s)", erreur->message,
969
g_file_info_get_name (pFileInfo),
970
g_file_info_get_display_name (pFileInfo),
971
g_file_info_get_content_type (pFileInfo));
972
g_error_free (erreur);
976
if (pFileInfo == NULL)
979
const gchar *cFileName = g_file_info_get_name (pFileInfo);
981
g_string_printf (sFilePath, "%s/%s", cURI, cFileName);
982
//GFile *file = g_file_new_for_uri (sFilePath->str);
983
//const gchar *cTargetURI = g_file_get_uri (file);
984
//g_print ("+ %s [%s]\n", cFileName, cTargetURI);
985
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
987
if (iFileType == G_FILE_TYPE_DIRECTORY && bRecursive)
989
g_string_printf (sFilePath, "%s/%s", cURI, cFileName);
990
iMeasure += MAX (1, cairo_dock_gio_vfs_measure_directory (sFilePath->str, iCountType, bRecursive, pCancel)); // un repertoire vide comptera pour 1.
994
if (iCountType == 1) // measure size.
996
iMeasure += g_file_info_get_size (pFileInfo);
998
else // measure nb files.
1003
g_object_unref (pFileInfo);
1004
} while (! g_atomic_int_get (pCancel));
1006
cd_debug ("measure cancelled");
1008
g_object_unref (pFileEnum);
1009
g_object_unref (pFile);
1010
g_string_free (sFilePath, TRUE);
1011
if (cURI != cBaseURI)
1018
static gchar *_cd_find_target_uri (const gchar *cBaseURI)
1020
GError *erreur = NULL;
1021
GFile *pFile = g_file_new_for_uri (cBaseURI);
1022
GFileInfo *pFileInfo = g_file_query_info (pFile,
1023
G_FILE_ATTRIBUTE_STANDARD_TARGET_URI,
1024
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1027
g_object_unref (pFile);
1030
cd_debug ("%s (%s) : %s", __func__, cBaseURI, erreur->message); // peut arriver avec un .mount, donc pas de warning.
1031
g_error_free (erreur);
1034
gchar *cTargetURI = g_strdup (g_file_info_get_attribute_string (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI));
1035
g_object_unref (pFileInfo);
1039
static void cairo_dock_gio_vfs_launch_uri (const gchar *cURI)
1041
g_return_if_fail (cURI != NULL);
1043
// in case it's a mount point, take the URI that can actually be launched.
1044
GError *erreur = NULL;
1045
gchar *cValidUri = (*cURI == '/' ? g_strconcat ("file://", cURI, NULL) : g_strdup (cURI));
1046
cd_message ("%s (%s)", __func__, cValidUri);
1048
gchar *cTargetURI = _cd_find_target_uri (cValidUri);
1049
cURI= (cTargetURI ? cTargetURI : cValidUri);
1051
// now, try to launch it with the default program know by gvfs.
1052
gboolean bSuccess = g_app_info_launch_default_for_uri (cURI,
1055
if (erreur != NULL || ! bSuccess) // error can happen (for instance, opening 'trash:/' on XFCE with a previous installation of nautilus) => try with another method.
1057
cd_debug ("gvfs-integration : couldn't launch '%s' [%s]", cURI, erreur->message);
1058
g_error_free (erreur);
1061
// get the mime-type.
1062
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1063
const gchar *cQuery = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE;
1064
GFileInfo *pFileInfo = g_file_query_info (pFile,
1066
G_FILE_QUERY_INFO_NONE,
1069
if (erreur != NULL) // if no mime-type (can happen with not mounted volumes), abort.
1071
cd_warning ("gvfs-integration : %s", erreur->message);
1072
g_error_free (erreur);
1076
// get all the apps that can launch it.
1077
const gchar *cMimeType = g_file_info_get_content_type (pFileInfo);
1078
GList *pAppsList = g_app_info_get_all_for_type (cMimeType);
1082
for (a = pAppsList; a != NULL; a = a->next)
1085
cExec = g_app_info_get_executable (pAppInfo);
1086
if (cExec) // use the first available. it is supposed to be the most suitable, but the default method doesn't seem to use it.
1088
gchar *cPath = g_filename_from_uri (cURI, NULL, NULL);
1089
cairo_dock_launch_command_printf ("%s \"%s\"", NULL, cExec, cPath?cPath:cURI); // in case the program doesn't handle URI (geeqie, etc).
1094
g_list_free (pAppsList);
1096
g_object_unref (pFile);
1099
g_free (cTargetURI);
1102
static GMount *_cd_find_mount_from_uri (const gchar *cURI, gchar **cTargetURI)
1104
cd_message ("%s (%s)", __func__, cURI);
1105
gchar *_cTargetURI = _cd_find_target_uri (cURI);
1107
GMount *pMount = NULL;
1108
if (_cTargetURI != NULL)
1110
cd_debug (" pointe sur %s", _cTargetURI);
1111
GFile *file = g_file_new_for_uri (_cTargetURI);
1112
pMount = g_file_find_enclosing_mount (file, NULL, NULL);
1113
g_object_unref (file);
1115
if (cTargetURI != NULL)
1116
*cTargetURI = _cTargetURI;
1118
g_free (_cTargetURI);
1122
static gchar *cairo_dock_gio_vfs_is_mounted (const gchar *cURI, gboolean *bIsMounted)
1124
cd_message ("%s (%s)", __func__, cURI);
1125
gchar *cTargetURI = NULL;
1127
GFile *pFile = g_file_new_for_uri (cURI);
1128
GFileType iType = g_file_query_file_type (pFile, G_FILE_QUERY_INFO_NONE, NULL);
1129
g_object_unref (pFile);
1130
cd_debug ("iType: %d\n", iType);
1132
if (iType == G_FILE_TYPE_MOUNTABLE) // look for the mount point it targets
1134
GMount *pMount = _cd_find_mount_from_uri (cURI, &cTargetURI);
1135
cd_debug (" cTargetURI : %s", cTargetURI);
1139
g_object_unref (pMount);
1143
if (cTargetURI != NULL && strcmp (cTargetURI, "file:///") == 0) // cas particulier ?
1146
*bIsMounted = FALSE;
1149
else if (iType == G_FILE_TYPE_UNKNOWN) // probably a remote share folder or whatever that is not yet mounted
1151
*bIsMounted = FALSE;
1153
else // any other types (directory, regular file, etc) that is on (or point to) a monted volume.
1160
static gchar * _cd_find_drive_name_from_URI (const gchar *cURI)
1162
g_return_val_if_fail (cURI != NULL, NULL);
1163
if (strncmp (cURI, "computer:///", 12) == 0)
1165
gchar *cDriveName = g_strdup (cURI+12);
1166
gchar *str = strrchr (cDriveName, '.');
1169
if (strcmp (str+1, "drive") == 0)
1174
str = strchr (cDriveName, '\\');
1182
g_free (cDriveName);
1186
static gboolean cairo_dock_gio_vfs_can_eject (const gchar *cURI)
1188
cd_message ("%s (%s)", __func__, cURI);
1189
gchar *cDriveName = _cd_find_drive_name_from_URI (cURI);
1190
if (cDriveName == NULL)
1193
gboolean bCanEject = _cd_find_can_eject_from_drive_name (cDriveName);
1194
//g_free (cDriveName);
1197
static gboolean cairo_dock_gio_vfs_eject_drive (const gchar *cURI)
1199
cd_message ("%s (%s)", __func__, cURI);
1200
gchar *cDriveName = _cd_find_drive_name_from_URI (cURI);
1201
GDrive *pDrive = _cd_find_drive_from_name (cDriveName);
1204
#if GLIB_CHECK_VERSION (2, 22, 0)
1205
g_drive_eject_with_operation (pDrive,
1206
G_MOUNT_UNMOUNT_NONE,
1212
g_drive_eject (pDrive,
1213
G_MOUNT_UNMOUNT_NONE,
1219
g_object_unref (pDrive);
1220
g_free (cDriveName);
1225
static void _gio_vfs_mount_callback (gpointer pObject, GAsyncResult *res, gpointer *data)
1226
//static void _gio_vfs_mount_callback (gboolean succeeded, char *error, char *detailed_error, gpointer *data)
1228
cd_message ("%s (%d)", __func__, GPOINTER_TO_INT (data[1]));
1230
CairoDockFMMountCallback pCallback = data[0];
1232
GError *erreur = NULL;
1234
if (GPOINTER_TO_INT (data[1]) == 1)
1237
bSuccess = (g_file_mount_mountable_finish (G_FILE (pObject), res, &erreur) != NULL);
1239
bSuccess = g_file_mount_enclosing_volume_finish (G_FILE (pObject), res, &erreur);
1241
else if (GPOINTER_TO_INT (data[1]) == 0)
1242
#if GLIB_CHECK_VERSION (2, 22, 0)
1243
bSuccess = g_mount_unmount_with_operation_finish (G_MOUNT (pObject), res, &erreur);
1245
bSuccess = g_mount_unmount_finish (G_MOUNT (pObject), res, &erreur);
1248
#if GLIB_CHECK_VERSION (2, 22, 0)
1249
bSuccess = g_mount_eject_with_operation_finish (G_MOUNT (pObject), res, &erreur);
1251
bSuccess = g_mount_eject_finish (G_MOUNT (pObject), res, &erreur);
1255
cd_warning ("gvfs-integration : %s", erreur->message);
1256
g_error_free (erreur);
1259
cd_message ("(un)mounted -> %d", bSuccess);
1260
if (pCallback != NULL)
1261
pCallback (GPOINTER_TO_INT (data[1]) == 1, bSuccess, data[2], data[3], data[4]);
1267
static void cairo_dock_gio_vfs_mount (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data)
1269
g_return_if_fail (cURI != NULL);
1270
cd_message ("%s (%s)", __func__, cURI);
1272
gchar *cTargetURI = _cd_find_target_uri (cURI);
1273
GFile *pFile = g_file_new_for_uri (cURI);
1275
gpointer *data = g_new (gpointer, 6); // libere dans la callback.
1276
data[0] = pCallback;
1277
data[1] = GINT_TO_POINTER (1); // mount
1278
data[2] = (cTargetURI ? g_path_get_basename (cTargetURI) : g_strdup (cURI));
1279
data[3] = g_strdup (cURI);
1280
data[4] = user_data;
1282
GMountOperation *mount_op = gtk_mount_operation_new (GTK_WINDOW (g_pPrimaryContainer->pWidget));
1283
g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
1285
GFileType iType = g_file_query_file_type (pFile, G_FILE_QUERY_INFO_NONE, NULL);
1286
cd_debug ("iType: %d\n", iType);
1287
if (iType == G_FILE_TYPE_MOUNTABLE)
1289
data[5] = GINT_TO_POINTER (1);
1290
g_file_mount_mountable (pFile,
1294
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1297
else // smb share folders typically have an unknown type; we have to use the other mount function for these types of mount points.
1299
data[5] = GINT_TO_POINTER (0);
1300
g_file_mount_enclosing_volume (pFile,
1304
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1307
// unref mount_op here - g_file_mount_enclosing_volume() does ref for itself
1308
g_object_unref (mount_op);
1309
g_object_unref (pFile);
1310
g_free (cTargetURI);
1313
static void cairo_dock_gio_vfs_unmount (const gchar *cURI, int iVolumeID, CairoDockFMMountCallback pCallback, gpointer user_data)
1315
g_return_if_fail (cURI != NULL);
1316
cd_message ("%s (%s)", __func__, cURI);
1318
gchar *cTargetURI = NULL;
1319
GMount *pMount = _cd_find_mount_from_uri (cURI, &cTargetURI);
1320
if (pMount == NULL || ! G_IS_MOUNT (pMount))
1325
if ( ! g_mount_can_unmount (pMount))
1328
gboolean bCanEject = g_mount_can_eject (pMount);
1329
gboolean bCanUnmount = g_mount_can_unmount (pMount);
1330
cd_message ("eject:%d / unmount:%d", bCanEject, bCanUnmount);
1331
if (! bCanEject && ! bCanUnmount)
1333
cd_warning ("can't unmount this volume (%s)", cURI);
1337
gpointer *data = g_new (gpointer, 5);
1338
data[0] = pCallback;
1339
data[1] = GINT_TO_POINTER (bCanEject ? 2 : 0);
1340
data[2] = g_mount_get_name (pMount);
1341
data[3] = g_strdup (cURI);
1342
data[4] = user_data;
1344
#if GLIB_CHECK_VERSION (2, 22, 0)
1345
g_mount_eject_with_operation (pMount,
1346
G_MOUNT_UNMOUNT_NONE,
1349
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1352
g_mount_eject (pMount,
1353
G_MOUNT_UNMOUNT_NONE,
1355
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1359
#if GLIB_CHECK_VERSION (2, 22, 0)
1360
g_mount_unmount_with_operation (pMount,
1361
G_MOUNT_UNMOUNT_NONE,
1364
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1367
g_mount_unmount (pMount,
1368
G_MOUNT_UNMOUNT_NONE,
1370
(GAsyncReadyCallback) _gio_vfs_mount_callback,
1376
static void _on_monitor_changed (GFileMonitor *monitor,
1379
GFileMonitorEvent event_type,
1382
CairoDockFMMonitorCallback pCallback = data[0];
1383
gpointer user_data = data[1];
1384
cd_message ("%s (%d , data : %x)", __func__, event_type, user_data);
1386
CairoDockFMEventType iEventType;
1389
///case G_FILE_MONITOR_EVENT_CHANGED : // ignorer celui-ci devrait permettre d'eviter la moitie des signaux inutiles que gvfs emet.
1390
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT :
1391
//case G_FILE_MONITOR_EVENT_UNMOUNTED : // pertinent ?...
1392
iEventType = CAIRO_DOCK_FILE_MODIFIED;
1393
cd_message ("modification d'un fichier");
1396
case G_FILE_MONITOR_EVENT_DELETED :
1397
iEventType = CAIRO_DOCK_FILE_DELETED;
1398
cd_message ("effacement d'un fichier");
1401
case G_FILE_MONITOR_EVENT_CREATED :
1402
iEventType = CAIRO_DOCK_FILE_CREATED;
1403
cd_message ("creation d'un fichier");
1409
gchar *cURI = g_file_get_uri (file);
1410
cd_message (" c'est le fichier %s", cURI);
1411
gchar *cPath = NULL;
1412
if (strncmp (cURI, "computer://", 11) == 0)
1414
if (event_type == G_FILE_MONITOR_EVENT_CHANGED)
1419
memcpy (cURI+4, "file", 4);
1420
cPath = g_filename_from_uri (cURI+4, NULL, NULL);
1421
cd_debug(" (path:%s)", cPath);
1423
cURI = g_strdup_printf ("computer://%s", cPath);
1424
cd_message ("son URI complete est : %s", cURI);
1427
pCallback (iEventType, cURI, user_data);
1432
static void cairo_dock_gio_vfs_add_monitor (const gchar *cURI, gboolean bDirectory, CairoDockFMMonitorCallback pCallback, gpointer user_data)
1434
g_return_if_fail (cURI != NULL);
1435
GError *erreur = NULL;
1436
GFileMonitor *pMonitor;
1437
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1439
pMonitor = g_file_monitor_directory (pFile,
1440
G_FILE_MONITOR_WATCH_MOUNTS,
1444
pMonitor = g_file_monitor_file (pFile,
1445
G_FILE_MONITOR_WATCH_MOUNTS,
1448
g_object_unref (pFile);
1451
cd_warning ("gvfs-integration : couldn't add monitor on '%s' (%d) [%s]", cURI, bDirectory, erreur->message);
1452
g_error_free (erreur);
1456
gpointer *data = g_new0 (gpointer, 3);
1457
data[0] = pCallback;
1458
data[1] = user_data;
1460
g_signal_connect (G_OBJECT (pMonitor), "changed", G_CALLBACK (_on_monitor_changed), data);
1462
g_hash_table_insert (s_hMonitorHandleTable, g_strdup (cURI), data);
1463
cd_message (">>> moniteur ajoute sur %s (%x)", cURI, user_data);
1466
static void cairo_dock_gio_vfs_remove_monitor (const gchar *cURI)
1470
cd_message (">>> moniteur supprime sur %s", cURI);
1471
g_hash_table_remove (s_hMonitorHandleTable, cURI);
1477
static gboolean cairo_dock_gio_vfs_delete_file (const gchar *cURI, gboolean bNoTrash)
1479
g_return_val_if_fail (cURI != NULL, FALSE);
1480
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1482
GError *erreur = NULL;
1486
const gchar *cQuery = G_FILE_ATTRIBUTE_STANDARD_TYPE;
1487
GFileInfo *pFileInfo = g_file_query_info (pFile,
1489
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1494
cd_warning ("gvfs-integration : %s", erreur->message);
1495
g_error_free (erreur);
1496
g_object_unref (pFile);
1500
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
1501
if (iFileType == G_FILE_TYPE_DIRECTORY)
1503
_cairo_dock_gio_vfs_empty_dir (cURI);
1506
bSuccess = g_file_delete (pFile, NULL, &erreur);
1509
cd_warning ("gvfs-integration : %s", erreur->message);
1510
g_error_free (erreur);
1515
bSuccess = g_file_trash (pFile, NULL, &erreur);
1518
cd_warning ("gvfs-integration : %s", erreur->message);
1519
g_error_free (erreur);
1522
g_object_unref (pFile);
1526
static gboolean cairo_dock_gio_vfs_rename_file (const gchar *cOldURI, const gchar *cNewName)
1528
g_return_val_if_fail (cOldURI != NULL, FALSE);
1529
GFile *pOldFile = (*cOldURI == '/' ? g_file_new_for_path (cOldURI) : g_file_new_for_uri (cOldURI));
1530
GError *erreur = NULL;
1531
GFile *pNewFile = g_file_set_display_name (pOldFile, cNewName, NULL, &erreur);
1534
cd_warning ("gvfs-integration : %s", erreur->message);
1535
g_error_free (erreur);
1537
gboolean bSuccess = (pNewFile != NULL);
1538
if (pNewFile != NULL)
1539
g_object_unref (pNewFile);
1540
g_object_unref (pOldFile);
1544
static gboolean cairo_dock_gio_vfs_move_file (const gchar *cURI, const gchar *cDirectoryURI)
1546
g_return_val_if_fail (cURI != NULL, FALSE);
1547
cd_message (" %s -> %s", cURI, cDirectoryURI);
1548
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1550
gchar *cFileName = g_file_get_basename (pFile);
1551
gchar *cNewFileURI = g_strconcat (cDirectoryURI, "/", cFileName, NULL); // un peu moyen mais bon...
1552
GFile *pDestinationFile = (*cNewFileURI == '/' ? g_file_new_for_path (cNewFileURI) : g_file_new_for_uri (cNewFileURI));
1553
g_free (cNewFileURI);
1556
GError *erreur = NULL;
1557
gboolean bSuccess = g_file_move (pFile,
1559
G_FILE_COPY_NOFOLLOW_SYMLINKS,
1561
NULL, // GFileProgressCallback
1566
cd_warning ("gvfs-integration : %s", erreur->message);
1567
g_error_free (erreur);
1569
g_object_unref (pFile);
1570
g_object_unref (pDestinationFile);
1574
static gboolean cairo_dock_gio_vfs_create_file (const gchar *cURI, gboolean bDirectory)
1576
g_return_val_if_fail (cURI != NULL, FALSE);
1577
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1579
GError *erreur = NULL;
1580
gboolean bSuccess = TRUE;
1581
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 18)
1583
g_file_make_directory_with_parents (pFile, NULL, &erreur);
1586
g_file_create (pFile, G_FILE_CREATE_PRIVATE, NULL, &erreur);
1589
cd_warning ("gvfs-integration : %s", erreur->message);
1590
g_error_free (erreur);
1593
g_object_unref (pFile);
1598
static void cairo_dock_gio_vfs_get_file_properties (const gchar *cURI, guint64 *iSize, time_t *iLastModificationTime, gchar **cMimeType, int *iUID, int *iGID, int *iPermissionsMask)
1600
g_return_if_fail (cURI != NULL);
1601
GFile *pFile = (*cURI == '/' ? g_file_new_for_path (cURI) : g_file_new_for_uri (cURI));
1602
GError *erreur = NULL;
1603
const gchar *cQuery = G_FILE_ATTRIBUTE_STANDARD_SIZE","
1604
G_FILE_ATTRIBUTE_TIME_MODIFIED","
1605
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE","
1606
G_FILE_ATTRIBUTE_UNIX_UID","
1607
G_FILE_ATTRIBUTE_UNIX_GID","
1608
G_FILE_ATTRIBUTE_ACCESS_CAN_READ","
1609
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE","
1610
G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE;
1611
GFileInfo *pFileInfo = g_file_query_info (pFile,
1613
G_FILE_QUERY_INFO_NONE, /// G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS
1618
cd_warning ("gvfs-integration : couldn't get file properties for '%s' [%s]", cURI, erreur->message);
1619
g_error_free (erreur);
1622
*iSize = g_file_info_get_attribute_uint64 (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE);
1623
*iLastModificationTime = (time_t) g_file_info_get_attribute_uint64 (pFileInfo, G_FILE_ATTRIBUTE_TIME_MODIFIED);
1624
*cMimeType = g_file_info_get_attribute_as_string (pFileInfo, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
1625
*iUID = g_file_info_get_attribute_uint32 (pFileInfo, G_FILE_ATTRIBUTE_UNIX_UID);
1626
*iGID = g_file_info_get_attribute_uint32 (pFileInfo, G_FILE_ATTRIBUTE_UNIX_GID);
1627
gboolean r = g_file_info_get_attribute_boolean (pFileInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
1628
gboolean w = g_file_info_get_attribute_boolean (pFileInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
1629
gboolean x = g_file_info_get_attribute_boolean (pFileInfo, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
1630
*iPermissionsMask = r * 8 * 8 + w * 8 + x;
1632
g_object_unref (pFileInfo);
1633
g_object_unref (pFile);
1637
static gchar *cairo_dock_gio_vfs_get_trash_path (const gchar *cNearURI, gchar **cFileInfoPath)
1639
if (cNearURI == NULL)
1640
return g_strdup ("trash://");
1641
gchar *cPath = NULL;
1642
/*GFile *pFile = g_file_new_for_uri ("trash://");
1643
gchar *cPath = g_file_get_path (pFile);
1644
g_object_unref (pFile);*/
1645
const gchar *xdgPath = g_getenv ("XDG_DATA_HOME");
1646
if (xdgPath != NULL)
1648
cPath = g_strdup_printf ("%s/Trash/files", xdgPath);
1649
if (cFileInfoPath != NULL)
1650
*cFileInfoPath = g_strdup_printf ("%s/Trash/info", xdgPath);
1654
cPath = g_strdup_printf ("%s/.local/share/Trash/files", g_getenv ("HOME"));
1655
if (cFileInfoPath != NULL)
1656
*cFileInfoPath = g_strdup_printf ("%s/.local/share/Trash/info", g_getenv ("HOME"));
1661
static gchar *cairo_dock_gio_vfs_get_desktop_path (void)
1663
GFile *pFile = g_file_new_for_uri ("desktop://");
1664
gchar *cPath = g_file_get_path (pFile);
1665
g_object_unref (pFile);
1669
static void _cairo_dock_gio_vfs_empty_dir (const gchar *cBaseURI)
1671
if (cBaseURI == NULL)
1674
GFile *pFile = (*cBaseURI == '/' ? g_file_new_for_path (cBaseURI) : g_file_new_for_uri (cBaseURI));
1675
GError *erreur = NULL;
1676
const gchar *cAttributes = G_FILE_ATTRIBUTE_STANDARD_TYPE","
1677
G_FILE_ATTRIBUTE_STANDARD_NAME;
1678
GFileEnumerator *pFileEnum = g_file_enumerate_children (pFile,
1680
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1685
cd_warning ("gvfs-integration : %s", erreur->message);
1686
g_object_unref (pFile);
1687
g_error_free (erreur);
1691
GString *sFileUri = g_string_new ("");
1692
GFileInfo *pFileInfo;
1696
pFileInfo = g_file_enumerator_next_file (pFileEnum, NULL, &erreur);
1699
cd_warning ("gvfs-integration : %s", erreur->message);
1700
g_error_free (erreur);
1704
if (pFileInfo == NULL)
1707
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
1708
const gchar *cFileName = g_file_info_get_name (pFileInfo);
1710
g_string_printf (sFileUri, "%s/%s", cBaseURI, cFileName);
1711
if (iFileType == G_FILE_TYPE_DIRECTORY)
1713
_cairo_dock_gio_vfs_empty_dir (sFileUri->str);
1716
file = (*cBaseURI == '/' ? g_file_new_for_path (sFileUri->str) : g_file_new_for_uri (sFileUri->str));
1717
g_file_delete (file, NULL, &erreur);
1720
cd_warning ("gvfs-integration : %s", erreur->message);
1721
g_error_free (erreur);
1724
g_object_unref (file);
1726
g_object_unref (pFileInfo);
1729
g_string_free (sFileUri, TRUE);
1730
g_object_unref (pFileEnum);
1731
g_object_unref (pFile);
1734
static inline int _convert_base16 (char c)
1737
if (c >= '0' && c <= '9')
1743
static void cairo_dock_gio_vfs_empty_trash (void)
1745
GFile *pFile = g_file_new_for_uri ("trash://");
1746
GError *erreur = NULL;
1747
const gchar *cAttributes = G_FILE_ATTRIBUTE_STANDARD_TARGET_URI","
1748
G_FILE_ATTRIBUTE_STANDARD_NAME","
1749
G_FILE_ATTRIBUTE_STANDARD_TYPE;
1750
GFileEnumerator *pFileEnum = g_file_enumerate_children (pFile,
1752
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1757
cd_warning ("gvfs-integration : %s", erreur->message);
1758
g_object_unref (pFile);
1759
g_error_free (erreur);
1763
GString *sFileUri = g_string_new ("");
1764
GFileInfo *pFileInfo;;
1767
pFileInfo = g_file_enumerator_next_file (pFileEnum, NULL, &erreur);
1770
cd_warning ("gvfs-integration : %s", erreur->message);
1771
g_error_free (erreur);
1775
if (pFileInfo == NULL)
1778
const gchar *cFileName = g_file_info_get_name (pFileInfo);
1779
//g_print (" - %s\n", cFileName);
1781
// il y'a 2 cas : un fichier dans la poubelle du home, et un fichier dans une poubelle d'un autre volume.
1782
if (cFileName && *cFileName == '\\') // nom de la forme "\media\Fabounet2\.Trash-1000\files\t%C3%A8st%201" et URI "trash:///%5Cmedia%5CFabounet2%5C.Trash-1000%5Cfiles%5Ct%25C3%25A8st%25201", mais cette URI ne marche pas des qu'il y'a des caracteres non ASCII-7 dans le nom (bug dans gio/gvfs ?). Donc on feinte, en construisant le chemin du fichier (et de son double dans 'info').
1784
g_string_printf (sFileUri, "file://%s", cFileName);
1785
g_strdelimit (sFileUri->str, "\\", '/');
1786
//g_print (" - %s\n", sFileUri->str);
1788
GFileType iFileType = g_file_info_get_file_type (pFileInfo);
1789
if (iFileType == G_FILE_TYPE_DIRECTORY) // can't delete a non-empty folder located on a different volume than home.
1791
_cairo_dock_gio_vfs_empty_dir (sFileUri->str);
1793
GFile *file = g_file_new_for_uri (sFileUri->str);
1794
g_file_delete (file, NULL, &erreur);
1795
g_object_unref (file);
1797
gchar *str = g_strrstr (sFileUri->str, "/files/");
1801
gchar *cInfo = g_strdup_printf ("%s/info/%s.trashinfo", sFileUri->str, str+7);
1802
//g_print (" - %s\n", cInfo);
1803
file = g_file_new_for_uri (cInfo);
1805
g_file_delete (file, NULL, NULL);
1806
g_object_unref (file);
1809
else // poubelle principale : nom de la forme "tȿst 1" et URI "trash:///t%C3%A8st%201"
1811
if (strchr (cFileName, '%')) // if there is a % inside the name, it disturb gio, so let's remove it.
1813
gchar *cTmpPath = g_strdup_printf ("/%s", cFileName);
1814
gchar *cEscapedFileName = g_filename_to_uri (cTmpPath, NULL, NULL);
1816
g_string_printf (sFileUri, "trash://%s", cEscapedFileName+7); // replace file:// with trash://
1817
g_free (cEscapedFileName);
1819
else // else it can handle the URI as usual.
1820
g_string_printf (sFileUri, "trash:///%s", cFileName);
1821
GFile *file = g_file_new_for_uri (sFileUri->str);
1822
/*gchar *cValidURI = g_file_get_uri (file);
1823
//g_print (" - %s\n", cValidURI);
1824
g_object_unref (file);
1826
file = g_file_new_for_uri (cValidURI);
1827
g_free (cValidURI);*/
1828
g_file_delete (file, NULL, &erreur);
1829
g_object_unref (file);
1833
cd_warning ("gvfs-integration : %s", erreur->message);
1834
g_error_free (erreur);
1838
g_object_unref (pFileInfo);
1841
g_string_free (sFileUri, TRUE);
1842
g_object_unref (pFileEnum);
1843
g_object_unref (pFile);
1846
static GList *cairo_dock_gio_vfs_list_apps_for_file (const gchar *cBaseURI)
1849
if (*cBaseURI == '/')
1850
cValidUri = g_filename_to_uri (cBaseURI, NULL, NULL);
1852
cValidUri = g_strdup (cBaseURI);
1853
GFile *pFile = g_file_new_for_uri (cValidUri);
1855
GError *erreur = NULL;
1856
const gchar *cQuery = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE;
1857
GFileInfo *pFileInfo = g_file_query_info (pFile,
1859
G_FILE_QUERY_INFO_NONE,
1863
if (erreur != NULL) // peut arriver si l'emplacement n'est pas monte, mais on signale tout de meme la raison avec un warning.
1865
cd_warning ("gvfs-integration : %s", erreur->message);
1866
g_error_free (erreur);
1868
g_object_unref (pFile);
1872
const gchar *cMimeType = g_file_info_get_content_type (pFileInfo);
1874
GList *pAppsList = g_app_info_get_all_for_type (cMimeType);
1876
GList *pList = NULL;
1880
for (a = pAppsList; a != NULL; a = a->next)
1883
pIcon = g_app_info_get_icon (pAppInfo);
1885
pData = g_new0 (gchar*, 4);
1886
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 24)
1887
pData[0] = g_strdup (g_app_info_get_display_name (pAppInfo));
1889
pData[0] = g_strdup (g_app_info_get_name (pAppInfo));
1891
pData[1] = g_strdup (g_app_info_get_executable (pAppInfo));
1893
#if (GLIB_MAJOR_VERSION > 2) || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 20)
1894
pData[2] = g_icon_to_string (pIcon);
1896
pData[2] = _cd_get_icon_path (pIcon, NULL);
1898
pList = g_list_prepend (pList, pData);
1900
pList = g_list_reverse (pList);
1903
g_object_unref (pFile);
1904
g_list_free (pAppsList);
1905
g_object_unref (pFileInfo);
1909
gboolean cairo_dock_gio_vfs_fill_backend(CairoDockDesktopEnvBackend *pVFSBackend)
1913
pVFSBackend->get_file_info = cairo_dock_gio_vfs_get_file_info;
1914
pVFSBackend->get_file_properties = cairo_dock_gio_vfs_get_file_properties;
1915
pVFSBackend->list_directory = cairo_dock_gio_vfs_list_directory;
1916
pVFSBackend->measure_directory = cairo_dock_gio_vfs_measure_directory;
1917
pVFSBackend->launch_uri = cairo_dock_gio_vfs_launch_uri;
1918
pVFSBackend->is_mounted = cairo_dock_gio_vfs_is_mounted;
1919
pVFSBackend->can_eject = cairo_dock_gio_vfs_can_eject;
1920
pVFSBackend->eject = cairo_dock_gio_vfs_eject_drive;
1921
pVFSBackend->mount = cairo_dock_gio_vfs_mount;
1922
pVFSBackend->unmount = cairo_dock_gio_vfs_unmount;
1923
pVFSBackend->add_monitor = cairo_dock_gio_vfs_add_monitor;
1924
pVFSBackend->remove_monitor = cairo_dock_gio_vfs_remove_monitor;
1925
pVFSBackend->delete_file = cairo_dock_gio_vfs_delete_file;
1926
pVFSBackend->rename = cairo_dock_gio_vfs_rename_file;
1927
pVFSBackend->move = cairo_dock_gio_vfs_move_file;
1928
pVFSBackend->create = cairo_dock_gio_vfs_create_file;
1929
pVFSBackend->get_trash_path = cairo_dock_gio_vfs_get_trash_path;
1930
pVFSBackend->empty_trash = cairo_dock_gio_vfs_empty_trash;
1931
pVFSBackend->get_desktop_path = cairo_dock_gio_vfs_get_desktop_path;
1932
pVFSBackend->list_apps_for_file = cairo_dock_gio_vfs_list_apps_for_file;
1940
gboolean cairo_dock_gio_vfs_init (void)
1945
gboolean cairo_dock_gio_vfs_fill_backend(CairoDockDesktopEnvBackend *pVFSBackend)