4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2005, 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 struct _DropBoxClass
{
43 void (*path_dropped
)(GtkWidget
*drop_box
, const guchar
*path
);
44 void (*clear
)(GtkWidget
*drop_box
);
55 /* Static prototypes */
56 static void drop_box_class_init(gpointer gclass
, gpointer data
);
57 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
);
58 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
);
59 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
);
60 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
61 GdkDragContext
*context
,
64 GtkSelectionData
*selection_data
,
69 /****************************************************************
70 * EXTERNAL INTERFACE *
71 ****************************************************************/
73 GtkWidget
*drop_box_new(const char *message
)
75 GtkWidget
*button
, *label
, *vbox
, *icon
;
78 GtkTargetEntry targets
[] = {
79 {"text/uri-list", 0, 0},
82 drop_box
= g_object_new(drop_box_get_type(), NULL
);
84 gtk_frame_set_shadow_type(GTK_FRAME(drop_box
), GTK_SHADOW_IN
);
85 gtk_container_set_border_width(GTK_CONTAINER(drop_box
), 4);
87 gtk_drag_dest_set(GTK_WIDGET(drop_box
), GTK_DEST_DEFAULT_ALL
,
88 targets
, sizeof(targets
) / sizeof(*targets
),
91 vbox
= gtk_vbox_new(FALSE
, 0);
92 gtk_container_add(GTK_CONTAINER(drop_box
), vbox
);
94 label
= gtk_label_new(message
);
95 gtk_misc_set_padding(GTK_MISC(label
), 10, 10);
96 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
98 drop_box
->label
= gtk_label_new(NULL
);
99 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->label
, FALSE
, TRUE
, 0);
100 gtk_misc_set_padding(GTK_MISC(drop_box
->label
), 2, 2);
102 drop_box
->buttons
= gtk_hbutton_box_new();
103 gtk_box_pack_start(GTK_BOX(vbox
), drop_box
->buttons
, FALSE
, TRUE
, 0);
105 button
= gtk_button_new_from_stock(GTK_STOCK_CLEAR
);
106 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
107 g_signal_connect(button
, "clicked",
108 G_CALLBACK(clear_clicked
), drop_box
);
110 mp
= type_to_icon(inode_directory
);
111 pixmap_make_small(mp
);
112 icon
= gtk_image_new_from_pixbuf(mp
->sm_pixbuf
);
114 button
= button_new_image_text(icon
, _("Show"));
115 gtk_box_pack_start(GTK_BOX(drop_box
->buttons
), button
, FALSE
, TRUE
, 0);
116 g_signal_connect(button
, "clicked",
117 G_CALLBACK(open_dir_clicked
), drop_box
);
119 gtk_tooltips_set_tip(tooltips
, button
,
120 _("Show the current choice in a filer window"), NULL
);
122 drop_box_set_path(drop_box
, NULL
);
124 gtk_widget_show_all(vbox
);
126 return GTK_WIDGET(drop_box
);
129 GType
drop_box_get_type(void)
131 static GType type
= 0;
135 static const GTypeInfo info
=
137 sizeof (DropBoxClass
),
138 NULL
, /* base_init */
139 NULL
, /* base_finalise */
141 NULL
, /* class_finalise */
142 NULL
, /* class_data */
148 type
= g_type_register_static(gtk_frame_get_type(),
149 "DropBox", &info
, 0);
155 void drop_box_set_path(DropBox
*drop_box
, const guchar
*path
)
159 null_g_free(&drop_box
->path
);
160 drop_box
->path
= g_strdup(path
);
167 copy
= g_strdup_printf("...%s", path
+ l
- 38);
169 copy
= g_strdup(path
);
170 gtk_widget_set_sensitive(drop_box
->buttons
, TRUE
);
174 copy
= g_strdup(_("<nothing>"));
175 gtk_widget_set_sensitive(drop_box
->buttons
, FALSE
);
178 gtk_label_set_text(GTK_LABEL(drop_box
->label
), copy
);
182 const gchar
*drop_box_get_path(DropBox
*drop_box
)
184 g_return_val_if_fail(drop_box
!= NULL
, NULL
);
186 return drop_box
->path
;
189 /****************************************************************
190 * INTERNAL FUNCTIONS *
191 ****************************************************************/
193 static void drop_box_class_init(gpointer gclass
, gpointer data
)
195 GtkWidgetClass
*widget
= (GtkWidgetClass
*) gclass
;
196 DropBoxClass
*drop_box
= (DropBoxClass
*) gclass
;
198 drop_box
->path_dropped
= NULL
;
199 drop_box
->clear
= NULL
;
201 widget
->drag_data_received
= drop_box_drag_data_received
;
203 g_signal_new("path_dropped",
204 G_TYPE_FROM_CLASS(gclass
),
206 G_STRUCT_OFFSET(DropBoxClass
, path_dropped
),
208 g_cclosure_marshal_VOID__STRING
,
209 G_TYPE_NONE
, 1, G_TYPE_STRING
);
211 g_signal_new("clear",
212 G_TYPE_FROM_CLASS(gclass
),
214 G_STRUCT_OFFSET(DropBoxClass
, clear
),
216 g_cclosure_marshal_VOID__VOID
,
220 static void drop_box_init(GTypeInstance
*object
, gpointer gclass
)
222 DropBox
*drop_box
= (DropBox
*) object
;
224 drop_box
->path
= NULL
;
225 drop_box
->label
= NULL
;
226 drop_box
->buttons
= NULL
;
229 static void clear_clicked(GtkWidget
*button
, DropBox
*drop_box
)
231 g_signal_emit_by_name(drop_box
, "clear");
234 static void open_dir_clicked(GtkWidget
*button
, DropBox
*drop_box
)
237 open_to_show(drop_box
->path
);
239 delayed_error(_("I can't show you the currently set item, "
240 "because nothing is currently set. Drag "
241 "something onto me!"));
244 static void drop_box_drag_data_received(GtkWidget
*drop_box
,
245 GdkDragContext
*context
,
248 GtkSelectionData
*selection_data
,
254 gboolean success
= FALSE
;
256 if (!selection_data
->data
)
257 goto err
; /* Timeout? */
259 uris
= uri_list_to_glist(selection_data
->data
);
261 if (g_list_length(uris
) != 1)
263 delayed_error(_("Sorry, you need to drop exactly one file "
264 "onto the drop area."));
268 path
= get_local_path((EscapedPath
*) uris
->data
);
273 _("Sorry, I can't use '%s' because it's not a local "
274 "file."), (guchar
*) uris
->data
);
278 if (!file_exists(path
))
280 delayed_error(_("Can't access '%s':\n%s"), path
,
285 g_signal_emit_by_name(drop_box
, "path_dropped", path
);
294 gtk_drag_finish(context
, success
, FALSE
, time
); /* Failure */