2 * ROX-Filer, filer for the ROX desktop project
3 * Copyright (C) 2006, Thomas Leonard and others (see changelog for details).
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA
20 /* drop_box.c - the "drop something here" widget */
35 #include "gui_support.h"
38 struct _DropBoxClass
{
41 void (*path_dropped
)(GtkWidget
*drop_box
, const guchar
*path
);
42 void (*clear
)(GtkWidget
*drop_box
);
53 /* Static prototypes */
54 static void drop_box_class_init(gpointer gclass
, gpointer data
);
55 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
);
56 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
);
57 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
);
58 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
59 GdkDragContext
*context
,
62 GtkSelectionData
*selection_data
,
67 /****************************************************************
68 * EXTERNAL INTERFACE *
69 ****************************************************************/
71 GtkWidget
*drop_box_new(const char *message
)
73 GtkWidget
*button
, *label
, *vbox
, *icon
;
76 GtkTargetEntry targets
[] = {
77 {"text/uri-list", 0, 0},
80 drop_box
= g_object_new(drop_box_get_type(), NULL
);
82 gtk_frame_set_shadow_type(GTK_FRAME(drop_box
), GTK_SHADOW_IN
);
83 gtk_container_set_border_width(GTK_CONTAINER(drop_box
), 4);
85 gtk_drag_dest_set(GTK_WIDGET(drop_box
), GTK_DEST_DEFAULT_ALL
,
86 targets
, sizeof(targets
) / sizeof(*targets
),
89 vbox
= gtk_vbox_new(FALSE
, 0);
90 gtk_container_add(GTK_CONTAINER(drop_box
), vbox
);
92 label
= gtk_label_new(message
);
93 gtk_misc_set_padding(GTK_MISC(label
), 10, 10);
94 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
96 drop_box
->label
= gtk_label_new(NULL
);
97 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->label
, FALSE
, TRUE
, 0);
98 gtk_misc_set_padding(GTK_MISC(drop_box
->label
), 2, 2);
100 drop_box
->buttons
= gtk_hbutton_box_new();
101 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->buttons
, FALSE
, TRUE
, 0);
103 button
= gtk_button_new_from_stock(GTK_STOCK_CLEAR
);
104 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
105 g_signal_connect(button
, "clicked",
106 G_CALLBACK(clear_clicked
), drop_box
);
108 mp
= type_to_icon(inode_directory
);
109 pixmap_make_small(mp
);
110 icon
= gtk_image_new_from_pixbuf(mp
->sm_pixbuf
);
112 button
= button_new_image_text(icon
, _("Show"));
113 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
114 g_signal_connect(button
, "clicked",
115 G_CALLBACK(open_dir_clicked
), drop_box
);
117 gtk_tooltips_set_tip(tooltips
, button
,
118 _("Show the current choice in a filer window"), NULL
);
120 drop_box_set_path(drop_box
, NULL
);
122 gtk_widget_show_all(vbox
);
124 return GTK_WIDGET(drop_box
);
127 GType
drop_box_get_type(void)
129 static GType type
= 0;
133 static const GTypeInfo info
=
135 sizeof (DropBoxClass
),
136 NULL
, /* base_init */
137 NULL
, /* base_finalise */
139 NULL
, /* class_finalise */
140 NULL
, /* class_data */
146 type
= g_type_register_static(gtk_frame_get_type(),
147 "DropBox", &info
, 0);
153 void drop_box_set_path(DropBox
*drop_box
, const guchar
*path
)
157 null_g_free(&drop_box
->path
);
158 drop_box
->path
= g_strdup(path
);
165 copy
= g_strdup_printf("...%s", path
+ l
- 38);
167 copy
= g_strdup(path
);
168 gtk_widget_set_sensitive(drop_box
->buttons
, TRUE
);
172 copy
= g_strdup(_("<nothing>"));
173 gtk_widget_set_sensitive(drop_box
->buttons
, FALSE
);
176 gtk_label_set_text(GTK_LABEL(drop_box
->label
), copy
);
180 const gchar
*drop_box_get_path(DropBox
*drop_box
)
182 g_return_val_if_fail(drop_box
!= NULL
, NULL
);
184 return drop_box
->path
;
187 /****************************************************************
188 * INTERNAL FUNCTIONS *
189 ****************************************************************/
191 static void drop_box_class_init(gpointer gclass
, gpointer data
)
193 GtkWidgetClass
*widget
= (GtkWidgetClass
*) gclass
;
194 DropBoxClass
*drop_box
= (DropBoxClass
*) gclass
;
196 drop_box
->path_dropped
= NULL
;
197 drop_box
->clear
= NULL
;
199 widget
->drag_data_received
= drop_box_drag_data_received
;
201 g_signal_new("path_dropped",
202 G_TYPE_FROM_CLASS(gclass
),
204 G_STRUCT_OFFSET(DropBoxClass
, path_dropped
),
206 g_cclosure_marshal_VOID__STRING
,
207 G_TYPE_NONE
, 1, G_TYPE_STRING
);
209 g_signal_new("clear",
210 G_TYPE_FROM_CLASS(gclass
),
212 G_STRUCT_OFFSET(DropBoxClass
, clear
),
214 g_cclosure_marshal_VOID__VOID
,
218 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
)
220 DropBox
*drop_box
= (DropBox
*) object
;
222 drop_box
->path
= NULL
;
223 drop_box
->label
= NULL
;
224 drop_box
->buttons
= NULL
;
227 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
)
229 g_signal_emit_by_name(drop_box
, "clear");
232 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
)
235 open_to_show(drop_box
->path
);
237 delayed_error(_("I can't show you the currently set item, "
238 "because nothing is currently set. Drag "
239 "something onto me!"));
242 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
243 GdkDragContext
*context
,
246 GtkSelectionData
*selection_data
,
252 gboolean success
= FALSE
;
254 if (!selection_data
->data
)
255 goto err
; /* Timeout? */
257 uris
= uri_list_to_glist(selection_data
->data
);
259 if (g_list_length(uris
) != 1)
261 delayed_error(_("Sorry, you need to drop exactly one file "
262 "onto the drop area."));
266 path
= get_local_path((EscapedPath
*) uris
->data
);
271 _("Sorry, I can't use '%s' because it's not a local "
272 "file."), (guchar
*) uris
->data
);
276 if (!file_exists(path
))
278 delayed_error(_("Can't access '%s':\n%s"), path
,
283 g_signal_emit_by_name(drop_box
, "path_dropped", path
);
292 gtk_drag_finish(context
, success
, FALSE
, time
); /* Failure */