diff options
Diffstat (limited to 'src/caja-emblem-sidebar.c')
-rw-r--r-- | src/caja-emblem-sidebar.c | 1174 |
1 files changed, 1174 insertions, 0 deletions
diff --git a/src/caja-emblem-sidebar.c b/src/caja-emblem-sidebar.c new file mode 100644 index 00000000..79de5299 --- /dev/null +++ b/src/caja-emblem-sidebar.c @@ -0,0 +1,1174 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* + * Caja + * + * Copyright (C) 1999, 2000, 2001 Eazel, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * + * Caja is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Caja 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: James Willcox <[email protected]> + * Alexander Larsson <[email protected]> + * + * This is a sidebar displaying emblems which can be dragged onto files to + * set/unset the chosen emblem. + * + */ + +#include <config.h> +#include "caja-emblem-sidebar.h" + +#include <stdio.h> +#include <eel/eel-gtk-macros.h> +#include <eel/eel-glib-extensions.h> +#include <eel/eel-string.h> +#include <eel/eel-wrap-table.h> +#include <eel/eel-labeled-image.h> +#include <eel/eel-graphic-effects.h> +#include <eel/eel-gdk-pixbuf-extensions.h> +#include <eel/eel-stock-dialogs.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <mateconf/mateconf-client.h> +#include <libcaja-private/caja-icon-dnd.h> +#include <libcaja-private/caja-emblem-utils.h> +#include <libcaja-private/caja-file-utilities.h> +#include <libcaja-private/caja-sidebar-provider.h> +#include <libcaja-private/caja-module.h> +#include <libcaja-private/caja-signaller.h> + +struct CajaEmblemSidebarDetails +{ + CajaWindowInfo *window; + MateConfClient *client; + GtkWidget *emblems_table; + GtkWidget *popup; + GtkWidget *popup_remove; + GtkWidget *popup_rename; + + char *popup_emblem_keyword; + char *popup_emblem_display_name; + GdkPixbuf *popup_emblem_pixbuf; +}; + +#define ERASE_EMBLEM_KEYWORD "erase" +#define STANDARD_EMBLEM_HEIGHT 52 +#define EMBLEM_LABEL_SPACING 2 + +static void caja_emblem_sidebar_iface_init (CajaSidebarIface *iface); +static void caja_emblem_sidebar_finalize (GObject *object); +static void caja_emblem_sidebar_populate (CajaEmblemSidebar *emblem_sidebar); +static void caja_emblem_sidebar_refresh (CajaEmblemSidebar *emblem_sidebar); +static void caja_emblem_sidebar_iface_init (CajaSidebarIface *iface); +static void sidebar_provider_iface_init (CajaSidebarProviderIface *iface); +static GType caja_emblem_sidebar_provider_get_type (void); + +static const GtkTargetEntry drag_types[] = +{ + {"property/keyword", 0, 0 } +}; + +enum +{ + TARGET_URI_LIST, + TARGET_URI, + TARGET_NETSCAPE_URL +}; + +static const GtkTargetEntry dest_types[] = +{ + {"text/uri-list", 0, TARGET_URI_LIST}, + {"text/plain", 0, TARGET_URI}, + {"_NETSCAPE_URL", 0, TARGET_NETSCAPE_URL} +}; + +typedef struct _Emblem +{ + GdkPixbuf *pixbuf; + char *uri; + char *name; + char *keyword; +} Emblem; + +typedef struct +{ + GObject parent; +} CajaEmblemSidebarProvider; + +typedef struct +{ + GObjectClass parent; +} CajaEmblemSidebarProviderClass; + + + + +G_DEFINE_TYPE_WITH_CODE (CajaEmblemSidebar, caja_emblem_sidebar, GTK_TYPE_VBOX, + G_IMPLEMENT_INTERFACE (CAJA_TYPE_SIDEBAR, + caja_emblem_sidebar_iface_init)); + +G_DEFINE_TYPE_WITH_CODE (CajaEmblemSidebarProvider, caja_emblem_sidebar_provider, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (CAJA_TYPE_SIDEBAR_PROVIDER, + sidebar_provider_iface_init)); + +static void +caja_emblem_sidebar_drag_data_get_cb (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *data, + guint info, + guint time, + CajaEmblemSidebar *emblem_sidebar) +{ + char *keyword; + + keyword = g_object_get_data (G_OBJECT (widget), "emblem-keyword"); + + g_return_if_fail (keyword != NULL); + + gtk_selection_data_set (data, gtk_selection_data_get_target (data), 8, + keyword, + strlen (keyword)); +} + +static void +caja_emblem_sidebar_enter_notify_cb (GtkWidget *widget, + CajaEmblemSidebar *emblem_sidebar) +{ + GdkPixbuf *pixbuf; + EelLabeledImage *image; + + pixbuf = g_object_get_data (G_OBJECT (widget), "prelight-pixbuf"); + image = g_object_get_data (G_OBJECT (widget), "labeled-image"); + + eel_labeled_image_set_pixbuf (EEL_LABELED_IMAGE (image), pixbuf); +} + +static void +caja_emblem_sidebar_leave_notify_cb (GtkWidget *widget, + CajaEmblemSidebar *emblem_sidebar) +{ + GdkPixbuf *pixbuf; + EelLabeledImage *image; + + pixbuf = g_object_get_data (G_OBJECT (widget), "original-pixbuf"); + image = g_object_get_data (G_OBJECT (widget), "labeled-image"); + + eel_labeled_image_set_pixbuf (EEL_LABELED_IMAGE (image), pixbuf); +} + +static gboolean +caja_emblem_sidebar_button_press_cb (GtkWidget *widget, + GdkEventButton *event, + CajaEmblemSidebar *emblem_sidebar) +{ + char *keyword, *name; + GdkPixbuf *pixbuf; + + if (event->button == 3) + { + keyword = g_object_get_data (G_OBJECT (widget), + "emblem-keyword"); + name = g_object_get_data (G_OBJECT (widget), + "emblem-display-name"); + pixbuf = g_object_get_data (G_OBJECT (widget), + "original-pixbuf"); + + emblem_sidebar->details->popup_emblem_keyword = keyword; + emblem_sidebar->details->popup_emblem_display_name = name; + emblem_sidebar->details->popup_emblem_pixbuf = pixbuf; + + gtk_widget_set_sensitive (emblem_sidebar->details->popup_remove, + caja_emblem_can_remove_emblem (keyword)); + gtk_widget_set_sensitive (emblem_sidebar->details->popup_rename, + caja_emblem_can_rename_emblem (keyword)); + + + gtk_menu_popup (GTK_MENU (emblem_sidebar->details->popup), + NULL, NULL, NULL, NULL, event->button, + event->time); + } + + return TRUE; +} + +static void +send_emblems_changed (void) +{ + g_signal_emit_by_name (caja_signaller_get_current (), + "emblems_changed"); +} + +static void +emblems_changed_callback (GObject *signaller, + CajaEmblemSidebar *emblem_sidebar) +{ + caja_emblem_sidebar_refresh (emblem_sidebar); +} + +static void +caja_emblem_sidebar_delete_cb (GtkWidget *menu_item, + CajaEmblemSidebar *emblem_sidebar) +{ + char *error; + + if (caja_emblem_remove_emblem (emblem_sidebar->details->popup_emblem_keyword)) + { + send_emblems_changed (); + } + else + { + error = g_strdup_printf (_("Could not remove emblem with name '%s'."), emblem_sidebar->details->popup_emblem_display_name); + eel_show_error_dialog (error, _("This is probably because the emblem is a permanent one, and not one that you added yourself."), + NULL); + g_free (error); + } +} + +static void +rename_dialog_response_cb (GtkWidget *dialog, int response, + CajaEmblemSidebar *emblem_sidebar) +{ + GtkWidget *entry; + char *keyword, *name, *error; + + keyword = g_object_get_data (G_OBJECT (dialog), "emblem-keyword"); + + if (response == GTK_RESPONSE_CANCEL) + { + g_free (keyword); + gtk_widget_destroy (dialog); + return; + } + else if (response == GTK_RESPONSE_HELP) + { + g_message ("Implement me!"); + return; + } + + entry = g_object_get_data (G_OBJECT (dialog), "entry"); + + name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + + gtk_widget_destroy (dialog); + + if (caja_emblem_rename_emblem (keyword, name)) + { + send_emblems_changed (); + } + else + { + error = g_strdup_printf (_("Could not rename emblem with name '%s'."), name); + eel_show_error_dialog (error, _("This is probably because the emblem is a permanent one, and not one that you added yourself."), + NULL); + g_free (error); + } + + g_free (keyword); + g_free (name); +} + +static GtkWidget * +create_rename_emblem_dialog (CajaEmblemSidebar *emblem_sidebar, + const char *keyword, const char *orig_name, + GdkPixbuf *pixbuf) +{ + GtkWidget *dialog, *label, *image, *entry, *hbox; + + image = gtk_image_new_from_pixbuf (pixbuf); + entry = gtk_entry_new (); + + dialog = gtk_dialog_new_with_buttons (_("Rename Emblem"), + NULL, + 0, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + GTK_STOCK_HELP, + GTK_RESPONSE_HELP, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_OK); + + g_object_set_data (G_OBJECT (dialog), "emblem-keyword", + g_strdup (keyword)); + g_object_set_data (G_OBJECT (dialog), "entry", + entry); + + label = gtk_label_new (_("Enter a new name for the displayed emblem:")); + gtk_widget_show (label); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label, + FALSE, FALSE, 8); + + + hbox = gtk_hbox_new (FALSE, 8); + gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 8); + + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); + + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 8); + gtk_widget_show_all (hbox); + + /* it would be nice to have the text selected, ready to be overwritten + * by the user, but that doesn't seem possible. + */ + gtk_widget_grab_focus (entry); + gtk_entry_set_text (GTK_ENTRY (entry), orig_name); + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, + TRUE, TRUE, 8); + + + return dialog; +} + +static void +caja_emblem_sidebar_rename_cb (GtkWidget *menu_item, + CajaEmblemSidebar *emblem_sidebar) +{ + GtkWidget *dialog; + + dialog = create_rename_emblem_dialog (emblem_sidebar, + emblem_sidebar->details->popup_emblem_keyword, + emblem_sidebar->details->popup_emblem_display_name, + emblem_sidebar->details->popup_emblem_pixbuf); + g_signal_connect (dialog, "response", + G_CALLBACK (rename_dialog_response_cb), + emblem_sidebar); + gtk_widget_show (dialog); +} + +static void +create_popup_menu (CajaEmblemSidebar *emblem_sidebar) +{ + GtkWidget *popup, *menu_item, *menu_image; + + popup = gtk_menu_new (); + + /* add the "rename" menu item */ + menu_image = gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, + GTK_ICON_SIZE_MENU); + gtk_widget_show (menu_image); + menu_item = gtk_image_menu_item_new_with_label (_("Rename")); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), + menu_image); + + g_signal_connect (menu_item, "activate", + G_CALLBACK (caja_emblem_sidebar_rename_cb), + emblem_sidebar); + gtk_widget_show (menu_item); + gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item); + emblem_sidebar->details->popup_rename = menu_item; + + /* add "delete" menu item */ + menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_DELETE, + NULL); + g_signal_connect (menu_item, "activate", + G_CALLBACK (caja_emblem_sidebar_delete_cb), + emblem_sidebar); + gtk_widget_show (menu_item); + gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item); + emblem_sidebar->details->popup_remove = menu_item; + + emblem_sidebar->details->popup = popup; +} + +static GtkWidget * +create_emblem_widget_with_pixbuf (CajaEmblemSidebar *emblem_sidebar, + const char *keyword, + const char *display_name, + GdkPixbuf *pixbuf) +{ + GtkWidget *image, *event_box; + GdkPixbuf *prelight_pixbuf; + + + image = eel_labeled_image_new (display_name, pixbuf); + + eel_labeled_image_set_fixed_image_height (EEL_LABELED_IMAGE (image), + STANDARD_EMBLEM_HEIGHT); + eel_labeled_image_set_spacing (EEL_LABELED_IMAGE (image), + EMBLEM_LABEL_SPACING); + event_box = gtk_event_box_new (); + gtk_container_add (GTK_CONTAINER (event_box), image); + + prelight_pixbuf = eel_create_spotlight_pixbuf (pixbuf); + + + gtk_drag_source_set (event_box, GDK_BUTTON1_MASK, drag_types, + G_N_ELEMENTS (drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE); + + gtk_drag_source_set_icon_pixbuf (event_box, pixbuf); + + + + g_signal_connect (event_box, "button_press_event", + G_CALLBACK (caja_emblem_sidebar_button_press_cb), + emblem_sidebar); + g_signal_connect (event_box, "drag-data-get", + G_CALLBACK (caja_emblem_sidebar_drag_data_get_cb), + emblem_sidebar); + g_signal_connect (event_box, "enter-notify-event", + G_CALLBACK (caja_emblem_sidebar_enter_notify_cb), + emblem_sidebar); + g_signal_connect (event_box, "leave-notify-event", + G_CALLBACK (caja_emblem_sidebar_leave_notify_cb), + emblem_sidebar); + + g_object_set_data_full (G_OBJECT (event_box), + "emblem-keyword", + g_strdup (keyword), g_free); + g_object_set_data_full (G_OBJECT (event_box), + "emblem-display-name", + g_strdup (display_name), g_free); + g_object_set_data_full (G_OBJECT (event_box), + "original-pixbuf", + pixbuf, g_object_unref); + g_object_set_data_full (G_OBJECT (event_box), + "prelight-pixbuf", + prelight_pixbuf, g_object_unref); + g_object_set_data (G_OBJECT (event_box), + "labeled-image", image); + + return event_box; + +} + +static GtkWidget * +create_emblem_widget (CajaEmblemSidebar *emblem_sidebar, + const char *name) +{ + GtkWidget *ret; + const char *display_name; + char *keyword; + GdkPixbuf *pixbuf; + CajaIconInfo *info; + + info = caja_icon_info_lookup_from_name (name, CAJA_ICON_SIZE_STANDARD); + + pixbuf = caja_icon_info_get_pixbuf_at_size (info, CAJA_ICON_SIZE_STANDARD); + + display_name = caja_icon_info_get_display_name (info); + + keyword = caja_emblem_get_keyword_from_icon_name (name); + if (display_name == NULL) + { + display_name = keyword; + } + + ret = create_emblem_widget_with_pixbuf (emblem_sidebar, keyword, + display_name, pixbuf); + g_free (keyword); + g_object_unref (info); + return ret; +} + +static void +emblem_name_entry_changed_cb (GtkWidget *entry, Emblem *emblem) +{ + char *text; + + g_free (emblem->name); + + text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); + + emblem->name = g_strdup (text); +} + + +static void +destroy_emblem (Emblem *emblem, gpointer user_data) +{ + g_return_if_fail (emblem != NULL); + + + if (emblem->pixbuf != NULL) + { + g_object_unref (emblem->pixbuf); + emblem->pixbuf = NULL; + } + + if (emblem->name != NULL) + { + g_free (emblem->name); + emblem->name = NULL; + } + + if (emblem->uri != NULL) + { + g_free (emblem->uri); + emblem->uri = NULL; + } + + if (emblem->keyword != NULL) + { + g_free (emblem->keyword); + emblem->keyword = NULL; + } + + g_free (emblem); +} + +static void +destroy_emblem_list (GSList *list) +{ + g_slist_foreach (list, (GFunc)destroy_emblem, NULL); + g_slist_free (list); +} + +static GtkWidget * +create_add_emblems_dialog (CajaEmblemSidebar *emblem_sidebar, + GSList *emblems) +{ + GtkWidget *dialog, *label, *table, *image; + GtkWidget *first_entry, *entry, *scroller, *hbox; + Emblem *emblem; + GSList *list; + int num_emblems; + + first_entry = NULL; + + dialog = gtk_dialog_new_with_buttons (_("Add Emblems..."), + NULL, + 0, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + GTK_STOCK_HELP, + GTK_RESPONSE_HELP, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_OK); + + /* FIXME: make a better message */ + if (g_slist_length (emblems) > 1) + { + label = gtk_label_new (_("Enter a descriptive name next to each emblem. This name will be used in other places to identify the emblem.")); + } + else + { + label = gtk_label_new (_("Enter a descriptive name next to the emblem. This name will be used in other places to identify the emblem.")); + } + + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + label, FALSE, FALSE, 8); + gtk_widget_show (label); + + scroller = eel_scrolled_wrap_table_new (TRUE, GTK_SHADOW_NONE, &table); + eel_wrap_table_set_x_spacing (EEL_WRAP_TABLE (table), 8); + eel_wrap_table_set_y_spacing (EEL_WRAP_TABLE (table), 8); + + num_emblems=0; + list = emblems; + while (list != NULL) + { + /* walk through the list of emblems, and create an image + * and entry for each one + */ + + emblem = (Emblem *)list->data; + list = list->next; + + image = gtk_image_new_from_pixbuf (emblem->pixbuf); + + hbox = gtk_hbox_new (TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + + entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); + g_signal_connect (entry, "changed", + G_CALLBACK (emblem_name_entry_changed_cb), + emblem); + + gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (table), hbox); + + if (num_emblems == 0) + { + first_entry = entry; + } + + num_emblems++; + } + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 8); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + scroller, TRUE, TRUE, 8); + gtk_widget_show_all (scroller); + + gtk_widget_grab_focus (first_entry); + + /* we expand the window to hold up to about 4 emblems, but after that + * let the scroller do its thing. Is there a better way to do this? + */ + gtk_window_set_default_size (GTK_WINDOW (dialog), 400, + MIN (120+(60*num_emblems), 350)); + + g_object_set_data_full (G_OBJECT (dialog), "emblems-to-add", + emblems, (GDestroyNotify)destroy_emblem_list); + + return dialog; +} + +static void +remove_widget (GtkWidget *widget, GtkContainer *container) +{ + gtk_container_remove (container, widget); +} + +static void +caja_emblem_sidebar_refresh (CajaEmblemSidebar *emblem_sidebar) +{ + caja_emblem_refresh_list (); + + gtk_container_foreach (GTK_CONTAINER (emblem_sidebar->details->emblems_table), + (GtkCallback)remove_widget, + emblem_sidebar->details->emblems_table); + + caja_emblem_sidebar_populate (emblem_sidebar); +} + +static void +add_emblems_dialog_response_cb (GtkWidget *dialog, int response, + CajaEmblemSidebar *emblem_sidebar) +{ + Emblem *emblem; + GSList *emblems; + GSList *l; + + switch (response) + { + case GTK_RESPONSE_CANCEL: + gtk_widget_destroy (dialog); + break; + + case GTK_RESPONSE_HELP: + g_message ("Implement me!"); + break; + + case GTK_RESPONSE_OK: + emblems = g_object_get_data (G_OBJECT (dialog), + "emblems-to-add"); + + for (l = emblems; l; l = l->next) + { + char *keyword; + + emblem = (Emblem *)l->data; + if (emblem->keyword != NULL) + { + /* this one has already been verified */ + continue; + } + + keyword = caja_emblem_create_unique_keyword (emblem->name); + if (!caja_emblem_verify_keyword + (GTK_WINDOW (dialog), keyword, emblem->name)) + { + g_free (keyword); + return; + } + else + { + emblem->keyword = keyword; + } + + } + + for (l = emblems; l; l = l->next) + { + emblem = (Emblem *)l->data; + + caja_emblem_install_custom_emblem (emblem->pixbuf, + emblem->keyword, + emblem->name, + GTK_WINDOW (dialog)); + } + + gtk_widget_destroy (dialog); + + send_emblems_changed (); + break; + } +} + +static void +show_add_emblems_dialog (CajaEmblemSidebar *emblem_sidebar, + GSList *emblems) +{ + GtkWidget *dialog; + + g_return_if_fail (emblems != NULL); + + dialog = create_add_emblems_dialog (emblem_sidebar, emblems); + + if (dialog == NULL) + { + return; + } + + g_signal_connect (dialog, "response", + G_CALLBACK (add_emblems_dialog_response_cb), + emblem_sidebar); + + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +caja_emblem_sidebar_drag_received_cb (GtkWidget *widget, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *data, + guint info, + guint time, + CajaEmblemSidebar *emblem_sidebar) +{ + GSList *emblems; + Emblem *emblem; + GdkPixbuf *pixbuf; + char *uri, *error, *uri_utf8; + char **uris; + GFile *f; + int i; + gboolean had_failure; + gint data_format, data_length; + const guchar *data_data; + + had_failure = FALSE; + emblems = NULL; + data_format = gtk_selection_data_get_format (data); + data_length = gtk_selection_data_get_length (data); + data_data = gtk_selection_data_get_data (data); + + switch (info) + { + case TARGET_URI_LIST: + if (data_format != 8 || + data_length == 0) + { + g_message ("URI list had wrong format (%d) or length (%d)\n", + data_format, data_length); + return; + } + + uris = g_uri_list_extract_uris (data_data); + if (uris == NULL) + { + break; + } + + for (i = 0; uris[i] != NULL; ++i) + { + f = g_file_new_for_uri (uris[i]); + pixbuf = caja_emblem_load_pixbuf_for_emblem (f); + + if (pixbuf == NULL) + { + /* this one apparently isn't an image, or + * at least not one that we know how to read + */ + had_failure = TRUE; + g_object_unref (f); + continue; + } + + emblem = g_new (Emblem, 1); + emblem->uri = g_file_get_uri (f); + emblem->name = NULL; /* created later on by the user */ + emblem->keyword = NULL; + emblem->pixbuf = pixbuf; + + g_object_unref (f); + + emblems = g_slist_prepend (emblems, emblem); + } + + g_strfreev (uris); + + if (had_failure && emblems != NULL) + { + eel_show_error_dialog (_("Some of the files could not be added as emblems."), _("The emblems do not appear to be valid images."), NULL); + } + else if (had_failure && emblems == NULL) + { + eel_show_error_dialog (_("None of the files could be added as emblems."), _("The emblems do not appear to be valid images."), NULL); + + } + + if (emblems != NULL) + { + show_add_emblems_dialog (emblem_sidebar, emblems); + } + + break; + + case TARGET_URI: + if (data_format != 8 || + data_length == 0) + { + g_warning ("URI had wrong format (%d) or length (%d)\n", + data_format, data_length); + return; + } + + uri = g_strndup (data_data, data_length); + + f = g_file_new_for_uri (uri); + pixbuf = caja_emblem_load_pixbuf_for_emblem (f); + + if (pixbuf != NULL) + { + emblem = g_new (Emblem, 1); + emblem->uri = uri; + emblem->name = NULL; + emblem->keyword = NULL; + emblem->pixbuf = pixbuf; + + emblems = g_slist_prepend (NULL, emblem); + + show_add_emblems_dialog (emblem_sidebar, emblems); + } + else + { + uri_utf8 = g_file_get_parse_name (f); + + if (uri_utf8) + { + error = g_strdup_printf (_("The file '%s' does not appear to be a valid image."), uri_utf8); + g_free (uri_utf8); + } + else + { + error = g_strdup (_("The dragged file does not appear to be a valid image.")); + } + eel_show_error_dialog (_("The emblem cannot be added."), error, NULL); + g_free (error); + g_free (uri_utf8); + } + + g_object_unref (f); + g_free (uri); + + break; + + case TARGET_NETSCAPE_URL: + if (data_format != 8 || + data_length == 0) + { + g_message ("URI had wrong format (%d) or length (%d)\n", + data_format, data_length); + return; + } + + /* apparently, this is a URI/title pair? or just a pair + * of identical URIs? Regardless, this seems to work... + */ + + uris = g_uri_list_extract_uris (data_data); + if (uris == NULL) + { + break; + } + + uri = uris[0]; + if (uri == NULL) + { + g_strfreev (uris); + break; + } + + f = g_file_new_for_uri (uri); + pixbuf = caja_emblem_load_pixbuf_for_emblem (f); + g_object_unref (f); + + if (pixbuf != NULL) + { + emblem = g_new (Emblem, 1); + emblem->uri = g_strdup (uri); + emblem->name = NULL; + emblem->keyword = NULL; + emblem->pixbuf = pixbuf; + + emblems = g_slist_prepend (NULL, emblem); + + show_add_emblems_dialog (emblem_sidebar, emblems); + } + else + { + g_warning ("Tried to load '%s', but failed.\n", + uri); + error = g_strdup_printf (_("The file '%s' does not appear to be a valid image."), uri); + eel_show_error_dialog (_("The emblem cannot be added."), error, NULL); + g_free (error); + } + + g_strfreev (uris); + + break; + } +} + +static GtkWidget * +caja_emblem_sidebar_create_container (CajaEmblemSidebar *emblem_sidebar) +{ + GtkWidget *emblems_table, *scroller; + + /* The emblems wrapped table */ + scroller = eel_scrolled_wrap_table_new (TRUE, GTK_SHADOW_IN, &emblems_table); + + gtk_container_set_border_width (GTK_CONTAINER (emblems_table), 8); + + /* set up dnd for adding emblems */ + gtk_drag_dest_set (scroller, + GTK_DEST_DEFAULT_ALL, + dest_types, G_N_ELEMENTS (dest_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE); + + g_signal_connect (scroller, "drag-data-received", + G_CALLBACK (caja_emblem_sidebar_drag_received_cb), + emblem_sidebar); + + gtk_widget_show (scroller); + + emblem_sidebar->details->emblems_table = emblems_table; + + return scroller; +} + +static gint +emblem_widget_sort_func (gconstpointer a, gconstpointer b) +{ + GObject *obj_a, *obj_b; + + obj_a = G_OBJECT (a); + obj_b = G_OBJECT (b); + + return strcmp (g_object_get_data (obj_a, "emblem-display-name"), + g_object_get_data (obj_b, "emblem-display-name")); +} + +static void +caja_emblem_sidebar_populate (CajaEmblemSidebar *emblem_sidebar) +{ + GList *icons, *l, *widgets; + GtkWidget *emblem_widget; + char *name; + char *path; + GdkPixbuf *erase_pixbuf; + + erase_pixbuf = NULL; + + path = caja_pixmap_file ("erase.png"); + if (path != NULL) + { + erase_pixbuf = gdk_pixbuf_new_from_file (path, NULL); + } + g_free (path); + + if (erase_pixbuf != NULL) + { + emblem_widget = create_emblem_widget_with_pixbuf (emblem_sidebar, + ERASE_EMBLEM_KEYWORD, + _("Erase"), + erase_pixbuf); + gtk_container_add (GTK_CONTAINER + (emblem_sidebar->details->emblems_table), + emblem_widget); + } + + + icons = caja_emblem_list_available (); + + l = icons; + widgets = NULL; + while (l != NULL) + { + name = (char *)l->data; + l = l->next; + + if (!caja_emblem_should_show_in_list (name)) + { + continue; + } + + emblem_widget = create_emblem_widget (emblem_sidebar, name); + + widgets = g_list_prepend (widgets, emblem_widget); + } + eel_g_list_free_deep (icons); + + /* sort the emblems by display name */ + widgets = g_list_sort (widgets, emblem_widget_sort_func); + + l = widgets; + while (l != NULL) + { + gtk_container_add + (GTK_CONTAINER (emblem_sidebar->details->emblems_table), + l->data); + l = l->next; + } + g_list_free (widgets); + + gtk_widget_show_all (emblem_sidebar->details->emblems_table); +} + +static void +caja_emblem_sidebar_init (CajaEmblemSidebar *emblem_sidebar) +{ + GtkWidget *widget; + + emblem_sidebar->details = g_new0 (CajaEmblemSidebarDetails, 1); + + emblem_sidebar->details->client = mateconf_client_get_default (); + + create_popup_menu (emblem_sidebar); + + widget = caja_emblem_sidebar_create_container (emblem_sidebar); + caja_emblem_sidebar_populate (emblem_sidebar); + + g_signal_connect_object (caja_signaller_get_current (), + "emblems_changed", + G_CALLBACK (emblems_changed_callback), emblem_sidebar, 0); + + gtk_box_pack_start (GTK_BOX (emblem_sidebar), widget, + TRUE, TRUE, 0); +} + +static void +caja_emblem_sidebar_finalize (GObject *object) +{ + CajaEmblemSidebar *emblem_sidebar; + + g_assert (CAJA_IS_EMBLEM_SIDEBAR (object)); + emblem_sidebar = CAJA_EMBLEM_SIDEBAR (object); + + if (emblem_sidebar->details != NULL) + { + if (emblem_sidebar->details->client != NULL) + { + g_object_unref (emblem_sidebar->details->client); + } + + g_free (emblem_sidebar->details); + } + + G_OBJECT_CLASS (caja_emblem_sidebar_parent_class)->finalize (object); +} + +static void +caja_emblem_sidebar_class_init (CajaEmblemSidebarClass *object_klass) +{ + GObjectClass *gobject_class; + + CajaEmblemSidebarClass *klass; + + klass = CAJA_EMBLEM_SIDEBAR_CLASS (object_klass); + gobject_class = G_OBJECT_CLASS (object_klass); + + gobject_class->finalize = caja_emblem_sidebar_finalize; +} + +static const char * +caja_emblem_sidebar_get_sidebar_id (CajaSidebar *sidebar) +{ + return CAJA_EMBLEM_SIDEBAR_ID; +} + +static char * +caja_emblem_sidebar_get_tab_label (CajaSidebar *sidebar) +{ + return g_strdup (_("Emblems")); +} + +static char * +caja_emblem_sidebar_get_tab_tooltip (CajaSidebar *sidebar) +{ + return g_strdup (_("Show Emblems")); +} + +static GdkPixbuf * +caja_emblem_sidebar_get_tab_icon (CajaSidebar *sidebar) +{ + return NULL; +} + +static void +caja_emblem_sidebar_is_visible_changed (CajaSidebar *sidebar, + gboolean is_visible) +{ + /* Do nothing */ +} + +static void +caja_emblem_sidebar_iface_init (CajaSidebarIface *iface) +{ + iface->get_sidebar_id = caja_emblem_sidebar_get_sidebar_id; + iface->get_tab_label = caja_emblem_sidebar_get_tab_label; + iface->get_tab_tooltip = caja_emblem_sidebar_get_tab_tooltip; + iface->get_tab_icon = caja_emblem_sidebar_get_tab_icon; + iface->is_visible_changed = caja_emblem_sidebar_is_visible_changed; +} + +static void +caja_emblem_sidebar_set_parent_window (CajaEmblemSidebar *sidebar, + CajaWindowInfo *window) +{ + sidebar->details->window = window; +} + +static CajaSidebar * +caja_emblem_sidebar_create (CajaSidebarProvider *provider, + CajaWindowInfo *window) +{ + CajaEmblemSidebar *sidebar; + + sidebar = g_object_new (caja_emblem_sidebar_get_type (), NULL); + caja_emblem_sidebar_set_parent_window (sidebar, window); + g_object_ref_sink (sidebar); + + return CAJA_SIDEBAR (sidebar); +} + +static void +sidebar_provider_iface_init (CajaSidebarProviderIface *iface) +{ + iface->create = caja_emblem_sidebar_create; +} + +static void +caja_emblem_sidebar_provider_init (CajaEmblemSidebarProvider *sidebar) +{ +} + +static void +caja_emblem_sidebar_provider_class_init (CajaEmblemSidebarProviderClass *class) +{ +} + +void +caja_emblem_sidebar_register (void) +{ + caja_module_add_type (caja_emblem_sidebar_provider_get_type ()); +} + |