summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Sullivan <sullivan@src.gnome.org>2000-06-02 20:57:37 +0000
committerJohn Sullivan <sullivan@src.gnome.org>2000-06-02 20:57:37 +0000
commitaa407de891e029e72e96dc7d334f2abc1f05e932 (patch)
treed51326458600a619e620d4e44907b84bce6dcb71
parentbbb7d78b40297eb81bcb373fed63f0dea5cb7c10 (diff)
downloadnautilus-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--ChangeLog44
-rw-r--r--libnautilus-extensions/nautilus-view-identifier.c6
-rw-r--r--libnautilus-extensions/nautilus-view-identifier.h5
-rw-r--r--libnautilus-private/nautilus-view-identifier.c6
-rw-r--r--libnautilus-private/nautilus-view-identifier.h5
-rw-r--r--src/nautilus-applicable-views.c73
-rw-r--r--src/nautilus-applicable-views.h11
-rw-r--r--src/nautilus-navigation-window.c157
-rw-r--r--src/nautilus-navigation-window.h2
-rw-r--r--src/nautilus-object-window.c157
-rw-r--r--src/nautilus-object-window.h2
-rw-r--r--src/nautilus-spatial-window.c157
-rw-r--r--src/nautilus-spatial-window.h2
-rw-r--r--src/nautilus-window-manage-views.c14
-rw-r--r--src/nautilus-window-private.h2
-rw-r--r--src/nautilus-window.c157
-rw-r--r--src/nautilus-window.h2
17 files changed, 545 insertions, 257 deletions
diff --git a/ChangeLog b/ChangeLog
index 2f5ddaed0..751dbd224 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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) */