diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | libnautilus-private/nautilus-view.c | 11 | ||||
-rw-r--r-- | libnautilus-private/nautilus-view.h | 14 | ||||
-rw-r--r-- | src/file-manager/fm-actions.h | 5 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.c | 247 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.h | 2 | ||||
-rw-r--r-- | src/file-manager/nautilus-directory-view-ui.xml | 17 | ||||
-rw-r--r-- | src/nautilus-location-bar.c | 32 | ||||
-rw-r--r-- | src/nautilus-spatial-window.c | 17 |
9 files changed, 348 insertions, 12 deletions
@@ -1,3 +1,18 @@ +2005-05-17 Alexander Larsson <alexl@redhat.com> + + * libnautilus-private/nautilus-view.[ch]: + Add nautilus_view_pop_up_location_context_menu + + * src/file-manager/fm-actions.h: + * src/file-manager/fm-directory-view.c: + * src/file-manager/fm-directory-view.h: + * src/file-manager/nautilus-directory-view-ui.xml: + * src/nautilus-location-bar.c: + * src/nautilus-spatial-window.c: + Add location context menu to location button/label. + + Patch from Christian Neumair + 2005-05-17 Christian Neumair <chris@gnome-de.org> * src/nautilus-spatial-window.c: diff --git a/libnautilus-private/nautilus-view.c b/libnautilus-private/nautilus-view.c index bad36efc8..66027cd3c 100644 --- a/libnautilus-private/nautilus-view.c +++ b/libnautilus-private/nautilus-view.c @@ -249,3 +249,14 @@ nautilus_view_get_zoom_level (NautilusView *view) return (* NAUTILUS_VIEW_GET_IFACE (view)->get_zoom_level) (view); } + +void +nautilus_view_pop_up_location_context_menu (NautilusView *view, + GdkEventButton *event) +{ + g_return_if_fail (NAUTILUS_IS_VIEW (view)); + + if (NAUTILUS_VIEW_GET_IFACE (view)->pop_up_location_context_menu != NULL) { + (* NAUTILUS_VIEW_GET_IFACE (view)->pop_up_location_context_menu) (view, event); + } +} diff --git a/libnautilus-private/nautilus-view.h b/libnautilus-private/nautilus-view.h index b4b90fe39..7eb57ba2e 100644 --- a/libnautilus-private/nautilus-view.h +++ b/libnautilus-private/nautilus-view.h @@ -105,7 +105,16 @@ struct _NautilusViewIface void (* restore_default_zoom_level) (NautilusView *view); gboolean (* can_zoom_in) (NautilusView *view); gboolean (* can_zoom_out) (NautilusView *view); - + + /* Request popup of context menu referring to the open location. + * This is triggered in spatial windows by right-clicking the location button, + * in navigational windows by right-clicking the "Location:" label in the + * navigation bar. + * The view may display the popup synchronously, asynchronously + * or not react to the popup request at all. */ + void (* pop_up_location_context_menu) (NautilusView *view, + GdkEventButton *event); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -114,7 +123,6 @@ struct _NautilusViewIface void (*_reserved5) (void); void (*_reserved6) (void); void (*_reserved7) (void); - void (*_reserved8) (void); }; GType nautilus_view_get_type (void); @@ -141,6 +149,8 @@ void nautilus_view_restore_default_zoom_level (NautilusView *v gboolean nautilus_view_can_zoom_in (NautilusView *view); gboolean nautilus_view_can_zoom_out (NautilusView *view); NautilusZoomLevel nautilus_view_get_zoom_level (NautilusView *view); +void nautilus_view_pop_up_location_context_menu (NautilusView *view, + GdkEventButton *event); G_END_DECLS diff --git a/src/file-manager/fm-actions.h b/src/file-manager/fm-actions.h index 432a1b2e6..825f0b5ae 100644 --- a/src/file-manager/fm-actions.h +++ b/src/file-manager/fm-actions.h @@ -27,6 +27,7 @@ #define FM_ACTION_OPEN "Open" #define FM_ACTION_OPEN_ALTERNATE "OpenAlternate" +#define FM_ACTION_LOCATION_OPEN_ALTERNATE "LocationOpenAlternate" #define FM_ACTION_OTHER_APPLICATION1 "OtherApplication1" #define FM_ACTION_OTHER_APPLICATION2 "OtherApplication2" #define FM_ACTION_NEW_FOLDER "New Folder" @@ -36,7 +37,9 @@ #define FM_ACTION_NO_TEMPLATES "No Templates" #define FM_ACTION_EMPTY_TRASH "Empty Trash" #define FM_ACTION_CUT "Cut" +#define FM_ACTION_LOCATION_CUT "LocationCut" #define FM_ACTION_COPY "Copy" +#define FM_ACTION_LOCATION_COPY "LocationCopy" #define FM_ACTION_PASTE "Paste" #define FM_ACTION_PASTE_FILES_INTO "Paste Files Into" #define FM_ACTION_NEW_LAUNCHER "New Launcher" @@ -46,7 +49,9 @@ #define FM_ACTION_SELECT_ALL "Select All" #define FM_ACTION_SELECT_PATTERN "Select Pattern" #define FM_ACTION_TRASH "Trash" +#define FM_ACTION_LOCATION_TRASH "LocationTrash" #define FM_ACTION_DELETE "Delete" +#define FM_ACTION_LOCATION_DELETE "LocationDelete" #define FM_ACTION_SHOW_HIDDEN_FILES "Show Hidden Files" #define FM_ACTION_CONNECT_TO_SERVER_LINK "Connect To Server Link" #define FM_ACTION_MOUNT_VOLUME "Mount Volume" diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index f25d5de4d..6c7e7a899 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -125,6 +125,8 @@ #define FM_DIRECTORY_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER "/background/Before Zoom Items/New Object Items/Scripts/Scripts Placeholder" #define FM_DIRECTORY_VIEW_POPUP_PATH_BACKGROUND_NEW_DOCUMENTS_PLACEHOLDER "/background/Before Zoom Items/New Object Items/New Documents/New Documents Placeholder" +#define FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION "/location" + #define MAX_MENU_LEVELS 5 enum { @@ -370,6 +372,20 @@ static void action_mount_volume_callback (GtkAction *action, static void action_unmount_volume_callback (GtkAction *action, gpointer data); +/* location popup-related actions */ + +static void action_location_open_alternate_callback (GtkAction *action, + gpointer callback_data); + +static void action_location_cut_callback (GtkAction *action, + gpointer callback_data); +static void action_location_copy_callback (GtkAction *action, + gpointer callback_data); +static void action_location_trash_callback (GtkAction *action, + gpointer callback_data); +static void action_location_delete_callback (GtkAction *action, + gpointer callback_data); + EEL_CLASS_BOILERPLATE (FMDirectoryView, fm_directory_view, GTK_TYPE_SCROLLED_WINDOW) EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, add_file) @@ -1578,6 +1594,8 @@ fm_directory_view_init_view_iface (NautilusViewIface *iface) iface->can_zoom_in = (gpointer)fm_directory_view_can_zoom_in; iface->can_zoom_out = (gpointer)fm_directory_view_can_zoom_out; iface->get_zoom_level = (gpointer)fm_directory_view_get_zoom_level; + + iface->pop_up_location_context_menu = (gpointer)fm_directory_view_pop_up_location_context_menu; } static void @@ -5260,15 +5278,13 @@ convert_file_list_to_uri_list (GList *files) static void copy_or_cut_files (FMDirectoryView *view, - gboolean cut) + GList *clipboard_contents, + gboolean cut) { int count; char *status_string, *name; - GList *clipboard_contents; ClipboardInfo *info; - clipboard_contents = fm_directory_view_get_selection (view); - info = g_new0 (ClipboardInfo, 1); info->file_uris = convert_file_list_to_uri_list (clipboard_contents); info->cut = cut; @@ -5311,8 +5327,6 @@ copy_or_cut_files (FMDirectoryView *view, } } - nautilus_file_list_free (clipboard_contents); - nautilus_window_info_set_status (view->details->window, status_string); g_free (status_string); @@ -5322,14 +5336,28 @@ static void action_copy_files_callback (GtkAction *action, gpointer callback_data) { - copy_or_cut_files (callback_data, FALSE); + FMDirectoryView *view; + GList *selection; + + view = FM_DIRECTORY_VIEW (callback_data); + + selection = fm_directory_view_get_selection (view); + copy_or_cut_files (view, selection, FALSE); + nautilus_file_list_free (selection); } static void action_cut_files_callback (GtkAction *action, gpointer callback_data) { - copy_or_cut_files (callback_data, TRUE); + FMDirectoryView *view; + GList *selection; + + view = FM_DIRECTORY_VIEW (callback_data); + + selection = fm_directory_view_get_selection (view); + copy_or_cut_files (view, selection, TRUE); + nautilus_file_list_free (selection); } static GList * @@ -5761,6 +5789,101 @@ action_connect_to_server_link_callback (GtkAction *action, } static void +action_location_open_alternate_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + + view = FM_DIRECTORY_VIEW (callback_data); + + file = view->details->directory_as_file; + g_return_if_fail (file != NULL); + + fm_directory_view_activate_file (view, + file, + NAUTILUS_WINDOW_OPEN_IN_NAVIGATION, + 0); +} + +static void +action_location_cut_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + GList *files; + + view = FM_DIRECTORY_VIEW (callback_data); + + file = fm_directory_view_get_directory_as_file (view); + g_return_if_fail (file != NULL); + + files = g_list_append (NULL, file); + copy_or_cut_files (view, files, TRUE); + g_list_free (files); +} + +static void +action_location_copy_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + GList *files; + + view = FM_DIRECTORY_VIEW (callback_data); + + file = fm_directory_view_get_directory_as_file (view); + g_return_if_fail (file != NULL); + + files = g_list_append (NULL, file); + copy_or_cut_files (view, files, FALSE); + g_list_free (files); +} + +static void +action_location_trash_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + GList *files; + + view = FM_DIRECTORY_VIEW (callback_data); + + file = fm_directory_view_get_directory_as_file (view); + g_return_if_fail (file != NULL); + + files = g_list_append (NULL, file); + trash_or_delete_files (view, files); + g_list_free (files); +} + +static void +action_location_delete_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + char *file_uri; + GList *files; + + view = FM_DIRECTORY_VIEW (callback_data); + + file = fm_directory_view_get_directory_as_file (view); + g_return_if_fail (file != NULL); + + file_uri = nautilus_file_get_uri (file); + + files = g_list_append (NULL, file_uri); + nautilus_file_operations_delete (files, GTK_WIDGET (view)); + + g_free (file_uri); + g_list_free (files); +} + +static void fm_directory_view_init_show_hidden_files (FMDirectoryView *view) { NautilusWindowShowHiddenFilesMode mode; @@ -5933,6 +6056,30 @@ static GtkActionEntry directory_view_entries[] = { N_("Open File and Close window"), "<alt><shift>Down", /* label, accelerator */ NULL, /* tooltip */ G_CALLBACK (action_open_close_parent_callback) }, + + /* Location-specific actions */ + { FM_ACTION_LOCATION_OPEN_ALTERNATE, NULL, /* name, stock id */ + N_("Open in Navigation Window"), "", /* label, accelerator */ + N_("Open the open folder in a navigation window"), /* tooltip */ + G_CALLBACK (action_location_open_alternate_callback) }, + + { FM_ACTION_LOCATION_CUT, GTK_STOCK_CUT, /* name, stock id */ + NULL, "", /* label, accelerator */ + N_("Prepare the open folder to be moved with a Paste Files command"), /* tooltip */ + G_CALLBACK (action_location_cut_callback) }, + { FM_ACTION_LOCATION_COPY, GTK_STOCK_COPY, /* name, stock id */ + NULL, "", /* label, accelerator */ + N_("Prepare the open folder to be copied with a Paste Files command"), /* tooltip */ + G_CALLBACK (action_location_copy_callback) }, + + { FM_ACTION_LOCATION_TRASH, GTK_STOCK_DELETE, /* name, stock id */ + N_("Mo_ve to Trash"), "", /* label, accelerator */ + N_("Move the open folder to the Trash"), /* tooltip */ + G_CALLBACK (action_location_trash_callback) }, + { FM_ACTION_LOCATION_DELETE, GTK_STOCK_DELETE, /* name, stock id */ + N_("_Delete"), "", /* label, accelerator */ + N_("Delete the open folder, without moving to the Trash"), /* tooltip */ + G_CALLBACK (action_location_delete_callback) }, }; static GtkToggleActionEntry directory_view_toggle_entries[] = { @@ -6223,6 +6370,62 @@ real_update_paste_menu (FMDirectoryView *view, } static void +real_update_location_menu (FMDirectoryView *view) +{ + GtkAction *action; + gboolean is_read_only; + gboolean show_separate_delete_command; + char *label; + char *tip; + + if (nautilus_window_info_get_window_type (view->details->window) == NAUTILUS_WINDOW_NAVIGATION) { + label = _("Open in New Window"); + } else { + label = _("_Browse Folder"); + } + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_LOCATION_OPEN_ALTERNATE); + g_object_set (action, + "label", label, + NULL); + + is_read_only = fm_directory_view_is_read_only (view); + + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_LOCATION_CUT); + gtk_action_set_sensitive (action, !is_read_only); + + if (view->details->directory_as_file != NULL && + nautilus_file_is_in_trash (view->details->directory_as_file)) { + label = _("_Delete from Trash"); + tip = _("Delete the open folder permanently"); + show_separate_delete_command = FALSE; + } else { + label = _("Mo_ve to Trash"); + tip = _("Move the open folder to the Trash"); + show_separate_delete_command = show_delete_command_auto_value; + } + + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_LOCATION_TRASH); + g_object_set (action, + "label", label, + "tooltip", tip, + NULL); + gtk_action_set_sensitive (action, !is_read_only); + + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_LOCATION_DELETE); + gtk_action_set_visible (action, show_separate_delete_command); + if (show_separate_delete_command) { + gtk_action_set_sensitive (action, !is_read_only); + } + + /* we silently assume that fm_directory_view_supports_properties always returns the same value. + * Therefore, we don't update the sensitivity of FM_ACTION_SELF_PROPERTIES */ +} + +static void clipboard_changed_callback (NautilusClipboardMonitor *monitor, FMDirectoryView *view) { GList *selection; @@ -6487,7 +6690,7 @@ real_update_menus (FMDirectoryView *view) **/ void fm_directory_view_pop_up_selection_context_menu (FMDirectoryView *view, - GdkEventButton *event) + GdkEventButton *event) { g_assert (FM_IS_DIRECTORY_VIEW (view)); @@ -6514,7 +6717,7 @@ fm_directory_view_pop_up_selection_context_menu (FMDirectoryView *view, **/ void fm_directory_view_pop_up_background_context_menu (FMDirectoryView *view, - GdkEventButton *event) + GdkEventButton *event) { g_assert (FM_IS_DIRECTORY_VIEW (view)); @@ -6530,6 +6733,30 @@ fm_directory_view_pop_up_background_context_menu (FMDirectoryView *view, event); } +/** + * fm_directory_view_pop_up_location_context_menu + * + * Pop up a context menu appropriate to the view globally. + * @view: FMDirectoryView of interest. + * @event: GdkEventButton triggering the popup. + * + **/ +void +fm_directory_view_pop_up_location_context_menu (FMDirectoryView *view, + GdkEventButton *event) +{ + g_assert (FM_IS_DIRECTORY_VIEW (view)); + + /* always update the menu before showing it. Shouldn't be too expensive. */ + real_update_location_menu (view); + + eel_pop_up_context_menu (create_popup_menu + (view, FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION), + EEL_DEFAULT_POPUP_MENU_DISPLACEMENT, + EEL_DEFAULT_POPUP_MENU_DISPLACEMENT, + event); +} + static void schedule_update_menus (FMDirectoryView *view) { diff --git a/src/file-manager/fm-directory-view.h b/src/file-manager/fm-directory-view.h index c77bba7a0..5a4be53b4 100644 --- a/src/file-manager/fm-directory-view.h +++ b/src/file-manager/fm-directory-view.h @@ -364,6 +364,8 @@ void fm_directory_view_pop_up_background_context_menu (FMDirect GdkEventButton *event); void fm_directory_view_pop_up_selection_context_menu (FMDirectoryView *view, GdkEventButton *event); +void fm_directory_view_pop_up_location_context_menu (FMDirectoryView *view, + GdkEventButton *event); void fm_directory_view_send_selection_change (FMDirectoryView *view); gboolean fm_directory_view_should_show_file (FMDirectoryView *view, NautilusFile *file); diff --git a/src/file-manager/nautilus-directory-view-ui.xml b/src/file-manager/nautilus-directory-view-ui.xml index 135a7e480..6084449dc 100644 --- a/src/file-manager/nautilus-directory-view-ui.xml +++ b/src/file-manager/nautilus-directory-view-ui.xml @@ -149,4 +149,21 @@ </placeholder> <menuitem name="Connect To Server Link" action="Connect To Server Link"/> </popup> +<popup name="location"> + <placeholder name="Open Placeholder"> + <menuitem name="LocationOpenAlternate" action="LocationOpenAlternate"/> + </placeholder> + <separator/> + <placeholder name="Clipboard Actions"> + <menuitem name="Cut" action="LocationCut"/> + <menuitem name="Copy" action="LocationCopy"/> + </placeholder> + <separator/> + <placeholder name="Dangerous File Actions"> + <menuitem name="Trash" action="LocationTrash"/> + <menuitem name="Delete" action="LocationDelete"/> + </placeholder> + <separator/> + <menuitem name="Properties" action="SelfProperties"/> +</popup> </ui> diff --git a/src/nautilus-location-bar.c b/src/nautilus-location-bar.c index de7aa3d5a..1bbb50df9 100644 --- a/src/nautilus-location-bar.c +++ b/src/nautilus-location-bar.c @@ -258,6 +258,33 @@ style_set_handler (GtkWidget *widget, GtkStyle *previous_style) gtk_widget_set_size_request (widget, width, -1); } +static gboolean +label_button_pressed_callback (GtkWidget *widget, + GdkEventButton *event) +{ + NautilusNavigationWindow *window; + NautilusView *view; + GtkWidget *label; + + if (event->button != 3) { + return FALSE; + } + + window = nautilus_location_bar_get_window (widget->parent); + view = NAUTILUS_WINDOW (window)->content_view; + label = GTK_BIN (widget)->child; + /* only pop-up if the URI in the entry matches the displayed location */ + if (view == NULL || + strcmp (gtk_label_get_text (GTK_LABEL (label)), LOCATION_LABEL)) { + return FALSE; + } + + nautilus_view_pop_up_location_context_menu (view, event); + + return FALSE; +} + + static int get_editable_number_of_chars (GtkEditable *editable) { @@ -402,6 +429,11 @@ nautilus_location_bar_init (NautilusLocationBar *bar) gtk_container_add (GTK_CONTAINER (bar), hbox); + + /* Label context menu */ + g_signal_connect (event_box, "button-press-event", + G_CALLBACK (label_button_pressed_callback), NULL); + /* Drag source */ gtk_drag_source_set (GTK_WIDGET (event_box), GDK_BUTTON1_MASK | GDK_BUTTON3_MASK, diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index ba3aa57db..d8258ce82 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -507,6 +507,19 @@ menu_popup_pos (GtkMenu *menu, *push_in = TRUE; } +static gboolean +location_button_pressed_callback (GtkWidget *widget, + GdkEventButton *event, + NautilusWindow *window) +{ + if (event->button == 3 && + window->content_view != NULL) { + nautilus_view_pop_up_location_context_menu (window->content_view, event); + } + + return FALSE; +} + static void location_button_clicked_callback (GtkWidget *widget, NautilusSpatialWindow *window) { @@ -716,6 +729,10 @@ nautilus_spatial_window_instance_init (NautilusSpatialWindow *window) gtk_widget_show (window->details->content_box); window->details->location_button = gtk_button_new (); + g_signal_connect (window->details->location_button, + "button-press-event", + G_CALLBACK (location_button_pressed_callback), + window); gtk_button_set_relief (GTK_BUTTON (window->details->location_button), GTK_RELIEF_NORMAL); rc_style = gtk_widget_get_modifier_style (window->details->location_button); |