4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@users.sourceforge.net>.
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 /* toolbar.c - for the button bars that go along the tops of windows */
38 extern int collection_menu_button
;
41 static GtkWidget
*create_options();
42 static void update_options();
43 static void set_options();
44 static void save_options();
45 static char *toolbar_type(char *data
);
47 static OptionsSection options
=
49 N_("Toolbar options"),
56 ToolbarType o_toolbar
= TOOLBAR_NORMAL
;
58 static GtkWidget
*menu_toolbar
;
59 static GtkTooltips
*tooltips
= NULL
;
61 /* TRUE if the button presses (or released) should open a new window,
62 * rather than reusing the existing one.
64 #define NEW_WIN_BUTTON(button_event) \
65 (o_new_window_on_1 ? ((GdkEventButton *) button_event)->button == 1 \
66 : ((GdkEventButton *) button_event)->button != 1)
68 typedef enum {DROP_TO_PARENT
, DROP_TO_HOME
} DropDest
;
70 /* Static prototypes */
71 static void toolbar_up_clicked(GtkWidget
*widget
, FilerWindow
*filer_window
);
72 static void toolbar_home_clicked(GtkWidget
*widget
, FilerWindow
*filer_window
);
73 static GtkWidget
*add_button(GtkWidget
*box
, MaskedPixmap
*icon
,
74 GtkSignalFunc cb
, FilerWindow
*filer_window
,
75 char *label
, char *tip
);
76 static GtkWidget
*create_toolbar(FilerWindow
*filer_window
);
77 static gboolean
drag_motion(GtkWidget
*widget
,
78 GdkDragContext
*context
,
82 FilerWindow
*filer_window
);
83 static void drag_leave(GtkWidget
*widget
,
84 GdkDragContext
*context
,
86 FilerWindow
*filer_window
);
87 static void handle_drops(FilerWindow
*filer_window
,
92 /****************************************************************
93 * EXTERNAL INTERFACE *
94 ****************************************************************/
96 void toolbar_init(void)
98 options_sections
= g_slist_prepend(options_sections
, &options
);
99 option_register("toolbar_type", toolbar_type
);
101 tooltips
= gtk_tooltips_new();
104 /* Create a new toolbar widget, suitable for adding to a filer window,
107 GtkWidget
*toolbar_new(FilerWindow
*filer_window
)
109 g_return_val_if_fail(filer_window
!= NULL
, NULL
);
110 g_return_val_if_fail(o_toolbar
!= TOOLBAR_NONE
, NULL
);
112 return create_toolbar(filer_window
);
117 /****************************************************************
118 * INTERNAL FUNCTIONS *
119 ****************************************************************/
121 static void toolbar_help_clicked(GtkWidget
*widget
, FilerWindow
*filer_window
)
123 filer_opendir(make_path(app_dir
, "Help")->str
);
126 static void toolbar_refresh_clicked(GtkWidget
*widget
,
127 FilerWindow
*filer_window
)
131 event
= gtk_get_current_event();
132 if (event
->type
== GDK_BUTTON_RELEASE
&&
133 ((GdkEventButton
*) event
)->button
!= 1)
135 filer_opendir(filer_window
->path
);
140 filer_update_dir(filer_window
, TRUE
);
144 static void toolbar_home_clicked(GtkWidget
*widget
, FilerWindow
*filer_window
)
148 event
= gtk_get_current_event();
149 if (event
->type
== GDK_BUTTON_RELEASE
&& NEW_WIN_BUTTON(event
))
151 filer_opendir(home_dir
);
154 filer_change_to(filer_window
, home_dir
, NULL
);
157 static void toolbar_up_clicked(GtkWidget
*widget
, FilerWindow
*filer_window
)
161 event
= gtk_get_current_event();
162 if (event
->type
== GDK_BUTTON_RELEASE
&& NEW_WIN_BUTTON(event
))
164 filer_open_parent(filer_window
);
167 change_to_parent(filer_window
);
170 static GtkWidget
*create_toolbar(FilerWindow
*filer_window
)
172 GtkWidget
*frame
, *box
;
175 frame
= gtk_frame_new(NULL
);
176 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
178 box
= gtk_hbutton_box_new();
179 gtk_button_box_set_child_size_default(16, 16);
180 gtk_hbutton_box_set_spacing_default(0);
181 gtk_button_box_set_layout(GTK_BUTTON_BOX(box
), GTK_BUTTONBOX_START
);
183 gtk_container_add(GTK_CONTAINER(frame
), box
);
185 b
= add_button(box
, im_up_icon
,
186 GTK_SIGNAL_FUNC(toolbar_up_clicked
),
188 _("Up"), _("Change to parent directory"));
189 handle_drops(filer_window
, b
, DROP_TO_PARENT
);
191 b
= add_button(box
, im_home_icon
,
192 GTK_SIGNAL_FUNC(toolbar_home_clicked
),
194 _("Home"), _("Change to home directory"));
195 handle_drops(filer_window
, b
, DROP_TO_HOME
);
197 add_button(box
, im_refresh_icon
,
198 GTK_SIGNAL_FUNC(toolbar_refresh_clicked
),
200 _("Scan"), _("Rescan directory contents"));
201 add_button(box
, im_help
,
202 GTK_SIGNAL_FUNC(toolbar_help_clicked
),
204 _("Help"), _("Show ROX-Filer help"));
209 /* This is used to simulate a click when button 3 is used (GtkButton
210 * normally ignores this). Currently, this button does not pop in -
211 * this may be fixed in future versions of GTK+.
213 static gint toolbar_other_button
= 0;
214 static gint
toolbar_adjust_pressed(GtkButton
*button
,
215 GdkEventButton
*event
,
216 FilerWindow
*filer_window
)
218 gint b
= event
->button
;
220 if ((b
== 2 || b
== 3) && toolbar_other_button
== 0)
222 toolbar_other_button
= event
->button
;
223 gtk_grab_add(GTK_WIDGET(button
));
224 gtk_button_pressed(button
);
230 static gint
toolbar_adjust_released(GtkButton
*button
,
231 GdkEventButton
*event
,
232 FilerWindow
*filer_window
)
234 if (event
->button
== toolbar_other_button
)
236 toolbar_other_button
= 0;
237 gtk_grab_remove(GTK_WIDGET(button
));
238 gtk_button_released(button
);
244 static GtkWidget
*add_button(GtkWidget
*box
, MaskedPixmap
*icon
,
245 GtkSignalFunc cb
, FilerWindow
*filer_window
,
246 char *label
, char *tip
)
248 GtkWidget
*button
, *icon_widget
;
250 button
= gtk_button_new();
251 gtk_button_set_relief(GTK_BUTTON(button
), GTK_RELIEF_NONE
);
252 GTK_WIDGET_UNSET_FLAGS(button
, GTK_CAN_FOCUS
);
254 gtk_signal_connect(GTK_OBJECT(button
), "button_press_event",
255 GTK_SIGNAL_FUNC(toolbar_adjust_pressed
), filer_window
);
256 gtk_signal_connect(GTK_OBJECT(button
), "button_release_event",
257 GTK_SIGNAL_FUNC(toolbar_adjust_released
), filer_window
);
258 gtk_signal_connect(GTK_OBJECT(button
), "clicked",
261 gtk_tooltips_set_tip(tooltips
, button
, tip
, NULL
);
263 icon_widget
= gtk_pixmap_new(icon
->pixmap
, icon
->mask
);
265 if (o_toolbar
== TOOLBAR_LARGE
)
267 GtkWidget
*vbox
, *text
;
269 vbox
= gtk_vbox_new(FALSE
, 0);
270 gtk_box_pack_start(GTK_BOX(vbox
), icon_widget
, TRUE
, TRUE
, 0);
272 text
= gtk_label_new(label
);
273 gtk_box_pack_start(GTK_BOX(vbox
), text
, FALSE
, TRUE
, 0);
275 gtk_container_add(GTK_CONTAINER(button
), vbox
);
278 gtk_container_add(GTK_CONTAINER(button
), icon_widget
);
280 gtk_container_add(GTK_CONTAINER(box
), button
);
285 /* Build up some option widgets to go in the options dialog, but don't
288 static GtkWidget
*create_options(void)
290 GtkWidget
*vbox
, *menu
, *hbox
;
292 vbox
= gtk_vbox_new(FALSE
, 0);
293 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 4);
295 hbox
= gtk_hbox_new(FALSE
, 4);
296 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
, 0);
298 gtk_box_pack_start(GTK_BOX(hbox
),
299 gtk_label_new(_("Toolbar type for new windows")),
301 menu_toolbar
= gtk_option_menu_new();
302 menu
= gtk_menu_new();
303 gtk_menu_append(GTK_MENU(menu
),
304 gtk_menu_item_new_with_label(_("None")));
305 gtk_menu_append(GTK_MENU(menu
),
306 gtk_menu_item_new_with_label(_("Normal")));
307 gtk_menu_append(GTK_MENU(menu
),
308 gtk_menu_item_new_with_label(_("Large")));
309 gtk_option_menu_set_menu(GTK_OPTION_MENU(menu_toolbar
), menu
);
310 gtk_box_pack_start(GTK_BOX(hbox
), menu_toolbar
, TRUE
, TRUE
, 0);
315 /* Reflect current state by changing the widgets in the options box */
316 static void update_options()
318 gtk_option_menu_set_history(GTK_OPTION_MENU(menu_toolbar
), o_toolbar
);
321 /* Set current values by reading the states of the widgets in the options box */
322 static void set_options()
324 GtkWidget
*item
, *menu
;
327 menu
= gtk_option_menu_get_menu(GTK_OPTION_MENU(menu_toolbar
));
328 item
= gtk_menu_get_active(GTK_MENU(menu
));
329 list
= gtk_container_children(GTK_CONTAINER(menu
));
330 o_toolbar
= (ToolbarType
) g_list_index(list
, item
);
334 static void save_options()
336 option_write("toolbar_type", o_toolbar
== TOOLBAR_NONE
? "None" :
337 o_toolbar
== TOOLBAR_NORMAL
? "Normal" :
338 o_toolbar
== TOOLBAR_LARGE
? "Large" :
342 static char *toolbar_type(char *data
)
344 if (g_strcasecmp(data
, "None") == 0)
345 o_toolbar
= TOOLBAR_NONE
;
346 else if (g_strcasecmp(data
, "Normal") == 0)
347 o_toolbar
= TOOLBAR_NORMAL
;
348 else if (g_strcasecmp(data
, "Large") == 0)
349 o_toolbar
= TOOLBAR_LARGE
;
351 return _("Unknown toolbar type");
356 /* Called during the drag when the mouse is in a widget registered
357 * as a drop target. Returns TRUE if we can accept the drop.
359 static gboolean
drag_motion(GtkWidget
*widget
,
360 GdkDragContext
*context
,
364 FilerWindow
*filer_window
)
366 GdkDragAction action
= context
->suggested_action
;
369 dest
= (DropDest
) gtk_object_get_data(GTK_OBJECT(widget
),
372 if (dest
== DROP_TO_HOME
)
373 g_dataset_set_data(context
, "drop_dest_path", home_dir
);
376 guchar
*slash
, *path
;
378 slash
= strrchr(filer_window
->path
, '/');
379 if (slash
== NULL
|| slash
== filer_window
->path
)
380 path
= g_strdup("/");
382 path
= g_strndup(filer_window
->path
,
383 slash
- filer_window
->path
);
384 g_dataset_set_data_full(context
, "drop_dest_path",
388 g_dataset_set_data(context
, "drop_dest_type", drop_dest_dir
);
389 gdk_drag_status(context
, action
, time
);
391 dnd_spring_load(context
);
392 gtk_button_set_relief(GTK_BUTTON(widget
), GTK_RELIEF_NORMAL
);
397 static void drag_leave(GtkWidget
*widget
,
398 GdkDragContext
*context
,
400 FilerWindow
*filer_window
)
402 gtk_button_set_relief(GTK_BUTTON(widget
), GTK_RELIEF_NONE
);
406 static void handle_drops(FilerWindow
*filer_window
,
410 make_drop_target(button
);
411 gtk_signal_connect(GTK_OBJECT(button
), "drag_motion",
412 GTK_SIGNAL_FUNC(drag_motion
), filer_window
);
413 gtk_signal_connect(GTK_OBJECT(button
), "drag_leave",
414 GTK_SIGNAL_FUNC(drag_leave
), filer_window
);
415 gtk_object_set_data(GTK_OBJECT(button
), "toolbar_dest",