diff options
author | John Sullivan <sullivan@src.gnome.org> | 2000-02-18 17:53:21 +0000 |
---|---|---|
committer | John Sullivan <sullivan@src.gnome.org> | 2000-02-18 17:53:21 +0000 |
commit | 0653c1cccc33f7ffedf99b0041b41c1a773b8c94 (patch) | |
tree | 70b4ec7d8c3f1cc6e14e9825d8530ae096964bd6 | |
parent | aa3046861f47e81bab7e11a1a48a242b2fe5efff (diff) | |
download | nautilus-0653c1cccc33f7ffedf99b0041b41c1a773b8c94.tar.gz |
Made bookmarks display just file/directory name (instead of path) by default;
made history items appear in Go menu.
32 files changed, 1273 insertions, 101 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index fbbe97844..fbd315606 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,76 @@ +2000-02-18 John Sullivan <sullivan@eazel.com> + + Made bookmarks (including in history list) for file system + items display just the name of the file or directory instead + of the entire path. Made history list appear in Go menu. + Still need to muck with CORBA so that history metaview is + getting the history list from Nautilus rather than + maintaining its own parallel copy. + + * libnautilus/nautilus-bookmark.h: + (nautilus_bookmark_new_with_name): Renamed this function, which + takes both a uri and a display name, from nautilus_bookmark_new. + (nautilus_bookmark_new): New function, takes just a uri. + + * libnautilus/nautilus-bookmark.c: + (nautilus_boookmark_new_with_name): Renamed. + (nautilus_bookmark_new): New function, determines what initial + name to use for a bookmark given its uri. Right now the only rule + it knows is to use just the leaf file/directory name for file + system uris. (Someday it should also know to get the page title + for web uris.) + + * libnautilus/nautilus-bookmark.c, + * components/history/ntl-history-view.c, + * src/nautilus-bookmarklist.c, + * src/nautilus-bookmarks-menu.c, + * src/nautilus-bookmarks-window.c, + * src/ntl-window-msgs.c: + Updated callers of old nautilus_bookmark_new to either use new + one-parameter version or to use nautilus_bookmark_new_with_name. + + * libnautilus/nautilus-directory.c: (nautilus_self_check_directory): + Added new test that catches gnome-vfs bug I ran into where the name + computed for uris with a trailing slash is "". Maciej plans to fix + this in gnome-vfs; for now, make check catches it. + + * src/nautilus-signaller.c, + * src/nautilus-signaller.h: New files for an object that manages + nautilus-wide signals (not associated with a particular window, e.g.). + The initial nautilus-wide signal is "history_list_changed". + * src/Makefile.am: Build these two new files. + + * src/ntl-window.h: + Removed window_signals from NautilusWindowClass struct, made it a static + variable in the file to better hide it and match existing practice; + Added go_menu and go_menu_separator_item widgets to the set maintained + for each window. (This will have to change when I convert the menus + to using BonoboUIHandler, but that's for another day.) + * src/ntl-window.c: + I added then later removed a signal to this class. In the process, I + cleaned up some of the signal-handling details: Added an enum for + signal names (currently only LAST_SIGNAL); moved array of signals to + a static variable instead of field in Class struct; used LAST_SIGNAL + instead of 0 in (nautilus_window_class_init). + Added static history_list variable. Perhaps this and related functions + belong in their own file. + (nautilus_add_to_history_list): New function, updates global history + list and emits "history_list_changed" signal. + (clear_go_menu_history): New function, erase all the bookmark menu + items from the Go menu. + (activate_bookmark_in_menu_item): New function, go to the uri in the + bookmark stored as user data in the given menu item. + (history_list_changed_cb): New function, updates history section of + Go menu. + (nautilus_window_init): Connect history_list_changed_cb to + "history_list_changed" signal of nautilus_signaller object. + (nautilus_window_constructed): Stores away pointers to Go menu and + separator between static & dynamic parts of this menu. + * src/ntl-window-private.h: (nautilus_add_to_history_list): Prototype + for new function. + * src/ntl-window-msgs.c: (nautilus_window_update_internals): Call + nautilus_add_to_history_list with the new uri. + 2000-02-17 Andy Hertzfeld <andy@eazel.com> improved index panel command buttons. There's still a problem with the button box removal, though. diff --git a/components/history/nautilus-history-view.c b/components/history/nautilus-history-view.c index 0d2b7fad1..4380f6240 100644 --- a/components/history/nautilus-history-view.c +++ b/components/history/nautilus-history-view.c @@ -99,7 +99,7 @@ hyperbola_navigation_history_notify_location_change (NautilusViewFrame *view, clist = hview->clist; gtk_clist_freeze(clist); - bookmark = nautilus_bookmark_new (loci->requested_uri, loci->requested_uri); + bookmark = nautilus_bookmark_new (loci->requested_uri); /* If a bookmark for this location was already in list, remove it * (no duplicates in list, new one goes at top) diff --git a/components/history/ntl-history-view.c b/components/history/ntl-history-view.c index 0d2b7fad1..4380f6240 100644 --- a/components/history/ntl-history-view.c +++ b/components/history/ntl-history-view.c @@ -99,7 +99,7 @@ hyperbola_navigation_history_notify_location_change (NautilusViewFrame *view, clist = hview->clist; gtk_clist_freeze(clist); - bookmark = nautilus_bookmark_new (loci->requested_uri, loci->requested_uri); + bookmark = nautilus_bookmark_new (loci->requested_uri); /* If a bookmark for this location was already in list, remove it * (no duplicates in list, new one goes at top) diff --git a/libnautilus-extensions/nautilus-bookmark.c b/libnautilus-extensions/nautilus-bookmark.c index 5d50775d8..65dcd3932 100644 --- a/libnautilus-extensions/nautilus-bookmark.c +++ b/libnautilus-extensions/nautilus-bookmark.c @@ -24,6 +24,10 @@ #include "nautilus-bookmark.h" #include "nautilus-icon-factory.h" +#include "nautilus-string.h" + +#include <libgnomevfs/gnome-vfs-types.h> +#include <libgnomevfs/gnome-vfs-uri.h> struct _NautilusBookmarkDetails { @@ -153,9 +157,9 @@ nautilus_bookmark_copy (const NautilusBookmark *bookmark) { g_return_val_if_fail(NAUTILUS_IS_BOOKMARK (bookmark), NULL); - return nautilus_bookmark_new( - nautilus_bookmark_get_name(bookmark), - nautilus_bookmark_get_uri(bookmark)); + return nautilus_bookmark_new_with_name( + nautilus_bookmark_get_uri(bookmark), + nautilus_bookmark_get_name(bookmark)); } const gchar * @@ -207,8 +211,18 @@ nautilus_bookmark_get_uri (const NautilusBookmark *bookmark) return bookmark->details->uri; } +/** + * nautilus_bookmark_new_with_name: + * + * Create a new NautilusBookmark from a text uri and a display name. + * @uri: Any uri, even a malformed or non-existent one. + * @name: A string to display to the user as the bookmark's name. + * + * Return value: A newly allocated NautilusBookmark. + * + **/ NautilusBookmark * -nautilus_bookmark_new (const gchar *name, const gchar *uri) +nautilus_bookmark_new_with_name (const gchar *uri, const gchar *name) { NautilusBookmark *new_bookmark; @@ -220,6 +234,55 @@ nautilus_bookmark_new (const gchar *name, const gchar *uri) return new_bookmark; } +/** + * nautilus_bookmark_new: + * + * Create a new NautilusBookmark from just a text uri. + * @uri: Any uri, even a malformed or non-existent one. + * + * Return value: A newly allocated NautilusBookmark, whose display + * name is chosen using default rules based on the uri. + * + **/ +NautilusBookmark * +nautilus_bookmark_new (const gchar *uri) +{ + /* Use default rules to determine the displayed name */ + + NautilusBookmark *result; + GnomeVFSURI *vfs_uri; + + result = NULL; + + /* For now, the only default rule is to use the file/directory name + * rather than the whole path. */ + /* FIXME: This needs to do better (use just file names for file:// urls, + * use page names for http://, etc.) + */ + + vfs_uri = gnome_vfs_uri_new (uri); + if (vfs_uri != NULL) + { + if (strcmp (vfs_uri->method_string, "file") == 0) + { + gchar *short_name; + + short_name = gnome_vfs_uri_extract_short_name (vfs_uri); + result = nautilus_bookmark_new_with_name (uri, short_name); + g_free (short_name); + } + + gnome_vfs_uri_unref (vfs_uri); + } + + if (result == NULL) + { + result = nautilus_bookmark_new_with_name (uri, uri); + } + + return result; +} + static GtkWidget * create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) { @@ -242,7 +305,7 @@ create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) * * Return a menu item representing a bookmark. * @bookmark: The bookmark the menu item represents. - * Return value: A newly-created bookmark. + * Return value: A newly-created bookmark, not yet shown. **/ GtkWidget * nautilus_bookmark_menu_item_new (const NautilusBookmark *bookmark) diff --git a/libnautilus-extensions/nautilus-bookmark.h b/libnautilus-extensions/nautilus-bookmark.h index e4120090a..871572f8f 100644 --- a/libnautilus-extensions/nautilus-bookmark.h +++ b/libnautilus-extensions/nautilus-bookmark.h @@ -54,12 +54,13 @@ struct _NautilusBookmarkClass { typedef struct _NautilusBookmarkClass NautilusBookmarkClass; -GtkType nautilus_bookmark_get_type (void); -NautilusBookmark *nautilus_bookmark_new (const gchar *name, - const gchar *uri); -NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); +GtkType nautilus_bookmark_get_type (void); +NautilusBookmark *nautilus_bookmark_new_with_name (const gchar *uri, + const gchar *name); +NautilusBookmark *nautilus_bookmark_new (const gchar *uri); +NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); gint nautilus_bookmark_compare_with (gconstpointer a, gconstpointer b); diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c index 56a028efd..209bc7e52 100644 --- a/libnautilus-extensions/nautilus-directory.c +++ b/libnautilus-extensions/nautilus-directory.c @@ -1922,6 +1922,14 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%25"), "%2525"); NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%2F"), "%252F"); + file_1 = nautilus_file_get ("file:///home/"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + + file_1 = nautilus_file_get ("file:///home"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + /* sorting */ file_1 = nautilus_file_get ("file:///etc"); file_2 = nautilus_file_get ("file:///usr"); @@ -1932,6 +1940,9 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) < 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort_reversed (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) > 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_1, NAUTILUS_FILE_SORT_BY_NAME) == 0, TRUE); + + nautilus_file_unref (file_1); + nautilus_file_unref (file_2); } #endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus-private/nautilus-bookmark.c b/libnautilus-private/nautilus-bookmark.c index 5d50775d8..65dcd3932 100644 --- a/libnautilus-private/nautilus-bookmark.c +++ b/libnautilus-private/nautilus-bookmark.c @@ -24,6 +24,10 @@ #include "nautilus-bookmark.h" #include "nautilus-icon-factory.h" +#include "nautilus-string.h" + +#include <libgnomevfs/gnome-vfs-types.h> +#include <libgnomevfs/gnome-vfs-uri.h> struct _NautilusBookmarkDetails { @@ -153,9 +157,9 @@ nautilus_bookmark_copy (const NautilusBookmark *bookmark) { g_return_val_if_fail(NAUTILUS_IS_BOOKMARK (bookmark), NULL); - return nautilus_bookmark_new( - nautilus_bookmark_get_name(bookmark), - nautilus_bookmark_get_uri(bookmark)); + return nautilus_bookmark_new_with_name( + nautilus_bookmark_get_uri(bookmark), + nautilus_bookmark_get_name(bookmark)); } const gchar * @@ -207,8 +211,18 @@ nautilus_bookmark_get_uri (const NautilusBookmark *bookmark) return bookmark->details->uri; } +/** + * nautilus_bookmark_new_with_name: + * + * Create a new NautilusBookmark from a text uri and a display name. + * @uri: Any uri, even a malformed or non-existent one. + * @name: A string to display to the user as the bookmark's name. + * + * Return value: A newly allocated NautilusBookmark. + * + **/ NautilusBookmark * -nautilus_bookmark_new (const gchar *name, const gchar *uri) +nautilus_bookmark_new_with_name (const gchar *uri, const gchar *name) { NautilusBookmark *new_bookmark; @@ -220,6 +234,55 @@ nautilus_bookmark_new (const gchar *name, const gchar *uri) return new_bookmark; } +/** + * nautilus_bookmark_new: + * + * Create a new NautilusBookmark from just a text uri. + * @uri: Any uri, even a malformed or non-existent one. + * + * Return value: A newly allocated NautilusBookmark, whose display + * name is chosen using default rules based on the uri. + * + **/ +NautilusBookmark * +nautilus_bookmark_new (const gchar *uri) +{ + /* Use default rules to determine the displayed name */ + + NautilusBookmark *result; + GnomeVFSURI *vfs_uri; + + result = NULL; + + /* For now, the only default rule is to use the file/directory name + * rather than the whole path. */ + /* FIXME: This needs to do better (use just file names for file:// urls, + * use page names for http://, etc.) + */ + + vfs_uri = gnome_vfs_uri_new (uri); + if (vfs_uri != NULL) + { + if (strcmp (vfs_uri->method_string, "file") == 0) + { + gchar *short_name; + + short_name = gnome_vfs_uri_extract_short_name (vfs_uri); + result = nautilus_bookmark_new_with_name (uri, short_name); + g_free (short_name); + } + + gnome_vfs_uri_unref (vfs_uri); + } + + if (result == NULL) + { + result = nautilus_bookmark_new_with_name (uri, uri); + } + + return result; +} + static GtkWidget * create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) { @@ -242,7 +305,7 @@ create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) * * Return a menu item representing a bookmark. * @bookmark: The bookmark the menu item represents. - * Return value: A newly-created bookmark. + * Return value: A newly-created bookmark, not yet shown. **/ GtkWidget * nautilus_bookmark_menu_item_new (const NautilusBookmark *bookmark) diff --git a/libnautilus-private/nautilus-bookmark.h b/libnautilus-private/nautilus-bookmark.h index e4120090a..871572f8f 100644 --- a/libnautilus-private/nautilus-bookmark.h +++ b/libnautilus-private/nautilus-bookmark.h @@ -54,12 +54,13 @@ struct _NautilusBookmarkClass { typedef struct _NautilusBookmarkClass NautilusBookmarkClass; -GtkType nautilus_bookmark_get_type (void); -NautilusBookmark *nautilus_bookmark_new (const gchar *name, - const gchar *uri); -NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); +GtkType nautilus_bookmark_get_type (void); +NautilusBookmark *nautilus_bookmark_new_with_name (const gchar *uri, + const gchar *name); +NautilusBookmark *nautilus_bookmark_new (const gchar *uri); +NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); gint nautilus_bookmark_compare_with (gconstpointer a, gconstpointer b); diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c index 56a028efd..209bc7e52 100644 --- a/libnautilus-private/nautilus-directory.c +++ b/libnautilus-private/nautilus-directory.c @@ -1922,6 +1922,14 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%25"), "%2525"); NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%2F"), "%252F"); + file_1 = nautilus_file_get ("file:///home/"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + + file_1 = nautilus_file_get ("file:///home"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + /* sorting */ file_1 = nautilus_file_get ("file:///etc"); file_2 = nautilus_file_get ("file:///usr"); @@ -1932,6 +1940,9 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) < 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort_reversed (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) > 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_1, NAUTILUS_FILE_SORT_BY_NAME) == 0, TRUE); + + nautilus_file_unref (file_1); + nautilus_file_unref (file_2); } #endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus/nautilus-bookmark.c b/libnautilus/nautilus-bookmark.c index 5d50775d8..65dcd3932 100644 --- a/libnautilus/nautilus-bookmark.c +++ b/libnautilus/nautilus-bookmark.c @@ -24,6 +24,10 @@ #include "nautilus-bookmark.h" #include "nautilus-icon-factory.h" +#include "nautilus-string.h" + +#include <libgnomevfs/gnome-vfs-types.h> +#include <libgnomevfs/gnome-vfs-uri.h> struct _NautilusBookmarkDetails { @@ -153,9 +157,9 @@ nautilus_bookmark_copy (const NautilusBookmark *bookmark) { g_return_val_if_fail(NAUTILUS_IS_BOOKMARK (bookmark), NULL); - return nautilus_bookmark_new( - nautilus_bookmark_get_name(bookmark), - nautilus_bookmark_get_uri(bookmark)); + return nautilus_bookmark_new_with_name( + nautilus_bookmark_get_uri(bookmark), + nautilus_bookmark_get_name(bookmark)); } const gchar * @@ -207,8 +211,18 @@ nautilus_bookmark_get_uri (const NautilusBookmark *bookmark) return bookmark->details->uri; } +/** + * nautilus_bookmark_new_with_name: + * + * Create a new NautilusBookmark from a text uri and a display name. + * @uri: Any uri, even a malformed or non-existent one. + * @name: A string to display to the user as the bookmark's name. + * + * Return value: A newly allocated NautilusBookmark. + * + **/ NautilusBookmark * -nautilus_bookmark_new (const gchar *name, const gchar *uri) +nautilus_bookmark_new_with_name (const gchar *uri, const gchar *name) { NautilusBookmark *new_bookmark; @@ -220,6 +234,55 @@ nautilus_bookmark_new (const gchar *name, const gchar *uri) return new_bookmark; } +/** + * nautilus_bookmark_new: + * + * Create a new NautilusBookmark from just a text uri. + * @uri: Any uri, even a malformed or non-existent one. + * + * Return value: A newly allocated NautilusBookmark, whose display + * name is chosen using default rules based on the uri. + * + **/ +NautilusBookmark * +nautilus_bookmark_new (const gchar *uri) +{ + /* Use default rules to determine the displayed name */ + + NautilusBookmark *result; + GnomeVFSURI *vfs_uri; + + result = NULL; + + /* For now, the only default rule is to use the file/directory name + * rather than the whole path. */ + /* FIXME: This needs to do better (use just file names for file:// urls, + * use page names for http://, etc.) + */ + + vfs_uri = gnome_vfs_uri_new (uri); + if (vfs_uri != NULL) + { + if (strcmp (vfs_uri->method_string, "file") == 0) + { + gchar *short_name; + + short_name = gnome_vfs_uri_extract_short_name (vfs_uri); + result = nautilus_bookmark_new_with_name (uri, short_name); + g_free (short_name); + } + + gnome_vfs_uri_unref (vfs_uri); + } + + if (result == NULL) + { + result = nautilus_bookmark_new_with_name (uri, uri); + } + + return result; +} + static GtkWidget * create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) { @@ -242,7 +305,7 @@ create_pixmap_widget_for_bookmark (const NautilusBookmark *bookmark) * * Return a menu item representing a bookmark. * @bookmark: The bookmark the menu item represents. - * Return value: A newly-created bookmark. + * Return value: A newly-created bookmark, not yet shown. **/ GtkWidget * nautilus_bookmark_menu_item_new (const NautilusBookmark *bookmark) diff --git a/libnautilus/nautilus-bookmark.h b/libnautilus/nautilus-bookmark.h index e4120090a..871572f8f 100644 --- a/libnautilus/nautilus-bookmark.h +++ b/libnautilus/nautilus-bookmark.h @@ -54,12 +54,13 @@ struct _NautilusBookmarkClass { typedef struct _NautilusBookmarkClass NautilusBookmarkClass; -GtkType nautilus_bookmark_get_type (void); -NautilusBookmark *nautilus_bookmark_new (const gchar *name, - const gchar *uri); -NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); -const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); +GtkType nautilus_bookmark_get_type (void); +NautilusBookmark *nautilus_bookmark_new_with_name (const gchar *uri, + const gchar *name); +NautilusBookmark *nautilus_bookmark_new (const gchar *uri); +NautilusBookmark *nautilus_bookmark_copy (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_name (const NautilusBookmark *bookmark); +const gchar *nautilus_bookmark_get_uri (const NautilusBookmark *bookmark); gint nautilus_bookmark_compare_with (gconstpointer a, gconstpointer b); diff --git a/libnautilus/nautilus-directory.c b/libnautilus/nautilus-directory.c index 56a028efd..209bc7e52 100644 --- a/libnautilus/nautilus-directory.c +++ b/libnautilus/nautilus-directory.c @@ -1922,6 +1922,14 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%25"), "%2525"); NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_escape_slashes ("%2F"), "%252F"); + file_1 = nautilus_file_get ("file:///home/"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + + file_1 = nautilus_file_get ("file:///home"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_file_get_name (file_1), "home"); + nautilus_file_unref (file_1); + /* sorting */ file_1 = nautilus_file_get ("file:///etc"); file_2 = nautilus_file_get ("file:///usr"); @@ -1932,6 +1940,9 @@ nautilus_self_check_directory (void) NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) < 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort_reversed (file_1, file_2, NAUTILUS_FILE_SORT_BY_NAME) > 0, TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_file_compare_for_sort (file_1, file_1, NAUTILUS_FILE_SORT_BY_NAME) == 0, TRUE); + + nautilus_file_unref (file_1); + nautilus_file_unref (file_2); } #endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/src/Makefile.am b/src/Makefile.am index ac2de643b..17f834793 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,6 +34,8 @@ nautilus_SOURCES= \ nautilus-index-title.h \ nautilus-self-check-functions.c \ nautilus-self-check-functions.h \ + nautilus-signaller.c \ + nautilus-signaller.h \ nautilus-zoom-control.c \ nautilus-zoom-control.h \ ntl-app.c \ diff --git a/src/nautilus-bookmarklist.c b/src/nautilus-bookmarklist.c index 143cafd89..ea4e4e80c 100644 --- a/src/nautilus-bookmarklist.c +++ b/src/nautilus-bookmarklist.c @@ -375,7 +375,7 @@ nautilus_bookmarklist_load_file (NautilusBookmarklist *bookmarks) bookmarks->list = g_list_append( bookmarks->list, - nautilus_bookmark_new(xml_name, xml_uri)); + nautilus_bookmark_new_with_name (xml_uri, xml_name)); xmlFree (xml_name); xmlFree (xml_uri); diff --git a/src/nautilus-bookmarks-menu.c b/src/nautilus-bookmarks-menu.c index b0ab0250a..caa5bbf3b 100644 --- a/src/nautilus-bookmarks-menu.c +++ b/src/nautilus-bookmarks-menu.c @@ -108,8 +108,7 @@ add_bookmark_cb(GtkMenuItem* item, gpointer func_data) current_uri = nautilus_window_get_requested_uri(bookmarks_menu->window); - /* FIXME: initial name should be extracted from http document title (e.g.) */ - bookmark = nautilus_bookmark_new(current_uri, current_uri); + bookmark = nautilus_bookmark_new(current_uri); if (!nautilus_bookmarklist_contains(bookmarks, bookmark)) { diff --git a/src/nautilus-bookmarks-window.c b/src/nautilus-bookmarks-window.c index 35b2be37d..b08f20c12 100644 --- a/src/nautilus-bookmarks-window.c +++ b/src/nautilus-bookmarks-window.c @@ -468,9 +468,9 @@ on_text_field_focus_out_event (GtkWidget *widget, g_assert(GTK_IS_ENTRY(name_field)); g_assert(GTK_IS_ENTRY(uri_field)); - bookmark = nautilus_bookmark_new( - gtk_entry_get_text(GTK_ENTRY(name_field)), - gtk_entry_get_text(GTK_ENTRY(uri_field))); + bookmark = nautilus_bookmark_new_with_name ( + gtk_entry_get_text(GTK_ENTRY(uri_field)), + gtk_entry_get_text(GTK_ENTRY(name_field))); selected_row = get_selected_row(); /* turn off list updating 'cuz otherwise the list-reordering code runs diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index b690e3169..65c795a99 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -31,19 +31,32 @@ #include <math.h> #include "nautilus.h" #include "nautilus-bookmarks-menu.h" +#include "nautilus-signaller.h" #include "explorer-location-bar.h" #include "ntl-index-panel.h" #include "ntl-window-private.h" #include "ntl-miniicon.h" #include <gdk-pixbuf/gdk-pixbuf.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-string.h> #include "nautilus-zoom-control.h" #include <ctype.h> +enum +{ + LAST_SIGNAL +}; + static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusView *new_view); +/* Object framework static variables */ static GnomeAppClass *parent_class = NULL; +static guint window_signals[LAST_SIGNAL]; + +/* Other static variables */ +static GSList *history_list = NULL; + /* Stuff for handling the CORBA interface */ typedef struct { @@ -224,6 +237,7 @@ static GnomeUIInfo edit_menu_info[] = { #define GO_MENU_FORWARD_ITEM_INDEX 1 #define GO_MENU_UP_ITEM_INDEX 2 #define GO_MENU_HOME_ITEM_INDEX 3 +#define GO_MENU_SEPARATOR_ITEM_INDEX 4 static GnomeUIInfo go_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -253,7 +267,7 @@ static GnomeUIInfo go_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'H', GDK_CONTROL_MASK, NULL }, -/* GNOMEUIINFO_SEPARATOR, */ /* FIXME: Uncomment separator when history list added. */ + GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_END }; @@ -278,6 +292,7 @@ static GnomeUIInfo debug_menu_info [] = { }; +#define GO_MENU_INDEX 2 #define BOOKMARKS_MENU_INDEX 3 static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_FILE_TREE (file_menu_info), @@ -323,6 +338,89 @@ static GnomeUIInfo toolbar_info[] = { GNOMEUIINFO_END }; +static void +clear_go_menu_history (NautilusWindow *window) +{ + GList *children; + GList *iterator; + GtkMenu *go_menu; + gboolean found_dynamic_items; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + go_menu = GTK_MENU (window->go_menu); + + /* Remove all the old history items */ + children = gtk_container_children (GTK_CONTAINER (go_menu)); + iterator = children; + found_dynamic_items = FALSE; + + while (iterator != NULL) + { + if (found_dynamic_items) + { + gtk_container_remove (GTK_CONTAINER (go_menu), iterator->data); + } + else if (iterator->data == window->go_menu_separator_item) + { + found_dynamic_items = TRUE; + } + iterator = g_list_next (iterator); + } + + g_assert (found_dynamic_items); + g_list_free (children); +} + +static void +activate_bookmark_in_menu_item (GtkMenuItem *menu_item, NautilusWindow *window) +{ + g_assert (GTK_IS_MENU_ITEM (menu_item)); + g_assert (NAUTILUS_IS_WINDOW (window)); + g_assert (NAUTILUS_IS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item)))); + + nautilus_window_goto_uri (window, nautilus_bookmark_get_uri ( + NAUTILUS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item))))); +} + +static void +history_list_changed_cb (NautilusSignaller *signaller, + NautilusWindow *window) +{ + GSList *iterator; + GtkMenu *go_menu; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + /* Remove old set of history items. */ + clear_go_menu_history (window); + + go_menu = GTK_MENU (window->go_menu); + + /* Add in a new set of history items. */ + for (iterator = history_list; iterator != NULL; iterator = g_slist_next (iterator)) + { + NautilusBookmark *bookmark; + GtkWidget *menu_item; + + bookmark = NAUTILUS_BOOKMARK (iterator->data); + menu_item = nautilus_bookmark_menu_item_new (bookmark); + /* Store the history list's bookmark in the menu item's data. + * The menu item holds no ref, but that's OK because the + * history list owns the bookmark and the menu item will be + * destroyed when the history list changes. + */ + gtk_object_set_user_data (GTK_OBJECT (menu_item), bookmark); + gtk_widget_show (GTK_WIDGET (menu_item)); + gtk_signal_connect(GTK_OBJECT(menu_item), + "activate", + activate_bookmark_in_menu_item, + window); + + gtk_menu_append (go_menu, menu_item); + } +} + GtkType nautilus_window_get_type(void) @@ -380,7 +478,6 @@ nautilus_window_class_init (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - int i; parent_class = gtk_type_class(gnome_app_get_type()); @@ -392,8 +489,7 @@ nautilus_window_class_init (NautilusWindowClass *klass) widget_class = (GtkWidgetClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); - i = 0; - gtk_object_class_add_signals (object_class, klass->window_signals, i); + gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, @@ -412,6 +508,12 @@ static void nautilus_window_init (NautilusWindow *window) { gtk_quit_add_destroy (1, GTK_OBJECT (window)); + + gtk_signal_connect_while_alive (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed", + history_list_changed_cb, + window, + GTK_OBJECT (window)); } static gboolean @@ -676,9 +778,12 @@ nautilus_window_constructed(NautilusWindow *window) window->reload_button = toolbar_info[TOOLBAR_RELOAD_BUTTON_INDEX].widget; window->stop_button = toolbar_info[TOOLBAR_STOP_BUTTON_INDEX].widget; + window->go_menu = GTK_MENU_ITEM (main_menu[GO_MENU_INDEX].widget)->submenu; + window->back_menu_item = go_menu_info[GO_MENU_BACK_ITEM_INDEX].widget; window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget; window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget; + window->go_menu_separator_item = go_menu_info[GO_MENU_SEPARATOR_ITEM_INDEX].widget; gtk_signal_connect (GTK_OBJECT (window->back_button), "button_press_event", @@ -1103,6 +1208,43 @@ nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) gtk_widget_set_sensitive(window->stop_button, allow); } +void +nautilus_add_to_history_list (const char *uri) +{ + /* Note that the history is shared amongst all windows so + * this is not a NautilusWindow function. Perhaps it belongs + * in its own file. + */ + NautilusBookmark *bookmark; + GSList *found_link; + + g_return_if_fail (nautilus_strlen(uri) > 0); + + bookmark = nautilus_bookmark_new (uri); + + found_link = g_slist_find_custom (history_list, + bookmark, + nautilus_bookmark_compare_with); + + /* Remove any older entry for this same item. There can be at most 1. */ + if (found_link != NULL) + { + gtk_object_unref (found_link->data); + history_list = g_slist_remove_link (history_list, found_link); + } + + /* New item goes first. */ + history_list = g_slist_prepend(history_list, bookmark); + + /* Tell world that history list has changed. At least all the + * NautilusWindows (not just this one) are listening. + */ + gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed"); +} + + + static void nautilus_window_request_location_change_cb (NautilusView *view, diff --git a/src/nautilus-navigation-window.h b/src/nautilus-navigation-window.h index 03d4ea267..122a98ece 100644 --- a/src/nautilus-navigation-window.h +++ b/src/nautilus-navigation-window.h @@ -43,10 +43,7 @@ typedef struct _NautilusWindow NautilusWindow; typedef struct { GnomeAppClass parent_spot; - GnomeAppClass *parent_class; - - guint window_signals[0]; } NautilusWindowClass; typedef struct _NautilusWindowStateInfo NautilusWindowStateInfo; @@ -71,7 +68,9 @@ struct _NautilusWindow { Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; - /* Back/Forward chain stuff. The data in these lists are NautilusBookmark pointers. */ + /* Back/Forward chain, and history list. + * The data in these lists are NautilusBookmark pointers. + */ GSList *back_list, *forward_list; /* Current views stuff */ @@ -87,6 +86,8 @@ struct _NautilusWindow { GtkWidget *back_menu_item; GtkWidget *forward_menu_item; GtkWidget *up_menu_item; + GtkWidget *go_menu; + GtkWidget *go_menu_separator_item; /* Pending changes */ NautilusNavigationInfo *pending_ni; diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index b690e3169..65c795a99 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -31,19 +31,32 @@ #include <math.h> #include "nautilus.h" #include "nautilus-bookmarks-menu.h" +#include "nautilus-signaller.h" #include "explorer-location-bar.h" #include "ntl-index-panel.h" #include "ntl-window-private.h" #include "ntl-miniicon.h" #include <gdk-pixbuf/gdk-pixbuf.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-string.h> #include "nautilus-zoom-control.h" #include <ctype.h> +enum +{ + LAST_SIGNAL +}; + static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusView *new_view); +/* Object framework static variables */ static GnomeAppClass *parent_class = NULL; +static guint window_signals[LAST_SIGNAL]; + +/* Other static variables */ +static GSList *history_list = NULL; + /* Stuff for handling the CORBA interface */ typedef struct { @@ -224,6 +237,7 @@ static GnomeUIInfo edit_menu_info[] = { #define GO_MENU_FORWARD_ITEM_INDEX 1 #define GO_MENU_UP_ITEM_INDEX 2 #define GO_MENU_HOME_ITEM_INDEX 3 +#define GO_MENU_SEPARATOR_ITEM_INDEX 4 static GnomeUIInfo go_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -253,7 +267,7 @@ static GnomeUIInfo go_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'H', GDK_CONTROL_MASK, NULL }, -/* GNOMEUIINFO_SEPARATOR, */ /* FIXME: Uncomment separator when history list added. */ + GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_END }; @@ -278,6 +292,7 @@ static GnomeUIInfo debug_menu_info [] = { }; +#define GO_MENU_INDEX 2 #define BOOKMARKS_MENU_INDEX 3 static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_FILE_TREE (file_menu_info), @@ -323,6 +338,89 @@ static GnomeUIInfo toolbar_info[] = { GNOMEUIINFO_END }; +static void +clear_go_menu_history (NautilusWindow *window) +{ + GList *children; + GList *iterator; + GtkMenu *go_menu; + gboolean found_dynamic_items; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + go_menu = GTK_MENU (window->go_menu); + + /* Remove all the old history items */ + children = gtk_container_children (GTK_CONTAINER (go_menu)); + iterator = children; + found_dynamic_items = FALSE; + + while (iterator != NULL) + { + if (found_dynamic_items) + { + gtk_container_remove (GTK_CONTAINER (go_menu), iterator->data); + } + else if (iterator->data == window->go_menu_separator_item) + { + found_dynamic_items = TRUE; + } + iterator = g_list_next (iterator); + } + + g_assert (found_dynamic_items); + g_list_free (children); +} + +static void +activate_bookmark_in_menu_item (GtkMenuItem *menu_item, NautilusWindow *window) +{ + g_assert (GTK_IS_MENU_ITEM (menu_item)); + g_assert (NAUTILUS_IS_WINDOW (window)); + g_assert (NAUTILUS_IS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item)))); + + nautilus_window_goto_uri (window, nautilus_bookmark_get_uri ( + NAUTILUS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item))))); +} + +static void +history_list_changed_cb (NautilusSignaller *signaller, + NautilusWindow *window) +{ + GSList *iterator; + GtkMenu *go_menu; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + /* Remove old set of history items. */ + clear_go_menu_history (window); + + go_menu = GTK_MENU (window->go_menu); + + /* Add in a new set of history items. */ + for (iterator = history_list; iterator != NULL; iterator = g_slist_next (iterator)) + { + NautilusBookmark *bookmark; + GtkWidget *menu_item; + + bookmark = NAUTILUS_BOOKMARK (iterator->data); + menu_item = nautilus_bookmark_menu_item_new (bookmark); + /* Store the history list's bookmark in the menu item's data. + * The menu item holds no ref, but that's OK because the + * history list owns the bookmark and the menu item will be + * destroyed when the history list changes. + */ + gtk_object_set_user_data (GTK_OBJECT (menu_item), bookmark); + gtk_widget_show (GTK_WIDGET (menu_item)); + gtk_signal_connect(GTK_OBJECT(menu_item), + "activate", + activate_bookmark_in_menu_item, + window); + + gtk_menu_append (go_menu, menu_item); + } +} + GtkType nautilus_window_get_type(void) @@ -380,7 +478,6 @@ nautilus_window_class_init (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - int i; parent_class = gtk_type_class(gnome_app_get_type()); @@ -392,8 +489,7 @@ nautilus_window_class_init (NautilusWindowClass *klass) widget_class = (GtkWidgetClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); - i = 0; - gtk_object_class_add_signals (object_class, klass->window_signals, i); + gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, @@ -412,6 +508,12 @@ static void nautilus_window_init (NautilusWindow *window) { gtk_quit_add_destroy (1, GTK_OBJECT (window)); + + gtk_signal_connect_while_alive (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed", + history_list_changed_cb, + window, + GTK_OBJECT (window)); } static gboolean @@ -676,9 +778,12 @@ nautilus_window_constructed(NautilusWindow *window) window->reload_button = toolbar_info[TOOLBAR_RELOAD_BUTTON_INDEX].widget; window->stop_button = toolbar_info[TOOLBAR_STOP_BUTTON_INDEX].widget; + window->go_menu = GTK_MENU_ITEM (main_menu[GO_MENU_INDEX].widget)->submenu; + window->back_menu_item = go_menu_info[GO_MENU_BACK_ITEM_INDEX].widget; window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget; window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget; + window->go_menu_separator_item = go_menu_info[GO_MENU_SEPARATOR_ITEM_INDEX].widget; gtk_signal_connect (GTK_OBJECT (window->back_button), "button_press_event", @@ -1103,6 +1208,43 @@ nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) gtk_widget_set_sensitive(window->stop_button, allow); } +void +nautilus_add_to_history_list (const char *uri) +{ + /* Note that the history is shared amongst all windows so + * this is not a NautilusWindow function. Perhaps it belongs + * in its own file. + */ + NautilusBookmark *bookmark; + GSList *found_link; + + g_return_if_fail (nautilus_strlen(uri) > 0); + + bookmark = nautilus_bookmark_new (uri); + + found_link = g_slist_find_custom (history_list, + bookmark, + nautilus_bookmark_compare_with); + + /* Remove any older entry for this same item. There can be at most 1. */ + if (found_link != NULL) + { + gtk_object_unref (found_link->data); + history_list = g_slist_remove_link (history_list, found_link); + } + + /* New item goes first. */ + history_list = g_slist_prepend(history_list, bookmark); + + /* Tell world that history list has changed. At least all the + * NautilusWindows (not just this one) are listening. + */ + gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed"); +} + + + static void nautilus_window_request_location_change_cb (NautilusView *view, diff --git a/src/nautilus-object-window.h b/src/nautilus-object-window.h index 03d4ea267..122a98ece 100644 --- a/src/nautilus-object-window.h +++ b/src/nautilus-object-window.h @@ -43,10 +43,7 @@ typedef struct _NautilusWindow NautilusWindow; typedef struct { GnomeAppClass parent_spot; - GnomeAppClass *parent_class; - - guint window_signals[0]; } NautilusWindowClass; typedef struct _NautilusWindowStateInfo NautilusWindowStateInfo; @@ -71,7 +68,9 @@ struct _NautilusWindow { Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; - /* Back/Forward chain stuff. The data in these lists are NautilusBookmark pointers. */ + /* Back/Forward chain, and history list. + * The data in these lists are NautilusBookmark pointers. + */ GSList *back_list, *forward_list; /* Current views stuff */ @@ -87,6 +86,8 @@ struct _NautilusWindow { GtkWidget *back_menu_item; GtkWidget *forward_menu_item; GtkWidget *up_menu_item; + GtkWidget *go_menu; + GtkWidget *go_menu_separator_item; /* Pending changes */ NautilusNavigationInfo *pending_ni; diff --git a/src/nautilus-signaller.c b/src/nautilus-signaller.c new file mode 100644 index 000000000..2602f3272 --- /dev/null +++ b/src/nautilus-signaller.c @@ -0,0 +1,80 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + fm-signaller.h: Class to manage nautilus-wide signals that don't + correspond to any particular object. + + Copyright (C) 1999, 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: John Sullivan <sullivan@eazel.com> +*/ + +#include <config.h> +#include "nautilus-signaller.h" + +#include <gtk/gtksignal.h> +#include <libnautilus/nautilus-gtk-macros.h> + +enum +{ + HISTORY_LIST_CHANGED, + LAST_SIGNAL +}; + +static guint nautilus_signaller_signals[LAST_SIGNAL]; + +static void nautilus_signaller_initialize_class (gpointer klass); +static void nautilus_signaller_initialize (gpointer object, gpointer klass); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusSignaller, nautilus_signaller, GTK_TYPE_OBJECT) + +static void +nautilus_signaller_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + nautilus_signaller_signals[HISTORY_LIST_CHANGED] = + gtk_signal_new ("history_list_changed", + GTK_RUN_LAST, + object_class->type, + 0, + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, nautilus_signaller_signals, LAST_SIGNAL); +} + +static void +nautilus_signaller_initialize (gpointer object, gpointer klass) +{ + /* placeholder to allow use of boilerplate macro */ +} + +NautilusSignaller * +nautilus_signaller_get_current (void) +{ + static NautilusSignaller *global_signaller = NULL; + + if (global_signaller == NULL) + { + global_signaller = gtk_type_new (NAUTILUS_TYPE_SIGNALLER); + } + + return global_signaller; +}
\ No newline at end of file diff --git a/src/nautilus-signaller.h b/src/nautilus-signaller.h new file mode 100644 index 000000000..a91aef865 --- /dev/null +++ b/src/nautilus-signaller.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-signaller.h: Class to manage nautilus-wide signals that don't + correspond to any particular object. + + Copyright (C) 1999, 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: John Sullivan <sullivan@eazel.com> +*/ + +#ifndef NAUTILUS_SIGNALLER_H +#define NAUTILUS_SIGNALLER_H + +#include <gtk/gtkobject.h> + +/* NautilusSignaller is a class that manages signals between + disconnected file manager code. File manager objects connect to these signals + so that other objects can cause them to be emitted later, without + the connecting and emit-causing objects needing to know about each + other. It seems a shame to have to invent a subclass and a special + object just for this purpose. Perhaps there's a better way to do + this kind of thing. +*/ + +typedef struct _NautilusSignaller NautilusSignaller; +typedef struct _NautilusSignallerClass NautilusSignallerClass; + +#define NAUTILUS_TYPE_SIGNALLER \ + (nautilus_signaller_get_type ()) +#define NAUTILUS_SIGNALLER(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_SIGNALLER, NautilusSignaller)) +#define NAUTILUS_SIGNALLER_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SIGNALLER, NautilusSignallerClass)) +#define NAUTILUS_IS_SIGNALLER(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_SIGNALLER)) +#define NAUTILUS_IS_SIGNALLER_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_SIGNALLER)) + +struct _NautilusSignaller +{ + GtkObject object; +}; + +struct _NautilusSignallerClass +{ + GtkObjectClass parent_class; + + void (* icon_text_changed) (NautilusSignaller *signaller); +}; + +/* Basic GtkObject requirements. */ +GtkType nautilus_signaller_get_type (void); + +/* Get the one and only NautilusSignaller to connect with or emit signals for */ +NautilusSignaller *nautilus_signaller_get_current (void); + +#endif /* NAUTILUS_SIGNALLER_H */ diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index b690e3169..65c795a99 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -31,19 +31,32 @@ #include <math.h> #include "nautilus.h" #include "nautilus-bookmarks-menu.h" +#include "nautilus-signaller.h" #include "explorer-location-bar.h" #include "ntl-index-panel.h" #include "ntl-window-private.h" #include "ntl-miniicon.h" #include <gdk-pixbuf/gdk-pixbuf.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-string.h> #include "nautilus-zoom-control.h" #include <ctype.h> +enum +{ + LAST_SIGNAL +}; + static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusView *new_view); +/* Object framework static variables */ static GnomeAppClass *parent_class = NULL; +static guint window_signals[LAST_SIGNAL]; + +/* Other static variables */ +static GSList *history_list = NULL; + /* Stuff for handling the CORBA interface */ typedef struct { @@ -224,6 +237,7 @@ static GnomeUIInfo edit_menu_info[] = { #define GO_MENU_FORWARD_ITEM_INDEX 1 #define GO_MENU_UP_ITEM_INDEX 2 #define GO_MENU_HOME_ITEM_INDEX 3 +#define GO_MENU_SEPARATOR_ITEM_INDEX 4 static GnomeUIInfo go_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -253,7 +267,7 @@ static GnomeUIInfo go_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'H', GDK_CONTROL_MASK, NULL }, -/* GNOMEUIINFO_SEPARATOR, */ /* FIXME: Uncomment separator when history list added. */ + GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_END }; @@ -278,6 +292,7 @@ static GnomeUIInfo debug_menu_info [] = { }; +#define GO_MENU_INDEX 2 #define BOOKMARKS_MENU_INDEX 3 static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_FILE_TREE (file_menu_info), @@ -323,6 +338,89 @@ static GnomeUIInfo toolbar_info[] = { GNOMEUIINFO_END }; +static void +clear_go_menu_history (NautilusWindow *window) +{ + GList *children; + GList *iterator; + GtkMenu *go_menu; + gboolean found_dynamic_items; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + go_menu = GTK_MENU (window->go_menu); + + /* Remove all the old history items */ + children = gtk_container_children (GTK_CONTAINER (go_menu)); + iterator = children; + found_dynamic_items = FALSE; + + while (iterator != NULL) + { + if (found_dynamic_items) + { + gtk_container_remove (GTK_CONTAINER (go_menu), iterator->data); + } + else if (iterator->data == window->go_menu_separator_item) + { + found_dynamic_items = TRUE; + } + iterator = g_list_next (iterator); + } + + g_assert (found_dynamic_items); + g_list_free (children); +} + +static void +activate_bookmark_in_menu_item (GtkMenuItem *menu_item, NautilusWindow *window) +{ + g_assert (GTK_IS_MENU_ITEM (menu_item)); + g_assert (NAUTILUS_IS_WINDOW (window)); + g_assert (NAUTILUS_IS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item)))); + + nautilus_window_goto_uri (window, nautilus_bookmark_get_uri ( + NAUTILUS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item))))); +} + +static void +history_list_changed_cb (NautilusSignaller *signaller, + NautilusWindow *window) +{ + GSList *iterator; + GtkMenu *go_menu; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + /* Remove old set of history items. */ + clear_go_menu_history (window); + + go_menu = GTK_MENU (window->go_menu); + + /* Add in a new set of history items. */ + for (iterator = history_list; iterator != NULL; iterator = g_slist_next (iterator)) + { + NautilusBookmark *bookmark; + GtkWidget *menu_item; + + bookmark = NAUTILUS_BOOKMARK (iterator->data); + menu_item = nautilus_bookmark_menu_item_new (bookmark); + /* Store the history list's bookmark in the menu item's data. + * The menu item holds no ref, but that's OK because the + * history list owns the bookmark and the menu item will be + * destroyed when the history list changes. + */ + gtk_object_set_user_data (GTK_OBJECT (menu_item), bookmark); + gtk_widget_show (GTK_WIDGET (menu_item)); + gtk_signal_connect(GTK_OBJECT(menu_item), + "activate", + activate_bookmark_in_menu_item, + window); + + gtk_menu_append (go_menu, menu_item); + } +} + GtkType nautilus_window_get_type(void) @@ -380,7 +478,6 @@ nautilus_window_class_init (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - int i; parent_class = gtk_type_class(gnome_app_get_type()); @@ -392,8 +489,7 @@ nautilus_window_class_init (NautilusWindowClass *klass) widget_class = (GtkWidgetClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); - i = 0; - gtk_object_class_add_signals (object_class, klass->window_signals, i); + gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, @@ -412,6 +508,12 @@ static void nautilus_window_init (NautilusWindow *window) { gtk_quit_add_destroy (1, GTK_OBJECT (window)); + + gtk_signal_connect_while_alive (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed", + history_list_changed_cb, + window, + GTK_OBJECT (window)); } static gboolean @@ -676,9 +778,12 @@ nautilus_window_constructed(NautilusWindow *window) window->reload_button = toolbar_info[TOOLBAR_RELOAD_BUTTON_INDEX].widget; window->stop_button = toolbar_info[TOOLBAR_STOP_BUTTON_INDEX].widget; + window->go_menu = GTK_MENU_ITEM (main_menu[GO_MENU_INDEX].widget)->submenu; + window->back_menu_item = go_menu_info[GO_MENU_BACK_ITEM_INDEX].widget; window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget; window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget; + window->go_menu_separator_item = go_menu_info[GO_MENU_SEPARATOR_ITEM_INDEX].widget; gtk_signal_connect (GTK_OBJECT (window->back_button), "button_press_event", @@ -1103,6 +1208,43 @@ nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) gtk_widget_set_sensitive(window->stop_button, allow); } +void +nautilus_add_to_history_list (const char *uri) +{ + /* Note that the history is shared amongst all windows so + * this is not a NautilusWindow function. Perhaps it belongs + * in its own file. + */ + NautilusBookmark *bookmark; + GSList *found_link; + + g_return_if_fail (nautilus_strlen(uri) > 0); + + bookmark = nautilus_bookmark_new (uri); + + found_link = g_slist_find_custom (history_list, + bookmark, + nautilus_bookmark_compare_with); + + /* Remove any older entry for this same item. There can be at most 1. */ + if (found_link != NULL) + { + gtk_object_unref (found_link->data); + history_list = g_slist_remove_link (history_list, found_link); + } + + /* New item goes first. */ + history_list = g_slist_prepend(history_list, bookmark); + + /* Tell world that history list has changed. At least all the + * NautilusWindows (not just this one) are listening. + */ + gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed"); +} + + + static void nautilus_window_request_location_change_cb (NautilusView *view, diff --git a/src/nautilus-spatial-window.h b/src/nautilus-spatial-window.h index 03d4ea267..122a98ece 100644 --- a/src/nautilus-spatial-window.h +++ b/src/nautilus-spatial-window.h @@ -43,10 +43,7 @@ typedef struct _NautilusWindow NautilusWindow; typedef struct { GnomeAppClass parent_spot; - GnomeAppClass *parent_class; - - guint window_signals[0]; } NautilusWindowClass; typedef struct _NautilusWindowStateInfo NautilusWindowStateInfo; @@ -71,7 +68,9 @@ struct _NautilusWindow { Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; - /* Back/Forward chain stuff. The data in these lists are NautilusBookmark pointers. */ + /* Back/Forward chain, and history list. + * The data in these lists are NautilusBookmark pointers. + */ GSList *back_list, *forward_list; /* Current views stuff */ @@ -87,6 +86,8 @@ struct _NautilusWindow { GtkWidget *back_menu_item; GtkWidget *forward_menu_item; GtkWidget *up_menu_item; + GtkWidget *go_menu; + GtkWidget *go_menu_separator_item; /* Pending changes */ NautilusNavigationInfo *pending_ni; diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c index 1361b115a..b7b63721f 100644 --- a/src/nautilus-window-manage-views.c +++ b/src/nautilus-window-manage-views.c @@ -190,26 +190,27 @@ nautilus_window_update_internals(NautilusWindow *window, NautilusNavigationInfo /* Maintain history lists. */ if(!window->is_reload) { + nautilus_add_to_history_list (loci->navinfo.requested_uri); + if (window->is_back) { - /* Going back. Remove one item from the prev list and add the current item to the next list. */ - + /* Going back. Remove one item from the back list and + * add the current item to the forward list. + */ g_assert(window->back_list); g_assert(!strcmp(nautilus_bookmark_get_uri (NAUTILUS_BOOKMARK (window->back_list->data)), loci->navinfo.requested_uri)); g_assert(window->ni); - /* FIXME: should get the title for the document a better way, so it is web page title, e.g. */ window->forward_list = g_slist_prepend(window->forward_list, - nautilus_bookmark_new (window->ni->requested_uri, - window->ni->requested_uri)); + nautilus_bookmark_new (window->ni->requested_uri)); gtk_object_unref(window->back_list->data); window->back_list = g_slist_remove_link(window->back_list, window->back_list); } else { /* Not going back. Could be an arbitrary new uri, or could be going forward in the forward list. - * Remove one item from the next if it's the same as the the request. - * Otherwise, clobber the entire next list. FIXME: This is not quite correct behavior (doesn't + * Remove one item from the forward list if it's the same as the request. + * Otherwise, clobber the entire forward list. FIXME: This is not quite correct behavior (doesn't * match web browsers) because it doesn't distinguish between using the Forward button or list * to move in the Forward chain and coincidentally visiting a site that happens to be in the * Forward chain. @@ -229,11 +230,12 @@ nautilus_window_update_internals(NautilusWindow *window, NautilusNavigationInfo } } - /* FIXME: should get the title for the document a better way, so it is web page title, e.g. */ if (window->ni) + { + /* Store bookmark for current location in back list, unless there is no current location */ window->back_list = g_slist_prepend(window->back_list, - nautilus_bookmark_new (window->ni->requested_uri, - window->ni->requested_uri)); + nautilus_bookmark_new (window->ni->requested_uri)); + } } } diff --git a/src/nautilus-window-private.h b/src/nautilus-window-private.h index 8143a8c8d..3c9ce778d 100644 --- a/src/nautilus-window-private.h +++ b/src/nautilus-window-private.h @@ -43,5 +43,6 @@ void nautilus_window_end_location_change(NautilusWindow *window); void nautilus_window_connect_view (NautilusWindow *window, NautilusView *view); void nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window); +void nautilus_add_to_history_list (const char *uri); #endif diff --git a/src/nautilus-window.c b/src/nautilus-window.c index b690e3169..65c795a99 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -31,19 +31,32 @@ #include <math.h> #include "nautilus.h" #include "nautilus-bookmarks-menu.h" +#include "nautilus-signaller.h" #include "explorer-location-bar.h" #include "ntl-index-panel.h" #include "ntl-window-private.h" #include "ntl-miniicon.h" #include <gdk-pixbuf/gdk-pixbuf.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-string.h> #include "nautilus-zoom-control.h" #include <ctype.h> +enum +{ + LAST_SIGNAL +}; + static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusView *new_view); +/* Object framework static variables */ static GnomeAppClass *parent_class = NULL; +static guint window_signals[LAST_SIGNAL]; + +/* Other static variables */ +static GSList *history_list = NULL; + /* Stuff for handling the CORBA interface */ typedef struct { @@ -224,6 +237,7 @@ static GnomeUIInfo edit_menu_info[] = { #define GO_MENU_FORWARD_ITEM_INDEX 1 #define GO_MENU_UP_ITEM_INDEX 2 #define GO_MENU_HOME_ITEM_INDEX 3 +#define GO_MENU_SEPARATOR_ITEM_INDEX 4 static GnomeUIInfo go_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -253,7 +267,7 @@ static GnomeUIInfo go_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'H', GDK_CONTROL_MASK, NULL }, -/* GNOMEUIINFO_SEPARATOR, */ /* FIXME: Uncomment separator when history list added. */ + GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_END }; @@ -278,6 +292,7 @@ static GnomeUIInfo debug_menu_info [] = { }; +#define GO_MENU_INDEX 2 #define BOOKMARKS_MENU_INDEX 3 static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_FILE_TREE (file_menu_info), @@ -323,6 +338,89 @@ static GnomeUIInfo toolbar_info[] = { GNOMEUIINFO_END }; +static void +clear_go_menu_history (NautilusWindow *window) +{ + GList *children; + GList *iterator; + GtkMenu *go_menu; + gboolean found_dynamic_items; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + go_menu = GTK_MENU (window->go_menu); + + /* Remove all the old history items */ + children = gtk_container_children (GTK_CONTAINER (go_menu)); + iterator = children; + found_dynamic_items = FALSE; + + while (iterator != NULL) + { + if (found_dynamic_items) + { + gtk_container_remove (GTK_CONTAINER (go_menu), iterator->data); + } + else if (iterator->data == window->go_menu_separator_item) + { + found_dynamic_items = TRUE; + } + iterator = g_list_next (iterator); + } + + g_assert (found_dynamic_items); + g_list_free (children); +} + +static void +activate_bookmark_in_menu_item (GtkMenuItem *menu_item, NautilusWindow *window) +{ + g_assert (GTK_IS_MENU_ITEM (menu_item)); + g_assert (NAUTILUS_IS_WINDOW (window)); + g_assert (NAUTILUS_IS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item)))); + + nautilus_window_goto_uri (window, nautilus_bookmark_get_uri ( + NAUTILUS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item))))); +} + +static void +history_list_changed_cb (NautilusSignaller *signaller, + NautilusWindow *window) +{ + GSList *iterator; + GtkMenu *go_menu; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + /* Remove old set of history items. */ + clear_go_menu_history (window); + + go_menu = GTK_MENU (window->go_menu); + + /* Add in a new set of history items. */ + for (iterator = history_list; iterator != NULL; iterator = g_slist_next (iterator)) + { + NautilusBookmark *bookmark; + GtkWidget *menu_item; + + bookmark = NAUTILUS_BOOKMARK (iterator->data); + menu_item = nautilus_bookmark_menu_item_new (bookmark); + /* Store the history list's bookmark in the menu item's data. + * The menu item holds no ref, but that's OK because the + * history list owns the bookmark and the menu item will be + * destroyed when the history list changes. + */ + gtk_object_set_user_data (GTK_OBJECT (menu_item), bookmark); + gtk_widget_show (GTK_WIDGET (menu_item)); + gtk_signal_connect(GTK_OBJECT(menu_item), + "activate", + activate_bookmark_in_menu_item, + window); + + gtk_menu_append (go_menu, menu_item); + } +} + GtkType nautilus_window_get_type(void) @@ -380,7 +478,6 @@ nautilus_window_class_init (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - int i; parent_class = gtk_type_class(gnome_app_get_type()); @@ -392,8 +489,7 @@ nautilus_window_class_init (NautilusWindowClass *klass) widget_class = (GtkWidgetClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); - i = 0; - gtk_object_class_add_signals (object_class, klass->window_signals, i); + gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, @@ -412,6 +508,12 @@ static void nautilus_window_init (NautilusWindow *window) { gtk_quit_add_destroy (1, GTK_OBJECT (window)); + + gtk_signal_connect_while_alive (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed", + history_list_changed_cb, + window, + GTK_OBJECT (window)); } static gboolean @@ -676,9 +778,12 @@ nautilus_window_constructed(NautilusWindow *window) window->reload_button = toolbar_info[TOOLBAR_RELOAD_BUTTON_INDEX].widget; window->stop_button = toolbar_info[TOOLBAR_STOP_BUTTON_INDEX].widget; + window->go_menu = GTK_MENU_ITEM (main_menu[GO_MENU_INDEX].widget)->submenu; + window->back_menu_item = go_menu_info[GO_MENU_BACK_ITEM_INDEX].widget; window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget; window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget; + window->go_menu_separator_item = go_menu_info[GO_MENU_SEPARATOR_ITEM_INDEX].widget; gtk_signal_connect (GTK_OBJECT (window->back_button), "button_press_event", @@ -1103,6 +1208,43 @@ nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) gtk_widget_set_sensitive(window->stop_button, allow); } +void +nautilus_add_to_history_list (const char *uri) +{ + /* Note that the history is shared amongst all windows so + * this is not a NautilusWindow function. Perhaps it belongs + * in its own file. + */ + NautilusBookmark *bookmark; + GSList *found_link; + + g_return_if_fail (nautilus_strlen(uri) > 0); + + bookmark = nautilus_bookmark_new (uri); + + found_link = g_slist_find_custom (history_list, + bookmark, + nautilus_bookmark_compare_with); + + /* Remove any older entry for this same item. There can be at most 1. */ + if (found_link != NULL) + { + gtk_object_unref (found_link->data); + history_list = g_slist_remove_link (history_list, found_link); + } + + /* New item goes first. */ + history_list = g_slist_prepend(history_list, bookmark); + + /* Tell world that history list has changed. At least all the + * NautilusWindows (not just this one) are listening. + */ + gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed"); +} + + + static void nautilus_window_request_location_change_cb (NautilusView *view, diff --git a/src/nautilus-window.h b/src/nautilus-window.h index 03d4ea267..122a98ece 100644 --- a/src/nautilus-window.h +++ b/src/nautilus-window.h @@ -43,10 +43,7 @@ typedef struct _NautilusWindow NautilusWindow; typedef struct { GnomeAppClass parent_spot; - GnomeAppClass *parent_class; - - guint window_signals[0]; } NautilusWindowClass; typedef struct _NautilusWindowStateInfo NautilusWindowStateInfo; @@ -71,7 +68,9 @@ struct _NautilusWindow { Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; - /* Back/Forward chain stuff. The data in these lists are NautilusBookmark pointers. */ + /* Back/Forward chain, and history list. + * The data in these lists are NautilusBookmark pointers. + */ GSList *back_list, *forward_list; /* Current views stuff */ @@ -87,6 +86,8 @@ struct _NautilusWindow { GtkWidget *back_menu_item; GtkWidget *forward_menu_item; GtkWidget *up_menu_item; + GtkWidget *go_menu; + GtkWidget *go_menu_separator_item; /* Pending changes */ NautilusNavigationInfo *pending_ni; diff --git a/src/ntl-window-msgs.c b/src/ntl-window-msgs.c index 1361b115a..b7b63721f 100644 --- a/src/ntl-window-msgs.c +++ b/src/ntl-window-msgs.c @@ -190,26 +190,27 @@ nautilus_window_update_internals(NautilusWindow *window, NautilusNavigationInfo /* Maintain history lists. */ if(!window->is_reload) { + nautilus_add_to_history_list (loci->navinfo.requested_uri); + if (window->is_back) { - /* Going back. Remove one item from the prev list and add the current item to the next list. */ - + /* Going back. Remove one item from the back list and + * add the current item to the forward list. + */ g_assert(window->back_list); g_assert(!strcmp(nautilus_bookmark_get_uri (NAUTILUS_BOOKMARK (window->back_list->data)), loci->navinfo.requested_uri)); g_assert(window->ni); - /* FIXME: should get the title for the document a better way, so it is web page title, e.g. */ window->forward_list = g_slist_prepend(window->forward_list, - nautilus_bookmark_new (window->ni->requested_uri, - window->ni->requested_uri)); + nautilus_bookmark_new (window->ni->requested_uri)); gtk_object_unref(window->back_list->data); window->back_list = g_slist_remove_link(window->back_list, window->back_list); } else { /* Not going back. Could be an arbitrary new uri, or could be going forward in the forward list. - * Remove one item from the next if it's the same as the the request. - * Otherwise, clobber the entire next list. FIXME: This is not quite correct behavior (doesn't + * Remove one item from the forward list if it's the same as the request. + * Otherwise, clobber the entire forward list. FIXME: This is not quite correct behavior (doesn't * match web browsers) because it doesn't distinguish between using the Forward button or list * to move in the Forward chain and coincidentally visiting a site that happens to be in the * Forward chain. @@ -229,11 +230,12 @@ nautilus_window_update_internals(NautilusWindow *window, NautilusNavigationInfo } } - /* FIXME: should get the title for the document a better way, so it is web page title, e.g. */ if (window->ni) + { + /* Store bookmark for current location in back list, unless there is no current location */ window->back_list = g_slist_prepend(window->back_list, - nautilus_bookmark_new (window->ni->requested_uri, - window->ni->requested_uri)); + nautilus_bookmark_new (window->ni->requested_uri)); + } } } diff --git a/src/ntl-window-private.h b/src/ntl-window-private.h index 8143a8c8d..3c9ce778d 100644 --- a/src/ntl-window-private.h +++ b/src/ntl-window-private.h @@ -43,5 +43,6 @@ void nautilus_window_end_location_change(NautilusWindow *window); void nautilus_window_connect_view (NautilusWindow *window, NautilusView *view); void nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window); +void nautilus_add_to_history_list (const char *uri); #endif diff --git a/src/ntl-window.c b/src/ntl-window.c index b690e3169..65c795a99 100644 --- a/src/ntl-window.c +++ b/src/ntl-window.c @@ -31,19 +31,32 @@ #include <math.h> #include "nautilus.h" #include "nautilus-bookmarks-menu.h" +#include "nautilus-signaller.h" #include "explorer-location-bar.h" #include "ntl-index-panel.h" #include "ntl-window-private.h" #include "ntl-miniicon.h" #include <gdk-pixbuf/gdk-pixbuf.h> #include <libnautilus/nautilus-gtk-extensions.h> +#include <libnautilus/nautilus-string.h> #include "nautilus-zoom-control.h" #include <ctype.h> +enum +{ + LAST_SIGNAL +}; + static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusView *new_view); +/* Object framework static variables */ static GnomeAppClass *parent_class = NULL; +static guint window_signals[LAST_SIGNAL]; + +/* Other static variables */ +static GSList *history_list = NULL; + /* Stuff for handling the CORBA interface */ typedef struct { @@ -224,6 +237,7 @@ static GnomeUIInfo edit_menu_info[] = { #define GO_MENU_FORWARD_ITEM_INDEX 1 #define GO_MENU_UP_ITEM_INDEX 2 #define GO_MENU_HOME_ITEM_INDEX 3 +#define GO_MENU_SEPARATOR_ITEM_INDEX 4 static GnomeUIInfo go_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -253,7 +267,7 @@ static GnomeUIInfo go_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'H', GDK_CONTROL_MASK, NULL }, -/* GNOMEUIINFO_SEPARATOR, */ /* FIXME: Uncomment separator when history list added. */ + GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_END }; @@ -278,6 +292,7 @@ static GnomeUIInfo debug_menu_info [] = { }; +#define GO_MENU_INDEX 2 #define BOOKMARKS_MENU_INDEX 3 static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_FILE_TREE (file_menu_info), @@ -323,6 +338,89 @@ static GnomeUIInfo toolbar_info[] = { GNOMEUIINFO_END }; +static void +clear_go_menu_history (NautilusWindow *window) +{ + GList *children; + GList *iterator; + GtkMenu *go_menu; + gboolean found_dynamic_items; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + go_menu = GTK_MENU (window->go_menu); + + /* Remove all the old history items */ + children = gtk_container_children (GTK_CONTAINER (go_menu)); + iterator = children; + found_dynamic_items = FALSE; + + while (iterator != NULL) + { + if (found_dynamic_items) + { + gtk_container_remove (GTK_CONTAINER (go_menu), iterator->data); + } + else if (iterator->data == window->go_menu_separator_item) + { + found_dynamic_items = TRUE; + } + iterator = g_list_next (iterator); + } + + g_assert (found_dynamic_items); + g_list_free (children); +} + +static void +activate_bookmark_in_menu_item (GtkMenuItem *menu_item, NautilusWindow *window) +{ + g_assert (GTK_IS_MENU_ITEM (menu_item)); + g_assert (NAUTILUS_IS_WINDOW (window)); + g_assert (NAUTILUS_IS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item)))); + + nautilus_window_goto_uri (window, nautilus_bookmark_get_uri ( + NAUTILUS_BOOKMARK (gtk_object_get_user_data (GTK_OBJECT (menu_item))))); +} + +static void +history_list_changed_cb (NautilusSignaller *signaller, + NautilusWindow *window) +{ + GSList *iterator; + GtkMenu *go_menu; + + g_assert (NAUTILUS_IS_WINDOW (window)); + + /* Remove old set of history items. */ + clear_go_menu_history (window); + + go_menu = GTK_MENU (window->go_menu); + + /* Add in a new set of history items. */ + for (iterator = history_list; iterator != NULL; iterator = g_slist_next (iterator)) + { + NautilusBookmark *bookmark; + GtkWidget *menu_item; + + bookmark = NAUTILUS_BOOKMARK (iterator->data); + menu_item = nautilus_bookmark_menu_item_new (bookmark); + /* Store the history list's bookmark in the menu item's data. + * The menu item holds no ref, but that's OK because the + * history list owns the bookmark and the menu item will be + * destroyed when the history list changes. + */ + gtk_object_set_user_data (GTK_OBJECT (menu_item), bookmark); + gtk_widget_show (GTK_WIDGET (menu_item)); + gtk_signal_connect(GTK_OBJECT(menu_item), + "activate", + activate_bookmark_in_menu_item, + window); + + gtk_menu_append (go_menu, menu_item); + } +} + GtkType nautilus_window_get_type(void) @@ -380,7 +478,6 @@ nautilus_window_class_init (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; - int i; parent_class = gtk_type_class(gnome_app_get_type()); @@ -392,8 +489,7 @@ nautilus_window_class_init (NautilusWindowClass *klass) widget_class = (GtkWidgetClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); - i = 0; - gtk_object_class_add_signals (object_class, klass->window_signals, i); + gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, @@ -412,6 +508,12 @@ static void nautilus_window_init (NautilusWindow *window) { gtk_quit_add_destroy (1, GTK_OBJECT (window)); + + gtk_signal_connect_while_alive (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed", + history_list_changed_cb, + window, + GTK_OBJECT (window)); } static gboolean @@ -676,9 +778,12 @@ nautilus_window_constructed(NautilusWindow *window) window->reload_button = toolbar_info[TOOLBAR_RELOAD_BUTTON_INDEX].widget; window->stop_button = toolbar_info[TOOLBAR_STOP_BUTTON_INDEX].widget; + window->go_menu = GTK_MENU_ITEM (main_menu[GO_MENU_INDEX].widget)->submenu; + window->back_menu_item = go_menu_info[GO_MENU_BACK_ITEM_INDEX].widget; window->forward_menu_item = go_menu_info[GO_MENU_FORWARD_ITEM_INDEX].widget; window->up_menu_item = go_menu_info[GO_MENU_UP_ITEM_INDEX].widget; + window->go_menu_separator_item = go_menu_info[GO_MENU_SEPARATOR_ITEM_INDEX].widget; gtk_signal_connect (GTK_OBJECT (window->back_button), "button_press_event", @@ -1103,6 +1208,43 @@ nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) gtk_widget_set_sensitive(window->stop_button, allow); } +void +nautilus_add_to_history_list (const char *uri) +{ + /* Note that the history is shared amongst all windows so + * this is not a NautilusWindow function. Perhaps it belongs + * in its own file. + */ + NautilusBookmark *bookmark; + GSList *found_link; + + g_return_if_fail (nautilus_strlen(uri) > 0); + + bookmark = nautilus_bookmark_new (uri); + + found_link = g_slist_find_custom (history_list, + bookmark, + nautilus_bookmark_compare_with); + + /* Remove any older entry for this same item. There can be at most 1. */ + if (found_link != NULL) + { + gtk_object_unref (found_link->data); + history_list = g_slist_remove_link (history_list, found_link); + } + + /* New item goes first. */ + history_list = g_slist_prepend(history_list, bookmark); + + /* Tell world that history list has changed. At least all the + * NautilusWindows (not just this one) are listening. + */ + gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), + "history_list_changed"); +} + + + static void nautilus_window_request_location_change_cb (NautilusView *view, diff --git a/src/ntl-window.h b/src/ntl-window.h index 03d4ea267..122a98ece 100644 --- a/src/ntl-window.h +++ b/src/ntl-window.h @@ -43,10 +43,7 @@ typedef struct _NautilusWindow NautilusWindow; typedef struct { GnomeAppClass parent_spot; - GnomeAppClass *parent_class; - - guint window_signals[0]; } NautilusWindowClass; typedef struct _NautilusWindowStateInfo NautilusWindowStateInfo; @@ -71,7 +68,9 @@ struct _NautilusWindow { Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; - /* Back/Forward chain stuff. The data in these lists are NautilusBookmark pointers. */ + /* Back/Forward chain, and history list. + * The data in these lists are NautilusBookmark pointers. + */ GSList *back_list, *forward_list; /* Current views stuff */ @@ -87,6 +86,8 @@ struct _NautilusWindow { GtkWidget *back_menu_item; GtkWidget *forward_menu_item; GtkWidget *up_menu_item; + GtkWidget *go_menu; + GtkWidget *go_menu_separator_item; /* Pending changes */ NautilusNavigationInfo *pending_ni; |