r1322: Converted MaskedPixmap to GObject.
[rox-filer.git] / ROX-Filer / src / icon.c
blob781ebb05efec7cf6344c03cf25c83e1dbe01111b
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* icon.c - shared code for the pinboard and panels */
24 #include "config.h"
26 #undef GTK_DISABLE_DEPRECATED
28 #include <string.h>
30 #include <gtk/gtkinvisible.h>
31 #include <gtk/gtk.h>
32 #include <libxml/parser.h>
34 #include "global.h"
36 #include "main.h"
37 #include "gui_support.h"
38 #include "support.h"
39 #include "pinboard.h"
40 #include "panel.h"
41 #include "icon.h"
42 #include "diritem.h"
43 #include "menu.h"
44 #include "appmenu.h"
45 #include "dnd.h"
46 #include "run.h"
47 #include "infobox.h"
48 #include "pixmaps.h"
49 #include "mount.h"
50 #include "appinfo.h"
51 #include "type.h"
52 #include "usericons.h"
54 typedef void (*RenameFn)(Icon *icon);
56 static GtkWidget *icon_menu; /* The popup icon menu */
57 static GtkWidget *icon_file_menu; /* The file submenu */
58 static GtkWidget *icon_file_item; /* 'File' label */
59 static GtkWidget *file_shift_item; /* 'Shift Open' label */
61 /* Widget which holds the selection when we have it */
62 static GtkWidget *selection_invisible = NULL;
63 static guint losing_selection = 0; /* > 0 => Don't send events */
64 gboolean tmp_icon_selected = FALSE; /* When dragging */
66 /* A list of selected Icons */
67 GList *icon_selection = NULL;
69 /* Each entry is a GList of Icons which have the given pathname.
70 * This allows us to update all necessary icons when something changes.
72 static GHashTable *icons_hash = NULL;
74 static Icon *menu_icon = NULL; /* Item clicked if there is no selection */
76 /* Static prototypes */
77 static void rename_activate(GtkWidget *dialog);
78 static void menu_closed(GtkWidget *widget);
79 static void panel_position_menu(GtkMenu *menu, gint *x, gint *y,
80 gboolean *push_in, gpointer data);
81 static gint lose_selection(GtkWidget *widget, GdkEventSelection *event);
82 static void selection_get(GtkWidget *widget,
83 GtkSelectionData *selection_data,
84 guint info,
85 guint time,
86 gpointer data);
87 static void remove_items(gpointer data, guint action, GtkWidget *widget);
88 static void file_op(gpointer data, guint action, GtkWidget *widget);
89 static void show_rename_box(GtkWidget *widget, Icon *icon, RenameFn callback);
91 enum {
92 ACTION_SHIFT,
93 ACTION_HELP,
94 ACTION_INFO,
95 ACTION_RUN_ACTION,
96 ACTION_SET_ICON,
97 ACTION_EDIT,
98 ACTION_LOCATION,
101 #undef N_
102 #define N_(x) x
103 static GtkItemFactoryEntry menu_def[] = {
104 {N_("ROX-Filer"), NULL, NULL, 0, "<Branch>"},
105 {">" N_("Help"), NULL, menu_rox_help, 0, NULL},
106 {">" N_("Options..."), NULL, menu_show_options, 0, NULL},
107 {">" N_("Home Directory"), NULL, open_home, 0, NULL},
108 {N_("File"), NULL, NULL, 0, "<Branch>"},
109 {">" N_("Shift Open"), NULL, file_op, ACTION_SHIFT, NULL},
110 {">" N_("Help"), NULL, file_op, ACTION_HELP, NULL},
111 {">" N_("Info"), NULL, file_op, ACTION_INFO, NULL},
112 {">" N_("Set Run Action..."), NULL, file_op, ACTION_RUN_ACTION, NULL},
113 {">" N_("Set Icon..."), NULL, file_op, ACTION_SET_ICON, NULL},
114 {N_("Edit Item"), NULL, file_op, ACTION_EDIT, NULL},
115 {N_("Show Location"), NULL, file_op, ACTION_LOCATION, NULL},
116 {N_("Remove Item(s)"), NULL, remove_items, 0, NULL},
119 /****************************************************************
120 * EXTERNAL INTERFACE *
121 ****************************************************************/
123 void icon_init(void)
125 guchar *tmp;
126 GList *items;
127 GtkItemFactory *item_factory;
128 GtkTargetEntry target_table[] =
130 {"text/uri-list", 0, TARGET_URI_LIST},
131 {"STRING", 0, TARGET_STRING},
134 icons_hash = g_hash_table_new(g_str_hash, g_str_equal);
136 item_factory = menu_create(menu_def,
137 sizeof(menu_def) / sizeof(*menu_def),
138 "<icon>", NULL);
140 tmp = g_strconcat("<icon>/", _("File"), NULL);
141 icon_menu = gtk_item_factory_get_widget(item_factory, "<icon>");
142 icon_file_menu = gtk_item_factory_get_widget(item_factory, tmp);
143 g_free(tmp);
145 /* File '' label... */
146 items = gtk_container_get_children(GTK_CONTAINER(icon_menu));
147 icon_file_item = GTK_BIN(g_list_nth(items, 1)->data)->child;
148 g_list_free(items);
150 /* Shift Open... label */
151 items = gtk_container_get_children(GTK_CONTAINER(icon_file_menu));
152 file_shift_item = GTK_BIN(items->data)->child;
153 g_list_free(items);
155 g_signal_connect(icon_menu, "unmap_event",
156 G_CALLBACK(menu_closed), NULL);
158 selection_invisible = gtk_invisible_new();
160 g_signal_connect(selection_invisible, "selection_clear_event",
161 G_CALLBACK(lose_selection), NULL);
163 g_signal_connect(selection_invisible, "selection_get",
164 G_CALLBACK(selection_get), NULL);
166 gtk_selection_add_targets(selection_invisible,
167 GDK_SELECTION_PRIMARY,
168 target_table,
169 sizeof(target_table) / sizeof(*target_table));
171 tooltips = gtk_tooltips_new();
174 /* The icons_hash table allows us to convert from a path to a list
175 * of icons that use that path.
176 * Add this icon to the list for its path.
178 void icon_hash_path(Icon *icon)
180 GList *list;
182 g_return_if_fail(icon != NULL);
184 /* g_print("[ hashing '%s' ]\n", icon->path); */
186 list = g_hash_table_lookup(icons_hash, icon->path);
187 list = g_list_prepend(list, icon);
188 g_hash_table_insert(icons_hash, icon->path, list);
191 /* Remove this icon from the icons_hash table */
192 void icon_unhash_path(Icon *icon)
194 GList *list;
196 g_return_if_fail(icon != NULL);
198 /* g_print("[ unhashing '%s' ]\n", icon->path); */
200 list = g_hash_table_lookup(icons_hash, icon->path);
201 g_return_if_fail(list != NULL);
203 list = g_list_remove(list, icon);
205 /* Remove it first; the hash key may have changed address */
206 g_hash_table_remove(icons_hash, icon->path);
207 if (list)
208 g_hash_table_insert(icons_hash,
209 ((Icon *) list->data)->path, list);
212 /* Called when the pointer moves over the icon */
213 void icon_may_update(Icon *icon)
215 MaskedPixmap *image;
216 int flags;
218 g_return_if_fail(icon != NULL);
220 image = icon->item->image;
221 flags = icon->item->flags;
223 if (image)
224 g_object_ref(image);
225 mount_update(FALSE);
226 diritem_restat(icon->path, icon->item);
228 if (icon->item->image != image || icon->item->flags != flags)
230 /* Appearance changed; need to redraw */
231 if (icon->panel)
232 gtk_widget_queue_draw(icon->widget);
233 else
234 pinboard_reshape_icon(icon);
237 if (image)
238 g_object_unref(image);
241 /* If path is on an icon then it may have changed... check! */
242 void icons_may_update(const gchar *path)
244 GList *affected;
246 affected = g_hash_table_lookup(icons_hash, path);
248 for (; affected; affected = affected->next)
249 icon_may_update((Icon *) affected->data);
252 typedef struct _CheckData CheckData;
253 struct _CheckData {
254 const gchar *path;
255 gboolean found;
258 static void check_has(gpointer key, GList *icons, CheckData *check)
260 Icon *icon;
262 g_return_if_fail(icons != NULL);
264 icon = icons->data;
266 if (is_sub_dir(icon->path, check->path))
267 check->found = TRUE;
270 /* Set the tooltip AND hide/show the label for panel icons */
271 void icon_set_tip(Icon *icon)
273 GtkWidget *widget;
274 XMLwrapper *ai;
275 xmlNode *node;
277 g_return_if_fail(icon != NULL);
279 widget = icon->panel ? icon->widget : icon->win;
281 if (icon->panel && icon->label)
283 if (panel_want_show_text(icon))
284 gtk_widget_show(icon->label);
285 else
286 gtk_widget_hide(icon->label);
289 if (icon->panel && icon->socket)
290 ai = NULL;
291 else
292 ai = appinfo_get(icon->path, icon->item);
294 if (ai && ((node = appinfo_get_section(ai, "Summary"))))
296 guchar *str;
297 str = xmlNodeListGetString(node->doc,
298 node->xmlChildrenNode, 1);
299 if (str)
301 gtk_tooltips_set_tip(tooltips, widget, str, NULL);
302 g_free(str);
305 else if (icon->panel && (!panel_want_show_text(icon)) && !icon->socket)
307 gtk_tooltips_set_tip(tooltips, widget,
308 icon->item->leafname, NULL);
310 else
311 gtk_tooltips_set_tip(tooltips, widget, NULL, NULL);
313 if (ai)
314 g_object_unref(ai);
317 /* Returns TRUE if any icon links to this item (or any item inside
318 * this item).
320 gboolean icons_require(const gchar *path)
322 CheckData check;
324 /* g_print("[ icons_require(%s)? ]\n", path); */
326 check.path = path;
327 check.found = FALSE;
328 g_hash_table_foreach(icons_hash, (GHFunc) check_has, &check);
330 return check.found;
333 /* Callback to update icons of a certain path */
334 static void update_icons(gpointer key, GList *icons, gpointer data)
336 icons_may_update((guchar *) key);
339 /* Check all icons to see if they have been updated */
340 void update_all_icons(void)
342 g_hash_table_foreach(icons_hash, (GHFunc) update_icons, NULL);
345 /* Show the menu for this panel (NULL for the pinboard).
346 * icon is the icon that was clicked on, if any.
348 void icon_show_menu(GdkEventButton *event, Icon *icon, Panel *panel)
350 int pos[3];
352 pos[0] = event->x_root;
353 pos[1] = event->y_root;
354 pos[2] = 1;
356 appmenu_remove();
358 menu_icon = icon;
360 /* Shade Remove Item(s) unless there is a selection */
361 menu_set_items_shaded(icon_menu,
362 (icon_selection || menu_icon) ? FALSE : TRUE,
363 4, 1);
365 menu_show_shift_action(file_shift_item, icon ? icon->item : NULL,
366 FALSE);
368 /* Shade the File/Edit/Show items unless an item was clicked */
369 if (icon)
371 guchar *tmp;
373 menu_set_items_shaded(icon_menu, FALSE, 1, 3);
374 menu_set_items_shaded(icon_file_menu, FALSE, 0, 5);
375 if (!can_set_run_action(icon->item))
376 menu_set_items_shaded(icon_file_menu, TRUE, 3, 1);
378 tmp = g_strdup_printf("%s '%s'",
379 basetype_name(icon->item),
380 icon->item->leafname);
381 gtk_label_set_text(GTK_LABEL(icon_file_item), tmp);
382 g_free(tmp);
384 /* Check for app-specific menu */
385 appmenu_add(icon->path, icon->item, icon_menu);
387 else
389 menu_set_items_shaded(icon_menu, TRUE, 1, 3);
390 menu_set_items_shaded(icon_file_menu, TRUE, 0, 5);
391 gtk_label_set_text(GTK_LABEL(icon_file_item), _("Nothing"));
394 if (panel)
396 PanelSide side = panel->side;
398 if (side == PANEL_LEFT)
399 pos[0] = -2;
400 else if (side == PANEL_RIGHT)
401 pos[0] = -1;
403 if (side == PANEL_TOP)
404 pos[1] = -2;
405 else if (side == PANEL_BOTTOM)
406 pos[1] = -1;
409 gtk_menu_popup(GTK_MENU(icon_menu), NULL, NULL,
410 panel ? panel_position_menu : position_menu,
411 (gpointer) pos, event->button, event->time);
414 void icon_set_selected(Icon *icon, gboolean selected)
416 gboolean clear = FALSE;
418 g_return_if_fail(icon != NULL);
420 if (icon->selected == selected)
421 return;
423 /* When selecting an icon on another panel, we need to unselect
424 * everything else afterwards.
426 if (selected && icon_selection)
428 Icon *current = (Icon *) icon_selection->data;
430 if (icon->panel != current->panel)
431 clear = TRUE;
434 icon->selected = selected;
436 gtk_widget_queue_draw(icon->widget);
438 if (selected)
440 icon_selection = g_list_prepend(icon_selection, icon);
441 if (losing_selection == 0 && !icon_selection->next)
443 /* Grab selection */
444 gtk_selection_owner_set(selection_invisible,
445 GDK_SELECTION_PRIMARY,
446 gdk_event_get_time(gtk_get_current_event()));
449 else
451 icon_selection = g_list_remove(icon_selection, icon);
452 if (losing_selection == 0 && !icon_selection)
454 /* Release selection */
455 gtk_selection_owner_set(NULL,
456 GDK_SELECTION_PRIMARY,
457 gdk_event_get_time(gtk_get_current_event()));
461 if (clear)
462 icon_select_only(icon);
465 /* Clear everything, except 'select', which is selected.
466 * If select is NULL, unselects everything.
468 void icon_select_only(Icon *select)
470 GList *to_clear, *next;
472 if (select)
473 icon_set_selected(select, TRUE);
475 to_clear = g_list_copy(icon_selection);
477 if (select)
478 to_clear = g_list_remove(to_clear, select);
480 for (next = to_clear; next; next = next->next)
481 icon_set_selected((Icon *) next->data, FALSE);
483 g_list_free(to_clear);
486 /* XXX: Under Gtk+ 2.0, can this get called twice? */
487 void icon_destroyed(Icon *icon)
489 g_return_if_fail(icon != NULL);
491 if (icon == menu_icon)
492 menu_icon = NULL;
494 if (icon->layout)
496 g_object_unref(G_OBJECT(icon->layout));
497 icon->layout = NULL;
500 icon_unhash_path(icon);
502 pinboard_wink_item(NULL, FALSE);
504 if (g_list_find(icon_selection, icon))
506 icon_selection = g_list_remove(icon_selection, icon);
508 if (!icon_selection)
509 gtk_selection_owner_set(NULL,
510 GDK_SELECTION_PRIMARY,
511 gdk_event_get_time(gtk_get_current_event()));
514 if (icon->panel == NULL)
516 gdk_pixmap_unref(icon->mask);
517 if (current_pinboard)
518 current_pinboard->icons =
519 g_list_remove(current_pinboard->icons, icon);
522 diritem_free(icon->item);
523 g_free(icon->path);
524 g_free(icon->src_path);
525 g_free(icon);
528 static void set_tip(gpointer key, GList *icons, gpointer data)
530 for (; icons; icons = icons->next)
532 Icon *icon = (Icon *) icons->data;
534 icon_set_tip(icon);
538 void icons_update_tip(void)
540 g_hash_table_foreach(icons_hash, (GHFunc) set_tip, NULL);
543 /* Removes trailing / chars and converts a leading '~/' (if any) to
544 * the user's home dir. g_free() the result.
546 gchar *icon_convert_path(const gchar *path)
548 guchar *retval;
549 int path_len;
551 g_return_val_if_fail(path != NULL, NULL);
553 path_len = strlen(path);
554 while (path_len > 1 && path[path_len - 1] == '/')
555 path_len--;
557 retval = g_strndup(path, path_len);
559 if (path[0] == '~' && (path[1] == '\0' || path[1] == '/'))
561 guchar *tmp = retval;
563 retval = g_strconcat(home_dir, retval + 1, NULL);
564 g_free(tmp);
567 return retval;
570 /****************************************************************
571 * INTERNAL FUNCTIONS *
572 ****************************************************************/
574 static void rename_activate(GtkWidget *dialog)
576 GtkWidget *entry, *src;
577 RenameFn callback;
578 Icon *icon;
579 const guchar *new_name, *new_src;
581 entry = g_object_get_data(G_OBJECT(dialog), "new_name");
582 icon = g_object_get_data(G_OBJECT(dialog), "callback_icon");
583 callback = g_object_get_data(G_OBJECT(dialog), "callback_fn");
584 src = g_object_get_data(G_OBJECT(dialog), "new_path");
586 g_return_if_fail(callback != NULL &&
587 entry != NULL &&
588 src != NULL &&
589 icon != NULL);
591 new_name = gtk_entry_get_text(GTK_ENTRY(entry));
592 new_src = gtk_entry_get_text(GTK_ENTRY(src));
594 if (*new_name == '\0')
595 report_error(
596 _("The label must contain at least one character!"));
597 else if (*new_src == '\0')
598 report_error(
599 _("The location must contain at least one character!"));
600 else
602 g_free(icon->item->leafname);
603 g_free(icon->src_path);
605 icon->src_path = g_strdup(new_src);
607 icon_unhash_path(icon);
608 g_free(icon->path);
609 icon->path = icon_convert_path(new_src);
610 icon_hash_path(icon);
612 icon->item->leafname = g_strdup(new_name);
613 /* XXX: Set name_width in size_and_shape? */
615 diritem_restat(icon->path, icon->item);
617 callback(icon);
618 gtk_widget_destroy(dialog);
622 static void menu_closed(GtkWidget *widget)
624 appmenu_remove();
625 menu_icon = NULL;
628 static void panel_position_menu(GtkMenu *menu, gint *x, gint *y,
629 gboolean *push_in, gpointer data)
631 int *pos = (int *) data;
632 GtkRequisition requisition;
634 gtk_widget_size_request(GTK_WIDGET(menu), &requisition);
636 if (pos[0] == -1)
637 *x = screen_width - MENU_MARGIN - requisition.width;
638 else if (pos[0] == -2)
639 *x = MENU_MARGIN;
640 else
641 *x = pos[0] - (requisition.width >> 2);
643 if (pos[1] == -1)
644 *y = screen_height - MENU_MARGIN - requisition.height;
645 else if (pos[1] == -2)
646 *y = MENU_MARGIN;
647 else
648 *y = pos[1] - (requisition.height >> 2);
650 *x = CLAMP(*x, 0, screen_width - requisition.width);
651 *y = CLAMP(*y, 0, screen_height - requisition.height);
653 *push_in = FALSE;
656 /* Called when another application takes the selection away from us */
657 static gint lose_selection(GtkWidget *widget, GdkEventSelection *event)
659 /* Don't send any events */
661 losing_selection++;
662 icon_select_only(NULL);
663 losing_selection--;
665 return TRUE;
668 /* Called when another application wants the contents of our selection */
669 static void selection_get(GtkWidget *widget,
670 GtkSelectionData *selection_data,
671 guint info,
672 guint time,
673 gpointer data)
675 GString *str;
676 GList *next;
677 guchar *leader = NULL;
679 str = g_string_new(NULL);
681 if (info == TARGET_URI_LIST)
682 leader = g_strdup_printf("file://%s", our_host_name_for_dnd());
684 for (next = icon_selection; next; next = next->next)
686 Icon *icon = (Icon *) next->data;
688 if (leader)
689 g_string_append(str, leader);
690 g_string_append(str, icon->path);
691 g_string_append_c(str, ' ');
694 g_free(leader);
696 gtk_selection_data_set(selection_data,
697 gdk_atom_intern("STRING", FALSE),
699 str->str,
700 str->len ? str->len - 1 : 0);
702 g_string_free(str, TRUE);
705 static void rename_cb(Icon *icon)
707 if (icon->panel)
709 gtk_widget_queue_clear(icon->widget);
710 panel_icon_renamed(icon);
711 panel_save(icon->panel);
713 else
715 pinboard_reshape_icon(icon);
716 pinboard_save();
720 static void remove_items(gpointer data, guint action, GtkWidget *widget)
722 Panel *panel;
723 GList *next;
725 if (menu_icon)
726 icon_set_selected(menu_icon, TRUE);
728 next = icon_selection;
730 if (!next)
732 delayed_error(
733 _("You must first select some items to remove"));
734 return;
737 panel = ((Icon *) next->data)->panel;
739 if (panel)
741 while (next)
743 Icon *icon = (Icon *) next->data;
745 next = next->next;
747 gtk_widget_destroy(icon->widget);
750 panel_save(panel);
752 else
754 while (next)
756 Icon *icon = (Icon *) next->data;
758 next = next->next;
760 gtk_widget_destroy(icon->win);
763 pinboard_save();
767 static void file_op(gpointer data, guint action, GtkWidget *widget)
769 if (!menu_icon)
771 delayed_error(_("You must open the menu over an item"));
772 return;
775 switch (action)
777 case ACTION_SHIFT:
778 run_diritem(menu_icon->path, menu_icon->item,
779 NULL, NULL, TRUE);
780 break;
781 case ACTION_EDIT:
782 show_rename_box(menu_icon->widget,
783 menu_icon, rename_cb);
784 break;
785 case ACTION_LOCATION:
786 open_to_show(menu_icon->path);
787 break;
788 case ACTION_HELP:
789 show_item_help(menu_icon->path, menu_icon->item);
790 break;
791 case ACTION_INFO:
792 infobox_new(menu_icon->path);
793 break;
794 case ACTION_RUN_ACTION:
795 if (can_set_run_action(menu_icon->item))
796 type_set_handler_dialog(
797 menu_icon->item->mime_type);
798 else
799 report_error(
800 _("You can only set the run action for a "
801 "regular file"));
802 break;
803 case ACTION_SET_ICON:
804 icon_set_handler_dialog(menu_icon->item,
805 menu_icon->path);
806 break;
810 /* Opens a box allowing the user to change the name of a pinned icon.
811 * If 'widget' is destroyed then the box will close.
812 * If the user chooses OK then the callback is called once the icon's
813 * name, src_path and path fields have been updated and the item field
814 * restatted.
816 static void show_rename_box(GtkWidget *widget, Icon *icon, RenameFn callback)
818 GtkWidget *dialog, *hbox, *vbox, *label, *entry, *button;
820 /* XXX: Use a real dialog box! */
821 dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
822 gtk_window_set_type_hint(GTK_WINDOW(dialog),
823 GDK_WINDOW_TYPE_HINT_DIALOG);
825 gtk_window_set_title(GTK_WINDOW(dialog), _("Edit Item"));
826 gtk_container_set_border_width(GTK_CONTAINER(dialog), 10);
828 vbox = gtk_vbox_new(FALSE, 4);
829 gtk_container_add(GTK_CONTAINER(dialog), vbox);
831 label = gtk_label_new(_("Clicking the icon opens:"));
832 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
834 entry = gtk_entry_new();
835 gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, FALSE, 2);
836 gtk_entry_set_text(GTK_ENTRY(entry), icon->src_path);
837 g_object_set_data(G_OBJECT(dialog), "new_path", entry);
838 g_signal_connect_swapped(entry, "activate",
839 G_CALLBACK(rename_activate), dialog);
841 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), TRUE, TRUE, 2);
843 label = gtk_label_new(_("The text displayed under the icon is:"));
844 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
845 entry = gtk_entry_new();
846 gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, FALSE, 2);
847 gtk_entry_set_text(GTK_ENTRY(entry), icon->item->leafname);
848 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
849 gtk_widget_grab_focus(entry);
850 g_object_set_data(G_OBJECT(dialog), "new_name", entry);
851 g_signal_connect_swapped(entry, "activate",
852 G_CALLBACK(rename_activate), dialog);
854 gtk_signal_connect_object_while_alive(GTK_OBJECT(widget),
855 "destroy",
856 GTK_SIGNAL_FUNC(gtk_widget_destroy),
857 GTK_OBJECT(dialog));
859 gtk_object_set_data(GTK_OBJECT(dialog), "callback_icon", icon);
860 gtk_object_set_data(GTK_OBJECT(dialog), "callback_fn", callback);
862 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), TRUE, TRUE, 2);
864 hbox = gtk_hbox_new(TRUE, 4);
865 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
867 button = gtk_button_new_with_label(_("OK"));
868 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
869 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
870 gtk_window_set_default(GTK_WINDOW(dialog), button);
871 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
872 GTK_SIGNAL_FUNC(rename_activate), GTK_OBJECT(dialog));
874 button = gtk_button_new_with_label(_("Cancel"));
875 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
876 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
877 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
878 GTK_SIGNAL_FUNC(gtk_widget_destroy),
879 GTK_OBJECT(dialog));
881 gtk_widget_show_all(dialog);