diff options
author | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-01-14 04:42:01 +0800 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-01-14 04:42:01 +0800 |
commit | af1c2ceaef7d949e36a7680f463c5e25f79c43d6 (patch) | |
tree | 19c94f1df613831ed8ab92b4ac904be0c20c673f /lib | |
parent | 12d96e8a6fc9eddaffdbad58754e712af5fc5fef (diff) | |
download | gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.gz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.bz2 gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.lz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.xz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.zst gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.zip |
Drop gnome-vfs dependency. Now Epiphany depends on glib >= 2.15.1.
Also, optional Zeroconf support depends on Avahi >= 0.6.22.
Bug #507152.
svn path=/trunk/; revision=7858
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/egg/Makefile.am | 6 | ||||
-rw-r--r-- | lib/ephy-file-chooser.c | 6 | ||||
-rw-r--r-- | lib/ephy-file-helpers.c | 708 | ||||
-rw-r--r-- | lib/ephy-file-helpers.h | 35 | ||||
-rw-r--r-- | lib/ephy-node-db.c | 17 | ||||
-rw-r--r-- | lib/ephy-string.c | 240 | ||||
-rw-r--r-- | lib/ephy-string.h | 6 |
8 files changed, 389 insertions, 630 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 5c3236bb6..b576d0398 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -77,6 +77,7 @@ nodist_libephymisc_la_SOURCES = \ libephymisc_la_CPPFLAGS = \ -I$(top_builddir)/lib \ + -I$(top_builddir)/lib/egg \ -DSHARE_DIR=\"$(pkgdatadir)\" \ -DEXTENSIONS_DIR=\""$(libdir)/epiphany/$(EPIPHANY_MAJOR)/extensions"\" \ $(AM_CPPFLAGS) diff --git a/lib/egg/Makefile.am b/lib/egg/Makefile.am index ba0586033..206aa0184 100644 --- a/lib/egg/Makefile.am +++ b/lib/egg/Makefile.am @@ -2,13 +2,15 @@ EGGSOURCES = \ eggtreemultidnd.c \ egg-editable-toolbar.c \ egg-toolbars-model.c \ - egg-toolbar-editor.c + egg-toolbar-editor.c \ + eel-app-launch-context.c EGGHEADERS = \ eggtreemultidnd.h \ egg-editable-toolbar.h \ egg-toolbars-model.h \ - egg-toolbar-editor.h + egg-toolbar-editor.h \ + eel-app-launch-context.h noinst_HEADERS = \ $(EGGHEADERS) \ diff --git a/lib/ephy-file-chooser.c b/lib/ephy-file-chooser.c index 0bdc52f48..9b3fa7d38 100644 --- a/lib/ephy-file-chooser.c +++ b/lib/ephy-file-chooser.c @@ -28,10 +28,10 @@ #include "ephy-gui.h" #include "ephy-debug.h" #include "ephy-stock-icons.h" +#include "ephy-string.h" #include <gtk/gtkstock.h> #include <gtk/gtkimage.h> -#include <libgnomevfs/gnome-vfs-utils.h> #include <glib/gi18n.h> #define EPHY_FILE_CHOOSER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_FILE_CHOOSER, EphyFileChooserPrivate)) @@ -175,12 +175,14 @@ ephy_file_chooser_set_persist_key (EphyFileChooser *dialog, const char *key) dir = eel_gconf_get_string (key); if (dir != NULL) { + /* FIXME: Maybe we will find a better way to do this when the + * gio-filechooser will be in GTK+ */ converted = g_filename_from_utf8 (dir, -1, NULL, NULL, NULL); if (converted != NULL) { - expanded = gnome_vfs_expand_initial_tilde (converted); + expanded = ephy_string_expand_initial_tilde (converted); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), expanded); diff --git a/lib/ephy-file-helpers.c b/lib/ephy-file-helpers.c index 8fb7b4970..65b74db8b 100644 --- a/lib/ephy-file-helpers.c +++ b/lib/ephy-file-helpers.c @@ -27,26 +27,22 @@ #include "ephy-prefs.h" #include "eel-gconf-extensions.h" +#include "eel-app-launch-context.h" #include "ephy-debug.h" +#include "ephy-string.h" #include <glib.h> #include <glib/gi18n.h> +#include <gio/gio.h> +#include <gio/gdesktopappinfo.h> #include <libgnome/gnome-init.h> -#include <libgnomevfs/gnome-vfs-utils.h> -#include <libgnomevfs/gnome-vfs-file-info.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-directory.h> -#include <libgnomevfs/gnome-vfs-xfer.h> #include <libxml/xmlreader.h> /* bug http://bugzilla.gnome.org/show_bug.cgi?id=156687 */ #undef GNOME_DISABLE_DEPRECATED #include <libgnome/gnome-desktop-item.h> -#define SN_API_NOT_YET_FROZEN -#include <libsn/sn.h> #include <gdk/gdk.h> -#include <gdk/gdkx.h> #include <gtk/gtkrecentmanager.h> #include <string.h> @@ -162,7 +158,7 @@ ephy_file_get_downloads_dir (void) g_return_val_if_fail (download_dir != NULL, NULL); - expanded = gnome_vfs_expand_initial_tilde (download_dir); + expanded = ephy_string_expand_initial_tilde (download_dir); g_free (download_dir); return expanded; @@ -433,35 +429,46 @@ ephy_file_find (const char *path, } gboolean -ephy_file_switch_temp_file (const char *filename, - const char *filename_temp) +ephy_file_switch_temp_file (GFile *file, + GFile *file_temp) { - char *old_file; + char *file_path, *file_temp_path; + char *old_file_path; gboolean old_exist; gboolean retval = TRUE; + GFile *old_file; - old_file = g_strconcat (filename, ".old", NULL); + file_path = g_file_get_path (file); + file_temp_path = g_file_get_path (file_temp); + old_file_path = g_strconcat (file_path, ".old", NULL); - old_exist = g_file_test (filename, G_FILE_TEST_EXISTS); + old_file = g_file_new_for_path (old_file_path); + old_exist = g_file_test (file_path, G_FILE_TEST_EXISTS); if (old_exist) { - if (rename (filename, old_file) < 0) + if (g_file_move (file, old_file, + G_FILE_COPY_OVERWRITE, + NULL, NULL, NULL, NULL) == FALSE) { - g_warning ("Failed to rename %s to %s", filename, old_file); + g_warning ("Failed to rename %s to %s", file_path, old_file_path); retval = FALSE; goto failed; } } - if (rename (filename_temp, filename) < 0) + if (g_file_move (file_temp, file, + G_FILE_COPY_OVERWRITE, + NULL, NULL, NULL, NULL) == FALSE) { - g_warning ("Failed to rename %s to %s", filename_temp, filename); + g_warning ("Failed to rename %s to %s", file_temp_path, file_path); - if (rename (old_file, filename) < 0) + if (g_file_move (old_file, file, + G_FILE_COPY_OVERWRITE, + NULL, NULL, NULL, NULL) == FALSE) { g_warning ("Failed to restore %s from %s", - filename, filename_temp); + file_path, file_temp_path); } retval = FALSE; goto failed; @@ -469,20 +476,24 @@ ephy_file_switch_temp_file (const char *filename, if (old_exist) { - if (unlink (old_file) < 0) + if (g_file_delete (old_file, + NULL, NULL) == FALSE) { - g_warning ("Failed to delete old file %s", old_file); + g_warning ("Failed to delete old file %s", old_file_path); } } failed: - g_free (old_file); + g_free (old_file_path); + g_free (file_path); + g_free (file_temp_path); + g_object_unref (old_file); return retval; } void -ephy_file_delete_on_exit (const char *path) +ephy_file_delete_on_exit (GFile *file) { /* does nothing now */ } @@ -583,441 +594,110 @@ ephy_file_check_mime (const char *mime_type) return permission; } -/* Copied from nautilus-program-choosing.c */ - -extern char **environ; - -/* Cut and paste from gdkspawn-x11.c */ -static gchar ** -my_gdk_spawn_make_environment_for_screen (GdkScreen *screen, - gchar **envp) -{ - gchar **retval = NULL; - gchar *display_name; - gint i, j = 0, env_len; - - g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); - - if (envp == NULL) - envp = environ; - - env_len = g_strv_length (envp); - retval = g_new (char *, env_len + 3); - - display_name = gdk_screen_make_display_name (screen); - - for (i = 0; envp[i] != NULL; i++) - if (!g_str_has_prefix (envp[i], "DISPLAY=") && - !g_str_has_prefix (envp[i], EPHY_UUID_ENVVAR "=")) - retval[j++] = g_strdup (envp[i]); - - retval[j++] = g_strconcat ("DISPLAY=", display_name, NULL); - retval[j++] = g_strdup (EPHY_UUID_ENVSTRING); - retval[j] = NULL; - - g_free (display_name); - - return retval; -} - -static void -sn_error_trap_push (SnDisplay *display, - Display *xdisplay) -{ - gdk_error_trap_push (); -} - -static void -sn_error_trap_pop (SnDisplay *display, - Display *xdisplay) -{ - gdk_error_trap_pop (); -} - -static char ** -make_spawn_environment_for_sn_context (SnLauncherContext *sn_context, - char **envp) -{ - char **retval; - int i, j, len; - - retval = NULL; - - if (envp == NULL) { - envp = environ; - } - - len = g_strv_length (envp); - retval = g_new (char *, len + 3); - - for (i = 0, j = 0; envp[i] != NULL; i++) { - if (!g_str_has_prefix (envp[i], "DESKTOP_STARTUP_ID=") && - !g_str_has_prefix (envp[i], EPHY_UUID_ENVVAR "=")) { - retval[j++] = g_strdup (envp[i]); - } - } - - retval[j++] = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", - sn_launcher_context_get_startup_id (sn_context)); - retval[j++] = g_strdup (EPHY_UUID_ENVSTRING); - retval[j] = NULL; - - return retval; -} - -/* This should be fairly long, as it's confusing to users if a startup - * ends when it shouldn't (it appears that the startup failed, and - * they have to relaunch the app). Also the timeout only matters when - * there are bugs and apps don't end their own startup sequence. - * - * This timeout is a "last resort" timeout that ignores whether the - * startup sequence has shown activity or not. Metacity and the - * tasklist have smarter, and correspondingly able-to-be-shorter - * timeouts. The reason our timeout is dumb is that we don't monitor - * the sequence (don't use an SnMonitorContext) - */ -#define STARTUP_TIMEOUT_LENGTH (30 /* seconds */ * 1000) - -typedef struct -{ - GdkScreen *screen; - GSList *contexts; - guint timeout_id; -} StartupTimeoutData; - -static void -free_startup_timeout (void *data) -{ - StartupTimeoutData *std; - - std = data; - - g_slist_foreach (std->contexts, - (GFunc) sn_launcher_context_unref, - NULL); - g_slist_free (std->contexts); - - if (std->timeout_id != 0) { - g_source_remove (std->timeout_id); - std->timeout_id = 0; - } - - g_free (std); -} - -static gboolean -startup_timeout (void *data) -{ - StartupTimeoutData *std; - GSList *tmp; - GTimeVal now; - int min_timeout; - - std = data; - - min_timeout = STARTUP_TIMEOUT_LENGTH; - - g_get_current_time (&now); - - tmp = std->contexts; - while (tmp != NULL) { - SnLauncherContext *sn_context; - GSList *next; - long tv_sec, tv_usec; - double elapsed; - - sn_context = tmp->data; - next = tmp->next; - - sn_launcher_context_get_last_active_time (sn_context, - &tv_sec, &tv_usec); - - elapsed = - ((((double)now.tv_sec - tv_sec) * G_USEC_PER_SEC + - (now.tv_usec - tv_usec))) / 1000.0; - - if (elapsed >= STARTUP_TIMEOUT_LENGTH) { - std->contexts = g_slist_remove (std->contexts, - sn_context); - sn_launcher_context_complete (sn_context); - sn_launcher_context_unref (sn_context); - } else { - min_timeout = MIN (min_timeout, (STARTUP_TIMEOUT_LENGTH - elapsed)); - } - - tmp = next; - } - - if (std->contexts == NULL) { - std->timeout_id = 0; - } else { - std->timeout_id = g_timeout_add (min_timeout, - startup_timeout, - std); - } - - /* always remove this one, but we may have reinstalled another one. */ - return FALSE; -} - -static void -add_startup_timeout (GdkScreen *screen, - SnLauncherContext *sn_context) -{ - StartupTimeoutData *data; - - data = g_object_get_data (G_OBJECT (screen), "nautilus-startup-data"); - if (data == NULL) { - data = g_new (StartupTimeoutData, 1); - data->screen = screen; - data->contexts = NULL; - data->timeout_id = 0; - - g_object_set_data_full (G_OBJECT (screen), "nautilus-startup-data", - data, free_startup_timeout); - } - - sn_launcher_context_ref (sn_context); - data->contexts = g_slist_prepend (data->contexts, sn_context); - - if (data->timeout_id == 0) { - data->timeout_id = g_timeout_add (STARTUP_TIMEOUT_LENGTH, - startup_timeout, - data); - } -} - gboolean -ephy_file_launch_application (GnomeVFSMimeApplication *application, - const char *parameter, - guint32 user_time) +ephy_file_launch_application (GAppInfo *app, + GList *files, + guint32 user_time, + GtkWidget *widget) { - GdkScreen *screen; - GList *uris = NULL; - char *uri; - char **envp; - GnomeVFSResult result; - SnLauncherContext *sn_context; - SnDisplay *sn_display; - - g_return_val_if_fail (application != NULL, FALSE); - g_return_val_if_fail (parameter != NULL, FALSE); - - uri = gnome_vfs_make_uri_canonical (parameter); - if (uri == NULL) return FALSE; - - uris = g_list_prepend (NULL, uri); - - /* FIXME multihead! */ - screen = gdk_screen_get_default (); - envp = my_gdk_spawn_make_environment_for_screen (screen, NULL); - - sn_display = sn_display_new (gdk_display, - sn_error_trap_push, - sn_error_trap_pop); - + GAppLaunchContext *context; + GdkDisplay *display; + GdkScreen *screen; - /* Only initiate notification if application supports it. */ - if (gnome_vfs_mime_application_supports_startup_notification (application)) + context = G_APP_LAUNCH_CONTEXT (eel_app_launch_context_new ()); + if (widget) { - char *name; - - sn_context = sn_launcher_context_new (sn_display, - screen ? gdk_screen_get_number (screen) : - DefaultScreen (gdk_display)); - - name = g_filename_display_basename (uri); - if (name != NULL) { - char *description; - - sn_launcher_context_set_name (sn_context, name); - - /* FIXME: i18n after string freeze! */ - description = g_strdup_printf ("Opening %s", name); - - sn_launcher_context_set_description (sn_context, description); - - g_free (name); - g_free (description); - } - - if (!sn_launcher_context_get_initiated (sn_context)) { - const char *binary_name; - char **old_envp; - - binary_name = gnome_vfs_mime_application_get_binary_name (application); - - sn_launcher_context_set_binary_name (sn_context, - binary_name); - - sn_launcher_context_initiate (sn_context, - g_get_prgname () ? g_get_prgname () : "unknown", - binary_name, - (Time) user_time); - - old_envp = envp; - envp = make_spawn_environment_for_sn_context (sn_context, envp); - g_strfreev (old_envp); - } - } else { - sn_context = NULL; - } - - result = gnome_vfs_mime_application_launch_with_env (application, uris, envp); - - if (sn_context != NULL) { - if (result != GNOME_VFS_OK) { - sn_launcher_context_complete (sn_context); /* end sequence */ - } else { - add_startup_timeout (screen ? screen : - gdk_display_get_default_screen (gdk_display_get_default ()), - sn_context); - } - sn_launcher_context_unref (sn_context); + display = gtk_widget_get_display (widget); + screen = gtk_widget_get_screen (widget); } - - sn_display_unref (sn_display); - - g_strfreev (envp); - g_list_foreach (uris, (GFunc) g_free,NULL); - g_list_free (uris); - - if (result != GNOME_VFS_OK) + else { - g_warning ("Cannot launch application '%s'\n", - gnome_vfs_mime_application_get_name (application)); + display = gdk_display_get_default (); + screen = gdk_screen_get_default (); } - - return result == GNOME_VFS_OK; -} - -/* End cut-paste-adapt from nautilus */ - -static int -launch_desktop_item (const char *desktop_file, - const char *parameter, - guint32 user_time, - GError **error) -{ - GnomeDesktopItem *item = NULL; - GdkScreen *screen; - GList *uris = NULL; - char *canonical; - int ret = -1; - char **envp; - /* FIXME multihead! */ - screen = gdk_screen_get_default (); - envp = my_gdk_spawn_make_environment_for_screen (screen, NULL); - - item = gnome_desktop_item_new_from_file (desktop_file, 0, NULL); - if (item == NULL) return FALSE; - - if (parameter != NULL) - { - canonical = gnome_vfs_make_uri_canonical (parameter); - uris = g_list_append (uris, canonical); - } - - gnome_desktop_item_set_launch_time (item, user_time); - ret = gnome_desktop_item_launch_with_env (item, uris, 0, envp, error); - - g_list_foreach (uris, (GFunc) g_free, NULL); - g_list_free (uris); - g_strfreev (envp); - gnome_desktop_item_unref (item); - - return ret; + eel_app_launch_context_set_display (EEL_APP_LAUNCH_CONTEXT (context), + display); + eel_app_launch_context_set_screen (EEL_APP_LAUNCH_CONTEXT (context), + screen); + eel_app_launch_context_set_timestamp (EEL_APP_LAUNCH_CONTEXT (context), + user_time); + + return g_app_info_launch (app, files, context, NULL); } gboolean ephy_file_launch_desktop_file (const char *filename, const char *parameter, - guint32 user_time) + guint32 user_time, + GtkWidget *widget) { - GError *error = NULL; - const char * const *dirs; - char *path = NULL; - int i, ret = -1; - - dirs = g_get_system_data_dirs (); - if (dirs == NULL) return FALSE; - - for (i = 0; dirs[i] != NULL; i++) - { - path = g_build_filename (dirs[i], "applications", filename, NULL); - - if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) break; - - g_free (path); - path = NULL; - } - - if (path != NULL) - { - ret = launch_desktop_item (path, parameter, user_time, &error); - - if (ret == -1 || error != NULL) - { - g_warning ("Cannot launch desktop item '%s': %s\n", - path, error ? error->message : "(unknown error)"); - g_clear_error (&error); - } - - g_free (path); - } + GDesktopAppInfo *app; + GFile *file; + GList *list = NULL; + gboolean ret; - return ret >= 0; + app = g_desktop_app_info_new (filename); + file = g_file_new_for_path (parameter); + list = g_list_append (list, file); + + ret = ephy_file_launch_application (G_APP_INFO (app), list, user_time, widget); + g_list_free (list); + g_object_unref (file); + return ret; } gboolean ephy_file_launch_handler (const char *mime_type, - const char *address, + GFile *file, guint32 user_time) { - GnomeVFSMimeApplication *app = NULL; - GnomeVFSFileInfo *info = NULL; - char *canonical; + GAppInfo *app = NULL; gboolean ret = FALSE; - g_return_val_if_fail (address != NULL, FALSE); - - canonical = gnome_vfs_make_uri_canonical (address); - if (canonical == NULL) return FALSE; + g_return_val_if_fail (file != NULL, FALSE); if (mime_type != NULL) { - app = gnome_vfs_mime_get_default_application (mime_type); + app = g_app_info_get_default_for_type (mime_type, + FALSE); } else { + GFileInfo *file_info; + char *type; + /* Sniff mime type and check if it's safe to open */ - info = gnome_vfs_file_info_new (); - if (gnome_vfs_get_file_info (canonical, info, - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE) == GNOME_VFS_OK && - (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) && - info->mime_type != NULL && - info->mime_type[0] != '\0' && - ephy_file_check_mime (info->mime_type) == EPHY_MIME_PERMISSION_SAFE) + file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, NULL, NULL); + if (file_info == NULL) { + return FALSE; + } + type = g_strdup (g_file_info_get_content_type (file_info)); + + g_object_unref (file_info); + + if (type != NULL && type[0] != '\0' && + ephy_file_check_mime (type) == EPHY_MIME_PERMISSION_SAFE) { /* FIXME rename tmp file to right extension ? */ - app = gnome_vfs_mime_get_default_application (info->mime_type); + app = g_app_info_get_default_for_type (type, FALSE); } - gnome_vfs_file_info_unref (info); + g_free (type); } if (app != NULL) { - ret = ephy_file_launch_application (app, address, user_time); - - gnome_vfs_mime_application_free (app); + GList *list = NULL; + + list = g_list_append (list, file); + ret = ephy_file_launch_application (app, list, user_time, NULL); + g_list_free (list); } else ret = FALSE; - g_free (canonical); - return ret; } @@ -1025,197 +705,34 @@ gboolean ephy_file_browse_to (const char *parameter, guint32 user_time) { - GnomeVFSURI *uri, *parent_uri, *desktop; + GFile *file, *parent, *desktop; char *desktop_dir; gboolean ret; - uri = gnome_vfs_uri_new (parameter); - parent_uri = gnome_vfs_uri_get_parent (uri); - + file = g_file_new_for_path (parameter); desktop_dir = ephy_file_desktop_dir (); - desktop = gnome_vfs_uri_new (desktop_dir); + desktop = g_file_new_for_path (desktop_dir); /* Don't do anything if destination is the desktop */ - if (gnome_vfs_uri_equal (desktop, parent_uri)) + if (g_file_contains_file (desktop, file)) { ret = FALSE; } else { + parent = g_file_get_parent (file); /* TODO find a way to make nautilus scroll to the actual file */ ret = ephy_file_launch_handler ("x-directory/normal", - gnome_vfs_uri_get_path (parent_uri), + parent, user_time); } g_free (desktop_dir); - gnome_vfs_uri_unref (uri); - gnome_vfs_uri_unref (parent_uri); - gnome_vfs_uri_unref (desktop); + g_object_unref (file); return ret; } -struct _EphyFileMonitor -{ - GnomeVFSMonitorHandle *handle; - EphyFileMonitorFunc callback; - EphyFileMonitorDelayFunc delay_func; - gpointer user_data; - char *uri; - guint delay; - guint timeout_id; - guint ticks; - GnomeVFSMonitorEventType type; -}; - -static gboolean -ephy_file_monitor_timeout_cb (EphyFileMonitor *monitor) -{ - if (monitor->ticks > 0) - { - monitor->ticks--; - - /* Run again */ - return TRUE; - } - - if (monitor->delay_func && - monitor->delay_func (monitor, monitor->user_data)) - { - monitor->ticks = DELAY_MAX_TICKS / 2; - - /* Run again */ - return TRUE; - } - - monitor->timeout_id = 0; - - monitor->callback (monitor, monitor->uri, monitor->type, monitor->user_data); - - /* don't run again */ - return FALSE; -} - -static void -ephy_file_monitor_cb (GnomeVFSMonitorHandle *handle, - const char *monitor_uri, - const char *info_uri, - GnomeVFSMonitorEventType event_type, - EphyFileMonitor *monitor) -{ - LOG ("File '%s' has changed, scheduling reload", monitor_uri); - - switch (event_type) - { - case GNOME_VFS_MONITOR_EVENT_CHANGED: - monitor->ticks = INITIAL_TICKS; - /* fall-through */ - case GNOME_VFS_MONITOR_EVENT_CREATED: - /* We make a lot of assumptions here, but basically we know - * that we just have to reload, by construction. - * Delay the reload a little bit so we don't endlessly - * reload while a file is written. - */ - monitor->type = event_type; - - if (monitor->ticks == 0) - { - monitor->ticks = 1; - } - else - { - /* Exponential backoff */ - monitor->ticks = MIN (monitor->ticks * 2, - DELAY_MAX_TICKS); - } - - if (monitor->timeout_id == 0) - { - monitor->timeout_id = - g_timeout_add (monitor->delay, - (GSourceFunc) ephy_file_monitor_timeout_cb, - monitor); - } - - break; - - case GNOME_VFS_MONITOR_EVENT_DELETED: - if (monitor->timeout_id != 0) - { - g_source_remove (monitor->timeout_id); - monitor->timeout_id = 0; - } - monitor->ticks = 0; - - monitor->callback (monitor, monitor->uri, event_type, monitor->user_data); - break; - case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: - case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: - case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: - default: - break; - } -} - -EphyFileMonitor * -ephy_file_monitor_add (const char *uri, - GnomeVFSMonitorType monitor_type, - guint delay, - EphyFileMonitorFunc callback, - EphyFileMonitorDelayFunc delay_func, - gpointer user_data) -{ - EphyFileMonitor *monitor; - - g_return_val_if_fail (uri != NULL, NULL); - g_return_val_if_fail (callback, NULL); - - monitor = g_new (EphyFileMonitor, 1); - monitor->callback = callback; - monitor->delay_func = delay_func; - monitor->user_data = user_data; - monitor->uri = g_strdup (uri); - monitor->delay = delay; - monitor->ticks = 0; - monitor->timeout_id = 0; - - if (gnome_vfs_monitor_add (&monitor->handle, uri, monitor_type, - (GnomeVFSMonitorCallback) ephy_file_monitor_cb, - monitor) != GNOME_VFS_OK) - { - LOG ("Failed to add file monitor for '%s'", uri); - - g_free (monitor->uri); - g_free (monitor); - return NULL; - } - - LOG ("File monitor for '%s' added", uri); - - return monitor; -} - -void -ephy_file_monitor_cancel (EphyFileMonitor *monitor) -{ - g_return_if_fail (monitor != NULL); - g_return_if_fail (monitor->handle != NULL); - g_return_if_fail (monitor->uri != NULL); - - LOG ("Cancelling file monitor for '%s'", monitor->uri); - - gnome_vfs_monitor_cancel (monitor->handle); - - if (monitor->timeout_id != 0) - { - g_source_remove (monitor->timeout_id); - } - - g_free (monitor->uri); - g_free (monitor); -} - /** * ephy_file_delete_directory: * @path: the path to remove @@ -1226,18 +743,14 @@ ephy_file_monitor_cancel (EphyFileMonitor *monitor) void ephy_file_delete_directory (const char *path) { - GList *list; - GnomeVFSResult ret; - - list = g_list_append (NULL, gnome_vfs_uri_new (path)); + GFile *file; + gboolean ret; - ret = gnome_vfs_xfer_delete_list (list, GNOME_VFS_XFER_ERROR_MODE_ABORT, - GNOME_VFS_XFER_EMPTY_DIRECTORIES, - NULL, NULL); + file = g_file_new_for_path (path); - gnome_vfs_uri_list_free (list); + ret = g_file_delete (file, NULL, NULL); - if (ret == GNOME_VFS_OK) + if (ret == TRUE) { LOG ("Deleted the profile dir '%s'", path); } @@ -1245,4 +758,5 @@ ephy_file_delete_directory (const char *path) { LOG ("Couldn't delete profile dir '%s'", path); } + g_object_unref (file); } diff --git a/lib/ephy-file-helpers.h b/lib/ephy-file-helpers.h index f7aa71281..408b975cb 100644 --- a/lib/ephy-file-helpers.h +++ b/lib/ephy-file-helpers.h @@ -24,8 +24,8 @@ #define EPHY_FILE_HELPERS_H #include <glib.h> -#include <libgnomevfs/gnome-vfs-mime-handlers.h> -#include <libgnomevfs/gnome-vfs-ops.h> +#include <gio/gio.h> +#include <gtk/gtkwidget.h> extern GQuark ephy_file_helpers_error_quark; #define EPHY_FILE_HELPERS_ERROR_QUARK (ephy_file_helpers_error_quark) @@ -39,10 +39,6 @@ typedef enum EPHY_MIME_PERMISSION_UNKNOWN = 3 } EphyMimePermission; -typedef struct _EphyFileMonitor EphyFileMonitor; -typedef void (* EphyFileMonitorFunc) (EphyFileMonitor*, const char*, GnomeVFSMonitorEventType, gpointer); -typedef gboolean (* EphyFileMonitorDelayFunc) (EphyFileMonitor*, gpointer); - gboolean ephy_file_helpers_init (const char *profile_dir, gboolean private_profile, gboolean keep_temp_dir, @@ -72,10 +68,10 @@ GSList *ephy_file_find (const char *path, const char *fname, gint maxdepth); -gboolean ephy_file_switch_temp_file (const char *filename, - const char *filename_temp); +gboolean ephy_file_switch_temp_file (GFile *file, + GFile *file_temp); -void ephy_file_delete_on_exit (const char *path); +void ephy_file_delete_on_exit (GFile *file); void ephy_file_add_recent_item (const char *uri, const char *mime_type); @@ -84,28 +80,21 @@ EphyMimePermission ephy_file_check_mime (const char *mime_type); gboolean ephy_file_launch_desktop_file (const char *filename, const char *parameter, - guint32 user_time); + guint32 user_time, + GtkWidget *widget); -gboolean ephy_file_launch_application (GnomeVFSMimeApplication *application, - const char *parameter, - guint32 user_time); +gboolean ephy_file_launch_application (GAppInfo *app, + GList *files, + guint32 user_time, + GtkWidget *parent); gboolean ephy_file_launch_handler (const char *mime_type, - const char *address, + GFile *file, guint32 user_time); gboolean ephy_file_browse_to (const char *parameter, guint32 user_time); -EphyFileMonitor *ephy_file_monitor_add (const char *uri, - GnomeVFSMonitorType monitor_type, - guint delay, - EphyFileMonitorFunc callback, - EphyFileMonitorDelayFunc delay_func, - gpointer user_data); - -void ephy_file_monitor_cancel (EphyFileMonitor *monitor); - void ephy_file_delete_directory (const char *path); G_END_DECLS diff --git a/lib/ephy-node-db.c b/lib/ephy-node-db.c index ebc3e20b5..15a4593ab 100644 --- a/lib/ephy-node-db.c +++ b/lib/ephy-node-db.c @@ -482,30 +482,35 @@ ephy_node_db_write_to_xml_safe (EphyNodeDb *db, { va_list argptr; int ret = 0; - char *tmp_file; + GFile *tmp_file, *file; + char *tmp_file_path; - tmp_file = g_strconcat ((const gchar *)filename, ".tmp", NULL); + tmp_file_path = g_strconcat ((const gchar *) filename, ".tmp", NULL); + tmp_file = g_file_new_for_path (tmp_file_path); + file = g_file_new_for_path ((const char *) filename); va_start (argptr, node); ret = ephy_node_db_write_to_xml_valist - (db, (const xmlChar *)tmp_file, root, version, comment, node, argptr); + (db, (const xmlChar *)tmp_file_path, root, version, comment, node, argptr); va_end (argptr); if (ret < 0) { - g_warning ("Failed to write XML data to %s", tmp_file); + g_warning ("Failed to write XML data to %s", tmp_file_path); goto failed; } - if (ephy_file_switch_temp_file ((const char *)filename, tmp_file) == FALSE) + if (ephy_file_switch_temp_file (file, tmp_file) == FALSE) { ret = -1; } failed: - g_free (tmp_file); + g_free (tmp_file_path); + g_object_unref (file); + g_object_unref (tmp_file); return ret; } diff --git a/lib/ephy-string.c b/lib/ephy-string.c index 391ad9b39..4dc8d8e9a 100644 --- a/lib/ephy-string.c +++ b/lib/ephy-string.c @@ -26,6 +26,8 @@ #include <string.h> #include <stdlib.h> #include <glib.h> +#include <sys/types.h> +#include <pwd.h> #define ELLIPSIS "\xe2\x80\xa6" @@ -286,3 +288,241 @@ ephy_string_enum_to_string (GType type, return retval; } + +/* Following code copied from gnome-vfs-private-utils.c */ + +static int +find_next_slash (const char *path, int current_offset) +{ + const char *match; + + g_assert (current_offset <= strlen (path)); + + match = strchr (path + current_offset, G_DIR_SEPARATOR); + return match == NULL ? -1 : match - path; +} + +static int +find_slash_before_offset (const char *path, int to) +{ + int result; + int next_offset; + + result = -1; + next_offset = 0; + for (;;) { + next_offset = find_next_slash (path, next_offset); + if (next_offset < 0 || next_offset >= to) { + break; + } + result = next_offset; + next_offset++; + } + return result; +} + +static void +collapse_slash_runs (char *path, int from_offset) +{ + int i; + /* Collapse multiple `/'s in a row. */ + for (i = from_offset;; i++) { + if (path[i] != G_DIR_SEPARATOR) { + break; + } + } + + if (from_offset < i) { + memmove (path + from_offset, path + i, strlen (path + i) + 1); + i = from_offset + 1; + } +} + +/* Canonicalize path, and return a new path. Do everything in situ. The new + path differs from path in: + + Multiple `/'s are collapsed to a single `/'. + Leading `./'s and trailing `/.'s are removed. + Non-leading `../'s and trailing `..'s are handled by removing + portions of the path. */ +char * +ephy_string_canonicalize_pathname (const char *cpath) +{ + char *path; + int i, marker; + + path = g_strdup (cpath); + + if (path == NULL || strlen (path) == 0) { + return ""; + } + + /* Walk along path looking for things to compact. */ + for (i = 0, marker = 0;;) { + if (!path[i]) + break; + + /* Check for `../', `./' or trailing `.' by itself. */ + if (path[i] == '.') { + /* Handle trailing `.' by itself. */ + if (path[i + 1] == '\0') { + if (i > 1 && path[i - 1] == G_DIR_SEPARATOR) { + /* strip the trailing /. */ + path[i - 1] = '\0'; + } else { + /* convert path "/." to "/" */ + path[i] = '\0'; + } + break; + } + + /* Handle `./'. */ + if (path[i + 1] == G_DIR_SEPARATOR) { + memmove (path + i, path + i + 2, + strlen (path + i + 2) + 1); + if (i == 0) { + /* don't leave leading '/' for paths that started + * as relative (.//foo) + */ + collapse_slash_runs (path, i); + marker = 0; + } + continue; + } + + /* Handle `../' or trailing `..' by itself. + * Remove the previous xxx/ part + */ + if (path[i + 1] == '.' + && (path[i + 2] == G_DIR_SEPARATOR + || path[i + 2] == '\0')) { + + /* ignore ../ at the beginning of a path */ + if (i != 0) { + marker = find_slash_before_offset (path, i - 1); + + /* Either advance past '/' or point to the first character */ + marker ++; + if (path [i + 2] == '\0' && marker > 1) { + /* If we are looking at a /.. at the end of the uri and we + * need to eat the last '/' too. + */ + marker--; + } + g_assert(marker < i); + + if (path[i + 2] == G_DIR_SEPARATOR) { + /* strip the entire ../ string */ + i++; + } + + memmove (path + marker, path + i + 2, + strlen (path + i + 2) + 1); + i = marker; + } else { + i = 2; + if (path[i] == G_DIR_SEPARATOR) { + i++; + } + } + collapse_slash_runs (path, i); + continue; + } + } + + /* advance to the next '/' */ + i = find_next_slash (path, i); + + /* If we didn't find any slashes, then there is nothing left to do. */ + if (i < 0) { + break; + } + + marker = i++; + collapse_slash_runs (path, i); + } + return path; +} + +/* End of copied code */ + +char * +ephy_string_get_host_name (const char *url) +{ + const char *start; + const char *p; + + if (url == NULL || g_str_has_prefix (url, "file://")) return NULL; + + start = strstr (url, "//"); + if (start == NULL || start == '\0') + { + /* Not an URL */ + return NULL; + } + if (strlen (start) > 2) + { + /* Go past the protocol part */ + start = start + 2; + } + else + { + /* Not an URL again */ + return NULL; + } + p = strchr (start, '@'); + if (p != NULL) + { + /* We have a username:password@hostname scheme, skip it. */ + if (strlen (p) > 1) start = ++p; + } + p = strchr (start, ':'); + if (p != NULL) + { + /* hostname:port, skip port */ + return g_strndup (start, (p - start)); + } + p = strchr (start, '/'); + if (p == NULL) + { + /* No more slashes in the url, we assume it's a host name */ + return g_strdup (start); + } + + return g_strndup (start, (p - start)); +} + +char * +ephy_string_expand_initial_tilde (const char *path) +{ + char *slash_after_user_name, *user_name; + struct passwd *passwd_file_entry; + + g_return_val_if_fail (path != NULL, NULL); + + if (path[0] != '~') { + return g_strdup (path); + } + + if (path[1] == '/' || path[1] == '\0') { + return g_strconcat (g_get_home_dir (), &path[1], NULL); + } + + slash_after_user_name = strchr (&path[1], '/'); + if (slash_after_user_name == NULL) { + user_name = g_strdup (&path[1]); + } else { + user_name = g_strndup (&path[1], + slash_after_user_name - &path[1]); + } + passwd_file_entry = getpwnam (user_name); + g_free (user_name); + + if (passwd_file_entry == NULL || passwd_file_entry->pw_dir == NULL) { + return g_strdup (path); + } + + return g_strconcat (passwd_file_entry->pw_dir, + slash_after_user_name, + NULL); +} diff --git a/lib/ephy-string.h b/lib/ephy-string.h index cbf8ec776..de7ebe292 100644 --- a/lib/ephy-string.h +++ b/lib/ephy-string.h @@ -49,6 +49,12 @@ guint ephy_string_enum_from_string (GType type, char *ephy_string_enum_to_string (GType type, guint enum_value); +char *ephy_string_canonicalize_pathname (const char *cpath); + +char *ephy_string_get_host_name (const char *url); + +char *ephy_string_expand_initial_tilde (const char *path); + G_END_DECLS #endif |