4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2003, 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)
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
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 /* drop_box.c - the "drop something here" widget */
37 #include "gui_support.h"
40 static gpointer parent_class
= NULL
;
42 struct _DropBoxClass
{
45 void (*path_dropped
)(GtkWidget
*drop_box
, const guchar
*path
);
46 void (*clear
)(GtkWidget
*drop_box
);
57 /* Static prototypes */
58 static void drop_box_class_init(gpointer gclass
, gpointer data
);
59 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
);
60 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
);
61 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
);
62 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
63 GdkDragContext
*context
,
66 GtkSelectionData
*selection_data
,
71 /****************************************************************
72 * EXTERNAL INTERFACE *
73 ****************************************************************/
75 GtkWidget
*drop_box_new(const char *message
)
77 GtkWidget
*button
, *label
, *vbox
, *icon
;
80 GtkTargetEntry targets
[] = {
81 {"text/uri-list", 0, 0},
84 drop_box
= g_object_new(drop_box_get_type(), NULL
);
86 gtk_frame_set_shadow_type(GTK_FRAME(drop_box
), GTK_SHADOW_IN
);
87 gtk_container_set_border_width(GTK_CONTAINER(drop_box
), 4);
89 gtk_drag_dest_set(GTK_WIDGET(drop_box
), GTK_DEST_DEFAULT_ALL
,
90 targets
, sizeof(targets
) / sizeof(*targets
),
93 vbox
= gtk_vbox_new(FALSE
, 0);
94 gtk_container_add(GTK_CONTAINER(drop_box
), vbox
);
96 label
= gtk_label_new(message
);
97 gtk_misc_set_padding(GTK_MISC(label
), 10, 10);
98 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
100 drop_box
->label
= gtk_label_new(NULL
);
101 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->label
, FALSE
, TRUE
, 0);
102 gtk_misc_set_padding(GTK_MISC(drop_box
->label
), 2, 2);
104 drop_box
->buttons
= gtk_hbutton_box_new();
105 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->buttons
, FALSE
, TRUE
, 0);
107 button
= gtk_button_new_from_stock(GTK_STOCK_CLEAR
);
108 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
109 g_signal_connect(button
, "clicked",
110 G_CALLBACK(clear_clicked
), drop_box
);
112 mp
= type_to_icon(inode_directory
);
113 pixmap_make_small(mp
);
114 icon
= gtk_image_new_from_pixbuf(mp
->sm_pixbuf
);
116 button
= button_new_image_text(icon
, _("Show"));
117 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
118 g_signal_connect(button
, "clicked",
119 G_CALLBACK(open_dir_clicked
), drop_box
);
121 gtk_tooltips_set_tip(tooltips
, button
,
122 _("Show the current choice in a filer window"), NULL
);
124 drop_box_set_path(drop_box
, NULL
);
126 gtk_widget_show_all(vbox
);
128 return GTK_WIDGET(drop_box
);
131 GType
drop_box_get_type(void)
133 static GType type
= 0;
137 static const GTypeInfo info
=
139 sizeof (DropBoxClass
),
140 NULL
, /* base_init */
141 NULL
, /* base_finalise */
143 NULL
, /* class_finalise */
144 NULL
, /* class_data */
150 type
= g_type_register_static(gtk_frame_get_type(),
151 "DropBox", &info
, 0);
157 void drop_box_set_path(DropBox
*drop_box
, const guchar
*path
)
161 null_g_free(&drop_box
->path
);
162 drop_box
->path
= g_strdup(path
);
169 copy
= g_strdup_printf("...%s", path
+ l
- 38);
171 copy
= g_strdup(path
);
172 gtk_widget_set_sensitive(drop_box
->buttons
, TRUE
);
176 copy
= g_strdup(_("<nothing>"));
177 gtk_widget_set_sensitive(drop_box
->buttons
, FALSE
);
180 gtk_label_set_text(GTK_LABEL(drop_box
->label
), copy
);
184 const gchar
*drop_box_get_path(DropBox
*drop_box
)
186 g_return_val_if_fail(drop_box
!= NULL
, NULL
);
188 return drop_box
->path
;
191 /****************************************************************
192 * INTERNAL FUNCTIONS *
193 ****************************************************************/
195 static void drop_box_class_init(gpointer gclass
, gpointer data
)
197 GtkWidgetClass
*widget
= (GtkWidgetClass
*) gclass
;
198 DropBoxClass
*drop_box
= (DropBoxClass
*) gclass
;
200 parent_class
= g_type_class_peek_parent(gclass
);
202 drop_box
->path_dropped
= NULL
;
204 widget
->drag_data_received
= drop_box_drag_data_received
;
206 g_signal_new("path_dropped",
207 G_TYPE_FROM_CLASS(gclass
),
209 G_STRUCT_OFFSET(DropBoxClass
, path_dropped
),
211 g_cclosure_marshal_VOID__STRING
,
212 G_TYPE_NONE
, 1, G_TYPE_STRING
);
214 g_signal_new("clear",
215 G_TYPE_FROM_CLASS(gclass
),
217 G_STRUCT_OFFSET(DropBoxClass
, clear
),
219 g_cclosure_marshal_VOID__VOID
,
223 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
)
225 DropBox
*drop_box
= (DropBox
*) object
;
227 drop_box
->path
= NULL
;
228 drop_box
->label
= NULL
;
229 drop_box
->buttons
= NULL
;
232 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
)
234 g_signal_emit_by_name(drop_box
, "clear");
237 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
)
240 open_to_show(drop_box
->path
);
242 delayed_error(_("I can't show you the currently set item, "
243 "because nothing is currently set. Drag "
244 "something onto me!"));
247 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
248 GdkDragContext
*context
,
251 GtkSelectionData
*selection_data
,
257 gboolean success
= FALSE
;
259 if (!selection_data
->data
)
260 goto err
; /* Timeout? */
262 uris
= uri_list_to_glist(selection_data
->data
);
264 if (g_list_length(uris
) != 1)
266 delayed_error(_("Sorry, you need to drop exactly one file "
267 "onto the drop area."));
271 path
= get_local_path((guchar
*) uris
->data
);
276 _("Sorry, I can't use '%s' because it's not a local "
277 "file."), (guchar
*) uris
->data
);
281 if (!file_exists(path
))
283 delayed_error(_("Can't access '%s':\n%s"), path
,
288 g_signal_emit_by_name(drop_box
, "path_dropped", path
);
297 gtk_drag_finish(context
, success
, FALSE
, time
); /* Failure */