[nautilus/wip/gbsneto/view-menu] view: handle view widget



commit 608b9a369e66c135e78263ff347384c89c64a995
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Aug 11 12:33:39 2015 -0300

    view: handle view widget
    
    Makes the view handle the view widget.

 src/nautilus-canvas-view.c  |   14 +++
 src/nautilus-empty-view.c   |    7 ++
 src/nautilus-list-view.c    |   15 +++
 src/nautilus-toolbar-ui.xml |    6 +
 src/nautilus-toolbar.c      |  237 +++++++++++++------------------------------
 src/nautilus-toolbar.h      |    5 +-
 src/nautilus-view.c         |  215 +++++++++++++++++++++++++++++++++++++--
 src/nautilus-view.h         |    6 +
 src/nautilus-window-slot.c  |   49 +++++++++
 src/nautilus-window-slot.h  |    6 +
 src/nautilus-window.c       |    8 +-
 src/nautilus-window.h       |    2 -
 12 files changed, 387 insertions(+), 183 deletions(-)
---
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index 53e37d9..879d1a6 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -105,6 +105,8 @@ struct NautilusCanvasViewDetails
        gboolean supports_manual_layout;
        gboolean supports_scaling;
        gboolean supports_keep_aligned;
+
+        GIcon *icon;
 };
 
 /* Note that the first item in this list is the default sort,
@@ -1834,6 +1836,8 @@ nautilus_canvas_view_finalize (GObject *object)
 
        canvas_view = NAUTILUS_CANVAS_VIEW (object);
 
+        g_clear_object (&canvas_view->details->icon);
+
        g_free (canvas_view->details);
 
        g_signal_handlers_disconnect_by_func (nautilus_preferences,
@@ -1853,6 +1857,14 @@ nautilus_canvas_view_finalize (GObject *object)
        G_OBJECT_CLASS (nautilus_canvas_view_parent_class)->finalize (object);
 }
 
+static GIcon*
+nautilus_canvas_view_get_icon (NautilusView *view)
+{
+        g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
+
+        return NAUTILUS_CANVAS_VIEW (view)->details->icon;
+}
+
 static void
 nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
 {
@@ -1896,6 +1908,7 @@ nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
        nautilus_view_class->get_view_id = nautilus_canvas_view_get_id;
        nautilus_view_class->get_first_visible_file = canvas_view_get_first_visible_file;
        nautilus_view_class->scroll_to_file = canvas_view_scroll_to_file;
+        nautilus_view_class->get_icon = nautilus_canvas_view_get_icon;
 
        properties[PROP_SUPPORTS_AUTO_LAYOUT] =
                g_param_spec_boolean ("supports-auto-layout",
@@ -1937,6 +1950,7 @@ nautilus_canvas_view_init (NautilusCanvasView *canvas_view)
 
        canvas_view->details = g_new0 (NautilusCanvasViewDetails, 1);
        canvas_view->details->sort = &sort_criteria[0];
+        canvas_view->details->icon = g_themed_icon_new ("view-grid-symbolic");
 
        canvas_container = create_canvas_container (canvas_view);
 
diff --git a/src/nautilus-empty-view.c b/src/nautilus-empty-view.c
index 9881b84..5ece1c4 100644
--- a/src/nautilus-empty-view.c
+++ b/src/nautilus-empty-view.c
@@ -229,6 +229,12 @@ nautilus_empty_view_get_id (NautilusView *view)
        return NAUTILUS_EMPTY_VIEW_ID;
 }
 
+static GIcon*
+nautilus_empty_view_get_icon (NautilusView *view)
+{
+        return NULL;
+}
+
 static void
 nautilus_empty_view_class_init (NautilusEmptyViewClass *class)
 {
@@ -266,6 +272,7 @@ nautilus_empty_view_class_init (NautilusEmptyViewClass *class)
        nautilus_view_class->get_view_id = nautilus_empty_view_get_id;
        nautilus_view_class->get_first_visible_file = nautilus_empty_view_get_first_visible_file;
        nautilus_view_class->scroll_to_file = nautilus_empty_view_scroll_to_file;
+        nautilus_view_class->get_icon = nautilus_empty_view_get_icon;
 }
 
 static void
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 20a4882..a9c50d5 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -97,6 +97,8 @@ struct NautilusListViewDetails {
        gulong clipboard_handler_id;
 
        GQuark last_sort_attr;
+
+        GIcon *icon;
 };
 
 struct SelectionForeachData {
@@ -3126,6 +3128,8 @@ nautilus_list_view_finalize (GObject *object)
                                              default_column_order_changed_callback,
                                              list_view);
 
+        g_clear_object (&list_view->details->icon);
+
        G_OBJECT_CLASS (nautilus_list_view_parent_class)->finalize (object);
 }
 
@@ -3240,6 +3244,14 @@ nautilus_list_view_get_id (NautilusView *view)
        return NAUTILUS_LIST_VIEW_ID;
 }
 
+static GIcon*
+nautilus_list_view_get_icon (NautilusView *view)
+{
+        g_return_val_if_fail (NAUTILUS_IS_LIST_VIEW (view), NULL);
+
+        return NAUTILUS_LIST_VIEW (view)->details->icon;
+}
+
 static void
 nautilus_list_view_class_init (NautilusListViewClass *class)
 {
@@ -3277,6 +3289,7 @@ nautilus_list_view_class_init (NautilusListViewClass *class)
        nautilus_view_class->get_view_id = nautilus_list_view_get_id;
        nautilus_view_class->get_first_visible_file = nautilus_list_view_get_first_visible_file;
        nautilus_view_class->scroll_to_file = list_view_scroll_to_file;
+        nautilus_view_class->get_icon = nautilus_list_view_get_icon;
 }
 
 static void
@@ -3285,6 +3298,8 @@ nautilus_list_view_init (NautilusListView *list_view)
        GActionGroup *view_action_group;
        list_view->details = g_new0 (NautilusListViewDetails, 1);
 
+        list_view->details->icon = g_themed_icon_new ("view-list-symbolic");
+
        /* ensure that the zoom level is always set before settings up the tree view columns */
        list_view->details->zoom_level = get_default_zoom_level ();
 
diff --git a/src/nautilus-toolbar-ui.xml b/src/nautilus-toolbar-ui.xml
index a417667..52d5d63 100644
--- a/src/nautilus-toolbar-ui.xml
+++ b/src/nautilus-toolbar-ui.xml
@@ -104,6 +104,12 @@
         <style>
           <class name="image-button"/>
         </style>
+        <child>
+          <object class="GtkImage" id="view_icon">
+            <property name="visible">True</property>
+            <property name="icon-size">1</property>
+          </object>
+        </child>
         <child internal-child="accessible">
           <object class="AtkObject">
             <property name="accessible-name" translatable="yes">View menu</property>
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index 3e33d28..c7c18a0 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -71,21 +71,18 @@ struct _NautilusToolbarPrivate {
         GtkWidget *operations_container;
         GtkWidget *operations_revealer;
         GtkWidget *operations_icon;
-       GtkWidget *view_menu_widget;
-       GtkWidget *sort_menu;
-       GtkWidget *sort_trash_time;
-       GtkWidget *sort_search_relevance;
-       GtkWidget *visible_columns;
-       GtkWidget *stop;
-       GtkWidget *reload;
-       GtkAdjustment *zoom_adjustment;
-       GtkWidget *zoom_level_scale;
+       GtkWidget *view_icon;
        GMenu *action_menu;
 
        GtkWidget *forward_button;
        GtkWidget *back_button;
 
         NautilusProgressInfoManager *progress_manager;
+
+        /* active slot & bindings */
+        NautilusWindowSlot *active_slot;
+        GBinding *icon_binding;
+        GBinding *view_widget_binding;
 };
 
 enum {
@@ -262,66 +259,6 @@ show_menu (NautilusToolbar *self,
                         button, event_time);
 }
 
-static void
-action_view_mode_state_changed (GActionGroup *action_group,
-                               gchar *action_name,
-                               GVariant *value,
-                               gpointer user_data)
-{
-       NautilusToolbar *self = user_data;
-       const gchar *view_mode = g_variant_get_string (value, NULL);
-       const gchar *name;
-       GtkWidget *image;
-
-       if (g_strcmp0 (view_mode, "list") == 0) {
-               name = "view-list-symbolic";
-       } else if (g_strcmp0 (view_mode, "grid") == 0) {
-               name = "view-grid-symbolic";
-       } else {
-               g_assert_not_reached ();
-       }
-
-       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
-action_reload_enabled_changed (GActionGroup *action_group,
-                              gchar *action_name,
-                              gboolean enabled,
-                              gpointer user_data)
-{
-       NautilusToolbar *self = user_data;
-       gtk_widget_set_visible (self->priv->reload, enabled);
-}
-
-static void
-action_stop_enabled_changed (GActionGroup *action_group,
-                            gchar *action_name,
-                            gboolean enabled,
-                            gpointer user_data)
-{
-       NautilusToolbar *self = user_data;
-       gtk_widget_set_visible (self->priv->stop, enabled);
-}
-
-static void
-nautilus_toolbar_set_window (NautilusToolbar *self,
-                            NautilusWindow *window)
-
-{
-       self->priv->window = window;
-
-       g_signal_connect (self->priv->window, "action-enabled-changed::stop",
-                         G_CALLBACK (action_stop_enabled_changed), self);
-       g_signal_connect (self->priv->window, "action-enabled-changed::reload",
-                         G_CALLBACK (action_reload_enabled_changed), self);
-       g_signal_connect (self->priv->window, "action-state-changed::view-mode",
-                         G_CALLBACK (action_view_mode_state_changed), self);
-}
-
 #define MENU_POPUP_TIMEOUT 1200
 
 typedef struct {
@@ -405,30 +342,6 @@ navigation_button_release_cb (GtkButton *button,
         return FALSE;
 }
 
-static void
-zoom_level_changed (GtkRange *range,
-                   NautilusToolbar *self)
-{
-       NautilusWindowSlot *slot;
-       NautilusView *view;
-       gdouble zoom_level;
-
-       zoom_level = gtk_range_get_value (range);
-       slot = nautilus_window_get_active_slot (self->priv->window);
-       view = nautilus_window_slot_get_current_view (slot);
-
-       g_action_group_change_action_state (nautilus_view_get_action_group (view),
-                                           "zoom-to-level",
-                                           g_variant_new_int32 ((gint) zoom_level));
-}
-
-static void
-view_menu_popover_closed (GtkPopover *popover,
-                         NautilusToolbar *self)
-{
-        gtk_widget_grab_focus (GTK_WIDGET (self->priv->window));
-}
-
 static gboolean
 should_hide_operations_button (NautilusToolbar *self)
 {
@@ -755,24 +668,6 @@ nautilus_toolbar_init (NautilusToolbar *self)
        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 =  GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_widget"));
-       self->priv->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
-       self->priv->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
-
-       self->priv->sort_menu =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
-       self->priv->sort_trash_time =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
-       self->priv->sort_search_relevance =  GTK_WIDGET (gtk_builder_get_object (builder, 
"sort_search_relevance"));
-       self->priv->visible_columns =  GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
-       self->priv->reload =  GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
-       self->priv->stop =  GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
-
-       g_signal_connect (self->priv->view_menu_widget, "closed",
-                         G_CALLBACK (view_menu_popover_closed), self);
-       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),
@@ -796,8 +691,6 @@ nautilus_toolbar_init (NautilusToolbar *self)
                          G_CALLBACK (navigation_button_press_cb), self);
        g_signal_connect (self->priv->forward_button, "button-release-event",
                          G_CALLBACK (navigation_button_release_cb), self);
-       g_signal_connect (self->priv->zoom_level_scale, "value-changed",
-                         G_CALLBACK (zoom_level_changed), self);
 
        gtk_widget_show_all (GTK_WIDGET (self));
        toolbar_update_appearance (self);
@@ -831,7 +724,7 @@ nautilus_toolbar_set_property (GObject *object,
 
        switch (property_id) {
        case PROP_WINDOW:
-               nautilus_toolbar_set_window (self, g_value_get_object (value));
+               self->priv->window = g_value_get_object (value);
                break;
        case PROP_SHOW_LOCATION_ENTRY:
                nautilus_toolbar_set_show_location_entry (self, g_value_get_boolean (value));
@@ -901,6 +794,7 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
        gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, operations_container);
        gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, operations_revealer);
        gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, view_button);
+        gtk_widget_class_bind_template_child_private (widget_class, NautilusToolbar, view_icon);
        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);
@@ -911,56 +805,6 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, on_operations_button_toggled);
 }
 
-void
-nautilus_toolbar_reset_menus (NautilusToolbar *self)
-{
-       NautilusWindowSlot *slot;
-       NautilusView *view;
-       GActionGroup *view_action_group;
-       GVariant *variant;
-       GVariantIter iter;
-       gboolean show_sort_trash, show_sort_search, show_sort_access, show_sort_modification, enable_sort;
-       const gchar *hint;
-
-       /* 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));
-
-       gtk_widget_set_visible (self->priv->visible_columns,
-                               g_action_group_has_action (view_action_group, "visible-columns"));
-
-       enable_sort = g_action_group_get_action_enabled (view_action_group, "sort");
-       show_sort_trash = show_sort_search = show_sort_modification = show_sort_access = FALSE;
-       gtk_widget_set_visible (self->priv->sort_menu, enable_sort);
-
-       if (enable_sort) {
-               variant = g_action_group_get_action_state_hint (view_action_group, "sort");
-               g_variant_iter_init (&iter, variant);
-
-               while (g_variant_iter_next (&iter, "&s", &hint)) {
-                       if (g_strcmp0 (hint, "trash-time") == 0)
-                               show_sort_trash = TRUE;
-                       if (g_strcmp0 (hint, "search-relevance") == 0)
-                               show_sort_search = TRUE;
-               }
-
-               g_variant_unref (variant);
-       }
-
-       gtk_widget_set_visible (self->priv->sort_trash_time, show_sort_trash);
-       gtk_widget_set_visible (self->priv->sort_search_relevance, show_sort_search);
-
-       variant = g_action_group_get_action_state (view_action_group, "zoom-to-level");
-       gtk_adjustment_set_value (self->priv->zoom_adjustment,
-                                 g_variant_get_int32 (variant));
-       g_variant_unref (variant);
-}
-
 GtkWidget *
 nautilus_toolbar_new ()
 {
@@ -1000,3 +844,68 @@ nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
                g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_LOCATION_ENTRY]);
        }
 }
+
+static gboolean
+nautilus_toolbar_view_widget_transform_to (GBinding     *binding,
+                                           const GValue *from_value,
+                                           GValue       *to_value,
+                                           gpointer      user_data)
+{
+        NautilusToolbar *toolbar;
+        GtkWidget *view_widget;
+
+        toolbar = NAUTILUS_TOOLBAR (user_data);
+        view_widget = g_value_get_object (from_value);
+
+        gtk_widget_set_sensitive (toolbar->priv->view_button, view_widget != NULL);
+
+        if (view_widget) {
+                if (!GTK_IS_POPOVER (view_widget)) {
+                        GtkWidget *popover;
+
+                        popover = gtk_popover_new (toolbar->priv->view_button);
+                        gtk_container_add (GTK_CONTAINER (popover), view_widget);
+
+                        view_widget = popover;
+                }
+        }
+
+        g_value_set_object (to_value, view_widget);
+
+        return TRUE;
+}
+
+void
+nautilus_toolbar_set_active_slot (NautilusToolbar    *toolbar,
+                                  NautilusWindowSlot *slot)
+{
+        g_return_if_fail (NAUTILUS_IS_TOOLBAR (toolbar));
+
+        g_clear_pointer (&toolbar->priv->icon_binding, g_binding_unbind);
+        g_clear_pointer (&toolbar->priv->view_widget_binding, g_binding_unbind);
+
+        if (toolbar->priv->active_slot != slot) {
+                toolbar->priv->active_slot = slot;
+
+                if (slot) {
+                        GIcon *icon;
+
+                        icon = nautilus_window_slot_get_icon (slot);
+
+                        gtk_image_set_from_gicon (GTK_IMAGE (toolbar->priv->view_icon), icon, 
GTK_ICON_SIZE_BUTTON);
+
+                        toolbar->priv->icon_binding = g_object_bind_property (slot, "icon",
+                                                                              toolbar->priv->view_icon, 
"gicon",
+                                                                              G_BINDING_DEFAULT);
+                        toolbar->priv->view_widget_binding =
+                                        g_object_bind_property_full (slot, "view-widget",
+                                                                     toolbar->priv->view_button, "popover",
+                                                                     G_BINDING_DEFAULT | 
G_BINDING_SYNC_CREATE,
+                                                                     (GBindingTransformFunc) 
nautilus_toolbar_view_widget_transform_to,
+                                                                     NULL,
+                                                                     toolbar,
+                                                                     NULL);
+                }
+
+        }
+}
diff --git a/src/nautilus-toolbar.h b/src/nautilus-toolbar.h
index f281b95..c66ef91 100644
--- a/src/nautilus-toolbar.h
+++ b/src/nautilus-toolbar.h
@@ -27,6 +27,7 @@
 
 #include <gtk/gtk.h>
 
+#include "nautilus-window-slot.h"
 
 #define NAUTILUS_TYPE_TOOLBAR nautilus_toolbar_get_type()
 #define NAUTILUS_TOOLBAR(obj) \
@@ -70,6 +71,8 @@ GMenu     *nautilus_toolbar_get_action_menu (NautilusToolbar *self);
 
 void nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
                                               gboolean show_location_entry);
-void nautilus_toolbar_reset_menus (NautilusToolbar *self);
+
+void       nautilus_toolbar_set_active_slot    (NautilusToolbar    *toolbar,
+                                                NautilusWindowSlot *slot);
 
 #endif /* __NAUTILUS_TOOLBAR_H__ */
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 073bacc..316ca3b 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -141,6 +141,8 @@ enum {
 enum {
        PROP_WINDOW_SLOT = 1,
        PROP_SUPPORTS_ZOOMING,
+        PROP_ICON,
+        PROP_VIEW_WIDGET,
        NUM_PROPERTIES
 };
 
@@ -238,6 +240,21 @@ struct NautilusViewDetails
         guint floating_bar_set_status_timeout_id;
         guint floating_bar_loading_timeout_id;
         GtkWidget *floating_bar;
+
+        /* View menu */
+        GtkWidget *view_menu_widget;
+        GtkWidget *view_icon;
+        GtkWidget *sort_menu;
+        GtkWidget *sort_trash_time;
+        GtkWidget *sort_search_relevance;
+        GtkWidget *visible_columns;
+        GtkWidget *stop;
+        GtkWidget *reload;
+        GtkAdjustment *zoom_adjustment;
+        GtkWidget *zoom_level_scale;
+
+        gulong stop_signal_handler;
+        gulong reload_signal_handler;
 };
 
 typedef struct {
@@ -593,6 +610,39 @@ nautilus_view_using_manual_layout (NautilusView  *view)
 }
 
 /**
+ * nautilus_view_get_icon:
+ * @view: a #NautilusView
+ *
+ * Retrieves the #GIcon that represents @view.
+ *
+ * Returns: (transfer none): the #Gicon that represents @view
+ */
+GIcon*
+nautilus_view_get_icon (NautilusView *view)
+{
+        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
+
+        return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->get_icon (view);
+}
+
+/**
+ * nautilus_view_get_view_widget:
+ * @view: a #NautilusView
+ *
+ * Retrieves the view menu, as a #GtkWidget. If it's %NULL,
+ * the button renders insensitive.
+ *
+ * Returns: (transfer none): a #GtkWidget for the view menu
+ */
+GtkWidget*
+nautilus_view_get_view_widget (NautilusView *view)
+{
+        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
+
+        return view->details->view_menu_widget;
+}
+
+/**
  * nautilus_view_can_rename_file
  *
  * Determine whether a file can be renamed.
@@ -1514,6 +1564,15 @@ action_select_pattern (GSimpleAction *action,
 }
 
 static void
+zoom_level_changed (GtkRange     *range,
+                    NautilusView *view)
+{
+        g_action_group_change_action_state (view->details->view_action_group,
+                                            "zoom-to-level",
+                                            g_variant_new_int32 (gtk_range_get_value (range)));
+}
+
+static void
 reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
                           NautilusDirectory *directory, GFile *target_location)
 {
@@ -6734,6 +6793,52 @@ nautilus_view_update_context_menus (NautilusView *view)
        NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->update_context_menus (view);
 }
 
+static void
+nautilus_view_reset_view_menu (NautilusView *view)
+{
+       GActionGroup *view_action_group;
+       GVariant *variant;
+       GVariantIter iter;
+       gboolean show_sort_trash, show_sort_search, show_sort_access, show_sort_modification, enable_sort;
+       const gchar *hint;
+
+       /* Allow actions from the current view to be activated through
+        * the view menu and action menu of the toolbar */
+       view_action_group = nautilus_view_get_action_group (view);
+        gtk_widget_insert_action_group (GTK_WIDGET (view),
+                                       "view",
+                                       G_ACTION_GROUP (view_action_group));
+
+       gtk_widget_set_visible (view->details->visible_columns,
+                               g_action_group_has_action (view_action_group, "visible-columns"));
+
+       enable_sort = g_action_group_get_action_enabled (view_action_group, "sort");
+       show_sort_trash = show_sort_search = show_sort_modification = show_sort_access = FALSE;
+       gtk_widget_set_visible (view->details->sort_menu, enable_sort);
+
+       if (enable_sort) {
+               variant = g_action_group_get_action_state_hint (view_action_group, "sort");
+               g_variant_iter_init (&iter, variant);
+
+               while (g_variant_iter_next (&iter, "&s", &hint)) {
+                       if (g_strcmp0 (hint, "trash-time") == 0)
+                               show_sort_trash = TRUE;
+                       if (g_strcmp0 (hint, "search-relevance") == 0)
+                               show_sort_search = TRUE;
+               }
+
+               g_variant_unref (variant);
+       }
+
+       gtk_widget_set_visible (view->details->sort_trash_time, show_sort_trash);
+       gtk_widget_set_visible (view->details->sort_search_relevance, show_sort_search);
+
+       variant = g_action_group_get_action_state (view_action_group, "zoom-to-level");
+       gtk_adjustment_set_value (view->details->zoom_adjustment,
+                                 g_variant_get_int32 (variant));
+       g_variant_unref (variant);
+}
+
 /* Convenience function to reset the menus owned by the view but managed on
  * the toolbar, and update them with the current state.
  * It will also update the actions state, which will also update children
@@ -6742,9 +6847,6 @@ nautilus_view_update_context_menus (NautilusView *view)
 void
 nautilus_view_update_toolbar_menus (NautilusView *view)
 {
-       NautilusToolbar *toolbar;
-       NautilusWindow *window;
-
        g_assert (NAUTILUS_IS_VIEW (view));
 
        /* Don't update after destroy (#349551),
@@ -6754,11 +6856,7 @@ nautilus_view_update_toolbar_menus (NautilusView *view)
            !view->details->active) {
                return;
        }
-       window = nautilus_view_get_window (view);
-       toolbar = NAUTILUS_TOOLBAR (nautilus_window_get_toolbar (window));
-       nautilus_toolbar_reset_menus (toolbar);
-       nautilus_window_reset_menus (window);
-
+       nautilus_view_reset_view_menu (view);
        nautilus_view_update_actions_state (view);
 }
 
@@ -7424,6 +7522,29 @@ real_get_selected_icon_locations (NautilusView *view)
 }
 
 static void
+nautilus_view_get_property (GObject    *object,
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+        NautilusView *view = NAUTILUS_VIEW (object);
+
+        switch (prop_id) {
+        case PROP_ICON:
+                g_value_set_object (value, nautilus_view_get_icon (view));
+                break;
+
+        case PROP_VIEW_WIDGET:
+                g_value_set_object (value, nautilus_view_get_view_widget (view));
+                break;
+
+        default:
+                g_assert_not_reached ();
+
+        }
+}
+
+static void
 nautilus_view_set_property (GObject         *object,
                            guint            prop_id,
                            const GValue    *value,
@@ -7526,29 +7647,68 @@ nautilus_view_scroll_event (GtkWidget *widget,
        return FALSE;
 }
 
+
+static void
+action_reload_enabled_changed (GActionGroup *action_group,
+                               gchar        *action_name,
+                               gboolean      enabled,
+                               NautilusView *view)
+{
+       gtk_widget_set_visible (view->details->reload, enabled);
+}
+
+static void
+action_stop_enabled_changed (GActionGroup *action_group,
+                             gchar        *action_name,
+                             gboolean      enabled,
+                             NautilusView *view)
+{
+       gtk_widget_set_visible (view->details->stop, enabled);
+}
+
 static void
 nautilus_view_parent_set (GtkWidget *widget,
                          GtkWidget *old_parent)
 {
+        NautilusWindow *window;
        NautilusView *view;
        GtkWidget *parent;
 
        view = NAUTILUS_VIEW (widget);
 
        parent = gtk_widget_get_parent (widget);
+        window = nautilus_view_get_window (view);
        g_assert (parent == NULL || old_parent == NULL);
 
        if (GTK_WIDGET_CLASS (nautilus_view_parent_class)->parent_set != NULL) {
                GTK_WIDGET_CLASS (nautilus_view_parent_class)->parent_set (widget, old_parent);
        }
 
+        if (view->details->stop_signal_handler > 0) {
+                g_signal_handler_disconnect (window, view->details->stop_signal_handler);
+                view->details->stop_signal_handler = 0;
+        }
+
+        if (view->details->reload_signal_handler > 0) {
+                g_signal_handler_disconnect (window, view->details->reload_signal_handler);
+                view->details->reload_signal_handler = 0;
+        }
+
        if (parent != NULL) {
                g_assert (old_parent == NULL);
 
-               if (view->details->slot == 
-                   nautilus_window_get_active_slot (nautilus_view_get_window (view))) {
+               if (view->details->slot == nautilus_window_get_active_slot (window)) {
                        view->details->active = TRUE;
                }
+
+               g_signal_connect (window,
+                                 "action-enabled-changed::stop",
+                                 G_CALLBACK (action_stop_enabled_changed),
+                                 view);
+                g_signal_connect (window,
+                                  "action-enabled-changed::reload",
+                                  G_CALLBACK (action_reload_enabled_changed),
+                                  view);
        } else {
                remove_update_context_menus_timeout_callback (view);
        }
@@ -7564,6 +7724,7 @@ nautilus_view_class_init (NautilusViewClass *klass)
        oclass = G_OBJECT_CLASS (klass);
 
        oclass->finalize = nautilus_view_finalize;
+        oclass->get_property = nautilus_view_get_property;
        oclass->set_property = nautilus_view_set_property;
 
        widget_class->destroy = nautilus_view_destroy;
@@ -7671,6 +7832,19 @@ nautilus_view_class_init (NautilusViewClass *klass)
                                      TRUE,
                                      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
                                      G_PARAM_STATIC_STRINGS);
+        properties[PROP_ICON] =
+                g_param_spec_object ("icon",
+                                     "Icon",
+                                     "The icon that represents the view",
+                                     G_TYPE_ICON,
+                                     G_PARAM_READABLE);
+
+        properties[PROP_VIEW_WIDGET] =
+                g_param_spec_object ("view-widget",
+                                     "View widget",
+                                     "The view's widget that will appear under the view menu button",
+                                     GTK_TYPE_WIDGET,
+                                     G_PARAM_READABLE);
 
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
 }
@@ -7702,6 +7876,24 @@ nautilus_view_init (NautilusView *view)
         gtk_widget_add_events (GTK_WIDGET (view),
                                GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
 
+        /* View menu */
+        builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-toolbar-view-menu.xml");
+       view->details->view_menu_widget =  g_object_ref (gtk_builder_get_object (builder, 
"view_menu_widget"));
+       view->details->zoom_level_scale = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_scale"));
+       view->details->zoom_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "zoom_adjustment"));
+
+       view->details->sort_menu =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
+       view->details->sort_trash_time =  GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
+       view->details->sort_search_relevance =  GTK_WIDGET (gtk_builder_get_object (builder, 
"sort_search_relevance"));
+       view->details->visible_columns =  GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
+       view->details->reload =  GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
+       view->details->stop =  GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
+
+        g_signal_connect (view->details->zoom_level_scale, "value-changed",
+                          G_CALLBACK (zoom_level_changed), view);
+
+        g_object_unref (builder);
+
         /* Scrolled Window */
         view->details->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view->details->scrolled_window),
@@ -7812,6 +8004,9 @@ nautilus_view_init (NautilusView *view)
        gtk_widget_insert_action_group (GTK_WIDGET (view),
                                        "view",
                                        G_ACTION_GROUP (view->details->view_action_group));
+        gtk_widget_insert_action_group (GTK_WIDGET (view->details->view_menu_widget),
+                                       "view",
+                                       G_ACTION_GROUP (view->details->view_action_group));
 
        app = g_application_get_default ();
 
diff --git a/src/nautilus-view.h b/src/nautilus-view.h
index 93fbc89..b6e73ce 100644
--- a/src/nautilus-view.h
+++ b/src/nautilus-view.h
@@ -276,6 +276,8 @@ struct NautilusViewClass {
                                                   const char            *uri);
 
        NautilusWindow * (*get_window)            (NautilusView *view);
+
+        GIcon *        (* get_icon)               (NautilusView *view);
 };
 
 /* GObject support */
@@ -390,4 +392,8 @@ GActionGroup *    nautilus_view_get_action_group           (NautilusView      *v
 GtkWidget*        nautilus_view_get_content_widget         (NautilusView      *view);
 gboolean          nautilus_view_is_search                  (NautilusView      *view);
 
+GIcon*            nautilus_view_get_icon                   (NautilusView      *view);
+
+GtkWidget*        nautilus_view_get_view_widget            (NautilusView      *view);
+
 #endif /* NAUTILUS_VIEW_H */
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index 766c6a5..0c5e393 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -55,6 +55,8 @@ enum {
 
 enum {
        PROP_WINDOW = 1,
+        PROP_ICON,
+        PROP_VIEW_WIDGET,
        NUM_PROPERTIES
 };
 
@@ -527,6 +529,12 @@ nautilus_window_slot_get_property (GObject *object,
        case PROP_WINDOW:
                g_value_set_object (value, slot->details->window);
                break;
+        case PROP_ICON:
+                g_value_set_object (value, nautilus_window_slot_get_icon (slot));
+                break;
+        case PROP_VIEW_WIDGET:
+                g_value_set_object (value, nautilus_window_slot_get_view_widget (slot));
+                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -2267,6 +2275,9 @@ nautilus_window_slot_switch_new_content_view (NautilusWindowSlot *slot)
                 gtk_container_add (GTK_CONTAINER (slot), widget);
                 gtk_widget_set_vexpand (widget, TRUE);
                gtk_widget_show (widget);
+
+                g_object_notify_by_pspec (G_OBJECT (slot), properties[PROP_ICON]);
+                g_object_notify_by_pspec (G_OBJECT (slot), properties[PROP_VIEW_WIDGET]);
        }
 }
 
@@ -2448,6 +2459,20 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
                                     NAUTILUS_TYPE_WINDOW,
                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
 
+        properties[PROP_ICON] =
+               g_param_spec_object ("icon",
+                                    "Icon that represents the slot",
+                                    "The icon that represents the slot",
+                                    G_TYPE_ICON,
+                                    G_PARAM_READABLE);
+
+        properties[PROP_VIEW_WIDGET] =
+               g_param_spec_object ("view-widget",
+                                    "Widget for the view menu",
+                                    "The widget for the view's menu",
+                                    GTK_TYPE_WIDGET,
+                                    G_PARAM_READABLE);
+
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
        g_type_class_add_private (klass, sizeof (NautilusWindowSlotDetails));
 }
@@ -2656,3 +2681,27 @@ nautilus_window_slot_new (NautilusWindow *window)
                             "window", window,
                             NULL);
 }
+
+GIcon*
+nautilus_window_slot_get_icon (NautilusWindowSlot *slot)
+{
+        NautilusView *view;
+
+        g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), NULL);
+
+        view = nautilus_window_slot_get_current_view (slot);
+
+        return view ? nautilus_view_get_icon (view) : NULL;
+}
+
+GtkWidget*
+nautilus_window_slot_get_view_widget (NautilusWindowSlot *slot)
+{
+        NautilusView *view;
+
+        g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), NULL);
+
+        view = nautilus_window_slot_get_current_view (slot);
+
+        return view ? nautilus_view_get_view_widget (view) : NULL;
+}
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
index 97ff788..c7c3e8a 100644
--- a/src/nautilus-window-slot.h
+++ b/src/nautilus-window-slot.h
@@ -127,4 +127,10 @@ void nautilus_window_slot_display_view_selection_failure   (NautilusWindow *wind
                                                             GFile          *location,
                                                             GError         *error);
 
+GIcon*   nautilus_window_slot_get_icon                     (NautilusWindowSlot *slot);
+
+GtkWidget* nautilus_window_slot_get_view_widget            (NautilusWindowSlot *slot);
+
+gboolean   nautilus_window_slot_get_active                 (NautilusWindowSlot *slot);
+
 #endif /* NAUTILUS_WINDOW_SLOT_H */
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index 6daebbf..eb0df24 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -768,12 +768,6 @@ update_cursor (NautilusWindow *window)
 }
 
 void
-nautilus_window_reset_menus (NautilusWindow *window)
-{
-       nautilus_window_sync_allow_stop (window, nautilus_window_get_active_slot (window));
-}
-
-void
 nautilus_window_sync_allow_stop (NautilusWindow *window,
                                 NautilusWindowSlot *slot)
 {
@@ -2278,6 +2272,8 @@ nautilus_window_set_active_slot (NautilusWindow *window, NautilusWindowSlot *new
                /* inform sidebar panels */
                 nautilus_window_report_location_change (window);
 
+                nautilus_toolbar_set_active_slot (NAUTILUS_TOOLBAR (window->priv->toolbar), new_slot);
+
                /* inform slot & view */
                 g_signal_emit_by_name (new_slot, "active");
        }
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 7bb3e2d..f018340 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -126,8 +126,6 @@ void     nautilus_window_back_or_forward      (NautilusWindow *window,
                                                gboolean        back,
                                                guint           distance,
                                                NautilusWindowOpenFlags flags);
-void nautilus_window_reset_menus (NautilusWindow *window);
-
 GtkWidget *         nautilus_window_get_notebook (NautilusWindow *window);
 
 NautilusWindowOpenFlags nautilus_event_get_window_open_flags   (void);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]