diff options
Diffstat (limited to 'src/nautilus-toolbar.c')
-rw-r--r-- | src/nautilus-toolbar.c | 425 |
1 files changed, 261 insertions, 164 deletions
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c index 642f524bc..d0e428436 100644 --- a/src/nautilus-toolbar.c +++ b/src/nautilus-toolbar.c @@ -28,7 +28,6 @@ #include "nautilus-location-entry.h" #include "nautilus-pathbar.h" -#include "nautilus-actions.h" #include <libnautilus-private/nautilus-global-preferences.h> #include <libnautilus-private/nautilus-ui-utilities.h> @@ -42,15 +41,32 @@ typedef enum { NAUTILUS_NAVIGATION_DIRECTION_FORWARD } NautilusNavigationDirection; -struct _NautilusToolbarPriv { +struct _NautilusToolbarPrivate { NautilusWindow *window; + GtkWidget *path_bar_container; + GtkWidget *location_entry_container; GtkWidget *path_bar; GtkWidget *location_entry; gboolean show_location_entry; guint popup_timeout_id; + + gdouble scale_zoom_level; + + GtkWidget *view_button; + GtkWidget *action_button; + + GtkWidget *view_menu_widget; + GtkAdjustment *zoom_adjustment_grid; + GtkAdjustment *zoom_adjustment_list; + GtkAdjustment *active_zoom_adjustment; + GtkWidget *zoom_level_scale; + GMenu *action_menu; + + GtkWidget *forward_button; + GtkWidget *back_button; }; enum { @@ -61,9 +77,37 @@ enum { static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; -G_DEFINE_TYPE (NautilusToolbar, nautilus_toolbar, GTK_TYPE_HEADER_BAR); +G_DEFINE_TYPE_WITH_PRIVATE(NautilusToolbar, nautilus_toolbar, GTK_TYPE_HEADER_BAR); static void unschedule_menu_popup_timeout (NautilusToolbar *self); +static gboolean show_widget_recursive (GtkWidget *widget, + gchar *id); + +static gboolean hide_widget_recursive (GtkWidget *widget, + gchar *id); +void +nautilus_toolbar_update_view_mode (NautilusToolbar *self, + const gchar *view_mode) +{ + gchar *name; + GtkWidget *image; + + if (g_strcmp0 (view_mode, "list") == 0) { + name = "view-list-symbolic"; + self->priv->active_zoom_adjustment = self->priv->zoom_adjustment_list; + } else if (g_strcmp0 (view_mode, "grid") == 0) { + name = "view-grid-symbolic"; + self->priv->active_zoom_adjustment = self->priv->zoom_adjustment_grid; + } + + gtk_range_set_adjustment (GTK_RANGE (self->priv->zoom_level_scale), + self->priv->active_zoom_adjustment); + + image = gtk_image_new (); + gtk_button_set_image (GTK_BUTTON (self->priv->view_button), image); + gtk_image_set_from_icon_name (GTK_IMAGE (image), name, + GTK_ICON_SIZE_MENU); +} static void toolbar_update_appearance (NautilusToolbar *self) @@ -79,45 +123,6 @@ toolbar_update_appearance (NautilusToolbar *self) !show_location_entry); } -static GtkWidget * -toolbar_create_toolbutton (NautilusToolbar *self, - gboolean create_menu, - gboolean create_toggle, - const gchar *name, - const gchar *tooltip) -{ - GtkWidget *button, *image; - GtkActionGroup *action_group; - GtkAction *action; - - action_group = nautilus_window_get_main_action_group (self->priv->window); - - if (create_menu) { - button = gtk_menu_button_new (); - } else if (create_toggle) { - button = gtk_toggle_button_new (); - } else { - button = gtk_button_new (); - } - - image = gtk_image_new (); - - gtk_button_set_image (GTK_BUTTON (button), image); - - if (create_menu) { - gtk_image_set_from_icon_name (GTK_IMAGE (image), name, - GTK_ICON_SIZE_MENU); - gtk_widget_set_tooltip_text (button, tooltip); - } else { - action = gtk_action_group_get_action (action_group, name); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action); - gtk_button_set_label (GTK_BUTTON (button), NULL); - gtk_widget_set_tooltip_text (button, gtk_action_get_tooltip (action)); - } - - return button; -} - static void activate_back_or_forward_menu_item (GtkMenuItem *menu_item, NautilusWindow *window, @@ -145,6 +150,25 @@ activate_forward_menu_item_callback (GtkMenuItem *menu_item, NautilusWindow *win activate_back_or_forward_menu_item (menu_item, window, FALSE); } +void +nautilus_toolbar_sync_navigation_buttons (NautilusToolbar *self) +{ + NautilusWindowSlot *active_slot; + GAction *action; + gboolean enabled; + + /* Check if the back and forward buttons need enabling or disabling. */ + active_slot = nautilus_window_get_active_slot (self->priv->window); + + action = g_action_map_lookup_action (G_ACTION_MAP (self->priv->window), "back"); + enabled = nautilus_window_slot_get_back_history (active_slot) != NULL; + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled); + + action = g_action_map_lookup_action (G_ACTION_MAP (self->priv->window), "forward"); + enabled = nautilus_window_slot_get_forward_history (active_slot) != NULL; + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled); +} + static void fill_menu (NautilusWindow *window, GtkWidget *menu, @@ -316,11 +340,10 @@ schedule_menu_popup_timeout (NautilusToolbar *self, popup_menu_timeout_cb, data, (GDestroyNotify) schedule_menu_data_free); } - static gboolean -tool_button_press_cb (GtkButton *button, - GdkEventButton *event, - gpointer user_data) +navigation_button_press_cb (GtkButton *button, + GdkEventButton *event, + gpointer user_data) { NautilusToolbar *self = user_data; @@ -338,7 +361,7 @@ tool_button_press_cb (GtkButton *button, } static gboolean -tool_button_release_cb (GtkButton *button, +navigation_button_release_cb (GtkButton *button, GdkEventButton *event, gpointer user_data) { @@ -350,137 +373,75 @@ tool_button_release_cb (GtkButton *button, } static void -navigation_button_setup_menu (NautilusToolbar *self, - GtkWidget *button, - NautilusNavigationDirection direction) +zoom_level_changed (GtkRange *range, + NautilusToolbar *self) { - g_object_set_data (G_OBJECT (button), "nav-direction", GUINT_TO_POINTER (direction)); - - g_signal_connect (button, "button-press-event", - G_CALLBACK (tool_button_press_cb), self); - g_signal_connect (button, "button-release-event", - G_CALLBACK (tool_button_release_cb), self); -} - -static gboolean -gear_menu_key_press (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data) -{ - GdkModifierType mask = gtk_accelerator_get_default_mod_mask (); + NautilusWindowSlot *slot; + NautilusView *view; + gdouble zoom_level; - if ((event->state & mask) == 0 && (event->keyval == GDK_KEY_F10)) { - gtk_menu_shell_deactivate (GTK_MENU_SHELL (widget)); - return TRUE; - } + zoom_level = gtk_range_get_value (range); + slot = nautilus_window_get_active_slot (self->priv->window); + view = nautilus_window_slot_get_current_view (slot); - return FALSE; + g_action_group_change_action_state (nautilus_view_get_action_group (view), + "zoom-to-level", + g_variant_new_int32 ((gint) zoom_level)); } static void -nautilus_toolbar_constructed (GObject *obj) +nautilus_toolbar_init (NautilusToolbar *self) { - NautilusToolbar *self = NAUTILUS_TOOLBAR (obj); - GtkWidget *toolbar; - GtkWidget *button; - GtkWidget *menu; - GtkWidget *box; - GtkUIManager *ui_manager; - - G_OBJECT_CLASS (nautilus_toolbar_parent_class)->constructed (obj); - - toolbar = GTK_WIDGET (obj); - - ui_manager = nautilus_window_get_ui_manager (self->priv->window); - - /* Back and Forward */ - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - /* Back */ - button = toolbar_create_toolbutton (self, FALSE, FALSE, NAUTILUS_ACTION_BACK, NULL); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_action_set_icon_name (gtk_activatable_get_related_action (GTK_ACTIVATABLE (button)), - "go-previous-symbolic"); - navigation_button_setup_menu (self, button, NAUTILUS_NAVIGATION_DIRECTION_BACK); - gtk_container_add (GTK_CONTAINER (box), button); + GtkBuilder *builder; - /* Forward */ - button = toolbar_create_toolbutton (self, FALSE, FALSE, NAUTILUS_ACTION_FORWARD, NULL); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_action_set_icon_name (gtk_activatable_get_related_action (GTK_ACTIVATABLE (button)), - "go-next-symbolic"); - navigation_button_setup_menu (self, button, NAUTILUS_NAVIGATION_DIRECTION_FORWARD); - gtk_container_add (GTK_CONTAINER (box), button); - - gtk_style_context_add_class (gtk_widget_get_style_context (box), - GTK_STYLE_CLASS_RAISED); - gtk_style_context_add_class (gtk_widget_get_style_context (box), - GTK_STYLE_CLASS_LINKED); - - gtk_header_bar_pack_start (GTK_HEADER_BAR (toolbar), box); + self->priv = nautilus_toolbar_get_instance_private (self); + gtk_widget_init_template (GTK_WIDGET (self)); self->priv->path_bar = g_object_new (NAUTILUS_TYPE_PATH_BAR, NULL); - gtk_header_bar_pack_start (GTK_HEADER_BAR (toolbar), self->priv->path_bar); + gtk_container_add (GTK_CONTAINER (self->priv->path_bar_container), + self->priv->path_bar); - /* entry-like location bar */ self->priv->location_entry = nautilus_location_entry_new (); - gtk_header_bar_pack_start (GTK_HEADER_BAR (toolbar), self->priv->location_entry); - - /* Action Menu */ - button = toolbar_create_toolbutton (self, TRUE, FALSE, "open-menu-symbolic", _("Location options")); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - menu = gtk_ui_manager_get_widget (ui_manager, "/ActionMenu"); - gtk_widget_set_halign (menu, GTK_ALIGN_END); - gtk_menu_button_set_popup (GTK_MENU_BUTTON (button), menu); - gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.gear-menu"); - g_signal_connect (menu, "key-press-event", G_CALLBACK (gear_menu_key_press), self); - - gtk_header_bar_pack_end (GTK_HEADER_BAR (toolbar), button); - - /* View buttons */ - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - button = toolbar_create_toolbutton (self, FALSE, TRUE, NAUTILUS_ACTION_VIEW_LIST, NULL); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_container_add (GTK_CONTAINER (box), button); - button = toolbar_create_toolbutton (self, FALSE, TRUE, NAUTILUS_ACTION_VIEW_GRID, NULL); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_container_add (GTK_CONTAINER (box), button); - button = toolbar_create_toolbutton (self, TRUE, FALSE, "go-down-symbolic", _("View options")); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_container_add (GTK_CONTAINER (box), button); - menu = gtk_ui_manager_get_widget (ui_manager, "/ViewMenu"); - gtk_menu_button_set_popup (GTK_MENU_BUTTON (button), menu); - - gtk_style_context_add_class (gtk_widget_get_style_context (box), - GTK_STYLE_CLASS_RAISED); - gtk_style_context_add_class (gtk_widget_get_style_context (box), - GTK_STYLE_CLASS_LINKED); - - gtk_header_bar_pack_end (GTK_HEADER_BAR (toolbar), box); - - /* search */ - button = toolbar_create_toolbutton (self, FALSE, TRUE, NAUTILUS_ACTION_SEARCH, NULL); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - gtk_widget_set_margin_start (button, 76); - gtk_header_bar_pack_end (GTK_HEADER_BAR (toolbar), button); - - g_signal_connect_swapped (nautilus_preferences, - "changed::" NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY, - G_CALLBACK (toolbar_update_appearance), self); - - gtk_widget_show_all (toolbar); + gtk_container_add (GTK_CONTAINER (self->priv->location_entry_container), + self->priv->location_entry); + + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml"); + self->priv->view_menu_widget = g_object_ref (GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_widget"))); + self->priv->zoom_level_scale = g_object_ref (GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"))); + self->priv->zoom_adjustment_grid = g_object_ref (GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment_grid"))); + self->priv->zoom_adjustment_list = g_object_ref (GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment_list"))); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (self->priv->view_button), + self->priv->view_menu_widget); + g_object_unref (builder); + + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-action-menu.xml"); + self->priv->action_menu = G_MENU (gtk_builder_get_object (builder, "action-menu")); + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->priv->action_button), + G_MENU_MODEL (self->priv->action_menu)); + g_object_unref (builder); + + g_signal_connect(self->priv->zoom_level_scale, "value-changed", + G_CALLBACK(zoom_level_changed), + self); + + g_object_set_data (G_OBJECT (self->priv->back_button), "nav-direction", + GUINT_TO_POINTER (NAUTILUS_NAVIGATION_DIRECTION_BACK)); + g_object_set_data (G_OBJECT (self->priv->forward_button), "nav-direction", + GUINT_TO_POINTER (NAUTILUS_NAVIGATION_DIRECTION_FORWARD)); + g_signal_connect (self->priv->back_button, "button-press-event", + G_CALLBACK (navigation_button_press_cb), self); + g_signal_connect (self->priv->back_button, "button-release-event", + G_CALLBACK (navigation_button_release_cb), self); + g_signal_connect (self->priv->forward_button, "button-press-event", + G_CALLBACK (navigation_button_press_cb), self); + g_signal_connect (self->priv->forward_button, "button-release-event", + G_CALLBACK (navigation_button_release_cb), self); + + gtk_widget_show_all (GTK_WIDGET (self)); toolbar_update_appearance (self); } static void -nautilus_toolbar_init (NautilusToolbar *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NAUTILUS_TYPE_TOOLBAR, - NautilusToolbarPriv); -} - -static void nautilus_toolbar_get_property (GObject *object, guint property_id, GValue *value, @@ -535,11 +496,12 @@ static void nautilus_toolbar_class_init (NautilusToolbarClass *klass) { GObjectClass *oclass; + GtkWidgetClass *widget_class; + widget_class = GTK_WIDGET_CLASS (klass); oclass = G_OBJECT_CLASS (klass); oclass->get_property = nautilus_toolbar_get_property; oclass->set_property = nautilus_toolbar_set_property; - oclass->constructed = nautilus_toolbar_constructed; oclass->dispose = nautilus_toolbar_dispose; properties[PROP_WINDOW] = @@ -556,8 +518,143 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass) FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_type_class_add_private (klass, sizeof (NautilusToolbarClass)); g_object_class_install_properties (oclass, NUM_PROPERTIES, properties); + + gtk_widget_class_set_template_from_resource (widget_class, + "/org/gnome/nautilus/nautilus-toolbar-ui.xml"); + + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, view_button); + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, action_button); + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, path_bar_container); + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, location_entry_container); + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, back_button); + gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, forward_button); +} + +static gboolean +hide_widget_recursive (GtkWidget *widget, + gchar *id) +{ + GList *children; + GList *child; + gboolean found = FALSE; + + if (g_strcmp0 (gtk_buildable_get_name (GTK_BUILDABLE (widget)), id) == 0) { + gtk_widget_hide (widget); + return TRUE; + } + + if (GTK_IS_CONTAINER (widget)) { + children = gtk_container_get_children (GTK_CONTAINER (widget)); + for (child = children; child != NULL && !found; child = child->next) { + found = hide_widget_recursive (child->data, id); + } + g_list_free (children); + } + + return found; +} + +void +nautilus_toolbar_action_menu_add_item (NautilusToolbar *self, + GMenuItem *item, + const gchar *section_name) +{ + nautilus_gmenu_add_item_in_submodel (self->priv->action_menu, + item, + section_name, + FALSE); +} + +void +nautilus_toolbar_reset_menus (NautilusToolbar *self) +{ + NautilusWindowSlot *slot; + NautilusView *view; + GActionGroup *view_action_group; + GtkBuilder *builder; + + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->priv->action_button), NULL); + + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-action-menu.xml"); + self->priv->action_menu = G_MENU (gtk_builder_get_object (builder, "action-menu")); + /* This ref the action_menu */ + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->priv->action_button), + G_MENU_MODEL (self->priv->action_menu)); + g_object_unref (builder); + + /* Allow actions from the current view to be activated through + * the view menu and action menu of the toolbar */ + slot = nautilus_window_get_active_slot (self->priv->window); + view = nautilus_window_slot_get_current_view (slot); + view_action_group = nautilus_view_get_action_group (view); + gtk_widget_insert_action_group (GTK_WIDGET (self), + "view", + G_ACTION_GROUP (view_action_group)); + + hide_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), "sort_menu"); + hide_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), "sort_trash_time"); + hide_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), "sort_search_relevance"); + hide_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), "visible_columns"); +} + +void +nautilus_toolbar_view_menu_widget_show_element (NautilusToolbar *self, + gchar *id) +{ + g_assert (NAUTILUS_IS_TOOLBAR (self)); + + show_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), id); +} + +void +nautilus_toolbar_view_menu_widget_hide_element (NautilusToolbar *self, + gchar *id) +{ + g_assert (NAUTILUS_IS_TOOLBAR (self)); + + hide_widget_recursive (GTK_WIDGET (self->priv->view_menu_widget), id); +} + +static gboolean +show_widget_recursive (GtkWidget *widget, + gchar *id) +{ + GList *children; + GList *child; + gboolean found = FALSE; + + if (g_strcmp0 (gtk_buildable_get_name (GTK_BUILDABLE (widget)), id) == 0) { + gtk_widget_show (widget); + return TRUE; + } + + if (GTK_IS_CONTAINER (widget)) { + children = gtk_container_get_children (GTK_CONTAINER (widget)); + for (child = children; child != NULL && !found; child = child->next) { + found = show_widget_recursive (child->data, id); + } + g_list_free (children); + } + + return found; +} + +void nautilus_toolbar_view_menu_widget_set_zoom_level (NautilusToolbar *self, + gdouble level) +{ + g_assert (NAUTILUS_IS_TOOLBAR (self)); + + /* We only want to change the level when there's and actual view + * mode set, so skip all other calls to here. Those calls came from + * update_toolbar_menus in the natuilus-view after a parent is set, etc. + * We will receive eventually a mode change and another update here by nautilus view + * update_toolbar_menus */ + if (self->priv->active_zoom_adjustment == NULL) + return; + + gtk_adjustment_set_value (GTK_ADJUSTMENT (self->priv->active_zoom_adjustment), + level); } GtkWidget * |