r3768: Updated years.
[rox-filer.git] / ROX-Filer / src / dropbox.c
blob15803660ad86c2e99dde4eaf952762d03335ba48
1 /*
2 * $Id$
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)
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 /* drop_box.c - the "drop something here" widget */
24 #include "config.h"
26 #include <gtk/gtk.h>
27 #include <errno.h>
28 #include <string.h>
30 #include "global.h"
32 #include "dropbox.h"
33 #include "main.h"
34 #include "type.h"
35 #include "pixmaps.h"
36 #include "support.h"
37 #include "gui_support.h"
38 #include "run.h"
40 struct _DropBoxClass {
41 GtkFrameClass parent;
43 void (*path_dropped)(GtkWidget *drop_box, const guchar *path);
44 void (*clear)(GtkWidget *drop_box);
47 struct _DropBox {
48 GtkFrame frame;
50 GtkWidget *buttons;
51 GtkWidget *label;
52 gchar *path;
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,
62 gint x,
63 gint y,
64 GtkSelectionData *selection_data,
65 guint drag_info,
66 guint32 time);
69 /****************************************************************
70 * EXTERNAL INTERFACE *
71 ****************************************************************/
73 GtkWidget *drop_box_new(const char *message)
75 GtkWidget *button, *label, *vbox, *icon;
76 MaskedPixmap *mp;
77 DropBox *drop_box;
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),
89 GDK_ACTION_COPY);
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);
113 g_object_unref(mp);
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;
133 if (!type)
135 static const GTypeInfo info =
137 sizeof (DropBoxClass),
138 NULL, /* base_init */
139 NULL, /* base_finalise */
140 drop_box_class_init,
141 NULL, /* class_finalise */
142 NULL, /* class_data */
143 sizeof(DropBox),
144 0, /* n_preallocs */
145 drop_box_init
148 type = g_type_register_static(gtk_frame_get_type(),
149 "DropBox", &info, 0);
152 return type;
155 void drop_box_set_path(DropBox *drop_box, const guchar *path)
157 char *copy;
159 null_g_free(&drop_box->path);
160 drop_box->path = g_strdup(path);
162 if (path)
164 int l;
165 l = strlen(path);
166 if (l > 40)
167 copy = g_strdup_printf("...%s", path + l - 38);
168 else
169 copy = g_strdup(path);
170 gtk_widget_set_sensitive(drop_box->buttons, TRUE);
172 else
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);
179 g_free(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),
205 G_SIGNAL_RUN_LAST,
206 G_STRUCT_OFFSET(DropBoxClass, path_dropped),
207 NULL, NULL,
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),
213 G_SIGNAL_RUN_LAST,
214 G_STRUCT_OFFSET(DropBoxClass, clear),
215 NULL, NULL,
216 g_cclosure_marshal_VOID__VOID,
217 G_TYPE_NONE, 0);
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)
236 if (drop_box->path)
237 open_to_show(drop_box->path);
238 else
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,
246 gint x,
247 gint y,
248 GtkSelectionData *selection_data,
249 guint drag_info,
250 guint32 time)
252 GList *uris = NULL;
253 guchar *path = NULL;
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."));
265 goto err;
268 path = get_local_path((EscapedPath *) uris->data);
270 if (!path)
272 delayed_error(
273 _("Sorry, I can't use '%s' because it's not a local "
274 "file."), (guchar *) uris->data);
275 goto err;
278 if (!file_exists(path))
280 delayed_error(_("Can't access '%s':\n%s"), path,
281 g_strerror(errno));
282 goto err;
285 g_signal_emit_by_name(drop_box, "path_dropped", path);
287 success = TRUE;
288 err:
289 if (path)
290 g_free(path);
292 if (uris)
293 g_list_free(uris);
294 gtk_drag_finish(context, success, FALSE, time); /* Failure */