[nautilus/wip/csoriano/destktop-split2: 19/50] window-slot: use inheritance for other locations view



commit 92114664cd4fbdd439c828dca478d531315012fc
Author: Carlos Soriano <csoriano gnome org>
Date:   Tue Mar 22 17:20:21 2016 +0100

    window-slot: use inheritance for other locations view
    
    We need to special case the other locations view when using that
    location, since it's not a files-view and doesn't support several things
    that we usually support, like the changes between icon view and list
    view.
    
    Also we specifically special case its creation in window slot and we
    disable few actions that are not available on it.
    
    This patch creates a other locations slot, which will handle all of it.
    The class that is responsible of creating one type of slot or another is
    the window, and will use a vfunc that will request whether the slot
    handles a location or not and will act accordingly.
    
    In upcoming patches we will move all the special casing of this and the
    desktop in the window slot to its respective subclasses now that we have
    everything ready.

 src/Makefile.am                            |    2 +
 src/nautilus-desktop-window.c              |    3 +-
 src/nautilus-other-locations-window-slot.c |   79 +++++++++++++++++++++
 src/nautilus-other-locations-window-slot.h |   36 ++++++++++
 src/nautilus-window-slot.c                 |  104 +++++++++++++++-------------
 src/nautilus-window-slot.h                 |    8 ++
 src/nautilus-window.c                      |   49 +++++++++++---
 src/nautilus-window.h                      |    3 +-
 8 files changed, 224 insertions(+), 60 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b4a3d7e..f00957c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,6 +185,8 @@ nautilus_no_main_sources = \
        nautilus-mime-actions.h                 \
        nautilus-notebook.c                     \
        nautilus-notebook.h                     \
+       nautilus-other-locations-window-slot.c  \
+       nautilus-other-locations-window-slot.h  \
        nautilus-pathbar.c                      \
        nautilus-pathbar.h                      \
        nautilus-places-view.c                  \
diff --git a/src/nautilus-desktop-window.c b/src/nautilus-desktop-window.c
index 45a2c19..5b78cb3 100644
--- a/src/nautilus-desktop-window.c
+++ b/src/nautilus-desktop-window.c
@@ -380,7 +380,8 @@ real_window_close (NautilusWindow *window)
 }
 
 static NautilusWindowSlot *
-real_create_slot (NautilusWindow *window)
+real_create_slot (NautilusWindow *window,
+                  GFile          *location)
 {
        return NAUTILUS_WINDOW_SLOT (nautilus_desktop_window_slot_new (window));
 }
diff --git a/src/nautilus-other-locations-window-slot.c b/src/nautilus-other-locations-window-slot.c
new file mode 100644
index 0000000..5807133
--- /dev/null
+++ b/src/nautilus-other-locations-window-slot.c
@@ -0,0 +1,79 @@
+/* nautilus-other-locations-window-slot.c
+ *
+ * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nautilus-other-locations-window-slot.h"
+#include "nautilus-desktop-canvas-view.h"
+#include "nautilus-places-view.h"
+
+struct _NautilusOtherLocationsWindowSlot
+{
+  NautilusWindowSlot parent_instance;
+};
+
+G_DEFINE_TYPE (NautilusOtherLocationsWindowSlot, nautilus_other_locations_window_slot, 
NAUTILUS_TYPE_WINDOW_SLOT)
+
+static gboolean
+real_handles_location (NautilusWindowSlot *self,
+                       GFile              *location)
+{
+  NautilusFile *file;
+  gboolean handles_location;
+
+  file = nautilus_file_get (location);
+  handles_location = nautilus_file_is_other_locations (file);
+  nautilus_file_unref (file);
+
+  return handles_location;
+}
+
+static NautilusView *
+real_get_view_for_location (NautilusWindowSlot *self,
+                            GFile              *location)
+{
+  return NAUTILUS_VIEW (nautilus_places_view_new ());
+}
+
+NautilusOtherLocationsWindowSlot *
+nautilus_other_locations_window_slot_new (NautilusWindow *window)
+{
+  return g_object_new (NAUTILUS_TYPE_OTHER_LOCATIONS_WINDOW_SLOT,
+                       "window", window,
+                       NULL);
+}
+
+static void
+nautilus_other_locations_window_slot_class_init (NautilusOtherLocationsWindowSlotClass *klass)
+{
+  NautilusWindowSlotClass *parent_class = NAUTILUS_WINDOW_SLOT_CLASS (klass);
+
+  parent_class->get_view_for_location = real_get_view_for_location;
+  parent_class->handles_location = real_handles_location;
+}
+
+static void
+nautilus_other_locations_window_slot_init (NautilusOtherLocationsWindowSlot *self)
+{
+  GAction *action;
+  GActionGroup *action_group;
+
+  /* Disable the ability to change between types of views */
+  action_group = gtk_widget_get_action_group (GTK_WIDGET (self), "slot");
+
+  action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "files-view-mode");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
+}
diff --git a/src/nautilus-other-locations-window-slot.h b/src/nautilus-other-locations-window-slot.h
new file mode 100644
index 0000000..24f6d44
--- /dev/null
+++ b/src/nautilus-other-locations-window-slot.h
@@ -0,0 +1,36 @@
+/* nautilus-other-locations-window-slot.h
+ *
+ * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NAUTILUS_OTHER_LOCATIONS_WINDOW_SLOT_H
+#define NAUTILUS_OTHER_LOCATIONS_WINDOW_SLOT_H
+
+#include "nautilus-window-slot.h"
+#include "nautilus-window.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_OTHER_LOCATIONS_WINDOW_SLOT (nautilus_other_locations_window_slot_get_type())
+
+G_DECLARE_FINAL_TYPE (NautilusOtherLocationsWindowSlot, nautilus_other_locations_window_slot, NAUTILUS, 
OTHER_LOCATIONS_WINDOW_SLOT, NautilusWindowSlot)
+
+NautilusOtherLocationsWindowSlot *nautilus_other_locations_window_slot_new (NautilusWindow *window);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_OTHER_LOCATIONS_WINDOW_SLOT_H */
+
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index d3583f8..1ef7e21 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -29,7 +29,6 @@
 #include "nautilus-desktop-canvas-view.h"
 #include "nautilus-list-view.h"
 #include "nautilus-mime-actions.h"
-#include "nautilus-places-view.h"
 #include "nautilus-special-location-bar.h"
 #include "nautilus-trash-bar.h"
 #include "nautilus-view.h"
@@ -120,7 +119,6 @@ typedef struct {
        GError *mount_error;
        gboolean tried_mount;
         gint view_mode_before_search;
-        gint view_mode_before_places;
 } NautilusWindowSlotPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (NautilusWindowSlot, nautilus_window_slot, GTK_TYPE_BOX);
@@ -144,6 +142,27 @@ static void nautilus_window_slot_set_search_visible (NautilusWindowSlot *self,
 static gboolean nautilus_window_slot_get_search_visible (NautilusWindowSlot *self);
 static void nautilus_window_slot_set_location (NautilusWindowSlot *self,
                                                GFile              *location);
+gboolean
+nautilus_window_slot_handles_location (NautilusWindowSlot *self,
+                                       GFile              *location)
+{
+        return NAUTILUS_WINDOW_SLOT_CLASS (G_OBJECT_GET_CLASS (self))->handles_location (self, location);
+}
+
+static gboolean
+real_handles_location (NautilusWindowSlot *self,
+                       GFile              *location)
+{
+        NautilusFile *file;
+        gboolean handles_location;
+
+        file = nautilus_file_get (location);
+        handles_location = !nautilus_file_is_other_locations (file) &&
+                           !nautilus_file_is_desktop_directory (file);
+        nautilus_file_unref (file);
+
+        return handles_location;
+}
 
 static NautilusView *
 nautilus_window_slot_get_view_for_location (NautilusWindowSlot *self,
@@ -166,55 +185,43 @@ real_get_view_for_location (NautilusWindowSlot *self,
         window = nautilus_window_slot_get_window (self);
         file = nautilus_file_get (location);
         view = NULL;
+        guint view_id;
 
-        if (nautilus_file_is_other_locations (file)) {
-                view = NAUTILUS_VIEW (nautilus_places_view_new ());
+        view_id = NAUTILUS_VIEW_INVALID_ID;
 
-                /* Save the current view, so we can go back after places view */
-                if (priv->content_view && NAUTILUS_IS_FILES_VIEW (priv->content_view)) {
-                        priv->view_mode_before_places = nautilus_files_view_get_view_id (NAUTILUS_FILES_VIEW 
(priv->content_view));
+        /* If we are in search, try to use by default list view. */
+        if (nautilus_file_is_in_search (file)) {
+                /* If it's already set, is because we already made the change to search mode,
+                 * so the view mode of the current view will be the one search is using,
+                 * which is not the one we are interested in */
+                if (priv->view_mode_before_search == NAUTILUS_VIEW_INVALID_ID) {
+                        priv->view_mode_before_search = nautilus_files_view_get_view_id (NAUTILUS_FILES_VIEW 
(priv->content_view));
                 }
-        } else {
-                guint view_id;
-
-                view_id = NAUTILUS_VIEW_INVALID_ID;
-
-                /* If we are in search, try to use by default list view. */
-                if (nautilus_file_is_in_search (file)) {
-                        /* If it's already set, is because we already made the change to search mode,
-                         * so the view mode of the current view will be the one search is using,
-                         * which is not the one we are interested in */
-                        if (priv->view_mode_before_search == NAUTILUS_VIEW_INVALID_ID) {
-                                priv->view_mode_before_search = nautilus_files_view_get_view_id 
(NAUTILUS_FILES_VIEW (priv->content_view));
-                        }
-                        view_id = g_settings_get_enum (nautilus_preferences, 
NAUTILUS_PREFERENCES_SEARCH_VIEW);
-                } else if (priv->content_view != NULL) {
-                        /* If there is already a view, just use the view mode that it's currently using, or
-                         * if we were on search before, use what we were using before entering
-                         * search mode */
-                        if (priv->view_mode_before_search != NAUTILUS_VIEW_INVALID_ID) {
-                                view_id = priv->view_mode_before_search;
-                                priv->view_mode_before_search = NAUTILUS_VIEW_INVALID_ID;
-                        } else if (NAUTILUS_IS_PLACES_VIEW (priv->content_view)) {
-                                view_id = priv->view_mode_before_places;
-                                priv->view_mode_before_places = NAUTILUS_VIEW_INVALID_ID;
-                        } else {
-                               view_id = nautilus_files_view_get_view_id (NAUTILUS_FILES_VIEW 
(priv->content_view));
-                        }
-               }
-
-                /* If there is not previous view in this slot, use the default view mode
-                 * from preferences */
-               if (view_id == NAUTILUS_VIEW_INVALID_ID) {
-                       view_id = g_settings_get_enum (nautilus_preferences, 
NAUTILUS_PREFERENCES_DEFAULT_FOLDER_VIEWER);
-               }
-
-                /* Try to reuse the current view */
-                if (nautilus_window_slot_content_view_matches (self, view_id)) {
-                        view = priv->content_view;
+                view_id = g_settings_get_enum (nautilus_preferences, NAUTILUS_PREFERENCES_SEARCH_VIEW);
+        } else if (priv->content_view != NULL) {
+                /* If there is already a view, just use the view mode that it's currently using, or
+                 * if we were on search before, use what we were using before entering
+                 * search mode */
+                if (priv->view_mode_before_search != NAUTILUS_VIEW_INVALID_ID) {
+                        view_id = priv->view_mode_before_search;
+                        priv->view_mode_before_search = NAUTILUS_VIEW_INVALID_ID;
                 } else {
-                        view = NAUTILUS_VIEW (nautilus_files_view_new (view_id, self));
+                       view_id = nautilus_files_view_get_view_id (NAUTILUS_FILES_VIEW (priv->content_view));
                 }
+
+        }
+
+        /* If there is not previous view in this slot, use the default view mode
+         * from preferences */
+        if (view_id == NAUTILUS_VIEW_INVALID_ID) {
+               view_id = g_settings_get_enum (nautilus_preferences, 
NAUTILUS_PREFERENCES_DEFAULT_FOLDER_VIEWER);
+        }
+
+        /* Try to reuse the current view */
+        if (nautilus_window_slot_content_view_matches (self, view_id)) {
+                view = priv->content_view;
+        } else {
+                view = NAUTILUS_VIEW (nautilus_files_view_new (view_id, self));
         }
 
         nautilus_file_unref (file);
@@ -233,9 +240,7 @@ nautilus_window_slot_content_view_matches (NautilusWindowSlot *self,
                return FALSE;
        }
 
-        if (id == NAUTILUS_VIEW_INVALID_ID && NAUTILUS_IS_PLACES_VIEW (priv->content_view)) {
-                return TRUE;
-        } else if (id != NAUTILUS_VIEW_INVALID_ID && NAUTILUS_IS_FILES_VIEW (priv->content_view)){
+        if (id != NAUTILUS_VIEW_INVALID_ID && NAUTILUS_IS_FILES_VIEW (priv->content_view)){
                 return nautilus_files_view_get_view_id (NAUTILUS_FILES_VIEW (priv->content_view)) == id;
         } else {
                 return FALSE;
@@ -2434,6 +2439,7 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
        klass->active = real_active;
        klass->inactive = real_inactive;
         klass->get_view_for_location = real_get_view_for_location;
+        klass->handles_location = real_handles_location;
 
        oclass->dispose = nautilus_window_slot_dispose;
        oclass->constructed = nautilus_window_slot_constructed;
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
index 9345f87..ed4c5eb 100644
--- a/src/nautilus-window-slot.h
+++ b/src/nautilus-window-slot.h
@@ -55,6 +55,11 @@ struct _NautilusWindowSlotClass {
          */
         NautilusView*  (* get_view_for_location) (NautilusWindowSlot *slot,
                                                   GFile              *location);
+        /* Whether this type of slot handles the location or not. This can be used
+         * for the special slots which handle special locations like the desktop
+         * or the other locations. */
+        gboolean (* handles_location) (NautilusWindowSlot *slot,
+                                       GFile              *location);
 };
 
 NautilusWindowSlot * nautilus_window_slot_new              (NautilusWindow     *window);
@@ -101,6 +106,9 @@ gboolean nautilus_window_slot_get_loading                  (NautilusWindowSlot *
 void     nautilus_window_slot_search                       (NautilusWindowSlot *slot,
                                                             const gchar        *text);
 
+gboolean nautilus_window_slot_handles_location (NautilusWindowSlot *self,
+                                                GFile              *location);
+
 /* Only used by slot-dnd */
 NautilusView*  nautilus_window_slot_get_current_view       (NautilusWindowSlot *slot);
 
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index b3b2ba7..45500ff 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -39,6 +39,7 @@
 #include "nautilus-toolbar.h"
 #include "nautilus-window-slot.h"
 #include "nautilus-list-view.h"
+#include "nautilus-other-locations-window-slot.h"
 
 #include <eel/eel-debug.h>
 #include <eel/eel-gtk-extensions.h>
@@ -80,6 +81,9 @@ static void mouse_forward_button_changed           (gpointer                  callbac
 static void use_extra_mouse_buttons_changed          (gpointer                  callback_data);
 static void nautilus_window_initialize_actions              (NautilusWindow *window);
 static GtkWidget * nautilus_window_ensure_location_entry (NautilusWindow *window);
+static void close_slot                                (NautilusWindow     *window,
+                                                       NautilusWindowSlot *slot,
+                                                       gboolean            remove_from_notebook);
 
 /* Sanity check: highest mouse button value I could find was 14. 5 is our 
  * lower threshold (well-documented to be the one of the button events for the 
@@ -524,15 +528,29 @@ disconnect_slot (NautilusWindow     *window,
 }
 
 static NautilusWindowSlot *
-nautilus_window_create_slot (NautilusWindow *window)
+nautilus_window_create_slot (NautilusWindow *window,
+                             GFile          *location)
 {
-       return NAUTILUS_WINDOW_CLASS (G_OBJECT_GET_CLASS(window))->create_slot (window);
+       return NAUTILUS_WINDOW_CLASS (G_OBJECT_GET_CLASS(window))->create_slot (window, location);
 }
 
 static NautilusWindowSlot *
-real_create_slot (NautilusWindow *window)
+real_create_slot (NautilusWindow *window,
+                  GFile          *location)
 {
-        return nautilus_window_slot_new (window);
+        NautilusFile *file = NULL;
+
+        if (location) {
+                file = nautilus_file_get (location);
+        }
+        /* If not file, assume we open the home directory. We will switch eventually
+         * to a different location if not.
+         */
+        if (file && nautilus_file_is_other_locations (file)) {
+                return NAUTILUS_WINDOW_SLOT (nautilus_other_locations_window_slot_new (window));
+        } else {
+                return nautilus_window_slot_new (window);
+        }
 }
 
 void
@@ -573,6 +591,11 @@ nautilus_window_open_location_full (NautilusWindow          *window,
         gboolean new_tab_at_end;
 
         active_slot = nautilus_window_get_active_slot (window);
+        /* The location owner can be one of the slots requesting to handle an
+         * unhandled location. But this slot can be destroyed when switching to
+         * a new slot. So keep the locaiton alive
+         */
+        g_object_ref (location);
 
         /* Assert that we are not managing new windows */
         g_assert (! (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW));
@@ -582,13 +605,19 @@ nautilus_window_open_location_full (NautilusWindow          *window,
                 if (new_tab_at_end)
                flags |= NAUTILUS_WINDOW_OPEN_SLOT_APPEND;
 
-               target_slot = nautilus_window_create_slot (window);
+               target_slot = nautilus_window_create_slot (window, location);
                 nautilus_window_initialize_slot (window, target_slot, flags);
        }
 
-       if (target_slot == NULL) {
-               target_slot = active_slot;
-       }
+        if (!target_slot)
+                target_slot = active_slot;
+
+       if (target_slot == NULL || !nautilus_window_slot_handles_location (active_slot, location)) {
+                target_slot = nautilus_window_create_slot (window, location);
+                nautilus_window_initialize_slot (window, target_slot, flags);
+                if (active_slot)
+                  close_slot (window, active_slot, TRUE);
+        }
 
         /* Make the opened location the one active if we weren't ask for the
          * oposite, since it's the most usual use case */
@@ -598,6 +627,8 @@ nautilus_window_open_location_full (NautilusWindow          *window,
         }
 
        nautilus_window_slot_open_location_full (target_slot, location, flags, selection);
+
+        g_object_unref (location);
 }
 
 static int
@@ -2139,7 +2170,7 @@ nautilus_window_constructed (GObject *self)
         * some actions trigger UI widgets to show/hide. */
        nautilus_window_initialize_actions (window);
 
-       slot = nautilus_window_create_slot (window);
+       slot = nautilus_window_create_slot (window, NULL);
         nautilus_window_initialize_slot (window, slot, 0);
        nautilus_window_set_active_slot (window, slot);
 
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 10cc2ba..c803df9 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -89,7 +89,8 @@ struct NautilusWindowClass {
         /* Use this in case your window has a special slot. Also is expected that
          * the slot is initialized with nautilus_window_initialize_slot.
          */
-        NautilusWindowSlot * (* create_slot) (NautilusWindow *window);
+        NautilusWindowSlot * (* create_slot) (NautilusWindow *window,
+                                              GFile          *location);
 };
 
 typedef struct _NautilusWindowPrivate NautilusWindowPrivate;


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