diff options
author | John Sullivan <sullivan@src.gnome.org> | 2000-06-02 20:57:37 +0000 |
---|---|---|
committer | John Sullivan <sullivan@src.gnome.org> | 2000-06-02 20:57:37 +0000 |
commit | aa407de891e029e72e96dc7d334f2abc1f05e932 (patch) | |
tree | d51326458600a619e620d4e44907b84bce6dcb71 | |
parent | bbb7d78b40297eb81bcb373fed63f0dea5cb7c10 (diff) | |
download | nautilus-aa407de891e029e72e96dc7d334f2abc1f05e932.tar.gz |
Finished task 968 (Add one-time viewer choice to "View as"
menu temporarily)
* libnautilus-extensions/nautilus-view-identifier.h,
* libnautilus-extensions/nautilus-view-identifier.c:
(nautilus_view_identifier_copy): New function, does the obvious.
* src/nautilus-applicable-views.h: Made NautilusNavigationInfo
store a NautilusViewIdentifier instead of just the iid part
in initial_content_iid (now initial_content_id).
* src/nautilus-applicable-views.c: (set_initial_content_id),
(got_file_info_callback), (nautilus_navigation_info_free):
Reworked code to handle change from char *iid to NautilusViewIdentifier.
* src/nautilus-window.h: New field for content_view_id,
a NautilusViewIdentifier for the current view.
* src/nautilus-window-private.h,
* src/nautilus-window-manage-views.c:
(nautilus_window_load_content_view): Now takes a
NautilusViewIdentifier * instead of just a char *,
and resets content_view_id field.
(nautilus_window_update_state): Reworked code to handle
initial_content_iid change.
* src/nautilus-window.c:
(nautilus_window_destroy): Destroy content_view_id.
(nautilus_window_switch_views), (view_menu_switch_views_callback):
Reworked to take NautilusViewIdentifier * instead of just char *.
(create_content_view_menu_item): New helper function, extracted
from nautilus_window_load_content_view_menu.
(replace_special_current_view_in_content_view_menu): New
function, does the work of putting the current content view
as the initial item in the menu, followed by a separator.
(nautilus_window_synch_content_view_menu): Calls
replace_special_current_view_in_content_menu if the current view
is not found in the menu.
(chose_component_callback): Took out fixed FIXMEs.
(nautilus_window_load_content_view_menu): Now calls function
that was extracted from it.
-rw-r--r-- | ChangeLog | 44 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-view-identifier.c | 6 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-view-identifier.h | 5 | ||||
-rw-r--r-- | libnautilus-private/nautilus-view-identifier.c | 6 | ||||
-rw-r--r-- | libnautilus-private/nautilus-view-identifier.h | 5 | ||||
-rw-r--r-- | src/nautilus-applicable-views.c | 73 | ||||
-rw-r--r-- | src/nautilus-applicable-views.h | 11 | ||||
-rw-r--r-- | src/nautilus-navigation-window.c | 157 | ||||
-rw-r--r-- | src/nautilus-navigation-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-object-window.c | 157 | ||||
-rw-r--r-- | src/nautilus-object-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-spatial-window.c | 157 | ||||
-rw-r--r-- | src/nautilus-spatial-window.h | 2 | ||||
-rw-r--r-- | src/nautilus-window-manage-views.c | 14 | ||||
-rw-r--r-- | src/nautilus-window-private.h | 2 | ||||
-rw-r--r-- | src/nautilus-window.c | 157 | ||||
-rw-r--r-- | src/nautilus-window.h | 2 |
17 files changed, 545 insertions, 257 deletions
@@ -1,3 +1,47 @@ +2000-06-02 John Sullivan <sullivan@eazel.com> + + Finished task 968 (Add one-time viewer choice to "View as" + menu temporarily) + + * libnautilus-extensions/nautilus-view-identifier.h, + * libnautilus-extensions/nautilus-view-identifier.c: + (nautilus_view_identifier_copy): New function, does the obvious. + + * src/nautilus-applicable-views.h: Made NautilusNavigationInfo + store a NautilusViewIdentifier instead of just the iid part + in initial_content_iid (now initial_content_id). + + * src/nautilus-applicable-views.c: (set_initial_content_id), + (got_file_info_callback), (nautilus_navigation_info_free): + Reworked code to handle change from char *iid to NautilusViewIdentifier. + + * src/nautilus-window.h: New field for content_view_id, + a NautilusViewIdentifier for the current view. + + * src/nautilus-window-private.h, + * src/nautilus-window-manage-views.c: + (nautilus_window_load_content_view): Now takes a + NautilusViewIdentifier * instead of just a char *, + and resets content_view_id field. + (nautilus_window_update_state): Reworked code to handle + initial_content_iid change. + + * src/nautilus-window.c: + (nautilus_window_destroy): Destroy content_view_id. + (nautilus_window_switch_views), (view_menu_switch_views_callback): + Reworked to take NautilusViewIdentifier * instead of just char *. + (create_content_view_menu_item): New helper function, extracted + from nautilus_window_load_content_view_menu. + (replace_special_current_view_in_content_view_menu): New + function, does the work of putting the current content view + as the initial item in the menu, followed by a separator. + (nautilus_window_synch_content_view_menu): Calls + replace_special_current_view_in_content_menu if the current view + is not found in the menu. + (chose_component_callback): Took out fixed FIXMEs. + (nautilus_window_load_content_view_menu): Now calls function + that was extracted from it. + 2000-06-02 Ramiro Estrugo <ramiro@eazel.com> Task 667. Unhardcode font strings. diff --git a/libnautilus-extensions/nautilus-view-identifier.c b/libnautilus-extensions/nautilus-view-identifier.c index b6a62d42e..3a0db2ea2 100644 --- a/libnautilus-extensions/nautilus-view-identifier.c +++ b/libnautilus-extensions/nautilus-view-identifier.c @@ -45,6 +45,12 @@ nautilus_view_identifier_new (const char *iid, const char *name) return new_identifier; } +NautilusViewIdentifier * +nautilus_view_identifier_copy (NautilusViewIdentifier *identifier) +{ + return nautilus_view_identifier_new (identifier->iid, identifier->name); +} + static GSList * get_lang_list (void) diff --git a/libnautilus-extensions/nautilus-view-identifier.h b/libnautilus-extensions/nautilus-view-identifier.h index 0f1586ebb..73022aa8c 100644 --- a/libnautilus-extensions/nautilus-view-identifier.h +++ b/libnautilus-extensions/nautilus-view-identifier.h @@ -25,6 +25,10 @@ #ifndef NAUTILUS_VIEW_IDENTIFIER_H #define NAUTILUS_VIEW_IDENTIFIER_H +/* FIXME: Without this define liboaf doesn't include popt.h, causing trouble + * later; this mechanism should be fixed. + */ +#define HAVE_POPT_H #include <liboaf/liboaf.h> typedef struct { @@ -38,6 +42,7 @@ NautilusViewIdentifier *nautilus_view_identifier_new_from_oaf_server_info (OAF_S char *name_attribute); NautilusViewIdentifier *nautilus_view_identifier_new_from_content_view (OAF_ServerInfo *server); NautilusViewIdentifier *nautilus_view_identifier_new_from_sidebar_panel (OAF_ServerInfo *server); +NautilusViewIdentifier *nautilus_view_identifier_copy (NautilusViewIdentifier *identifier); void nautilus_view_identifier_free (NautilusViewIdentifier *identifier); void nautilus_view_identifier_list_free (GList *identifiers); diff --git a/libnautilus-private/nautilus-view-identifier.c b/libnautilus-private/nautilus-view-identifier.c index b6a62d42e..3a0db2ea2 100644 --- a/libnautilus-private/nautilus-view-identifier.c +++ b/libnautilus-private/nautilus-view-identifier.c @@ -45,6 +45,12 @@ nautilus_view_identifier_new (const char *iid, const char *name) return new_identifier; } +NautilusViewIdentifier * +nautilus_view_identifier_copy (NautilusViewIdentifier *identifier) +{ + return nautilus_view_identifier_new (identifier->iid, identifier->name); +} + static GSList * get_lang_list (void) diff --git a/libnautilus-private/nautilus-view-identifier.h b/libnautilus-private/nautilus-view-identifier.h index 0f1586ebb..73022aa8c 100644 --- a/libnautilus-private/nautilus-view-identifier.h +++ b/libnautilus-private/nautilus-view-identifier.h @@ -25,6 +25,10 @@ #ifndef NAUTILUS_VIEW_IDENTIFIER_H #define NAUTILUS_VIEW_IDENTIFIER_H +/* FIXME: Without this define liboaf doesn't include popt.h, causing trouble + * later; this mechanism should be fixed. + */ +#define HAVE_POPT_H #include <liboaf/liboaf.h> typedef struct { @@ -38,6 +42,7 @@ NautilusViewIdentifier *nautilus_view_identifier_new_from_oaf_server_info (OAF_S char *name_attribute); NautilusViewIdentifier *nautilus_view_identifier_new_from_content_view (OAF_ServerInfo *server); NautilusViewIdentifier *nautilus_view_identifier_new_from_sidebar_panel (OAF_ServerInfo *server); +NautilusViewIdentifier *nautilus_view_identifier_copy (NautilusViewIdentifier *identifier); void nautilus_view_identifier_free (NautilusViewIdentifier *identifier); void nautilus_view_identifier_list_free (GList *identifiers); diff --git a/src/nautilus-applicable-views.c b/src/nautilus-applicable-views.c index 684737951..1a7faf8f4 100644 --- a/src/nautilus-applicable-views.c +++ b/src/nautilus-applicable-views.c @@ -108,26 +108,29 @@ check_iid (gconstpointer a, gconstpointer b) } /** - * set_initial_content_iid: + * set_initial_content_id: * - * Sets the iid that will determine which content view to use when + * Sets the NautilusViewIdentifier that will determine which content view to use when * a URI is displayed. * * @navinfo: The NautilusNavigationInfo representing the URI that's about * to be displayed. - * @fallback_value: The iid to use for the content view if no better + * @fallback_value: The NautilusViewIdentifier to use for the content view if no better * one can be determined. */ static void -set_initial_content_iid (NautilusNavigationInfo *navinfo, - const char *fallback_value) +set_initial_content_id (NautilusNavigationInfo *navinfo, + NautilusViewIdentifier *fallback_view_id) { - char *remembered_value = NULL; - const char *value = NULL; + char *remembered_value; + NautilusViewIdentifier *new_id; + GList *node; - g_assert (fallback_value != NULL); + g_assert (fallback_view_id != NULL); g_assert (g_list_length (navinfo->content_identifiers) > 0); + new_id = NULL; + /* NOTE: Darin doesn't like the unpredictability of this three-choice system. * He'd prefer a global setting and perhaps an explicit location-specific * setting that doesn't affect any other locations. Maybe we should change @@ -138,9 +141,10 @@ set_initial_content_iid (NautilusNavigationInfo *navinfo, /* Use the remembered value if it's non-NULL and in the list of choices. */ if (remembered_value != NULL) { - if (g_list_find_custom (navinfo->content_identifiers, - remembered_value, check_iid)) { - value = remembered_value; + node = g_list_find_custom (navinfo->content_identifiers, + remembered_value, check_iid); + if (node != NULL) { + new_id = node->data; } else { g_message ("Unknown iid \"%s\" stored for %s", remembered_value, @@ -148,24 +152,25 @@ set_initial_content_iid (NautilusNavigationInfo *navinfo, } } - if (value == NULL) { + if (new_id == NULL) { /* Can't use remembered value, use referring value if * it's non-NULL and in the list of choices. */ if (navinfo->referring_iid != NULL) { - if (g_list_find_custom (navinfo->content_identifiers, - navinfo->referring_iid, check_iid)) { - value = navinfo->referring_iid; + node = g_list_find_custom (navinfo->content_identifiers, + navinfo->referring_iid, check_iid); + if (node != NULL) { + new_id = node->data; } } /* Can't use remembered or referring value, use fallback value. */ - if (value == NULL) { - value = fallback_value; + if (new_id == NULL) { + new_id = fallback_view_id; } } - navinfo->initial_content_iid = g_strdup (value); + navinfo->initial_content_id = nautilus_view_identifier_copy (new_id); g_free (remembered_value); } @@ -194,7 +199,7 @@ got_file_info_callback (GnomeVFSAsyncHandle *ah, NautilusNavigationCallback notify_ready; gpointer notify_ready_data; NautilusNavigationResult result_code; - const char *fallback_iid; + NautilusViewIdentifier *fallback_id; GList *components; GList *p; OAF_ServerInfo *default_component; @@ -232,14 +237,17 @@ got_file_info_callback (GnomeVFSAsyncHandle *ah, gnome_vfs_mime_component_list_free (components); - /* FIXME: should also merge the default into - navinfo->content_identifiers if not already there */ - default_component = nautilus_mime_get_default_component_for_uri (navinfo->navinfo.requested_uri); if (default_component != NULL) { - fallback_iid = g_strdup (default_component->iid); - + fallback_id = nautilus_view_identifier_new_from_content_view (default_component); + + /* FIXME: This merges the default component into the list if it + * wasn't already there. This might not be the right thing to do + * since the View As menu already handles the case where the current + * view is not in the standard list. I don't know when this case happens + * in practice though. + */ if (g_list_find_custom (navinfo->content_identifiers, default_component->iid, (GCompareFunc) view_identifier_has_iid) == NULL) { navinfo->content_identifiers = g_list_insert_sorted @@ -249,15 +257,13 @@ got_file_info_callback (GnomeVFSAsyncHandle *ah, } CORBA_free (default_component); - } else { - if (navinfo->content_identifiers != NULL) { - fallback_iid = ((NautilusViewIdentifier *) - (navinfo->content_identifiers->data))->iid; - } + } else if (navinfo->content_identifiers != NULL) { + /* No default component, just take first one from list. */ + fallback_id = nautilus_view_identifier_copy (navinfo->content_identifiers->data); } #ifdef DEBUG_MJS - printf ("XXXXXX - fallback_iid: %s\n", fallback_iid); + printf ("XXXXXX - fallback_id: %s (%s)\n", fallback_id->iid, fallback_id->name); #endif if (navinfo->content_identifiers != NULL) { @@ -277,8 +283,9 @@ got_file_info_callback (GnomeVFSAsyncHandle *ah, /* Now that all the content_identifiers are in place, we're ready to choose * the initial one. */ - g_assert (fallback_iid != NULL); - set_initial_content_iid (navinfo, fallback_iid); + g_assert (fallback_id != NULL); + set_initial_content_id (navinfo, fallback_id); + nautilus_view_identifier_free (fallback_id); out: (* notify_ready) (result_code, navinfo, notify_ready_data); @@ -371,8 +378,8 @@ nautilus_navigation_info_free (NautilusNavigationInfo *info) nautilus_view_identifier_list_free (info->content_identifiers); nautilus_g_list_free_deep (info->explicit_iids); + nautilus_view_identifier_free (info->initial_content_id); g_free (info->referring_iid); - g_free (info->initial_content_iid); g_free (info->navinfo.requested_uri); g_free (info->navinfo.actual_uri); g_free (info->navinfo.content_type); diff --git a/src/nautilus-applicable-views.h b/src/nautilus-applicable-views.h index 3eab81985..4cb88c8d0 100644 --- a/src/nautilus-applicable-views.h +++ b/src/nautilus-applicable-views.h @@ -32,6 +32,7 @@ #include <libgnomevfs/gnome-vfs-types.h> #include <libnautilus/nautilus-view-component.h> #include <libnautilus-extensions/nautilus-directory.h> +#include <libnautilus-extensions/nautilus-view-identifier.h> typedef struct NautilusNavigationInfo NautilusNavigationInfo; @@ -57,11 +58,11 @@ typedef void (*NautilusNavigationCallback) (NautilusNavigationResult result, struct NautilusNavigationInfo { Nautilus_NavigationInfo navinfo; - char *referring_iid; /* iid of content view that we're coming from */ - char *initial_content_iid; /* iid to use for content view that we're going to display */ - GList *content_identifiers; /* list of NautilusViewIdentifiers */ - GList *files; /* NautilusFile's for files in the dir, if it is one. */ - GList *explicit_iids; /* IIDs explicitly mentioned in the metafile. */ + char *referring_iid; /* iid of content view that we're coming from */ + NautilusViewIdentifier *initial_content_id; /* NautilusViewIdentifier for content view that we're going to display */ + GList *content_identifiers; /* list of NautilusViewIdentifiers */ + GList *files; /* NautilusFile's for files in the dir, if it is one. */ + GList *explicit_iids; /* IIDs explicitly mentioned in the metafile. */ /* internal usage */ NautilusNavigationCallback callback; diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index 92b707df2..1b54db3b2 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -50,7 +50,6 @@ #include <libnautilus-extensions/nautilus-metadata.h> #include <libnautilus-extensions/nautilus-program-choosing.h> #include <libnautilus-extensions/nautilus-string.h> -#include <libnautilus-extensions/nautilus-view-identifier.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> #include <libnautilus/nautilus-undo-manager.h> @@ -533,6 +532,8 @@ nautilus_window_destroy (NautilusWindow *window) nautilus_window_toolbar_remove_theme_callback(); g_list_free (window->sidebar_panels); + + nautilus_view_identifier_free (window->content_view_id); CORBA_free (window->ni); CORBA_free (window->si); @@ -664,31 +665,117 @@ nautilus_window_realize (GtkWidget *widget) */ static void -nautilus_window_switch_views (NautilusWindow *window, const char *iid) +nautilus_window_switch_views (NautilusWindow *window, NautilusViewIdentifier *id) { NautilusDirectory *directory; NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_WINDOW (window)->ni != NULL); - g_return_if_fail (iid != NULL); + g_return_if_fail (id != NULL); directory = nautilus_directory_get (window->ni->requested_uri); g_assert (directory != NULL); nautilus_directory_set_metadata (directory, NAUTILUS_METADATA_KEY_INITIAL_VIEW, NULL, - iid); + id->iid); nautilus_directory_unref (directory); nautilus_window_allow_stop (window, TRUE); - view = nautilus_window_load_content_view (window, iid, window->ni, NULL); + view = nautilus_window_load_content_view (window, id, window->ni, NULL); nautilus_window_set_state_info (window, (NautilusWindowStateItem)NEW_CONTENT_VIEW_ACTIVATED, view, (NautilusWindowStateItem)0); } +static void +view_menu_switch_views_callback (GtkWidget *widget, gpointer data) +{ + NautilusWindow *window; + NautilusViewIdentifier *identifier; + + g_return_if_fail (GTK_IS_MENU_ITEM (widget)); + g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); + + window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); + identifier = (NautilusViewIdentifier *)gtk_object_get_data (GTK_OBJECT (widget), "identifier"); + + nautilus_window_switch_views (window, identifier); +} + +static GtkWidget * +create_content_view_menu_item (NautilusWindow *window, NautilusViewIdentifier *identifier) +{ + GtkWidget *menu_item; + char *menu_label; + + menu_label = g_strdup_printf (_("View as %s"), identifier->name); + menu_item = gtk_menu_item_new_with_label (menu_label); + g_free (menu_label); + + gtk_signal_connect + (GTK_OBJECT (menu_item), + "activate", + GTK_SIGNAL_FUNC (view_menu_switch_views_callback), + NULL); + + /* Store copy of iid in item; free when item destroyed. */ + gtk_object_set_data_full (GTK_OBJECT (menu_item), + "identifier", + nautilus_view_identifier_copy (identifier), + (GtkDestroyNotify) nautilus_view_identifier_free); + + /* Store reference to window in item; no need to free this. */ + gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + gtk_widget_show (menu_item); + + return menu_item; +} + +/* Make a special first item in the "View as" option menu that represents + * the current content view. This should only be called if the current + * content view isn't already in the "View as" option menu. + */ +static void +replace_special_current_view_in_content_view_menu (NautilusWindow *window) +{ + GList *menu_item_list; + GtkWidget *menu; + GtkWidget *first_menu_item; + GtkWidget *new_menu_item; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + /* Remove menu before changing contents so it is resized properly + * when reattached later in this function. + */ + gtk_widget_ref (menu); + gtk_option_menu_remove_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + menu_item_list = gtk_container_children (GTK_CONTAINER (menu)); + first_menu_item = GTK_WIDGET (menu_item_list->data); + g_list_free (menu_item_list); + + if (GPOINTER_TO_INT (gtk_object_get_data + (GTK_OBJECT (first_menu_item), "current content view")) == TRUE) { + gtk_container_remove (GTK_CONTAINER (menu), first_menu_item); + } else { + /* Prepend separator. */ + new_menu_item = gtk_menu_item_new (); + gtk_widget_show (new_menu_item); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + } + + new_menu_item = create_content_view_menu_item (window, window->content_view_id); + gtk_object_set_data (GTK_OBJECT (new_menu_item), "current content view", GINT_TO_POINTER (TRUE)); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), menu); + gtk_widget_unref (menu); +} + /** * nautilus_window_synch_content_view_menu: * @@ -702,7 +789,7 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) { GList *children, *child; GtkWidget *menu; - const char *item_iid; + NautilusViewIdentifier *item_id; int index, matching_index; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -711,24 +798,26 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) if (menu == NULL) { return; } + children = gtk_container_children (GTK_CONTAINER (menu)); matching_index = -1; for (child = children, index = 0; child != NULL; child = child->next, ++index) { - item_iid = (const char *)(gtk_object_get_data (GTK_OBJECT (child->data), "iid")); - if (nautilus_strcmp (window->content_view->iid, item_iid) == 0) { + item_id = (NautilusViewIdentifier *)(gtk_object_get_data (GTK_OBJECT (child->data), "identifier")); + if (item_id != NULL && strcmp (window->content_view->iid, item_id->iid) == 0) { matching_index = index; break; } } - if (matching_index != -1) { - gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), - matching_index); - } else { - g_warning ("In nautilus_window_synch_content_view_menu, couldn't find matching menu item."); + if (matching_index == -1) { + replace_special_current_view_in_content_view_menu (window); + matching_index = 0; } + gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), + matching_index); + g_list_free (children); } @@ -738,9 +827,7 @@ chose_component_callback (NautilusViewIdentifier *identifier, gpointer callback_ g_return_if_fail (NAUTILUS_IS_WINDOW (callback_data)); if (identifier != NULL) { - /* FIXME: Need to add menu item for new identifier to "View as" menu. */ - /* FIXME: After switching, option menu doesn't synch to new value. */ - nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier->iid); + nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier); } } @@ -774,21 +861,6 @@ view_menu_choose_view_callback (GtkWidget *widget, gpointer data) nautilus_file_unref (file); } -static void -view_menu_switch_views_callback (GtkWidget *widget, gpointer data) -{ - NautilusWindow *window; - const char *iid; - - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); - - window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); - iid = (const char *)gtk_object_get_data (GTK_OBJECT (widget), "iid"); - - nautilus_window_switch_views (window, iid); -} - void nautilus_window_load_content_view_menu (NautilusWindow *window, NautilusNavigationInfo *ni) @@ -797,8 +869,6 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, GtkWidget *new_menu; int index; GtkWidget *menu_item; - NautilusViewIdentifier *identifier; - char *menu_label; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (GTK_IS_OPTION_MENU (window->view_as_option_menu)); @@ -809,27 +879,8 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, /* Add a menu item for each available content view type */ index = 0; for (p = ni->content_identifiers; p != NULL; p = p->next) { - identifier = (NautilusViewIdentifier *) p->data; - menu_label = g_strdup_printf (_("View as %s"), identifier->name); - menu_item = gtk_menu_item_new_with_label (menu_label); - g_free (menu_label); - - gtk_signal_connect - (GTK_OBJECT (menu_item), - "activate", - GTK_SIGNAL_FUNC (view_menu_switch_views_callback), - NULL); - - /* Store copy of iid in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (identifier->iid), - g_free); - - /* Store reference to window in item; no need to free this. */ - gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + menu_item = create_content_view_menu_item (window, (NautilusViewIdentifier *) p->data); gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); ++index; } diff --git a/src/nautilus-navigation-window.h b/src/nautilus-navigation-window.h index 6775fb4f5..64ee4dea7 100644 --- a/src/nautilus-navigation-window.h +++ b/src/nautilus-navigation-window.h @@ -31,6 +31,7 @@ #include <libgnomeui/gnome-app.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> #include <libnautilus-extensions/nautilus-bookmark.h> +#include <libnautilus-extensions/nautilus-view-identifier.h> #include "nautilus-applicable-views.h" #include "nautilus-view-frame.h" #include "nautilus-sidebar.h" @@ -93,6 +94,7 @@ struct _NautilusWindow { /* Current views stuff */ NautilusViewFrame *content_view; + NautilusViewIdentifier *content_view_id; GList *sidebar_panels; /* Widgets to keep track of (for state changes, etc) */ diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index 92b707df2..1b54db3b2 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -50,7 +50,6 @@ #include <libnautilus-extensions/nautilus-metadata.h> #include <libnautilus-extensions/nautilus-program-choosing.h> #include <libnautilus-extensions/nautilus-string.h> -#include <libnautilus-extensions/nautilus-view-identifier.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> #include <libnautilus/nautilus-undo-manager.h> @@ -533,6 +532,8 @@ nautilus_window_destroy (NautilusWindow *window) nautilus_window_toolbar_remove_theme_callback(); g_list_free (window->sidebar_panels); + + nautilus_view_identifier_free (window->content_view_id); CORBA_free (window->ni); CORBA_free (window->si); @@ -664,31 +665,117 @@ nautilus_window_realize (GtkWidget *widget) */ static void -nautilus_window_switch_views (NautilusWindow *window, const char *iid) +nautilus_window_switch_views (NautilusWindow *window, NautilusViewIdentifier *id) { NautilusDirectory *directory; NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_WINDOW (window)->ni != NULL); - g_return_if_fail (iid != NULL); + g_return_if_fail (id != NULL); directory = nautilus_directory_get (window->ni->requested_uri); g_assert (directory != NULL); nautilus_directory_set_metadata (directory, NAUTILUS_METADATA_KEY_INITIAL_VIEW, NULL, - iid); + id->iid); nautilus_directory_unref (directory); nautilus_window_allow_stop (window, TRUE); - view = nautilus_window_load_content_view (window, iid, window->ni, NULL); + view = nautilus_window_load_content_view (window, id, window->ni, NULL); nautilus_window_set_state_info (window, (NautilusWindowStateItem)NEW_CONTENT_VIEW_ACTIVATED, view, (NautilusWindowStateItem)0); } +static void +view_menu_switch_views_callback (GtkWidget *widget, gpointer data) +{ + NautilusWindow *window; + NautilusViewIdentifier *identifier; + + g_return_if_fail (GTK_IS_MENU_ITEM (widget)); + g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); + + window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); + identifier = (NautilusViewIdentifier *)gtk_object_get_data (GTK_OBJECT (widget), "identifier"); + + nautilus_window_switch_views (window, identifier); +} + +static GtkWidget * +create_content_view_menu_item (NautilusWindow *window, NautilusViewIdentifier *identifier) +{ + GtkWidget *menu_item; + char *menu_label; + + menu_label = g_strdup_printf (_("View as %s"), identifier->name); + menu_item = gtk_menu_item_new_with_label (menu_label); + g_free (menu_label); + + gtk_signal_connect + (GTK_OBJECT (menu_item), + "activate", + GTK_SIGNAL_FUNC (view_menu_switch_views_callback), + NULL); + + /* Store copy of iid in item; free when item destroyed. */ + gtk_object_set_data_full (GTK_OBJECT (menu_item), + "identifier", + nautilus_view_identifier_copy (identifier), + (GtkDestroyNotify) nautilus_view_identifier_free); + + /* Store reference to window in item; no need to free this. */ + gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + gtk_widget_show (menu_item); + + return menu_item; +} + +/* Make a special first item in the "View as" option menu that represents + * the current content view. This should only be called if the current + * content view isn't already in the "View as" option menu. + */ +static void +replace_special_current_view_in_content_view_menu (NautilusWindow *window) +{ + GList *menu_item_list; + GtkWidget *menu; + GtkWidget *first_menu_item; + GtkWidget *new_menu_item; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + /* Remove menu before changing contents so it is resized properly + * when reattached later in this function. + */ + gtk_widget_ref (menu); + gtk_option_menu_remove_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + menu_item_list = gtk_container_children (GTK_CONTAINER (menu)); + first_menu_item = GTK_WIDGET (menu_item_list->data); + g_list_free (menu_item_list); + + if (GPOINTER_TO_INT (gtk_object_get_data + (GTK_OBJECT (first_menu_item), "current content view")) == TRUE) { + gtk_container_remove (GTK_CONTAINER (menu), first_menu_item); + } else { + /* Prepend separator. */ + new_menu_item = gtk_menu_item_new (); + gtk_widget_show (new_menu_item); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + } + + new_menu_item = create_content_view_menu_item (window, window->content_view_id); + gtk_object_set_data (GTK_OBJECT (new_menu_item), "current content view", GINT_TO_POINTER (TRUE)); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), menu); + gtk_widget_unref (menu); +} + /** * nautilus_window_synch_content_view_menu: * @@ -702,7 +789,7 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) { GList *children, *child; GtkWidget *menu; - const char *item_iid; + NautilusViewIdentifier *item_id; int index, matching_index; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -711,24 +798,26 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) if (menu == NULL) { return; } + children = gtk_container_children (GTK_CONTAINER (menu)); matching_index = -1; for (child = children, index = 0; child != NULL; child = child->next, ++index) { - item_iid = (const char *)(gtk_object_get_data (GTK_OBJECT (child->data), "iid")); - if (nautilus_strcmp (window->content_view->iid, item_iid) == 0) { + item_id = (NautilusViewIdentifier *)(gtk_object_get_data (GTK_OBJECT (child->data), "identifier")); + if (item_id != NULL && strcmp (window->content_view->iid, item_id->iid) == 0) { matching_index = index; break; } } - if (matching_index != -1) { - gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), - matching_index); - } else { - g_warning ("In nautilus_window_synch_content_view_menu, couldn't find matching menu item."); + if (matching_index == -1) { + replace_special_current_view_in_content_view_menu (window); + matching_index = 0; } + gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), + matching_index); + g_list_free (children); } @@ -738,9 +827,7 @@ chose_component_callback (NautilusViewIdentifier *identifier, gpointer callback_ g_return_if_fail (NAUTILUS_IS_WINDOW (callback_data)); if (identifier != NULL) { - /* FIXME: Need to add menu item for new identifier to "View as" menu. */ - /* FIXME: After switching, option menu doesn't synch to new value. */ - nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier->iid); + nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier); } } @@ -774,21 +861,6 @@ view_menu_choose_view_callback (GtkWidget *widget, gpointer data) nautilus_file_unref (file); } -static void -view_menu_switch_views_callback (GtkWidget *widget, gpointer data) -{ - NautilusWindow *window; - const char *iid; - - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); - - window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); - iid = (const char *)gtk_object_get_data (GTK_OBJECT (widget), "iid"); - - nautilus_window_switch_views (window, iid); -} - void nautilus_window_load_content_view_menu (NautilusWindow *window, NautilusNavigationInfo *ni) @@ -797,8 +869,6 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, GtkWidget *new_menu; int index; GtkWidget *menu_item; - NautilusViewIdentifier *identifier; - char *menu_label; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (GTK_IS_OPTION_MENU (window->view_as_option_menu)); @@ -809,27 +879,8 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, /* Add a menu item for each available content view type */ index = 0; for (p = ni->content_identifiers; p != NULL; p = p->next) { - identifier = (NautilusViewIdentifier *) p->data; - menu_label = g_strdup_printf (_("View as %s"), identifier->name); - menu_item = gtk_menu_item_new_with_label (menu_label); - g_free (menu_label); - - gtk_signal_connect - (GTK_OBJECT (menu_item), - "activate", - GTK_SIGNAL_FUNC (view_menu_switch_views_callback), - NULL); - - /* Store copy of iid in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (identifier->iid), - g_free); - - /* Store reference to window in item; no need to free this. */ - gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + menu_item = create_content_view_menu_item (window, (NautilusViewIdentifier *) p->data); gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); ++index; } diff --git a/src/nautilus-object-window.h b/src/nautilus-object-window.h index 6775fb4f5..64ee4dea7 100644 --- a/src/nautilus-object-window.h +++ b/src/nautilus-object-window.h @@ -31,6 +31,7 @@ #include <libgnomeui/gnome-app.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> #include <libnautilus-extensions/nautilus-bookmark.h> +#include <libnautilus-extensions/nautilus-view-identifier.h> #include "nautilus-applicable-views.h" #include "nautilus-view-frame.h" #include "nautilus-sidebar.h" @@ -93,6 +94,7 @@ struct _NautilusWindow { /* Current views stuff */ NautilusViewFrame *content_view; + NautilusViewIdentifier *content_view_id; GList *sidebar_panels; /* Widgets to keep track of (for state changes, etc) */ diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index 92b707df2..1b54db3b2 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -50,7 +50,6 @@ #include <libnautilus-extensions/nautilus-metadata.h> #include <libnautilus-extensions/nautilus-program-choosing.h> #include <libnautilus-extensions/nautilus-string.h> -#include <libnautilus-extensions/nautilus-view-identifier.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> #include <libnautilus/nautilus-undo-manager.h> @@ -533,6 +532,8 @@ nautilus_window_destroy (NautilusWindow *window) nautilus_window_toolbar_remove_theme_callback(); g_list_free (window->sidebar_panels); + + nautilus_view_identifier_free (window->content_view_id); CORBA_free (window->ni); CORBA_free (window->si); @@ -664,31 +665,117 @@ nautilus_window_realize (GtkWidget *widget) */ static void -nautilus_window_switch_views (NautilusWindow *window, const char *iid) +nautilus_window_switch_views (NautilusWindow *window, NautilusViewIdentifier *id) { NautilusDirectory *directory; NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_WINDOW (window)->ni != NULL); - g_return_if_fail (iid != NULL); + g_return_if_fail (id != NULL); directory = nautilus_directory_get (window->ni->requested_uri); g_assert (directory != NULL); nautilus_directory_set_metadata (directory, NAUTILUS_METADATA_KEY_INITIAL_VIEW, NULL, - iid); + id->iid); nautilus_directory_unref (directory); nautilus_window_allow_stop (window, TRUE); - view = nautilus_window_load_content_view (window, iid, window->ni, NULL); + view = nautilus_window_load_content_view (window, id, window->ni, NULL); nautilus_window_set_state_info (window, (NautilusWindowStateItem)NEW_CONTENT_VIEW_ACTIVATED, view, (NautilusWindowStateItem)0); } +static void +view_menu_switch_views_callback (GtkWidget *widget, gpointer data) +{ + NautilusWindow *window; + NautilusViewIdentifier *identifier; + + g_return_if_fail (GTK_IS_MENU_ITEM (widget)); + g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); + + window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); + identifier = (NautilusViewIdentifier *)gtk_object_get_data (GTK_OBJECT (widget), "identifier"); + + nautilus_window_switch_views (window, identifier); +} + +static GtkWidget * +create_content_view_menu_item (NautilusWindow *window, NautilusViewIdentifier *identifier) +{ + GtkWidget *menu_item; + char *menu_label; + + menu_label = g_strdup_printf (_("View as %s"), identifier->name); + menu_item = gtk_menu_item_new_with_label (menu_label); + g_free (menu_label); + + gtk_signal_connect + (GTK_OBJECT (menu_item), + "activate", + GTK_SIGNAL_FUNC (view_menu_switch_views_callback), + NULL); + + /* Store copy of iid in item; free when item destroyed. */ + gtk_object_set_data_full (GTK_OBJECT (menu_item), + "identifier", + nautilus_view_identifier_copy (identifier), + (GtkDestroyNotify) nautilus_view_identifier_free); + + /* Store reference to window in item; no need to free this. */ + gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + gtk_widget_show (menu_item); + + return menu_item; +} + +/* Make a special first item in the "View as" option menu that represents + * the current content view. This should only be called if the current + * content view isn't already in the "View as" option menu. + */ +static void +replace_special_current_view_in_content_view_menu (NautilusWindow *window) +{ + GList *menu_item_list; + GtkWidget *menu; + GtkWidget *first_menu_item; + GtkWidget *new_menu_item; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + /* Remove menu before changing contents so it is resized properly + * when reattached later in this function. + */ + gtk_widget_ref (menu); + gtk_option_menu_remove_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + menu_item_list = gtk_container_children (GTK_CONTAINER (menu)); + first_menu_item = GTK_WIDGET (menu_item_list->data); + g_list_free (menu_item_list); + + if (GPOINTER_TO_INT (gtk_object_get_data + (GTK_OBJECT (first_menu_item), "current content view")) == TRUE) { + gtk_container_remove (GTK_CONTAINER (menu), first_menu_item); + } else { + /* Prepend separator. */ + new_menu_item = gtk_menu_item_new (); + gtk_widget_show (new_menu_item); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + } + + new_menu_item = create_content_view_menu_item (window, window->content_view_id); + gtk_object_set_data (GTK_OBJECT (new_menu_item), "current content view", GINT_TO_POINTER (TRUE)); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), menu); + gtk_widget_unref (menu); +} + /** * nautilus_window_synch_content_view_menu: * @@ -702,7 +789,7 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) { GList *children, *child; GtkWidget *menu; - const char *item_iid; + NautilusViewIdentifier *item_id; int index, matching_index; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -711,24 +798,26 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) if (menu == NULL) { return; } + children = gtk_container_children (GTK_CONTAINER (menu)); matching_index = -1; for (child = children, index = 0; child != NULL; child = child->next, ++index) { - item_iid = (const char *)(gtk_object_get_data (GTK_OBJECT (child->data), "iid")); - if (nautilus_strcmp (window->content_view->iid, item_iid) == 0) { + item_id = (NautilusViewIdentifier *)(gtk_object_get_data (GTK_OBJECT (child->data), "identifier")); + if (item_id != NULL && strcmp (window->content_view->iid, item_id->iid) == 0) { matching_index = index; break; } } - if (matching_index != -1) { - gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), - matching_index); - } else { - g_warning ("In nautilus_window_synch_content_view_menu, couldn't find matching menu item."); + if (matching_index == -1) { + replace_special_current_view_in_content_view_menu (window); + matching_index = 0; } + gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), + matching_index); + g_list_free (children); } @@ -738,9 +827,7 @@ chose_component_callback (NautilusViewIdentifier *identifier, gpointer callback_ g_return_if_fail (NAUTILUS_IS_WINDOW (callback_data)); if (identifier != NULL) { - /* FIXME: Need to add menu item for new identifier to "View as" menu. */ - /* FIXME: After switching, option menu doesn't synch to new value. */ - nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier->iid); + nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier); } } @@ -774,21 +861,6 @@ view_menu_choose_view_callback (GtkWidget *widget, gpointer data) nautilus_file_unref (file); } -static void -view_menu_switch_views_callback (GtkWidget *widget, gpointer data) -{ - NautilusWindow *window; - const char *iid; - - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); - - window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); - iid = (const char *)gtk_object_get_data (GTK_OBJECT (widget), "iid"); - - nautilus_window_switch_views (window, iid); -} - void nautilus_window_load_content_view_menu (NautilusWindow *window, NautilusNavigationInfo *ni) @@ -797,8 +869,6 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, GtkWidget *new_menu; int index; GtkWidget *menu_item; - NautilusViewIdentifier *identifier; - char *menu_label; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (GTK_IS_OPTION_MENU (window->view_as_option_menu)); @@ -809,27 +879,8 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, /* Add a menu item for each available content view type */ index = 0; for (p = ni->content_identifiers; p != NULL; p = p->next) { - identifier = (NautilusViewIdentifier *) p->data; - menu_label = g_strdup_printf (_("View as %s"), identifier->name); - menu_item = gtk_menu_item_new_with_label (menu_label); - g_free (menu_label); - - gtk_signal_connect - (GTK_OBJECT (menu_item), - "activate", - GTK_SIGNAL_FUNC (view_menu_switch_views_callback), - NULL); - - /* Store copy of iid in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (identifier->iid), - g_free); - - /* Store reference to window in item; no need to free this. */ - gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + menu_item = create_content_view_menu_item (window, (NautilusViewIdentifier *) p->data); gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); ++index; } diff --git a/src/nautilus-spatial-window.h b/src/nautilus-spatial-window.h index 6775fb4f5..64ee4dea7 100644 --- a/src/nautilus-spatial-window.h +++ b/src/nautilus-spatial-window.h @@ -31,6 +31,7 @@ #include <libgnomeui/gnome-app.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> #include <libnautilus-extensions/nautilus-bookmark.h> +#include <libnautilus-extensions/nautilus-view-identifier.h> #include "nautilus-applicable-views.h" #include "nautilus-view-frame.h" #include "nautilus-sidebar.h" @@ -93,6 +94,7 @@ struct _NautilusWindow { /* Current views stuff */ NautilusViewFrame *content_view; + NautilusViewIdentifier *content_view_id; GList *sidebar_panels; /* Widgets to keep track of (for state changes, etc) */ diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c index 1864a7d80..63fa314c5 100644 --- a/src/nautilus-window-manage-views.c +++ b/src/nautilus-window-manage-views.c @@ -43,7 +43,6 @@ #include <libnautilus-extensions/nautilus-string.h> #include <libnautilus-extensions/nautilus-gtk-extensions.h> #include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus-extensions/nautilus-view-identifier.h> #include <libnautilus-extensions/nautilus-global-preferences.h> #include "nautilus-application.h" #include "nautilus-applicable-views.h" @@ -683,7 +682,7 @@ nautilus_window_request_location_change (NautilusWindow *window, NautilusViewFrame * nautilus_window_load_content_view (NautilusWindow *window, - const char *iid, + NautilusViewIdentifier *id, Nautilus_NavigationInfo *navinfo, NautilusViewFrame **requesting_view) { @@ -691,11 +690,11 @@ nautilus_window_load_content_view (NautilusWindow *window, NautilusViewFrame *new_view; CORBA_Environment environment; - g_return_val_if_fail(iid, NULL); + g_return_val_if_fail(id, NULL); g_return_val_if_fail(navinfo, NULL); if (!NAUTILUS_IS_VIEW_FRAME (content_view) - || strcmp (nautilus_view_frame_get_iid (content_view), iid) != 0) { + || strcmp (nautilus_view_frame_get_iid (content_view), id->iid) != 0) { if (requesting_view != NULL && *requesting_view == window->content_view) { /* If we are going to be zapping the old view, @@ -710,7 +709,7 @@ nautilus_window_load_content_view (NautilusWindow *window, nautilus_window_connect_content_view (window, new_view); - if (!nautilus_view_frame_load_client (new_view, iid)) { + if (!nautilus_view_frame_load_client (new_view, id->iid)) { gtk_widget_unref(GTK_WIDGET(new_view)); new_view = NULL; } @@ -734,6 +733,9 @@ nautilus_window_load_content_view (NautilusWindow *window, (nautilus_view_frame_get_client_objref (new_view), &environment); CORBA_exception_free(&environment); + + nautilus_view_identifier_free (window->content_view_id); + window->content_view_id = nautilus_view_identifier_copy (id); nautilus_view_frame_set_active_errors (new_view, TRUE); } @@ -862,7 +864,7 @@ nautilus_window_update_state (gpointer data) GList *sidebar_panel_identifiers = NULL; window->new_content_view = nautilus_window_load_content_view - (window, window->pending_ni->initial_content_iid, + (window, window->pending_ni->initial_content_id, &window->pending_ni->navinfo, &window->new_requesting_view); diff --git a/src/nautilus-window-private.h b/src/nautilus-window-private.h index eaeb9131b..96c6d91eb 100644 --- a/src/nautilus-window-private.h +++ b/src/nautilus-window-private.h @@ -45,7 +45,7 @@ void nautilus_window_begin_location_change(NautilusWindow *window, void nautilus_window_load_content_view_menu (NautilusWindow *window, NautilusNavigationInfo *ni); void nautilus_window_synch_content_view_menu (NautilusWindow *window); NautilusViewFrame *nautilus_window_load_content_view(NautilusWindow *window, - const char *iid, + NautilusViewIdentifier *id, Nautilus_NavigationInfo *navinfo, NautilusViewFrame **requesting_view); void nautilus_window_connect_content_view (NautilusWindow *window, diff --git a/src/nautilus-window.c b/src/nautilus-window.c index 92b707df2..1b54db3b2 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -50,7 +50,6 @@ #include <libnautilus-extensions/nautilus-metadata.h> #include <libnautilus-extensions/nautilus-program-choosing.h> #include <libnautilus-extensions/nautilus-string.h> -#include <libnautilus-extensions/nautilus-view-identifier.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> #include <libnautilus/nautilus-undo-manager.h> @@ -533,6 +532,8 @@ nautilus_window_destroy (NautilusWindow *window) nautilus_window_toolbar_remove_theme_callback(); g_list_free (window->sidebar_panels); + + nautilus_view_identifier_free (window->content_view_id); CORBA_free (window->ni); CORBA_free (window->si); @@ -664,31 +665,117 @@ nautilus_window_realize (GtkWidget *widget) */ static void -nautilus_window_switch_views (NautilusWindow *window, const char *iid) +nautilus_window_switch_views (NautilusWindow *window, NautilusViewIdentifier *id) { NautilusDirectory *directory; NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_WINDOW (window)->ni != NULL); - g_return_if_fail (iid != NULL); + g_return_if_fail (id != NULL); directory = nautilus_directory_get (window->ni->requested_uri); g_assert (directory != NULL); nautilus_directory_set_metadata (directory, NAUTILUS_METADATA_KEY_INITIAL_VIEW, NULL, - iid); + id->iid); nautilus_directory_unref (directory); nautilus_window_allow_stop (window, TRUE); - view = nautilus_window_load_content_view (window, iid, window->ni, NULL); + view = nautilus_window_load_content_view (window, id, window->ni, NULL); nautilus_window_set_state_info (window, (NautilusWindowStateItem)NEW_CONTENT_VIEW_ACTIVATED, view, (NautilusWindowStateItem)0); } +static void +view_menu_switch_views_callback (GtkWidget *widget, gpointer data) +{ + NautilusWindow *window; + NautilusViewIdentifier *identifier; + + g_return_if_fail (GTK_IS_MENU_ITEM (widget)); + g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); + + window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); + identifier = (NautilusViewIdentifier *)gtk_object_get_data (GTK_OBJECT (widget), "identifier"); + + nautilus_window_switch_views (window, identifier); +} + +static GtkWidget * +create_content_view_menu_item (NautilusWindow *window, NautilusViewIdentifier *identifier) +{ + GtkWidget *menu_item; + char *menu_label; + + menu_label = g_strdup_printf (_("View as %s"), identifier->name); + menu_item = gtk_menu_item_new_with_label (menu_label); + g_free (menu_label); + + gtk_signal_connect + (GTK_OBJECT (menu_item), + "activate", + GTK_SIGNAL_FUNC (view_menu_switch_views_callback), + NULL); + + /* Store copy of iid in item; free when item destroyed. */ + gtk_object_set_data_full (GTK_OBJECT (menu_item), + "identifier", + nautilus_view_identifier_copy (identifier), + (GtkDestroyNotify) nautilus_view_identifier_free); + + /* Store reference to window in item; no need to free this. */ + gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + gtk_widget_show (menu_item); + + return menu_item; +} + +/* Make a special first item in the "View as" option menu that represents + * the current content view. This should only be called if the current + * content view isn't already in the "View as" option menu. + */ +static void +replace_special_current_view_in_content_view_menu (NautilusWindow *window) +{ + GList *menu_item_list; + GtkWidget *menu; + GtkWidget *first_menu_item; + GtkWidget *new_menu_item; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + /* Remove menu before changing contents so it is resized properly + * when reattached later in this function. + */ + gtk_widget_ref (menu); + gtk_option_menu_remove_menu (GTK_OPTION_MENU (window->view_as_option_menu)); + + menu_item_list = gtk_container_children (GTK_CONTAINER (menu)); + first_menu_item = GTK_WIDGET (menu_item_list->data); + g_list_free (menu_item_list); + + if (GPOINTER_TO_INT (gtk_object_get_data + (GTK_OBJECT (first_menu_item), "current content view")) == TRUE) { + gtk_container_remove (GTK_CONTAINER (menu), first_menu_item); + } else { + /* Prepend separator. */ + new_menu_item = gtk_menu_item_new (); + gtk_widget_show (new_menu_item); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + } + + new_menu_item = create_content_view_menu_item (window, window->content_view_id); + gtk_object_set_data (GTK_OBJECT (new_menu_item), "current content view", GINT_TO_POINTER (TRUE)); + gtk_menu_prepend (GTK_MENU (menu), new_menu_item); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), menu); + gtk_widget_unref (menu); +} + /** * nautilus_window_synch_content_view_menu: * @@ -702,7 +789,7 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) { GList *children, *child; GtkWidget *menu; - const char *item_iid; + NautilusViewIdentifier *item_id; int index, matching_index; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); @@ -711,24 +798,26 @@ nautilus_window_synch_content_view_menu (NautilusWindow *window) if (menu == NULL) { return; } + children = gtk_container_children (GTK_CONTAINER (menu)); matching_index = -1; for (child = children, index = 0; child != NULL; child = child->next, ++index) { - item_iid = (const char *)(gtk_object_get_data (GTK_OBJECT (child->data), "iid")); - if (nautilus_strcmp (window->content_view->iid, item_iid) == 0) { + item_id = (NautilusViewIdentifier *)(gtk_object_get_data (GTK_OBJECT (child->data), "identifier")); + if (item_id != NULL && strcmp (window->content_view->iid, item_id->iid) == 0) { matching_index = index; break; } } - if (matching_index != -1) { - gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), - matching_index); - } else { - g_warning ("In nautilus_window_synch_content_view_menu, couldn't find matching menu item."); + if (matching_index == -1) { + replace_special_current_view_in_content_view_menu (window); + matching_index = 0; } + gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), + matching_index); + g_list_free (children); } @@ -738,9 +827,7 @@ chose_component_callback (NautilusViewIdentifier *identifier, gpointer callback_ g_return_if_fail (NAUTILUS_IS_WINDOW (callback_data)); if (identifier != NULL) { - /* FIXME: Need to add menu item for new identifier to "View as" menu. */ - /* FIXME: After switching, option menu doesn't synch to new value. */ - nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier->iid); + nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier); } } @@ -774,21 +861,6 @@ view_menu_choose_view_callback (GtkWidget *widget, gpointer data) nautilus_file_unref (file); } -static void -view_menu_switch_views_callback (GtkWidget *widget, gpointer data) -{ - NautilusWindow *window; - const char *iid; - - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); - - window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); - iid = (const char *)gtk_object_get_data (GTK_OBJECT (widget), "iid"); - - nautilus_window_switch_views (window, iid); -} - void nautilus_window_load_content_view_menu (NautilusWindow *window, NautilusNavigationInfo *ni) @@ -797,8 +869,6 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, GtkWidget *new_menu; int index; GtkWidget *menu_item; - NautilusViewIdentifier *identifier; - char *menu_label; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (GTK_IS_OPTION_MENU (window->view_as_option_menu)); @@ -809,27 +879,8 @@ nautilus_window_load_content_view_menu (NautilusWindow *window, /* Add a menu item for each available content view type */ index = 0; for (p = ni->content_identifiers; p != NULL; p = p->next) { - identifier = (NautilusViewIdentifier *) p->data; - menu_label = g_strdup_printf (_("View as %s"), identifier->name); - menu_item = gtk_menu_item_new_with_label (menu_label); - g_free (menu_label); - - gtk_signal_connect - (GTK_OBJECT (menu_item), - "activate", - GTK_SIGNAL_FUNC (view_menu_switch_views_callback), - NULL); - - /* Store copy of iid in item; free when item destroyed. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), - "iid", - g_strdup (identifier->iid), - g_free); - - /* Store reference to window in item; no need to free this. */ - gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); + menu_item = create_content_view_menu_item (window, (NautilusViewIdentifier *) p->data); gtk_menu_append (GTK_MENU (new_menu), menu_item); - gtk_widget_show (menu_item); ++index; } diff --git a/src/nautilus-window.h b/src/nautilus-window.h index 6775fb4f5..64ee4dea7 100644 --- a/src/nautilus-window.h +++ b/src/nautilus-window.h @@ -31,6 +31,7 @@ #include <libgnomeui/gnome-app.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> #include <libnautilus-extensions/nautilus-bookmark.h> +#include <libnautilus-extensions/nautilus-view-identifier.h> #include "nautilus-applicable-views.h" #include "nautilus-view-frame.h" #include "nautilus-sidebar.h" @@ -93,6 +94,7 @@ struct _NautilusWindow { /* Current views stuff */ NautilusViewFrame *content_view; + NautilusViewIdentifier *content_view_id; GList *sidebar_panels; /* Widgets to keep track of (for state changes, etc) */ |