summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog-20000414107
-rw-r--r--components/history/nautilus-history-view.c23
-rw-r--r--components/history/ntl-history-view.c23
-rw-r--r--libnautilus-extensions/nautilus-string.c40
-rw-r--r--libnautilus-extensions/nautilus-string.h3
-rw-r--r--libnautilus-private/nautilus-string.c40
-rw-r--r--libnautilus-private/nautilus-string.h3
-rw-r--r--libnautilus/nautilus-string.c40
-rw-r--r--libnautilus/nautilus-string.h3
-rw-r--r--src/file-manager/fm-directory-view-icons.c41
-rw-r--r--src/file-manager/fm-directory-view.c433
-rw-r--r--src/file-manager/fm-directory-view.h16
-rw-r--r--src/nautilus-navigation-window-menus.c69
-rw-r--r--src/nautilus-view-frame-nautilus-view.c4
-rw-r--r--src/nautilus-window-menus.c69
-rw-r--r--src/ntl-prefs.c2
-rw-r--r--src/ntl-view-nautilus.c4
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);