diff options
-rw-r--r-- | ChangeLog-20000414 | 107 | ||||
-rw-r--r-- | components/history/nautilus-history-view.c | 23 | ||||
-rw-r--r-- | components/history/ntl-history-view.c | 23 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-string.c | 40 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-string.h | 3 | ||||
-rw-r--r-- | libnautilus-private/nautilus-string.c | 40 | ||||
-rw-r--r-- | libnautilus-private/nautilus-string.h | 3 | ||||
-rw-r--r-- | libnautilus/nautilus-string.c | 40 | ||||
-rw-r--r-- | libnautilus/nautilus-string.h | 3 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view-icons.c | 41 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.c | 433 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.h | 16 | ||||
-rw-r--r-- | src/nautilus-navigation-window-menus.c | 69 | ||||
-rw-r--r-- | src/nautilus-view-frame-nautilus-view.c | 4 | ||||
-rw-r--r-- | src/nautilus-window-menus.c | 69 | ||||
-rw-r--r-- | src/ntl-prefs.c | 2 | ||||
-rw-r--r-- | src/ntl-view-nautilus.c | 4 |
17 files changed, 767 insertions, 153 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index abadb1c06..e8a7f5274 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,110 @@ +2000-03-06 John Sullivan <sullivan@eazel.com> + + The file manager now uses Bonobo menu-merging to install + and remove its menu items from the window's menu bar. + I didn't put Zoom In/Zoom Out in the menu bar because + that seems unnecessary once the control works (they're + still in the right-click menu). I haven't yet put + Stretch/Restore in the menu bar, will do so soon. And + now you get a whole bunch of Gtk-CRITICALs when closing + a window because of all the double-destroyed bonobo menu + items (just like the two you used to get). Hope to fix + this soon. Added new "Settings" menu, which needs to be + organized better someday, and will be. + + * components/history/ntl-history-view.c: + (menu_setup): Removed function. + (make_obj): Removed code to set up merged menu. This was + sample code for menu merging; now that we have real menu + merging working elsewhere we don't need this sample. + + * libnautilus/nautilus-string.h, + * libnautilus/nautilus-string.c: + (nautilus_strstrip): New function, strips all occurrences + of a given char from a char *. + (nautilus_self_check_string): Added tests for nautilus_strstrip. + + * src/ntl-view-nautilus.c: + (nautilus_view_try_load_client): Activate the new bonobo control + when it's installed. + (destroy_nautilus_view): Deactivate the bonobo control. + + * src/nautilus-window-menus.c: + edit_menu_info[]: Removed "Preferences..." and preceding separator. + settings_menu_info[]: New menu, added "General Settings..." + (formerly "Preferences...") and "Use Eazel Theme Icons". + main_menu[]: Include settings_menu_info. + (edit_menu_prefs_cb): Renamed to general_settings_cb + (use_eazel_theme_icons_cb): New function, swaps themes. + (update_eazel_theme_menu_item): New function, sets the toggle state + of this menu item based on current theme. + (nautilus_window_initialize_menus): Call update_eazel_theme_menu_item + explicitly, also wire it up to theme change signal. + + * src/ntl-prefs.c: (nautilus_prefs_ui_show): Renamed dialog + from "Preferences" to "General Settings" to match menu item. This + name will probably go away entirely eventually, but may as well + keep it consistent for now. + + * src/file-manager/fm-directory-view.h: (merge_menus): New function + pointer. (update_menus): New function pointer. + (fm_directory_view_update_menus): Prototype for new function. * + src/file-manager/fm-directory-view.c: + (fm_directory_view_initialize_class): Set up merge_menus and + update_menus function pointers. (bonobo_menu_open_cb), + (bonobo_menu_open_in_new_window_cb), (bonobo_menu_delete_cb): New + callback functions with parameters the way Bonobo likes 'em. + (get_bonobo_control): New utility function for getting the + BonoboControl out of an FMDirectoryView. + (bonobo_control_activate_cb): New function, called when the view's + BonoboControl is activated or deactivated. Merges menus on + activate, unsets bonobo container on deactivate. + (fm_directory_view_initialize): Wire up bonobo_control_activate_cb + to "activate" signal of view's bonobo control. + (use_eazel_theme_icons_cb): Removed this function (it's in the + standard Nautilus menus now, not component-dependent). + (delete_one): Added a FIXME comment noting that the view is being + told to delete the entire selection for every selected item. + (fm_directory_view_delete_with_confirm): Moved the guts of + delete_cb into here so it can be conveniently called from both + bonobo menu and right-click menu. (delete_cb): Now just calls + fm_directory_view_delete_with_confirm. + (add_check_menu_item): Removed function, had only been used by + eazel theme icons menu item. + (fm_directory_view_real_append_background_context_menu_items): + Removed eazel theme icons menu item from right-click menu (now + accessible always in the Settings menu). + (compute_menu_item_info): New function, determines current label + and sensitivity for dynamic menu items, common to both bonobo menus + and context menus. Uses nautilus_strstrip to remove underlines used + for accelerators when item is used for context menu. + (append_one_selection_context_menu_item): New helper function, + wraps up common code for constructing a menu item for the + selection-dependent part of the context menu. + (fm_directory_view_real_append_selection_context_menu_items): + Replaced a lot of duplicated code with calls to + append_one_selection_context_menu_item. + (fm_directory_view_real_merge_menus): New funciton. Here lieth the + code to put directory view menu items into the window's menu bar. + (update_one_menu_item): New function, uses compute_menu_item_info + to update the label & sensitivity of one bonobo-style menu item. + (fm_directory_view_real_update_menus): New function, calls + update_one_menu_item on each menu item whose label or sensitivity + is dynamic. + (fm_directory_view_notify_selection_changed): + Call fm_directory_view_update_menus to update menu labels & + sensitivity that depend on the selection. + (fm_directory_view_merge_menus): New function, calls the function pointer. + (fm_directory_view_update_menus): New function, calls the function pointer. + + * src/file-manager/fm-directory-view-icons.c: + (fm_directory_view_icons_initialize_class): Supply function pointer + for merge_menus. + (customize_icon_text_cb): Just added comments about its dual use. + (fm_directory_view_icons_merge_menus): Merge a "Customize Icon Text" + item into the Settings menu. Still need to do the Stretch/Restore items + here. + 2000-03-06 Darin Adler <darin@eazel.com> Fixed bug in Unstretch I just introduced. diff --git a/components/history/nautilus-history-view.c b/components/history/nautilus-history-view.c index 4fa8386ca..6c5d2201a 100644 --- a/components/history/nautilus-history-view.c +++ b/components/history/nautilus-history-view.c @@ -192,31 +192,11 @@ do_destroy(GtkObject *obj, HistoryView *hview) gtk_main_quit(); } -static void -menu_setup(BonoboObject *ctl, HistoryView *hview) -{ - Bonobo_UIHandler remote_uih; - GnomeUIInfo history_menu[] = { - GNOMEUIINFO_MENU_NEW_ITEM("_Do nothing (menu merge test)", "Testing", NULL, NULL), - GNOMEUIINFO_END - }; - - hview->uih = bonobo_control_get_ui_handler(BONOBO_CONTROL(ctl)); - remote_uih = bonobo_control_get_remote_ui_handler(BONOBO_CONTROL(ctl)); - bonobo_ui_handler_set_container(hview->uih, remote_uih); - - bonobo_ui_handler_menu_new_subtree(hview->uih, "/History", _("H_istory"), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, - NULL, 0, 0); - bonobo_ui_handler_menu_add_tree(hview->uih, "/History", - bonobo_ui_handler_menu_parse_uiinfo_tree(history_menu)); -} - static BonoboObject * make_obj(BonoboGenericFactory *Factory, const char *goad_id, gpointer closure) { GtkWidget *wtmp; GtkCList *clist; - BonoboObject *ctl; HistoryView *hview; g_return_val_if_fail(!strcmp(goad_id, "ntl_history_view"), NULL); @@ -243,9 +223,6 @@ make_obj(BonoboGenericFactory *Factory, const char *goad_id, gpointer closure) gtk_signal_connect (GTK_OBJECT (hview->view), "destroy", do_destroy, hview); object_count++; - ctl = nautilus_view_frame_get_bonobo_control (NAUTILUS_VIEW_FRAME (hview->view)); - gtk_signal_connect(GTK_OBJECT (ctl), "set_frame", menu_setup, hview); - hview->clist = (GtkCList *)clist; /* set description */ diff --git a/components/history/ntl-history-view.c b/components/history/ntl-history-view.c index 4fa8386ca..6c5d2201a 100644 --- a/components/history/ntl-history-view.c +++ b/components/history/ntl-history-view.c @@ -192,31 +192,11 @@ do_destroy(GtkObject *obj, HistoryView *hview) gtk_main_quit(); } -static void -menu_setup(BonoboObject *ctl, HistoryView *hview) -{ - Bonobo_UIHandler remote_uih; - GnomeUIInfo history_menu[] = { - GNOMEUIINFO_MENU_NEW_ITEM("_Do nothing (menu merge test)", "Testing", NULL, NULL), - GNOMEUIINFO_END - }; - - hview->uih = bonobo_control_get_ui_handler(BONOBO_CONTROL(ctl)); - remote_uih = bonobo_control_get_remote_ui_handler(BONOBO_CONTROL(ctl)); - bonobo_ui_handler_set_container(hview->uih, remote_uih); - - bonobo_ui_handler_menu_new_subtree(hview->uih, "/History", _("H_istory"), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, - NULL, 0, 0); - bonobo_ui_handler_menu_add_tree(hview->uih, "/History", - bonobo_ui_handler_menu_parse_uiinfo_tree(history_menu)); -} - static BonoboObject * make_obj(BonoboGenericFactory *Factory, const char *goad_id, gpointer closure) { GtkWidget *wtmp; GtkCList *clist; - BonoboObject *ctl; HistoryView *hview; g_return_val_if_fail(!strcmp(goad_id, "ntl_history_view"), NULL); @@ -243,9 +223,6 @@ make_obj(BonoboGenericFactory *Factory, const char *goad_id, gpointer closure) gtk_signal_connect (GTK_OBJECT (hview->view), "destroy", do_destroy, hview); object_count++; - ctl = nautilus_view_frame_get_bonobo_control (NAUTILUS_VIEW_FRAME (hview->view)); - gtk_signal_connect(GTK_OBJECT (ctl), "set_frame", menu_setup, hview); - hview->clist = (GtkCList *)clist; /* set description */ diff --git a/libnautilus-extensions/nautilus-string.c b/libnautilus-extensions/nautilus-string.c index 36a84a65b..d2df8e286 100644 --- a/libnautilus-extensions/nautilus-string.c +++ b/libnautilus-extensions/nautilus-string.c @@ -167,6 +167,35 @@ nautilus_string_to_int (const char *string, int *integer) return TRUE; } +/** + * nautilus_strstrip: + * Remove all occurrences of a character from a string. The + * original string is modified, and also returned for convenience. + * + * @string_null_allowed: The string to be stripped. + * @remove_this: The char to remove from @string_null_allowed + * + * Return value: @string_null_allowed, after removing all occurrences + * of @remove_this. + */ +char * +nautilus_strstrip (char *string_null_allowed, char remove_this) +{ + if (string_null_allowed != NULL) { + char *pos; + + pos = string_null_allowed; + while (*pos != '\0') { + if (*pos == remove_this) { + g_memmove (pos, pos + 1, strlen (pos)); + } + ++pos; + } + } + + return string_null_allowed; +} + gboolean nautilus_eat_string_to_int (char *string, int *integer) { @@ -203,6 +232,7 @@ void nautilus_self_check_string (void) { int integer; + char *test_string; NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (NULL), 0); NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (""), 0); @@ -261,6 +291,16 @@ nautilus_self_check_string (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("foo:bar", ":"), "foo"); NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("footle:bar", "tle:"), "foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (NULL, '_'), NULL); + test_string = g_strdup ("foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + #define TEST_INTEGER_CONVERSION_FUNCTIONS(string, boolean_result, integer_result) \ NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_string_to_int (string, &integer), boolean_result); \ NAUTILUS_CHECK_INTEGER_RESULT (call_string_to_int (string), integer_result); \ diff --git a/libnautilus-extensions/nautilus-string.h b/libnautilus-extensions/nautilus-string.h index 35a08f373..9d269dcd7 100644 --- a/libnautilus-extensions/nautilus-string.h +++ b/libnautilus-extensions/nautilus-string.h @@ -47,6 +47,9 @@ char * nautilus_strdup_prefix (const char *source_null_allowed, gboolean nautilus_has_suffix (const char *target_null_allowed, const char *suffix_null_allowed); +char * nautilus_strstrip (char *string_null_allowed, + char remove_this); + /* Conversions to and from strings. */ gboolean nautilus_string_to_int (const char *string, diff --git a/libnautilus-private/nautilus-string.c b/libnautilus-private/nautilus-string.c index 36a84a65b..d2df8e286 100644 --- a/libnautilus-private/nautilus-string.c +++ b/libnautilus-private/nautilus-string.c @@ -167,6 +167,35 @@ nautilus_string_to_int (const char *string, int *integer) return TRUE; } +/** + * nautilus_strstrip: + * Remove all occurrences of a character from a string. The + * original string is modified, and also returned for convenience. + * + * @string_null_allowed: The string to be stripped. + * @remove_this: The char to remove from @string_null_allowed + * + * Return value: @string_null_allowed, after removing all occurrences + * of @remove_this. + */ +char * +nautilus_strstrip (char *string_null_allowed, char remove_this) +{ + if (string_null_allowed != NULL) { + char *pos; + + pos = string_null_allowed; + while (*pos != '\0') { + if (*pos == remove_this) { + g_memmove (pos, pos + 1, strlen (pos)); + } + ++pos; + } + } + + return string_null_allowed; +} + gboolean nautilus_eat_string_to_int (char *string, int *integer) { @@ -203,6 +232,7 @@ void nautilus_self_check_string (void) { int integer; + char *test_string; NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (NULL), 0); NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (""), 0); @@ -261,6 +291,16 @@ nautilus_self_check_string (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("foo:bar", ":"), "foo"); NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("footle:bar", "tle:"), "foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (NULL, '_'), NULL); + test_string = g_strdup ("foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + #define TEST_INTEGER_CONVERSION_FUNCTIONS(string, boolean_result, integer_result) \ NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_string_to_int (string, &integer), boolean_result); \ NAUTILUS_CHECK_INTEGER_RESULT (call_string_to_int (string), integer_result); \ diff --git a/libnautilus-private/nautilus-string.h b/libnautilus-private/nautilus-string.h index 35a08f373..9d269dcd7 100644 --- a/libnautilus-private/nautilus-string.h +++ b/libnautilus-private/nautilus-string.h @@ -47,6 +47,9 @@ char * nautilus_strdup_prefix (const char *source_null_allowed, gboolean nautilus_has_suffix (const char *target_null_allowed, const char *suffix_null_allowed); +char * nautilus_strstrip (char *string_null_allowed, + char remove_this); + /* Conversions to and from strings. */ gboolean nautilus_string_to_int (const char *string, diff --git a/libnautilus/nautilus-string.c b/libnautilus/nautilus-string.c index 36a84a65b..d2df8e286 100644 --- a/libnautilus/nautilus-string.c +++ b/libnautilus/nautilus-string.c @@ -167,6 +167,35 @@ nautilus_string_to_int (const char *string, int *integer) return TRUE; } +/** + * nautilus_strstrip: + * Remove all occurrences of a character from a string. The + * original string is modified, and also returned for convenience. + * + * @string_null_allowed: The string to be stripped. + * @remove_this: The char to remove from @string_null_allowed + * + * Return value: @string_null_allowed, after removing all occurrences + * of @remove_this. + */ +char * +nautilus_strstrip (char *string_null_allowed, char remove_this) +{ + if (string_null_allowed != NULL) { + char *pos; + + pos = string_null_allowed; + while (*pos != '\0') { + if (*pos == remove_this) { + g_memmove (pos, pos + 1, strlen (pos)); + } + ++pos; + } + } + + return string_null_allowed; +} + gboolean nautilus_eat_string_to_int (char *string, int *integer) { @@ -203,6 +232,7 @@ void nautilus_self_check_string (void) { int integer; + char *test_string; NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (NULL), 0); NAUTILUS_CHECK_INTEGER_RESULT (nautilus_strlen (""), 0); @@ -261,6 +291,16 @@ nautilus_self_check_string (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("foo:bar", ":"), "foo"); NAUTILUS_CHECK_STRING_RESULT (nautilus_strdup_prefix ("footle:bar", "tle:"), "foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (NULL, '_'), NULL); + test_string = g_strdup ("foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + test_string = g_strdup ("_foo_"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_strstrip (test_string, '_'), "foo"); + #define TEST_INTEGER_CONVERSION_FUNCTIONS(string, boolean_result, integer_result) \ NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_string_to_int (string, &integer), boolean_result); \ NAUTILUS_CHECK_INTEGER_RESULT (call_string_to_int (string), integer_result); \ diff --git a/libnautilus/nautilus-string.h b/libnautilus/nautilus-string.h index 35a08f373..9d269dcd7 100644 --- a/libnautilus/nautilus-string.h +++ b/libnautilus/nautilus-string.h @@ -47,6 +47,9 @@ char * nautilus_strdup_prefix (const char *source_null_allowed, gboolean nautilus_has_suffix (const char *target_null_allowed, const char *suffix_null_allowed); +char * nautilus_strstrip (char *string_null_allowed, + char remove_this); + /* Conversions to and from strings. */ gboolean nautilus_string_to_int (const char *string, diff --git a/src/file-manager/fm-directory-view-icons.c b/src/file-manager/fm-directory-view-icons.c index 81af4b985..67c0bbea2 100644 --- a/src/file-manager/fm-directory-view-icons.c +++ b/src/file-manager/fm-directory-view-icons.c @@ -47,6 +47,9 @@ #define DEFAULT_BACKGROUND_COLOR "rgb:FFFF/FFFF/FFFF" +/* Paths to use when creating & referring to bonobo menu items */ +#define FM_DIRECTORY_VIEW_ICONS_MENU_PATH_CUSTOMIZE_ICON_TEXT "/Settings/Icon Text" + /* forward declarations */ static void add_icon_at_free_position (FMDirectoryViewIcons *icon_view, @@ -84,6 +87,8 @@ static GList * fm_directory_view_icons_get_selection static NautilusZoomLevel fm_directory_view_icons_get_zoom_level (FMDirectoryViewIcons *view); static void fm_directory_view_icons_initialize (FMDirectoryViewIcons *icon_view); static void fm_directory_view_icons_initialize_class (FMDirectoryViewIconsClass *klass); +static void fm_directory_view_icons_merge_menus (FMDirectoryView *view, + BonoboUIHandler *ui_handler); static void fm_directory_view_icons_select_all (FMDirectoryView *view); static void fm_directory_view_icons_set_zoom_level (FMDirectoryViewIcons *view, NautilusZoomLevel new_level); @@ -149,6 +154,8 @@ fm_directory_view_icons_initialize_class (FMDirectoryViewIconsClass *klass) = fm_directory_view_icons_append_selection_context_menu_items; fm_directory_view_class->append_background_context_menu_items = fm_directory_view_icons_append_background_context_menu_items; + fm_directory_view_class->merge_menus + = fm_directory_view_icons_merge_menus; /* FIXME: Read this from global preferences */ default_icon_text_attribute_names = g_strdup ("name|size|date_modified|type"); @@ -363,12 +370,16 @@ fm_directory_view_icons_append_selection_context_menu_items (FMDirectoryView *vi gtk_menu_append (menu, menu_item); } +/** + * + * Note that this is used both as a Bonobo menu callback and a signal callback. + * The first parameter is different in these cases, but we just ignore it anyway. + */ static void -customize_icon_text_cb (GtkMenuItem *menu_item, gpointer view) +customize_icon_text_cb (gpointer ignored, gpointer view) { GtkWindow *window; - g_assert (GTK_IS_MENU_ITEM (menu_item)); g_assert (FM_IS_DIRECTORY_VIEW_ICONS (view)); window = GTK_WINDOW (fm_icon_text_window_get_or_create ()); @@ -398,7 +409,8 @@ fm_directory_view_icons_append_background_context_menu_items (FMDirectoryView *v menu_item = gtk_menu_item_new_with_label (_("Customize Icon Text...")); gtk_widget_show (menu_item); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - GTK_SIGNAL_FUNC (customize_icon_text_cb), view); + GTK_SIGNAL_FUNC (customize_icon_text_cb), + view); gtk_menu_append (menu, menu_item); } @@ -673,6 +685,29 @@ fm_directory_view_icons_get_selection (FMDirectoryView *view) } static void +fm_directory_view_icons_merge_menus (FMDirectoryView *view, BonoboUIHandler *ui_handler) +{ + g_assert (FM_IS_DIRECTORY_VIEW_ICONS (view)); + + g_message ("called fm_directory_view_icons_merge_menus"); + NAUTILUS_CALL_PARENT_CLASS (FM_DIRECTORY_VIEW_CLASS, + merge_menus, + (view, ui_handler)); + + bonobo_ui_handler_menu_new_item (ui_handler, + FM_DIRECTORY_VIEW_ICONS_MENU_PATH_CUSTOMIZE_ICON_TEXT, + _("Customize _Icon Text..."), + _("Choose which information appears beneath each icon's name"), + -1, + BONOBO_UI_HANDLER_PIXMAP_NONE, + NULL, + 0, + 0, + (BonoboUIHandlerCallbackFunc)customize_icon_text_cb, + view); +} + +static void fm_directory_view_icons_select_all (FMDirectoryView *view) { GnomeIconContainer *icon_container; diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 343fe9a63..8b703dd81 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -30,6 +30,7 @@ #include <gtk/gtkmenu.h> #include <gtk/gtkcheckmenuitem.h> +#include <bonobo/bonobo-control.h> #include <gnome.h> #include <libgnome/gnome-i18n.h> #include <libgnomevfs/gnome-vfs-async-ops.h> @@ -42,9 +43,16 @@ #include <libnautilus/nautilus-gtk-macros.h> #include <libnautilus/nautilus-gtk-extensions.h> #include <libnautilus/nautilus-icon-factory.h> +#include <libnautilus/nautilus-string.h> #define DISPLAY_TIMEOUT_INTERVAL_MSECS 500 +/* Paths to use when creating & referring to bonobo menu items */ +#define FM_DIRECTORY_VIEW_MENU_PATH_OPEN "/File/Open" +#define FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW "/File/OpenNew" +#define FM_DIRECTORY_VIEW_MENU_PATH_DELETE "/File/Delete" +#define FM_DIRECTORY_VIEW_MENU_PATH_SELECT_ALL "/Edit/Select All" + enum { ADD_ENTRY, @@ -82,10 +90,12 @@ static int display_selection_info_idle_cb (gpointer data); static void display_selection_info (FMDirectoryView *view); static void fm_directory_view_initialize_class (FMDirectoryViewClass *klass); static void fm_directory_view_initialize (FMDirectoryView *view); +static void fm_directory_view_delete_with_confirm (FMDirectoryView *view, GList *files); static void fm_directory_view_destroy (GtkObject *object); static void fm_directory_view_append_background_context_menu_items (FMDirectoryView *view, GtkMenu *menu); +static void fm_directory_view_merge_menus (FMDirectoryView *view, BonoboUIHandler *ui_handler); static void fm_directory_view_real_append_background_context_menu_items (FMDirectoryView *view, GtkMenu *menu); @@ -93,8 +103,11 @@ static void fm_directory_view_real_append_selection_context_menu_items (FMDirectoryView *view, GtkMenu *menu, GList *files); +static void fm_directory_view_real_merge_menus (FMDirectoryView *view, BonoboUIHandler *ui_handler); +static void fm_directory_view_real_update_menus (FMDirectoryView *view); static GtkMenu *create_selection_context_menu (FMDirectoryView *view); static GtkMenu *create_background_context_menu (FMDirectoryView *view); +static BonoboControl *get_bonobo_control (FMDirectoryView *view); static void stop_location_change_cb (NautilusViewFrame *view_frame, FMDirectoryView *directory_view); static void notify_location_change_cb (NautilusViewFrame *view_frame, @@ -102,6 +115,7 @@ static void notify_location_change_cb (NautilusViewFrame *view_frame, FMDirectoryView *directory_view); static void open_cb (GtkMenuItem *item, NautilusFile *file); static void open_in_new_window_cb (GtkMenuItem *item, GList *files); +static void open_one_in_new_window (gpointer data, gpointer user_data); static void select_all_cb (GtkMenuItem *item, FMDirectoryView *directory_view); static void zoom_in_cb (GtkMenuItem *item, FMDirectoryView *directory_view); static void zoom_out_cb (GtkMenuItem *item, FMDirectoryView *directory_view); @@ -185,6 +199,8 @@ fm_directory_view_initialize_class (FMDirectoryViewClass *klass) klass->append_selection_context_menu_items = fm_directory_view_real_append_selection_context_menu_items; klass->append_background_context_menu_items = fm_directory_view_real_append_background_context_menu_items; + klass->merge_menus = fm_directory_view_real_merge_menus; + klass->update_menus = fm_directory_view_real_update_menus; /* Function pointers that subclasses must override */ @@ -199,6 +215,102 @@ fm_directory_view_initialize_class (FMDirectoryViewClass *klass) } static void +bonobo_menu_open_cb (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) +{ + FMDirectoryView *view; + GList *selection; + + g_assert (FM_IS_DIRECTORY_VIEW (user_data)); + + view = FM_DIRECTORY_VIEW (user_data); + selection = fm_directory_view_get_selection (view); + + /* UI should have prevented this from being called unless exactly + * one item is selected. + */ + g_assert (g_list_length(selection) == 1); + + fm_directory_view_activate_entry (view, + NAUTILUS_FILE (selection->data), + FALSE); + + nautilus_file_list_free (selection); +} + +static void +bonobo_menu_open_in_new_window_cb (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) +{ + FMDirectoryView *view; + GList *selection; + + g_assert (FM_IS_DIRECTORY_VIEW (user_data)); + + view = FM_DIRECTORY_VIEW (user_data); + selection = fm_directory_view_get_selection (view); + + /* UI should have prevented this from being called unless at least + * one item is selected. + */ + g_assert (g_list_length(selection) > 0); + + g_list_foreach (selection, open_one_in_new_window, view); + + nautilus_file_list_free (selection); +} + +static void +bonobo_menu_delete_cb (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) +{ + FMDirectoryView *view; + GList *selection; + + g_assert (FM_IS_DIRECTORY_VIEW (user_data)); + + view = FM_DIRECTORY_VIEW (user_data); + selection = fm_directory_view_get_selection (view); + + /* UI should have prevented this from being called unless at least + * one item is selected. + */ + g_assert (g_list_length(selection) > 0); + + fm_directory_view_delete_with_confirm (view, selection); + + nautilus_file_list_free (selection); +} + +static BonoboControl * +get_bonobo_control (FMDirectoryView *view) +{ + return BONOBO_CONTROL (nautilus_view_frame_get_bonobo_control ( + NAUTILUS_VIEW_FRAME (view->details->view_frame))); +} + +static void +bonobo_control_activate_cb (BonoboObject *control, gboolean state, gpointer user_data) +{ + FMDirectoryView *view; + BonoboUIHandler *local_ui_handler; + + g_assert (FM_IS_DIRECTORY_VIEW (user_data)); + + view = FM_DIRECTORY_VIEW (user_data); + + local_ui_handler = bonobo_control_get_ui_handler (BONOBO_CONTROL (control)); + + if (state) { + bonobo_ui_handler_set_container (local_ui_handler, + bonobo_control_get_remote_ui_handler (BONOBO_CONTROL (control))); + /* Add new menu items and perhaps whole menus */ + fm_directory_view_merge_menus (view, local_ui_handler); + /* Set initial sensitivity, wording, toggle state, etc. */ + fm_directory_view_update_menus (view); + } else { + bonobo_ui_handler_unset_container (local_ui_handler); + } +} + +static void fm_directory_view_initialize (FMDirectoryView *directory_view) { directory_view->details = g_new0 (FMDirectoryViewDetails, 1); @@ -221,6 +333,11 @@ fm_directory_view_initialize (FMDirectoryView *directory_view) GTK_SIGNAL_FUNC (notify_location_change_cb), directory_view); + gtk_signal_connect (GTK_OBJECT (get_bonobo_control (directory_view)), + "activate", + bonobo_control_activate_cb, + directory_view); + gtk_widget_show (GTK_WIDGET (directory_view)); } @@ -456,7 +573,7 @@ stop_load (FMDirectoryView *view, gboolean error) /* handle the "select all" menu command */ static void -select_all_cb(GtkMenuItem *item, FMDirectoryView *directory_view) +select_all_cb (GtkMenuItem *item, FMDirectoryView *directory_view) { fm_directory_view_select_all (directory_view); } @@ -475,20 +592,6 @@ zoom_out_cb (GtkMenuItem *item, FMDirectoryView *directory_view) fm_directory_view_bump_zoom_level (directory_view, -1); } -static void -use_eazel_theme_icons_cb (GtkCheckMenuItem *item, FMDirectoryView *directory_view) -{ - char *theme; - - theme = nautilus_icon_factory_get_theme (); - if (nautilus_strcmp (theme, "eazel") == 0) { - nautilus_icon_factory_set_theme (NULL); - } else { - nautilus_icon_factory_set_theme ("eazel"); - } - g_free (theme); -} - static gboolean display_pending_files (FMDirectoryView *view) { @@ -896,6 +999,7 @@ delete_one (gpointer data, gpointer user_data) if (result == GNOME_VFS_OK) { /* invoke a method of the view to delete from the model and container */ + /* FIXME: Deleting the entire selection is being called once per selected item! */ fm_directory_view_delete_selection(FM_DIRECTORY_VIEW(user_data)); } else { @@ -970,18 +1074,23 @@ confirm_delete (FMDirectoryView *directory_view, GList *files) } static void -delete_cb (GtkMenuItem *item, GList *files) +fm_directory_view_delete_with_confirm (FMDirectoryView *view, GList *files) { - FMDirectoryView *directory_view; - - directory_view = FM_DIRECTORY_VIEW (gtk_object_get_data (GTK_OBJECT (item), - "directory_view")); - - if (confirm_delete (directory_view, files)) { - g_list_foreach (files, delete_one, directory_view); + g_assert (FM_IS_DIRECTORY_VIEW (view)); + + if (confirm_delete (view, files)) { + g_list_foreach (files, delete_one, view); } } +static void +delete_cb (GtkMenuItem *item, GList *files) +{ + fm_directory_view_delete_with_confirm (FM_DIRECTORY_VIEW (gtk_object_get_data (GTK_OBJECT (item), + "directory_view")), + files); +} + /* handle the open command */ static void @@ -1035,100 +1144,208 @@ add_menu_item (FMDirectoryView *view, GtkMenu *menu, const char *label, } static void -add_check_menu_item (FMDirectoryView *view, GtkMenu *menu, const char *label, - void (* toggled_handler) (GtkCheckMenuItem *, FMDirectoryView *), - gboolean sensitive, - gboolean active) -{ - GtkWidget *menu_item; - - menu_item = gtk_check_menu_item_new_with_label (label); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), active); - gtk_signal_connect (GTK_OBJECT (menu_item), "toggled", - GTK_SIGNAL_FUNC (toggled_handler), view); - finish_adding_menu_item (menu, menu_item, sensitive); -} - -static void fm_directory_view_real_append_background_context_menu_items (FMDirectoryView *view, GtkMenu *menu) { - char *theme; - - theme = nautilus_icon_factory_get_theme (); - add_menu_item (view, menu, _("Select All"), select_all_cb, TRUE); add_menu_item (view, menu, _("Zoom In"), zoom_in_cb, fm_directory_view_can_zoom_in (view)); add_menu_item (view, menu, _("Zoom Out"), zoom_out_cb, fm_directory_view_can_zoom_out (view)); - add_check_menu_item (view, menu, _("Use Eazel Theme Icons"), - use_eazel_theme_icons_cb, - TRUE, nautilus_strcmp (theme, "eazel") == 0); +} - g_free (theme); +static void +compute_menu_item_info (const char *path, + int selection_length, + gboolean include_accelerator_underbars, + char **return_name, + gboolean *return_sensitivity) +{ + if (strcmp (path, FM_DIRECTORY_VIEW_MENU_PATH_OPEN) == 0) { + *return_name = g_strdup_printf (_("_Open")); + *return_sensitivity = selection_length == 1; + } else if (strcmp (path, FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW) == 0) { + if (selection_length <= 1) { + *return_name = g_strdup (_("Open in _New Window")); + } else { + *return_name = g_strdup_printf (_("Open in %d _New Windows"), selection_length); + } + *return_sensitivity = selection_length > 0; + } else if (strcmp (path, FM_DIRECTORY_VIEW_MENU_PATH_DELETE) == 0) { + *return_name = g_strdup (_("_Delete...")); + *return_sensitivity = selection_length > 0; + } else { + g_assert_not_reached (); + } + + if (!include_accelerator_underbars) { + nautilus_strstrip (*return_name, '_'); + } } static void +append_one_selection_context_menu_item (GtkMenu *menu, + const char *path, + int item_count, + const char *item_data_id, + gpointer item_data, + GtkDestroyNotify item_data_destroy_func, + gboolean ref_item_data, + GtkSignalFunc callback, + gpointer callback_data) +{ + GtkWidget *menu_item; + char *label_string; + gboolean sensitive; + + compute_menu_item_info (path, item_count, FALSE, &label_string, &sensitive); + menu_item = gtk_menu_item_new_with_label (label_string); + g_free (label_string); + if (sensitive) + { + if (item_data != NULL) { + gtk_object_set_data_full (GTK_OBJECT (menu_item), + item_data_id, + item_data, + item_data_destroy_func); + if (ref_item_data) { + gtk_object_ref (GTK_OBJECT (item_data)); + } + } + + gtk_signal_connect (GTK_OBJECT (menu_item), + "activate", + callback, + callback_data); + } + + finish_adding_menu_item (menu, menu_item, sensitive); +} + +static void fm_directory_view_real_append_selection_context_menu_items (FMDirectoryView *view, GtkMenu *menu, GList *files) { - GtkWidget *menu_item; int item_count; - char *label_string; item_count = g_list_length (files); g_assert (item_count >= 1); - menu_item = gtk_menu_item_new_with_label (_("Open")); - if (item_count > 1) - { - /* Can only open a single item in the same window */ - gtk_widget_set_sensitive (menu_item, FALSE); - } - else - { - /* Store directory view in menu item so callback can access it. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), "directory_view", - view, (GtkDestroyNotify) gtk_object_unref); - gtk_object_ref (GTK_OBJECT (view)); - gtk_signal_connect(GTK_OBJECT (menu_item), "activate", - GTK_SIGNAL_FUNC (open_cb), files->data); - } - gtk_widget_show (menu_item); - gtk_menu_append (menu, menu_item); + append_one_selection_context_menu_item (menu, + FM_DIRECTORY_VIEW_MENU_PATH_OPEN, + item_count, + "directory_view", + view, + (GtkDestroyNotify)gtk_object_unref, + TRUE, + open_cb, + files->data); + + append_one_selection_context_menu_item (menu, + FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW, + item_count, + "directory_view", + view, + (GtkDestroyNotify)gtk_object_unref, + TRUE, + open_in_new_window_cb, + files); + + append_one_selection_context_menu_item (menu, + FM_DIRECTORY_VIEW_MENU_PATH_DELETE, + item_count, + "directory_view", + view, + (GtkDestroyNotify)gtk_object_unref, + TRUE, + delete_cb, + files); +} - if (item_count == 1) { - label_string = g_strdup (_("Open in New Window")); - } else { - label_string = g_strdup_printf (_("Open in %d New Windows"), item_count); - } - menu_item = gtk_menu_item_new_with_label (label_string); - g_free (label_string); - /* Store directory view in menu item so callback can access it. */ - gtk_object_set_data_full (GTK_OBJECT (menu_item), "directory_view", - view, (GtkDestroyNotify) gtk_object_unref); - gtk_object_ref (GTK_OBJECT (view)); - gtk_signal_connect(GTK_OBJECT (menu_item), "activate", - GTK_SIGNAL_FUNC (open_in_new_window_cb), files); - gtk_widget_show (menu_item); - gtk_menu_append (menu, menu_item); +static void +fm_directory_view_real_merge_menus (FMDirectoryView *view, BonoboUIHandler *ui_handler) +{ + /* FIXME: The first few items here have magic number indexes. Need to + * invent and use a scheme whereby Nautilus publishes some or all of + * its menu item paths so that components can merge items into the + * right places without special knowledge like this. + */ + bonobo_ui_handler_menu_new_item (ui_handler, + FM_DIRECTORY_VIEW_MENU_PATH_OPEN, + _("_Open"), + _("Open the selected item in this window"), + 1, + BONOBO_UI_HANDLER_PIXMAP_NONE, + NULL, + 'O', + GDK_CONTROL_MASK, + bonobo_menu_open_cb, + view); + bonobo_ui_handler_menu_new_item (ui_handler, + FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW, + _("Open in New Window"), + _("Open each selected item in a new window"), + 2, + BONOBO_UI_HANDLER_PIXMAP_NONE, + NULL, + 0, + 0, + bonobo_menu_open_in_new_window_cb, + view); + bonobo_ui_handler_menu_new_item (ui_handler, + FM_DIRECTORY_VIEW_MENU_PATH_DELETE, + _("Delete..."), + _("Delete all selected items"), + 3, + BONOBO_UI_HANDLER_PIXMAP_NONE, + NULL, + 0, + 0, + bonobo_menu_delete_cb, + view); + bonobo_ui_handler_menu_new_item (ui_handler, + FM_DIRECTORY_VIEW_MENU_PATH_SELECT_ALL, + _("Select All"), + _("Select all items in this window"), + bonobo_ui_handler_menu_get_pos (ui_handler, FM_DIRECTORY_VIEW_MENU_PATH_SELECT_ALL), + BONOBO_UI_HANDLER_PIXMAP_NONE, + NULL, + 0, + 0, + (BonoboUIHandlerCallbackFunc)select_all_cb, + view); +} - /* create and install the "Delete" item */ - - menu_item = gtk_menu_item_new_with_label (_("Delete...")); - gtk_object_set_data_full (GTK_OBJECT (menu_item), "directory_view", - view, (GtkDestroyNotify) gtk_object_unref); - gtk_object_ref (GTK_OBJECT (view)); - gtk_signal_connect(GTK_OBJECT (menu_item), "activate", - GTK_SIGNAL_FUNC (delete_cb), files); - gtk_widget_show (menu_item); - gtk_menu_append (menu, menu_item); +static void +update_one_menu_item (BonoboUIHandler *local_ui_handler, const char* menu_path, int item_count) +{ + char *label_string; + gboolean sensitive; + + compute_menu_item_info (menu_path, item_count, TRUE, &label_string, &sensitive); + bonobo_ui_handler_menu_set_sensitivity (local_ui_handler, menu_path, sensitive); + bonobo_ui_handler_menu_set_label (local_ui_handler, menu_path, label_string); + g_free (label_string); } -/* FIXME - need better architecture for setting these. */ +static void +fm_directory_view_real_update_menus (FMDirectoryView *view) +{ + BonoboUIHandler *handler; + GList *selection; + int count; + + handler = bonobo_control_get_ui_handler (get_bonobo_control (view)); + selection = fm_directory_view_get_selection (view); + count = g_list_length (selection); + nautilus_file_list_free (selection); + + update_one_menu_item (handler, FM_DIRECTORY_VIEW_MENU_PATH_OPEN, count); + update_one_menu_item (handler, FM_DIRECTORY_VIEW_MENU_PATH_OPEN_IN_NEW_WINDOW, count); + update_one_menu_item (handler, FM_DIRECTORY_VIEW_MENU_PATH_DELETE, count); +} static GtkMenu * create_selection_context_menu (FMDirectoryView *view) @@ -1259,6 +1476,9 @@ fm_directory_view_notify_selection_changed (FMDirectoryView *view) { g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); + /* Update menu item states to match selection */ + fm_directory_view_update_menus (view); + /* Schedule a display of the new selection. */ if (view->details->display_selection_idle_id == 0) view->details->display_selection_idle_id @@ -1356,6 +1576,23 @@ fm_directory_view_load_uri (FMDirectoryView *view, view); } + +/** + * fm_directory_view_merge_menus: + * + * Add this view's menus to the window's menu bar. + * @view: FMDirectoryView in question. + * @ui_handler: BonoboUIHandler to use for bonobo_menu calls. + */ +static void +fm_directory_view_merge_menus (FMDirectoryView *view, BonoboUIHandler *ui_handler) +{ + g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); + g_return_if_fail (BONOBO_IS_UI_HANDLER (ui_handler)); + + (* FM_DIRECTORY_VIEW_CLASS (GTK_OBJECT (view)->klass)->merge_menus) (view, ui_handler); +} + static void disconnect_model_handlers (FMDirectoryView *view) { @@ -1400,3 +1637,17 @@ fm_directory_view_stop (FMDirectoryView *view) display_pending_files (view); stop_load (view, FALSE); } + +/** + * fm_directory_view_update_menus: + * + * Update the sensitivity and wording of dynamic menu items. + * @view: FMDirectoryView in question. + */ +void +fm_directory_view_update_menus (FMDirectoryView *view) +{ + g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); + + (* FM_DIRECTORY_VIEW_CLASS (GTK_OBJECT (view)->klass)->update_menus) (view); +} diff --git a/src/file-manager/fm-directory-view.h b/src/file-manager/fm-directory-view.h index 6909df49d..b0b17455d 100644 --- a/src/file-manager/fm-directory-view.h +++ b/src/file-manager/fm-directory-view.h @@ -25,6 +25,7 @@ #ifndef FM_DIRECTORY_VIEW_H #define FM_DIRECTORY_VIEW_H +#include <bonobo/bonobo-ui-handler.h> #include <gtk/gtkmenu.h> #include <gtk/gtkscrolledwindow.h> #include <libnautilus/ntl-content-view-frame.h> @@ -132,6 +133,20 @@ struct _FMDirectoryViewClass { /* select_all is a function pointer that subclasses must override to * select all of the items in the view */ void (* select_all) (FMDirectoryView *view); + + /* merge_menus is a function pointer that subclasses can override to + * add their own menu items to the window's menu bar. + * If overridden, subclasses must call parent class's function. + */ + void (* merge_menus) (FMDirectoryView *view, + BonoboUIHandler *ui_handler); + + /* update_menus is a function pointer that subclasses can override to + * update the sensitivity or wording of menu items in the menu bar. + * It is called (at least) whenever the selection changes. If overridden, + * subclasses must call parent class's function. + */ + void (* update_menus) (FMDirectoryView *view); }; @@ -177,5 +192,6 @@ void fm_directory_view_notify_selection_changed (FMDir NautilusDirectory * fm_directory_view_get_model (FMDirectoryView *view); void fm_directory_view_pop_up_background_context_menu (FMDirectoryView *view); void fm_directory_view_pop_up_selection_context_menu (FMDirectoryView *view); +void fm_directory_view_update_menus (FMDirectoryView *view); #endif /* FM_DIRECTORY_VIEW_H */ diff --git a/src/nautilus-navigation-window-menus.c b/src/nautilus-navigation-window-menus.c index 27fb9b326..7e5d2583d 100644 --- a/src/nautilus-navigation-window-menus.c +++ b/src/nautilus-navigation-window-menus.c @@ -32,6 +32,7 @@ #include <libnautilus/nautilus-gtk-extensions.h> #include <libnautilus/nautilus-icon-factory.h> +#include <libnautilus/nautilus-string.h> static void activate_bookmark_in_menu_item (BonoboUIHandler *uih, @@ -53,6 +54,7 @@ static void debug_menu_show_color_picker_cb (GtkWidget *wid NautilusWindow *window); static void refresh_bookmarks_in_go_menu (NautilusWindow *window); static void refresh_bookmarks_in_bookmarks_menu (NautilusWindow *window); +static void update_eazel_theme_menu_item (NautilusWindow *window); /* Struct that stores all the info necessary to activate a bookmark. */ @@ -99,8 +101,8 @@ file_menu_exit_cb (GtkWidget *widget, } static void -edit_menu_prefs_cb(GtkWidget *widget, - GtkWindow *mainwin) +general_settings_cb (GtkWidget *widget, + GtkWindow *mainwin) { nautilus_prefs_ui_show(mainwin); } @@ -138,8 +140,6 @@ static GnomeUIInfo edit_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'A', GDK_CONTROL_MASK, NULL }, - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_MENU_PREFERENCES_ITEM(edit_menu_prefs_cb, NULL), GNOMEUIINFO_END }; @@ -226,6 +226,40 @@ static GnomeUIInfo bookmarks_menu_info[] = { GNOMEUIINFO_END }; +static void +use_eazel_theme_icons_cb (GtkCheckMenuItem *item, gpointer user_data) +{ + char *theme; + + theme = nautilus_icon_factory_get_theme (); + if (nautilus_strcmp (theme, "eazel") == 0) { + nautilus_icon_factory_set_theme (NULL); + } else { + nautilus_icon_factory_set_theme ("eazel"); + } + g_free (theme); +} + +static GnomeUIInfo settings_menu_info[] = { + { + GNOME_APP_UI_ITEM, + N_("General Settings..."), N_("Customize various aspects of Nautilus's appearance and behavior"), + general_settings_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_TOGGLEITEM, + N_("Use _Eazel Theme Icons"), + N_("Select whether to use standard or Eazel icons"), + use_eazel_theme_icons_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, (GdkModifierType)0, NULL + }, + GNOMEUIINFO_END +}; + static GnomeUIInfo help_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -248,6 +282,7 @@ static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_EDIT_TREE (edit_menu_info), GNOMEUIINFO_SUBTREE(N_("_Go"), go_menu_info), GNOMEUIINFO_SUBTREE(N_("_Bookmarks"), bookmarks_menu_info), + GNOMEUIINFO_MENU_SETTINGS_TREE (settings_menu_info), GNOMEUIINFO_MENU_HELP_TREE (help_menu_info), GNOMEUIINFO_SUBTREE(N_("_Debug"), debug_menu_info), GNOMEUIINFO_END @@ -532,8 +567,9 @@ nautilus_window_initialize_menus (NautilusWindow *window) bonobo_ui_handler_menu_add_list (ui_handler, "/", menu_items); bonobo_ui_handler_menu_free_list (menu_items); - /* desensitize the items that haven't yet been implemented - * FIXME: these all need to be implemented. + /* Desensitize the items that aren't implemented at this level. + * Some (hopefully all) will be overridden by implementations by the + * different content views. */ bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Undo", FALSE); bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Cut", FALSE); @@ -542,6 +578,16 @@ nautilus_window_initialize_menus (NautilusWindow *window) bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Clear", FALSE); bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Select All", FALSE); + /* Set initial toggle state of Eazel theme menu item */ + update_eazel_theme_menu_item (window); + + /* Sign up to be notified of icon theme changes so Use Eazel Theme Icons + * menu item will show correct toggle state. */ + gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (), + "theme_changed", + update_eazel_theme_menu_item, + GTK_OBJECT (window)); + nautilus_window_initialize_bookmarks_menu (window); nautilus_window_initialize_go_menu (window); } @@ -622,3 +668,14 @@ refresh_bookmarks_in_go_menu (NautilusWindow *window) } } +static void +update_eazel_theme_menu_item (NautilusWindow *window) +{ + g_assert (NAUTILUS_IS_WINDOW (window)); + + bonobo_ui_handler_menu_set_toggle_state ( + window->uih, + "/Settings/Use Eazel Theme Icons", + nautilus_eat_strcmp (nautilus_icon_factory_get_theme (), "eazel") == 0); +} + diff --git a/src/nautilus-view-frame-nautilus-view.c b/src/nautilus-view-frame-nautilus-view.c index d626534ae..870b92808 100644 --- a/src/nautilus-view-frame-nautilus-view.c +++ b/src/nautilus-view-frame-nautilus-view.c @@ -55,6 +55,8 @@ nautilus_view_try_load_client(NautilusView *view, CORBA_Object obj, CORBA_Enviro bonobo_object_add_interface(BONOBO_OBJECT(nvi->control_frame), view->view_frame); bonobo_control_frame_bind_to_control(BONOBO_CONTROL_FRAME(nvi->control_frame), control); + /* We activate the bonobo control immediately */ + bonobo_control_frame_control_activate (BONOBO_CONTROL_FRAME (nvi->control_frame)); view->client_widget = bonobo_control_frame_get_widget(BONOBO_CONTROL_FRAME(nvi->control_frame)); Bonobo_Unknown_unref(control, ev); @@ -73,6 +75,8 @@ destroy_nautilus_view(NautilusView *view, CORBA_Environment *ev) { NautilusViewInfo *nvi = view->component_data; + bonobo_control_frame_control_deactivate (BONOBO_CONTROL_FRAME (nvi->control_frame)); + CORBA_Object_release(nvi->view_client, ev); g_free(nvi); diff --git a/src/nautilus-window-menus.c b/src/nautilus-window-menus.c index 27fb9b326..7e5d2583d 100644 --- a/src/nautilus-window-menus.c +++ b/src/nautilus-window-menus.c @@ -32,6 +32,7 @@ #include <libnautilus/nautilus-gtk-extensions.h> #include <libnautilus/nautilus-icon-factory.h> +#include <libnautilus/nautilus-string.h> static void activate_bookmark_in_menu_item (BonoboUIHandler *uih, @@ -53,6 +54,7 @@ static void debug_menu_show_color_picker_cb (GtkWidget *wid NautilusWindow *window); static void refresh_bookmarks_in_go_menu (NautilusWindow *window); static void refresh_bookmarks_in_bookmarks_menu (NautilusWindow *window); +static void update_eazel_theme_menu_item (NautilusWindow *window); /* Struct that stores all the info necessary to activate a bookmark. */ @@ -99,8 +101,8 @@ file_menu_exit_cb (GtkWidget *widget, } static void -edit_menu_prefs_cb(GtkWidget *widget, - GtkWindow *mainwin) +general_settings_cb (GtkWidget *widget, + GtkWindow *mainwin) { nautilus_prefs_ui_show(mainwin); } @@ -138,8 +140,6 @@ static GnomeUIInfo edit_menu_info[] = { GNOME_APP_PIXMAP_NONE, NULL, 'A', GDK_CONTROL_MASK, NULL }, - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_MENU_PREFERENCES_ITEM(edit_menu_prefs_cb, NULL), GNOMEUIINFO_END }; @@ -226,6 +226,40 @@ static GnomeUIInfo bookmarks_menu_info[] = { GNOMEUIINFO_END }; +static void +use_eazel_theme_icons_cb (GtkCheckMenuItem *item, gpointer user_data) +{ + char *theme; + + theme = nautilus_icon_factory_get_theme (); + if (nautilus_strcmp (theme, "eazel") == 0) { + nautilus_icon_factory_set_theme (NULL); + } else { + nautilus_icon_factory_set_theme ("eazel"); + } + g_free (theme); +} + +static GnomeUIInfo settings_menu_info[] = { + { + GNOME_APP_UI_ITEM, + N_("General Settings..."), N_("Customize various aspects of Nautilus's appearance and behavior"), + general_settings_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, 0, NULL + }, + GNOMEUIINFO_SEPARATOR, + { + GNOME_APP_UI_TOGGLEITEM, + N_("Use _Eazel Theme Icons"), + N_("Select whether to use standard or Eazel icons"), + use_eazel_theme_icons_cb, NULL, NULL, + GNOME_APP_PIXMAP_NONE, NULL, + 0, (GdkModifierType)0, NULL + }, + GNOMEUIINFO_END +}; + static GnomeUIInfo help_menu_info[] = { { GNOME_APP_UI_ITEM, @@ -248,6 +282,7 @@ static GnomeUIInfo main_menu[] = { GNOMEUIINFO_MENU_EDIT_TREE (edit_menu_info), GNOMEUIINFO_SUBTREE(N_("_Go"), go_menu_info), GNOMEUIINFO_SUBTREE(N_("_Bookmarks"), bookmarks_menu_info), + GNOMEUIINFO_MENU_SETTINGS_TREE (settings_menu_info), GNOMEUIINFO_MENU_HELP_TREE (help_menu_info), GNOMEUIINFO_SUBTREE(N_("_Debug"), debug_menu_info), GNOMEUIINFO_END @@ -532,8 +567,9 @@ nautilus_window_initialize_menus (NautilusWindow *window) bonobo_ui_handler_menu_add_list (ui_handler, "/", menu_items); bonobo_ui_handler_menu_free_list (menu_items); - /* desensitize the items that haven't yet been implemented - * FIXME: these all need to be implemented. + /* Desensitize the items that aren't implemented at this level. + * Some (hopefully all) will be overridden by implementations by the + * different content views. */ bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Undo", FALSE); bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Cut", FALSE); @@ -542,6 +578,16 @@ nautilus_window_initialize_menus (NautilusWindow *window) bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Clear", FALSE); bonobo_ui_handler_menu_set_sensitivity(ui_handler, "/Edit/Select All", FALSE); + /* Set initial toggle state of Eazel theme menu item */ + update_eazel_theme_menu_item (window); + + /* Sign up to be notified of icon theme changes so Use Eazel Theme Icons + * menu item will show correct toggle state. */ + gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (), + "theme_changed", + update_eazel_theme_menu_item, + GTK_OBJECT (window)); + nautilus_window_initialize_bookmarks_menu (window); nautilus_window_initialize_go_menu (window); } @@ -622,3 +668,14 @@ refresh_bookmarks_in_go_menu (NautilusWindow *window) } } +static void +update_eazel_theme_menu_item (NautilusWindow *window) +{ + g_assert (NAUTILUS_IS_WINDOW (window)); + + bonobo_ui_handler_menu_set_toggle_state ( + window->uih, + "/Settings/Use Eazel Theme Icons", + nautilus_eat_strcmp (nautilus_icon_factory_get_theme (), "eazel") == 0); +} + diff --git a/src/ntl-prefs.c b/src/ntl-prefs.c index cfa88a1e3..6d4baea08 100644 --- a/src/ntl-prefs.c +++ b/src/ntl-prefs.c @@ -104,7 +104,7 @@ nautilus_prefs_ui_show(GtkWindow *transient_for) { GtkWidget *notebook; - dialog = gnome_dialog_new(_("Preferences"), _("OK"), _("Cancel"), NULL); + dialog = gnome_dialog_new(_("General Settings"), _("OK"), _("Cancel"), NULL); gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); diff --git a/src/ntl-view-nautilus.c b/src/ntl-view-nautilus.c index d626534ae..870b92808 100644 --- a/src/ntl-view-nautilus.c +++ b/src/ntl-view-nautilus.c @@ -55,6 +55,8 @@ nautilus_view_try_load_client(NautilusView *view, CORBA_Object obj, CORBA_Enviro bonobo_object_add_interface(BONOBO_OBJECT(nvi->control_frame), view->view_frame); bonobo_control_frame_bind_to_control(BONOBO_CONTROL_FRAME(nvi->control_frame), control); + /* We activate the bonobo control immediately */ + bonobo_control_frame_control_activate (BONOBO_CONTROL_FRAME (nvi->control_frame)); view->client_widget = bonobo_control_frame_get_widget(BONOBO_CONTROL_FRAME(nvi->control_frame)); Bonobo_Unknown_unref(control, ev); @@ -73,6 +75,8 @@ destroy_nautilus_view(NautilusView *view, CORBA_Environment *ev) { NautilusViewInfo *nvi = view->component_data; + bonobo_control_frame_control_deactivate (BONOBO_CONTROL_FRAME (nvi->control_frame)); + CORBA_Object_release(nvi->view_client, ev); g_free(nvi); |