2008-04-30 Cosimo Cecchi <cosimoc@gnome.org>
[nautilus.git] / src / nautilus-navigation-action.c
blob0647dc630dd2fd07e60a5415f7ca7ee4990088e0
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
3 /*
4 * Nautilus
6 * Copyright (C) 2004 Red Hat, Inc.
7 * Copyright (C) 2003 Marco Pesenti Gritti
9 * Nautilus is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * Nautilus is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Based on ephy-navigation-action.h from Epiphany
25 * Authors: Alexander Larsson <alexl@redhat.com>
26 * Marco Pesenti Gritti
30 #include <config.h>
32 #include "nautilus-navigation-action.h"
33 #include "nautilus-navigation-window.h"
35 #include <gtk/gtkimage.h>
36 #include <gtk/gtkimagemenuitem.h>
37 #include <gtk/gtktoolbar.h>
38 #include <gtk/gtkmenutoolbutton.h>
40 static void nautilus_navigation_action_init (NautilusNavigationAction *action);
41 static void nautilus_navigation_action_class_init (NautilusNavigationActionClass *class);
43 static GObjectClass *parent_class = NULL;
45 #define NAUTILUS_NAVIGATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), NAUTILUS_TYPE_NAVIGATION_ACTION, NautilusNavigationActionPrivate))
47 struct NautilusNavigationActionPrivate
49 NautilusNavigationWindow *window;
50 NautilusNavigationDirection direction;
51 char *arrow_tooltip;
54 enum
56 PROP_0,
57 PROP_ARROW_TOOLTIP,
58 PROP_DIRECTION,
59 PROP_WINDOW
62 GType
63 nautilus_navigation_action_get_type (void)
65 static GType type = 0;
67 if (type == 0) {
68 const GTypeInfo type_info = {
69 sizeof (NautilusNavigationActionClass),
70 (GBaseInitFunc) NULL,
71 (GBaseFinalizeFunc) NULL,
72 (GClassInitFunc) nautilus_navigation_action_class_init,
73 (GClassFinalizeFunc) NULL,
74 NULL,
75 sizeof (NautilusNavigationAction),
76 0, /* n_preallocs */
77 (GInstanceInitFunc) nautilus_navigation_action_init,
80 type = g_type_register_static (GTK_TYPE_ACTION,
81 "NautilusNavigationAction",
82 &type_info, 0);
85 return type;
88 static void
89 activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
90 NautilusNavigationWindow *window,
91 gboolean back)
93 int index;
95 g_assert (GTK_IS_MENU_ITEM (menu_item));
96 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
98 index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "user_data"));
100 nautilus_navigation_window_back_or_forward (window, back, index);
103 static void
104 activate_back_menu_item_callback (GtkMenuItem *menu_item, NautilusNavigationWindow *window)
106 activate_back_or_forward_menu_item (menu_item, window, TRUE);
109 static void
110 activate_forward_menu_item_callback (GtkMenuItem *menu_item, NautilusNavigationWindow *window)
112 activate_back_or_forward_menu_item (menu_item, window, FALSE);
115 static void
116 fill_menu (NautilusNavigationWindow *window,
117 GtkWidget *menu,
118 gboolean back)
120 GtkWidget *menu_item;
121 int index;
122 GList *list;
124 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
126 list = back ? window->back_list : window->forward_list;
127 index = 0;
128 while (list != NULL) {
129 menu_item = nautilus_bookmark_menu_item_new (NAUTILUS_BOOKMARK (list->data));
130 g_object_set_data (G_OBJECT (menu_item), "user_data", GINT_TO_POINTER (index));
131 gtk_widget_show (GTK_WIDGET (menu_item));
132 g_signal_connect_object (menu_item, "activate",
133 back
134 ? G_CALLBACK (activate_back_menu_item_callback)
135 : G_CALLBACK (activate_forward_menu_item_callback),
136 window, 0);
138 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
139 list = g_list_next (list);
140 ++index;
145 static void
146 show_menu_callback (GtkMenuToolButton *button,
147 NautilusNavigationAction *action)
149 NautilusNavigationActionPrivate *p;
150 NautilusNavigationWindow *window;
151 GtkWidget *menu;
152 GList *children;
153 GList *li;
155 p = action->priv;
156 window = action->priv->window;
158 menu = gtk_menu_tool_button_get_menu (button);
160 children = gtk_container_get_children (GTK_CONTAINER (menu));
161 for (li = children; li; li = li->next) {
162 gtk_container_remove (GTK_CONTAINER (menu), li->data);
164 g_list_free (children);
166 switch (p->direction) {
167 case NAUTILUS_NAVIGATION_DIRECTION_FORWARD:
168 fill_menu (window, menu, FALSE);
169 break;
170 case NAUTILUS_NAVIGATION_DIRECTION_BACK:
171 fill_menu (window, menu, TRUE);
172 break;
173 default:
174 g_assert_not_reached ();
175 break;
179 static void
180 connect_proxy (GtkAction *action, GtkWidget *proxy)
182 if (GTK_IS_MENU_TOOL_BUTTON (proxy)) {
183 NautilusNavigationAction *naction = NAUTILUS_NAVIGATION_ACTION (action);
184 GtkMenuToolButton *button = GTK_MENU_TOOL_BUTTON (proxy);
185 GtkWidget *menu;
187 /* set an empty menu, so the arrow button becomes sensitive */
188 menu = gtk_menu_new ();
189 gtk_menu_tool_button_set_menu (button, menu);
191 gtk_menu_tool_button_set_arrow_tooltip_text (button,
192 naction->priv->arrow_tooltip);
194 g_signal_connect (proxy, "show-menu",
195 G_CALLBACK (show_menu_callback), action);
198 (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
201 static void
202 disconnect_proxy (GtkAction *action, GtkWidget *proxy)
204 if (GTK_IS_MENU_TOOL_BUTTON (proxy)) {
205 g_signal_handlers_disconnect_by_func (proxy, G_CALLBACK (show_menu_callback), action);
208 (* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy);
211 static void
212 nautilus_navigation_action_finalize (GObject *object)
214 NautilusNavigationAction *action = NAUTILUS_NAVIGATION_ACTION (object);
216 g_free (action->priv->arrow_tooltip);
218 (* G_OBJECT_CLASS (parent_class)->finalize) (object);
221 static void
222 nautilus_navigation_action_set_property (GObject *object,
223 guint prop_id,
224 const GValue *value,
225 GParamSpec *pspec)
227 NautilusNavigationAction *nav;
229 nav = NAUTILUS_NAVIGATION_ACTION (object);
231 switch (prop_id)
233 case PROP_ARROW_TOOLTIP:
234 g_free (nav->priv->arrow_tooltip);
235 nav->priv->arrow_tooltip = g_value_dup_string (value);
236 break;
237 case PROP_DIRECTION:
238 nav->priv->direction = g_value_get_int (value);
239 break;
240 case PROP_WINDOW:
241 nav->priv->window = NAUTILUS_NAVIGATION_WINDOW (g_value_get_object (value));
242 break;
246 static void
247 nautilus_navigation_action_get_property (GObject *object,
248 guint prop_id,
249 GValue *value,
250 GParamSpec *pspec)
252 NautilusNavigationAction *nav;
254 nav = NAUTILUS_NAVIGATION_ACTION (object);
256 switch (prop_id)
258 case PROP_ARROW_TOOLTIP:
259 g_value_set_string (value, nav->priv->arrow_tooltip);
260 break;
261 case PROP_DIRECTION:
262 g_value_set_int (value, nav->priv->direction);
263 break;
264 case PROP_WINDOW:
265 g_value_set_object (value, nav->priv->window);
266 break;
270 static void
271 nautilus_navigation_action_class_init (NautilusNavigationActionClass *class)
273 GObjectClass *object_class = G_OBJECT_CLASS (class);
274 GtkActionClass *action_class = GTK_ACTION_CLASS (class);
276 object_class->finalize = nautilus_navigation_action_finalize;
277 object_class->set_property = nautilus_navigation_action_set_property;
278 object_class->get_property = nautilus_navigation_action_get_property;
280 parent_class = g_type_class_peek_parent (class);
282 action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
283 action_class->connect_proxy = connect_proxy;
284 action_class->disconnect_proxy = disconnect_proxy;
286 g_object_class_install_property (object_class,
287 PROP_ARROW_TOOLTIP,
288 g_param_spec_string ("arrow-tooltip",
289 "Arrow Tooltip",
290 "Arrow Tooltip",
291 NULL,
292 G_PARAM_READWRITE));
293 g_object_class_install_property (object_class,
294 PROP_DIRECTION,
295 g_param_spec_int ("direction",
296 "Direction",
297 "Direction",
299 G_MAXINT,
301 G_PARAM_READWRITE));
302 g_object_class_install_property (object_class,
303 PROP_WINDOW,
304 g_param_spec_object ("window",
305 "Window",
306 "The navigation window",
307 G_TYPE_OBJECT,
308 G_PARAM_READWRITE));
310 g_type_class_add_private (object_class, sizeof(NautilusNavigationActionPrivate));
313 static void
314 nautilus_navigation_action_init (NautilusNavigationAction *action)
316 action->priv = NAUTILUS_NAVIGATION_ACTION_GET_PRIVATE (action);