diff options
Diffstat (limited to 'libslab/directory-tile.c')
-rw-r--r-- | libslab/directory-tile.c | 675 |
1 files changed, 0 insertions, 675 deletions
diff --git a/libslab/directory-tile.c b/libslab/directory-tile.c deleted file mode 100644 index 0a6f1920..00000000 --- a/libslab/directory-tile.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * This file is part of libtile. - * - * Copyright (c) 2006 Novell, Inc. - * - * Libtile is free software; you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * Libtile is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libslab; if not, write to the Free Software Foundation, Inc., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "directory-tile.h" -#include "config.h" - -#include <glib/gi18n-lib.h> -#include <string.h> -#include <gio/gio.h> -#include <gdk/gdk.h> -#include <unistd.h> - -#include "slab-mate-util.h" -#include "mate-utils.h" -#include "libslab-utils.h" - -#define GNOME_MAIN_MENU_SCHEMA "org.mate.gnome-main-menu.file-area" -#define SETTINGS_FILE_MGR_OPEN_KEY "file-mgr-open-cmd" -#define SETTINGS_SEND_TO_CMD_KEY "file-send-to-cmd" - -#define CAJA_SCHEMA "org.mate.caja.preferences" -#define SETTINGS_ENABLE_DELETE_KEY "enable-delete" -#define SETTINGS_CONFIRM_DELETE_KEY "confirm-trash" - -G_DEFINE_TYPE (DirectoryTile, directory_tile, NAMEPLATE_TILE_TYPE) - -static void directory_tile_finalize (GObject *); -static void directory_tile_style_set (GtkWidget *, GtkStyle *); - -static void directory_tile_private_setup (DirectoryTile *); -static void load_image (DirectoryTile *); - -static GtkWidget *create_header (const gchar *); - -static void header_size_allocate_cb (GtkWidget *, GtkAllocation *, gpointer); - -static void open_with_default_trigger (Tile *, TileEvent *, TileAction *); -static void rename_trigger (Tile *, TileEvent *, TileAction *); -static void move_to_trash_trigger (Tile *, TileEvent *, TileAction *); -static void delete_trigger (Tile *, TileEvent *, TileAction *); -static void send_to_trigger (Tile *, TileEvent *, TileAction *); - -static void rename_entry_activate_cb (GtkEntry *, gpointer); -static gboolean rename_entry_key_release_cb (GtkWidget *, GdkEventKey *, gpointer); -static void settings_enable_delete_cb (GSettings *, gchar *, gpointer); - -static void disown_spawned_child (gpointer); - -typedef struct -{ - gchar *basename; - gchar *mime_type; - gchar *icon_name; - - GtkBin *header_bin; - GAppInfo *default_app; - - gboolean image_is_broken; - - gboolean delete_enabled; - - GSettings *caja_settings; - GSettings *gnome_main_menu_settings; -} DirectoryTilePrivate; - -#define DIRECTORY_TILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DIRECTORY_TILE_TYPE, DirectoryTilePrivate)) - -static void directory_tile_class_init (DirectoryTileClass *this_class) -{ - GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (this_class); - - g_obj_class->finalize = directory_tile_finalize; - - widget_class->style_set = directory_tile_style_set; - - g_type_class_add_private (this_class, sizeof (DirectoryTilePrivate)); -} - -GtkWidget * -directory_tile_new (const gchar *in_uri, const gchar *title, const gchar *icon_name, const gchar *mime_type) -{ - DirectoryTile *this; - DirectoryTilePrivate *priv; - - gchar *uri; - GtkWidget *image; - GtkWidget *header; - GtkMenu *context_menu; - - GtkContainer *menu_ctnr; - GtkWidget *menu_item; - - TileAction *action; - - gchar *basename; - - gchar *markup; - - AtkObject *accessible; - - gchar *filename; - gchar *tooltip_text; - - - uri = g_strdup (in_uri); - - image = gtk_image_new (); - - if (! title) { - markup = g_path_get_basename (uri); - basename = g_uri_unescape_string (markup, NULL); - g_free (markup); - } - else - basename = g_strdup (title); - - header = create_header (basename); - - filename = g_filename_from_uri (uri, NULL, NULL); - - if (filename) - tooltip_text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); - else - tooltip_text = NULL; - - g_free (filename); - - context_menu = GTK_MENU (gtk_menu_new ()); - - this = g_object_new ( - DIRECTORY_TILE_TYPE, - "tile-uri", uri, - "nameplate-image", image, - "nameplate-header", header, - "context-menu", context_menu, - NULL); - gtk_widget_set_tooltip_text (GTK_WIDGET (this), tooltip_text); - - g_free (uri); - if (tooltip_text) - g_free (tooltip_text); - - priv = DIRECTORY_TILE_GET_PRIVATE (this); - priv->basename = g_strdup (basename); - priv->header_bin = GTK_BIN (header); - priv->icon_name = g_strdup (icon_name); - priv->mime_type = g_strdup (mime_type); - - directory_tile_private_setup (this); - - TILE (this)->actions = g_new0 (TileAction *, 6); - TILE (this)->n_actions = 6; - - menu_ctnr = GTK_CONTAINER (TILE (this)->context_menu); - - /* make open with default action */ - - markup = g_markup_printf_escaped (_("<b>Open</b>")); - action = tile_action_new (TILE (this), open_with_default_trigger, markup, TILE_ACTION_OPENS_NEW_WINDOW); - g_free (markup); - - TILE (this)->default_action = action; - - menu_item = GTK_WIDGET (GTK_WIDGET (tile_action_get_menu_item (action))); - - TILE (this)->actions [DIRECTORY_TILE_ACTION_OPEN] = action; - - gtk_container_add (menu_ctnr, menu_item); - - /* insert separator */ - - menu_item = gtk_separator_menu_item_new (); - gtk_container_add (menu_ctnr, menu_item); - - /* make rename action */ - - action = tile_action_new (TILE (this), rename_trigger, _("Rename..."), 0); - TILE (this)->actions[DIRECTORY_TILE_ACTION_RENAME] = action; - - menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); - gtk_container_add (menu_ctnr, menu_item); - - /* make send to action */ - - /* Only allow Send To for local files, ideally this would use something - * equivalent to mate_vfs_uri_is_local, but that method will stat the file and - * that can hang in some conditions. */ - - if (!strncmp (TILE (this)->uri, "file://", 7)) - { - action = tile_action_new (TILE (this), send_to_trigger, _("Send To..."), - TILE_ACTION_OPENS_NEW_WINDOW); - - menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); - } - else - { - action = NULL; - - menu_item = gtk_menu_item_new_with_label (_("Send To...")); - gtk_widget_set_sensitive (menu_item, FALSE); - } - - TILE (this)->actions[DIRECTORY_TILE_ACTION_SEND_TO] = action; - - gtk_container_add (menu_ctnr, menu_item); - - /* insert separator */ - - menu_item = gtk_separator_menu_item_new (); - gtk_container_add (menu_ctnr, menu_item); - - /* make move to trash action */ - - action = tile_action_new (TILE (this), move_to_trash_trigger, _("Move to Trash"), 0); - TILE (this)->actions[DIRECTORY_TILE_ACTION_MOVE_TO_TRASH] = action; - - menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); - gtk_container_add (menu_ctnr, menu_item); - - /* make delete action */ - - if (priv->delete_enabled) - { - action = tile_action_new (TILE (this), delete_trigger, _("Delete"), 0); - TILE (this)->actions[DIRECTORY_TILE_ACTION_DELETE] = action; - - menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); - gtk_container_add (menu_ctnr, menu_item); - } - - gtk_widget_show_all (GTK_WIDGET (TILE (this)->context_menu)); - - load_image (this); - - accessible = gtk_widget_get_accessible (GTK_WIDGET (this)); - if (basename) - atk_object_set_name (accessible, basename); - - g_free (basename); - - return GTK_WIDGET (this); -} - -static void -directory_tile_private_setup (DirectoryTile *tile) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - - if (priv->mime_type) - priv->default_app = g_app_info_get_default_for_type (priv->mime_type, TRUE); - else - priv->default_app = NULL; - - priv->gnome_main_menu_settings = g_settings_new (GNOME_MAIN_MENU_SCHEMA); - priv->caja_settings = g_settings_new (CAJA_SCHEMA); - - priv->delete_enabled = g_settings_get_boolean (priv->caja_settings, SETTINGS_ENABLE_DELETE_KEY); - - g_signal_connect (priv->caja_settings, "changed::" SETTINGS_ENABLE_DELETE_KEY, - G_CALLBACK (settings_enable_delete_cb), tile); -} - -static void -directory_tile_init (DirectoryTile *tile) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - - priv->default_app = NULL; - priv->basename = NULL; - priv->header_bin = NULL; - priv->icon_name = NULL; - priv->mime_type = NULL; - priv->image_is_broken = TRUE; - priv->delete_enabled = FALSE; - priv->gnome_main_menu_settings = NULL; - priv->caja_settings = NULL; -} - -static void -directory_tile_finalize (GObject *g_object) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (g_object); - - g_free (priv->basename); - g_free (priv->icon_name); - g_free (priv->mime_type); - - if (priv->default_app) - g_object_unref (priv->default_app); - - g_object_unref (priv->gnome_main_menu_settings); - g_object_unref (priv->caja_settings); - - (* G_OBJECT_CLASS (directory_tile_parent_class)->finalize) (g_object); -} - -static void -directory_tile_style_set (GtkWidget *widget, GtkStyle *prev_style) -{ - load_image (DIRECTORY_TILE (widget)); -} - -static void -load_image (DirectoryTile *tile) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - gchar *icon_name; - - if (priv->icon_name) - icon_name = priv->icon_name; - else - icon_name = "folder"; - - priv->image_is_broken = slab_load_image ( - GTK_IMAGE (NAMEPLATE_TILE (tile)->image), GTK_ICON_SIZE_DND, icon_name); -} - -static GtkWidget * -create_header (const gchar *name) -{ - GtkWidget *header_bin; - GtkWidget *header; - - header = gtk_label_new (name); - gtk_label_set_ellipsize (GTK_LABEL (header), PANGO_ELLIPSIZE_END); -#if GTK_CHECK_VERSION (3, 16, 0) - gtk_label_set_xalign (GTK_LABEL (header), 0.0); -#else - gtk_misc_set_alignment (GTK_MISC (header), 0.0, 0.5); -#endif - - header_bin = gtk_alignment_new (0.0, 0.5, 1.0, 0.0); - gtk_container_add (GTK_CONTAINER (header_bin), header); - - g_signal_connect (G_OBJECT (header), "size-allocate", G_CALLBACK (header_size_allocate_cb), - NULL); - - return header_bin; -} - -static void -header_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer user_data) -{ - gtk_widget_set_size_request (widget, alloc->width, -1); -} - -static void -rename_entry_activate_cb (GtkEntry *entry, gpointer user_data) -{ - DirectoryTile *tile = DIRECTORY_TILE (user_data); - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - - GFile *src_file; - GFile *dst_file; - - gchar *dirname; - gchar *dst_uri; - gchar *src_path; - - GtkWidget *child; - GtkWidget *header; - - gboolean res; - GError *error = NULL; - - if (strlen (gtk_entry_get_text (entry)) < 1) - return; - - src_file = g_file_new_for_uri (TILE (tile)->uri); - - src_path = g_filename_from_uri (TILE (tile)->uri, NULL, NULL); - dirname = g_path_get_dirname (src_path); - dst_uri = g_build_filename (dirname, gtk_entry_get_text (entry), NULL); - dst_file = g_file_new_for_uri (dst_uri); - - g_free (dirname); - g_free (src_path); - - res = g_file_move (src_file, dst_file, - G_FILE_COPY_NONE, NULL, NULL, NULL, &error); - - if (res) { - g_free (priv->basename); - priv->basename = g_strdup (gtk_entry_get_text (entry)); - } - else { - g_warning ("unable to move [%s] to [%s]: %s\n", TILE (tile)->uri, dst_uri, - error->message); - g_error_free (error); - } - - g_free (dst_uri); - g_object_unref (src_file); - g_object_unref (dst_file); - - header = gtk_label_new (priv->basename); -#if GTK_CHECK_VERSION (3, 16, 0) - gtk_label_set_xalign (GTK_LABEL (header), 0.0); -#else - gtk_misc_set_alignment (GTK_MISC (header), 0.0, 0.5); -#endif - - child = gtk_bin_get_child (priv->header_bin); - - if (child) - gtk_widget_destroy (child); - - gtk_container_add (GTK_CONTAINER (priv->header_bin), header); - - gtk_widget_show (header); -} - -static gboolean -rename_entry_key_release_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) -{ - return TRUE; -} - -static void -settings_enable_delete_cb (GSettings *settings, gchar *key, gpointer user_data) -{ - Tile *tile = TILE (user_data); - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (user_data); - - GtkMenuShell *menu; - gboolean delete_enabled; - - TileAction *action; - GtkWidget *menu_item; - - menu = GTK_MENU_SHELL (tile->context_menu); - - delete_enabled = g_settings_get_boolean (settings, key); - - if (delete_enabled == priv->delete_enabled) - return; - - priv->delete_enabled = delete_enabled; - - if (priv->delete_enabled) - { - action = tile_action_new (tile, delete_trigger, _("Delete"), 0); - tile->actions[DIRECTORY_TILE_ACTION_DELETE] = action; - - menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); - gtk_menu_shell_insert (menu, menu_item, 7); - - gtk_widget_show_all (menu_item); - } - else - { - g_object_unref (tile->actions[DIRECTORY_TILE_ACTION_DELETE]); - - tile->actions[DIRECTORY_TILE_ACTION_DELETE] = NULL; - } -} - -static void -rename_trigger (Tile *tile, TileEvent *event, TileAction *action) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - - GtkWidget *child; - GtkWidget *entry; - - - entry = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (entry), priv->basename); - gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); - - child = gtk_bin_get_child (priv->header_bin); - - if (child) - gtk_widget_destroy (child); - - gtk_container_add (GTK_CONTAINER (priv->header_bin), entry); - - g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (rename_entry_activate_cb), tile); - - g_signal_connect (G_OBJECT (entry), "key_release_event", - G_CALLBACK (rename_entry_key_release_cb), NULL); - - gtk_widget_show (entry); - gtk_widget_grab_focus (entry); -} - -static void -move_to_trash_trigger (Tile *tile, TileEvent *event, TileAction *action) -{ - GFile *src_file; - gboolean res; - GError *error = NULL; - - src_file = g_file_new_for_uri (TILE (tile)->uri); - - res = g_file_trash (src_file, NULL, &error); - if (!res) { - g_warning ("unable to move [%s] to the trash: %s\n", TILE (tile)->uri, - error->message); - g_error_free (error); - } - - g_object_unref (src_file); -} - -static void -delete_trigger (Tile *tile, TileEvent *event, TileAction *action) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - GtkDialog *confirm_dialog; - gint result; - - GFile *src_file; - gboolean res; - GError *error = NULL; - - if (g_settings_get_boolean (priv->caja_settings, SETTINGS_CONFIRM_DELETE_KEY)) { - confirm_dialog = GTK_DIALOG(gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING, - GTK_BUTTONS_NONE, _("Are you sure you want to permanently delete \"%s\"?"), DIRECTORY_TILE_GET_PRIVATE (tile)->basename)); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(confirm_dialog), _("If you delete an item, it is permanently lost.")); - - gtk_dialog_add_button (confirm_dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_dialog_add_button (confirm_dialog, GTK_STOCK_DELETE, GTK_RESPONSE_YES); - gtk_dialog_set_default_response (GTK_DIALOG (confirm_dialog), GTK_RESPONSE_YES); - - result = gtk_dialog_run (confirm_dialog); - - gtk_widget_destroy (GTK_WIDGET (confirm_dialog)); - - if (result != GTK_RESPONSE_YES) - return; - } - - src_file = g_file_new_for_uri (TILE (tile)->uri); - - res = g_file_delete (src_file, NULL, &error); - - if (!res) { - g_warning ("unable to delete [%s]: %s\n", TILE (tile)->uri, - error->message); - g_error_free (error); - } - - g_object_unref (src_file); -} - -static void -send_to_trigger (Tile *tile, TileEvent *event, TileAction *action) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - gchar *cmd; - gint argc; - gchar **argv_parsed = NULL; - gchar **argv = NULL; - - gchar *path; - gchar *dirname; - gchar *basename; - - GError *error = NULL; - - gint i; - - - cmd = g_settings_get_string (priv->gnome_main_menu_settings, SETTINGS_SEND_TO_CMD_KEY); - - if (! g_shell_parse_argv (cmd, & argc, & argv_parsed, NULL)) - goto exit; - - argv = g_new0 (gchar *, argc + 1); - - path = g_filename_from_uri (tile->uri, NULL, NULL); - dirname = g_path_get_dirname (path); - basename = g_path_get_basename (path); - - for (i = 0; i < argc; ++i) { - if (strstr (argv_parsed [i], "DIRNAME")) - argv [i] = string_replace_once (argv_parsed [i], "DIRNAME", dirname); - else if (strstr (argv_parsed [i], "BASENAME")) - argv [i] = string_replace_once (argv_parsed [i], "BASENAME", basename); - else - argv [i] = g_strdup (argv_parsed [i]); - } - - argv [argc] = NULL; - - g_free (path); - g_free (dirname); - g_free (basename); - - g_spawn_async ( - NULL, argv, NULL, G_SPAWN_SEARCH_PATH, - disown_spawned_child, NULL, NULL, & error); - - if (error) { - cmd = g_strjoinv (" ", argv); - libslab_handle_g_error ( - & error, "%s: can't execute search [%s]\n", G_STRFUNC, cmd); - g_free (cmd); - } - - g_strfreev (argv); - -exit: - - g_free (cmd); - g_strfreev (argv_parsed); -} - -static void -disown_spawned_child (gpointer user_data) -{ - setsid (); - setpgid (0, 0); -} - -static void -open_with_default_trigger (Tile *tile, TileEvent *event, TileAction *action) -{ - DirectoryTilePrivate *priv = DIRECTORY_TILE_GET_PRIVATE (tile); - GList *uris = NULL; - gboolean res; - GdkAppLaunchContext *launch_context; - GError *error = NULL; - - if (priv->default_app) - { - uris = g_list_append (uris, TILE (tile)->uri); - - launch_context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (tile))); - gdk_app_launch_context_set_screen (launch_context, - gtk_widget_get_screen (GTK_WIDGET (tile))); - gdk_app_launch_context_set_timestamp (launch_context, - event->time); - - res = g_app_info_launch_uris (priv->default_app, uris, - G_APP_LAUNCH_CONTEXT (launch_context), - &error); - - if (!res) { - g_warning - ("error: could not launch application with [%s]: %s\n", - TILE (tile)->uri, error->message); - g_error_free (error); - } - - g_list_free (uris); - g_object_unref (launch_context); - } else { - gchar *cmd; - cmd = string_replace_once ( - g_settings_get_string (priv->gnome_main_menu_settings, SETTINGS_FILE_MGR_OPEN_KEY), "FILE_URI", tile->uri); - spawn_process (cmd); - g_free (cmd); - } -} |