Commit 21586bbc authored by John Sullivan's avatar John Sullivan

First checkin for right-click menus on the Back and Forward buttons. They work,

but there are a few finishing touches outstanding.
parent f90a9976
2000-02-14 John Sullivan <sullivan@eazel.com>
Back and Forward buttons now sprout right-click menus.
Still work to do to put small icons in them, and to
make them keep the back/forward chain intact.
* libnautilus/nautilus-gtk-extensions.h:
* libnautilus/nautilus-gtk-extensions.c:
(nautilus_pop_up_context_menu): New helper function used
when displaying right-click context menus.
* src/file-manager/fm-directory-view.c:
(popup_context_menu): Removed (moved & renamed to
nautilus_pop_up_context_menu).
(fm_directory_view_popup_item_context_menu),
(fm_directory_view_popup_background_context_menu):
Now use nautilus_pop_up_context_menu.
* src/ntl-window.c:
(activate_back_or_forward_menu_item): New function, go to the
appropriate location.
(activate_back_menu_item_cb): New function, call
activate_back_or_forward_menu_item.
(activate_forward_menu_item_cb): New function, call
activate_back_or_forward_menu_item.
(create_back_or_forward_menu): New function, create and populate a
menu from the back list or the forward list.
(back_or_forward_button_clicked_cb): New function, pop up the result
of create_back_or_forward_menu.
(nautilus_window_constructed): Wire up context menu code to
back and forward buttons.
2000-02-14 Darin Adler <darin@eazel.com>
* libnautilus/nautilus-icon-factory.c:
......
......@@ -133,3 +133,32 @@ nautilus_gtk_selection_data_free_deep (GtkSelectionData *data)
g_free (data->data);
gtk_selection_data_free (data);
}
/**
* nautilus_pop_up_context_menu:
*
* Pop up a context menu under the mouse. This assumes that
* a mouse down event just occurred, with the 3rd button pressed.
* (Context menus only appear with the 3rd mouse button, by UI
* convention.) The menu is sunk after use, so it will be destroyed
* unless the caller first ref'ed it.
*
* This function is more of a helper function than a gtk extension,
* so perhaps it belongs in a different file.
*
* @menu: The menu to pop up under the mouse.
**/
void
nautilus_pop_up_context_menu (GtkMenu *menu)
{
g_return_if_fail (GTK_IS_MENU (menu));
/* We pass current time here instead of extracting it from
* the event, for API simplicity. This does not seem to make
* any practical difference. See man XGrabPointer for details.
*/
gtk_menu_popup (menu, NULL, NULL, NULL,
NULL, 3, GDK_CURRENT_TIME);
gtk_object_sink (GTK_OBJECT(menu));
}
......@@ -27,6 +27,7 @@
#ifndef NAUTILUS_GTK_EXTENSIONS_H
#define NAUTILUS_GTK_EXTENSIONS_H 1
#include <gtk/gtkmenu.h>
#include <gtk/gtkwindow.h>
guint nautilus_gtk_signal_connect_free_data (GtkObject *object,
......@@ -39,4 +40,6 @@ void nautilus_gtk_window_present (GtkWindow
GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data);
void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data);
void nautilus_pop_up_context_menu (GtkMenu *menu);
#endif /* NAUTILUS_GTK_EXTENSIONS_H */
......@@ -133,3 +133,32 @@ nautilus_gtk_selection_data_free_deep (GtkSelectionData *data)
g_free (data->data);
gtk_selection_data_free (data);
}
/**
* nautilus_pop_up_context_menu:
*
* Pop up a context menu under the mouse. This assumes that
* a mouse down event just occurred, with the 3rd button pressed.
* (Context menus only appear with the 3rd mouse button, by UI
* convention.) The menu is sunk after use, so it will be destroyed
* unless the caller first ref'ed it.
*
* This function is more of a helper function than a gtk extension,
* so perhaps it belongs in a different file.
*
* @menu: The menu to pop up under the mouse.
**/
void
nautilus_pop_up_context_menu (GtkMenu *menu)
{
g_return_if_fail (GTK_IS_MENU (menu));
/* We pass current time here instead of extracting it from
* the event, for API simplicity. This does not seem to make
* any practical difference. See man XGrabPointer for details.
*/
gtk_menu_popup (menu, NULL, NULL, NULL,
NULL, 3, GDK_CURRENT_TIME);
gtk_object_sink (GTK_OBJECT(menu));
}
......@@ -27,6 +27,7 @@
#ifndef NAUTILUS_GTK_EXTENSIONS_H
#define NAUTILUS_GTK_EXTENSIONS_H 1
#include <gtk/gtkmenu.h>
#include <gtk/gtkwindow.h>
guint nautilus_gtk_signal_connect_free_data (GtkObject *object,
......@@ -39,4 +40,6 @@ void nautilus_gtk_window_present (GtkWindow
GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data);
void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data);
void nautilus_pop_up_context_menu (GtkMenu *menu);
#endif /* NAUTILUS_GTK_EXTENSIONS_H */
......@@ -133,3 +133,32 @@ nautilus_gtk_selection_data_free_deep (GtkSelectionData *data)
g_free (data->data);
gtk_selection_data_free (data);
}
/**
* nautilus_pop_up_context_menu:
*
* Pop up a context menu under the mouse. This assumes that
* a mouse down event just occurred, with the 3rd button pressed.
* (Context menus only appear with the 3rd mouse button, by UI
* convention.) The menu is sunk after use, so it will be destroyed
* unless the caller first ref'ed it.
*
* This function is more of a helper function than a gtk extension,
* so perhaps it belongs in a different file.
*
* @menu: The menu to pop up under the mouse.
**/
void
nautilus_pop_up_context_menu (GtkMenu *menu)
{
g_return_if_fail (GTK_IS_MENU (menu));
/* We pass current time here instead of extracting it from
* the event, for API simplicity. This does not seem to make
* any practical difference. See man XGrabPointer for details.
*/
gtk_menu_popup (menu, NULL, NULL, NULL,
NULL, 3, GDK_CURRENT_TIME);
gtk_object_sink (GTK_OBJECT(menu));
}
......@@ -27,6 +27,7 @@
#ifndef NAUTILUS_GTK_EXTENSIONS_H
#define NAUTILUS_GTK_EXTENSIONS_H 1
#include <gtk/gtkmenu.h>
#include <gtk/gtkwindow.h>
guint nautilus_gtk_signal_connect_free_data (GtkObject *object,
......@@ -39,4 +40,6 @@ void nautilus_gtk_window_present (GtkWindow
GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data);
void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data);
void nautilus_pop_up_context_menu (GtkMenu *menu);
#endif /* NAUTILUS_GTK_EXTENSIONS_H */
......@@ -35,6 +35,7 @@
#include <libgnomevfs/gnome-vfs-file-info.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libnautilus/nautilus-gtk-extensions.h>
#include <libnautilus/nautilus-gtk-macros.h>
#include <libnautilus/nautilus-alloc.h>
......@@ -777,18 +778,6 @@ open_in_new_window_cb (GtkMenuItem *item, NautilusFile *file)
}
static void
popup_context_menu (GtkMenu *menu)
{
gtk_object_ref (GTK_OBJECT(menu));
gtk_object_sink (GTK_OBJECT(menu));
gtk_menu_popup (menu, NULL, NULL, NULL,
NULL, 3, GDK_CURRENT_TIME);
gtk_object_unref (GTK_OBJECT(menu));
}
static void
fm_directory_view_real_append_background_context_menu_items (FMDirectoryView *view,
GtkMenu *menu)
......@@ -931,7 +920,7 @@ fm_directory_view_popup_item_context_menu (FMDirectoryView *view,
g_assert (FM_IS_DIRECTORY_VIEW (view));
g_assert (NAUTILUS_IS_FILE (file));
popup_context_menu (create_item_context_menu (view, file));
nautilus_pop_up_context_menu (create_item_context_menu (view, file));
}
/**
......@@ -948,7 +937,7 @@ fm_directory_view_popup_background_context_menu (FMDirectoryView *view)
{
g_assert (FM_IS_DIRECTORY_VIEW (view));
popup_context_menu (create_background_context_menu (view));
nautilus_pop_up_context_menu (create_background_context_menu (view));
}
......
......@@ -459,6 +459,97 @@ nautilus_window_goto_uri_cb (GtkWidget *widget,
nautilus_window_goto_uri(NAUTILUS_WINDOW(window), uri);
}
static void
activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
NautilusWindow *window,
gboolean back)
{
int index;
const char *uri;
g_assert (GTK_IS_MENU_ITEM (menu_item));
g_assert (NAUTILUS_IS_WINDOW (window));
index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (menu_item)));
uri = g_slist_nth_data (back ? window->uris_prev : window->uris_next, index);
/* FIXME: This should do the equivalent of going back or forward n times,
* rather than just going to the right uri. This is needed to
* keep the back/forward chain intact.
*/
nautilus_window_goto_uri (window, uri);
}
static void
activate_back_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, TRUE);
}
static void
activate_forward_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, FALSE);
}
static GtkMenu *
create_back_or_forward_menu (NautilusWindow *window, gboolean back)
{
GtkMenu *menu;
GtkWidget *menu_item;
GSList *uri_in_list;
int index;
g_assert (NAUTILUS_IS_WINDOW (window));
menu = GTK_MENU (gtk_menu_new ());
uri_in_list = back ? window->uris_prev : window->uris_next;
index = 0;
while (uri_in_list != NULL)
{
menu_item = gtk_menu_item_new_with_label (uri_in_list->data);
gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (index));
gtk_widget_show (GTK_WIDGET (menu_item));
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
back ? activate_back_menu_item_cb : activate_forward_menu_item_cb,
window);
gtk_menu_append (menu, menu_item);
uri_in_list = g_slist_next (uri_in_list);
++index;
}
return menu;
}
static int
back_or_forward_button_clicked_cb (GtkWidget *widget,
GdkEventButton *event,
gpointer *user_data)
{
gboolean back;
g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
g_return_val_if_fail (NAUTILUS_IS_WINDOW (user_data), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
back = NAUTILUS_WINDOW (user_data)->back_button == widget;
g_assert (back || NAUTILUS_WINDOW (user_data)->forward_button == widget);
if (event->button == 3)
{
nautilus_pop_up_context_menu (
create_back_or_forward_menu (NAUTILUS_WINDOW (user_data),
back));
return TRUE;
}
return FALSE;
}
static void
nautilus_window_constructed(NautilusWindow *window)
{
......@@ -584,6 +675,15 @@ nautilus_window_constructed(NautilusWindow *window)
window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget;
window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget;
gtk_signal_connect (GTK_OBJECT (window->back_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
gtk_signal_connect (GTK_OBJECT (window->forward_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
/* Set initial sensitivity of some buttons & menu items
* now that they're all created.
......
......@@ -459,6 +459,97 @@ nautilus_window_goto_uri_cb (GtkWidget *widget,
nautilus_window_goto_uri(NAUTILUS_WINDOW(window), uri);
}
static void
activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
NautilusWindow *window,
gboolean back)
{
int index;
const char *uri;
g_assert (GTK_IS_MENU_ITEM (menu_item));
g_assert (NAUTILUS_IS_WINDOW (window));
index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (menu_item)));
uri = g_slist_nth_data (back ? window->uris_prev : window->uris_next, index);
/* FIXME: This should do the equivalent of going back or forward n times,
* rather than just going to the right uri. This is needed to
* keep the back/forward chain intact.
*/
nautilus_window_goto_uri (window, uri);
}
static void
activate_back_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, TRUE);
}
static void
activate_forward_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, FALSE);
}
static GtkMenu *
create_back_or_forward_menu (NautilusWindow *window, gboolean back)
{
GtkMenu *menu;
GtkWidget *menu_item;
GSList *uri_in_list;
int index;
g_assert (NAUTILUS_IS_WINDOW (window));
menu = GTK_MENU (gtk_menu_new ());
uri_in_list = back ? window->uris_prev : window->uris_next;
index = 0;
while (uri_in_list != NULL)
{
menu_item = gtk_menu_item_new_with_label (uri_in_list->data);
gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (index));
gtk_widget_show (GTK_WIDGET (menu_item));
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
back ? activate_back_menu_item_cb : activate_forward_menu_item_cb,
window);
gtk_menu_append (menu, menu_item);
uri_in_list = g_slist_next (uri_in_list);
++index;
}
return menu;
}
static int
back_or_forward_button_clicked_cb (GtkWidget *widget,
GdkEventButton *event,
gpointer *user_data)
{
gboolean back;
g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
g_return_val_if_fail (NAUTILUS_IS_WINDOW (user_data), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
back = NAUTILUS_WINDOW (user_data)->back_button == widget;
g_assert (back || NAUTILUS_WINDOW (user_data)->forward_button == widget);
if (event->button == 3)
{
nautilus_pop_up_context_menu (
create_back_or_forward_menu (NAUTILUS_WINDOW (user_data),
back));
return TRUE;
}
return FALSE;
}
static void
nautilus_window_constructed(NautilusWindow *window)
{
......@@ -584,6 +675,15 @@ nautilus_window_constructed(NautilusWindow *window)
window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget;
window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget;
gtk_signal_connect (GTK_OBJECT (window->back_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
gtk_signal_connect (GTK_OBJECT (window->forward_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
/* Set initial sensitivity of some buttons & menu items
* now that they're all created.
......
......@@ -459,6 +459,97 @@ nautilus_window_goto_uri_cb (GtkWidget *widget,
nautilus_window_goto_uri(NAUTILUS_WINDOW(window), uri);
}
static void
activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
NautilusWindow *window,
gboolean back)
{
int index;
const char *uri;
g_assert (GTK_IS_MENU_ITEM (menu_item));
g_assert (NAUTILUS_IS_WINDOW (window));
index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (menu_item)));
uri = g_slist_nth_data (back ? window->uris_prev : window->uris_next, index);
/* FIXME: This should do the equivalent of going back or forward n times,
* rather than just going to the right uri. This is needed to
* keep the back/forward chain intact.
*/
nautilus_window_goto_uri (window, uri);
}
static void
activate_back_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, TRUE);
}
static void
activate_forward_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, FALSE);
}
static GtkMenu *
create_back_or_forward_menu (NautilusWindow *window, gboolean back)
{
GtkMenu *menu;
GtkWidget *menu_item;
GSList *uri_in_list;
int index;
g_assert (NAUTILUS_IS_WINDOW (window));
menu = GTK_MENU (gtk_menu_new ());
uri_in_list = back ? window->uris_prev : window->uris_next;
index = 0;
while (uri_in_list != NULL)
{
menu_item = gtk_menu_item_new_with_label (uri_in_list->data);
gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (index));
gtk_widget_show (GTK_WIDGET (menu_item));
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
back ? activate_back_menu_item_cb : activate_forward_menu_item_cb,
window);
gtk_menu_append (menu, menu_item);
uri_in_list = g_slist_next (uri_in_list);
++index;
}
return menu;
}
static int
back_or_forward_button_clicked_cb (GtkWidget *widget,
GdkEventButton *event,
gpointer *user_data)
{
gboolean back;
g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
g_return_val_if_fail (NAUTILUS_IS_WINDOW (user_data), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
back = NAUTILUS_WINDOW (user_data)->back_button == widget;
g_assert (back || NAUTILUS_WINDOW (user_data)->forward_button == widget);
if (event->button == 3)
{
nautilus_pop_up_context_menu (
create_back_or_forward_menu (NAUTILUS_WINDOW (user_data),
back));
return TRUE;
}
return FALSE;
}
static void
nautilus_window_constructed(NautilusWindow *window)
{
......@@ -584,6 +675,15 @@ nautilus_window_constructed(NautilusWindow *window)
window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget;
window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget;
gtk_signal_connect (GTK_OBJECT (window->back_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
gtk_signal_connect (GTK_OBJECT (window->forward_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
/* Set initial sensitivity of some buttons & menu items
* now that they're all created.
......
......@@ -459,6 +459,97 @@ nautilus_window_goto_uri_cb (GtkWidget *widget,
nautilus_window_goto_uri(NAUTILUS_WINDOW(window), uri);
}
static void
activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
NautilusWindow *window,
gboolean back)
{
int index;
const char *uri;
g_assert (GTK_IS_MENU_ITEM (menu_item));
g_assert (NAUTILUS_IS_WINDOW (window));
index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (menu_item)));
uri = g_slist_nth_data (back ? window->uris_prev : window->uris_next, index);
/* FIXME: This should do the equivalent of going back or forward n times,
* rather than just going to the right uri. This is needed to
* keep the back/forward chain intact.
*/
nautilus_window_goto_uri (window, uri);
}
static void
activate_back_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, TRUE);
}
static void
activate_forward_menu_item_cb (GtkMenuItem *menu_item, NautilusWindow *window)
{
activate_back_or_forward_menu_item (menu_item, window, FALSE);
}
static GtkMenu *
create_back_or_forward_menu (NautilusWindow *window, gboolean back)
{
GtkMenu *menu;
GtkWidget *menu_item;
GSList *uri_in_list;
int index;
g_assert (NAUTILUS_IS_WINDOW (window));
menu = GTK_MENU (gtk_menu_new ());
uri_in_list = back ? window->uris_prev : window->uris_next;
index = 0;
while (uri_in_list != NULL)
{
menu_item = gtk_menu_item_new_with_label (uri_in_list->data);
gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (index));
gtk_widget_show (GTK_WIDGET (menu_item));
gtk_signal_connect(GTK_OBJECT(menu_item),
"activate",
back ? activate_back_menu_item_cb : activate_forward_menu_item_cb,
window);
gtk_menu_append (menu, menu_item);
uri_in_list = g_slist_next (uri_in_list);
++index;
}
return menu;
}
static int
back_or_forward_button_clicked_cb (GtkWidget *widget,
GdkEventButton *event,
gpointer *user_data)
{
gboolean back;
g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
g_return_val_if_fail (NAUTILUS_IS_WINDOW (user_data), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
back = NAUTILUS_WINDOW (user_data)->back_button == widget;
g_assert (back || NAUTILUS_WINDOW (user_data)->forward_button == widget);
if (event->button == 3)
{
nautilus_pop_up_context_menu (
create_back_or_forward_menu (NAUTILUS_WINDOW (user_data),
back));
return TRUE;
}
return FALSE;
}
static void
nautilus_window_constructed(NautilusWindow *window)
{
......@@ -584,6 +675,15 @@ nautilus_window_constructed(NautilusWindow *window)
window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget;
window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget;
gtk_signal_connect (GTK_OBJECT (window->back_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
gtk_signal_connect (GTK_OBJECT (window->forward_button),
"button_press_event",
GTK_SIGNAL_FUNC (back_or_forward_button_clicked_cb),
window);
/* Set initial sensitivity of some buttons & menu items
* now that they're all created.
......
......@@ -459,6 +459,97 @@ nautilus_window_goto_uri_cb (GtkWidget *widget,
nautilus_window_goto_uri(NAUTILUS_WINDOW(window), uri);
}
static void
activate_back_or_forward_menu_item (GtkMenuItem *menu_item,
NautilusWindow *window,
gboolean back)