[gnome-photos/wip/rishi/invariant: 2/2] Merge PhotosModeController into PhotosItemManager



commit ee3a5edb69987ce6a28d6bb29a6f7f98aafa91c1
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Oct 9 17:51:26 2015 +0200

    Merge PhotosModeController into PhotosItemManager
    
    The legal ways to request a state change are now clearer and stricter
    than before:
     - You cannot move to the preview directly. You must set a non-NULL
       active item to do that.
     - You cannot set a NULL active item to go back from the preview. You
       must use the go_back method for that.
    
    We assert pre and post conditions for state transitions to enforce
    these rules and catch programmer errors.
    
    Earlier, the mode would be updated after "load-started" was emitted.
    That is no longer the case. Signals are emitted only after the state
    change is complete. So adjust accordingly.
    
    Stop abusing "load-started" to do things that should be performed in
    the "window-mode-changed" handler. ie. code that should not be run
    while navigating within the preview.
    
    Untangle and consolidate the search save and restore logic. Instead of
    using hard to read and racy conditions in a
    PhotosItemManager::active-changed handler, we have now split it into
    the "window-mode-changed" and "active-collection-changed" handlers.
    This is much easier to read and understand. The logic to relax the
    search criteria when viewing a collection has now been moved to
    PhotosEmbed from PhotosOverviewSearchbar. Otherwise, the
    "active-collection-changed" handlers in these two classes would stomp
    on each other.
    
    Even though the state represented by these two classes are tightly
    coupled (preview must have an active item, and you can't be in
    overview with an active item, etc.), ItemManager sounds like a
    misnomer for the purposes served by the ModeController. Due to my
    inability to think of a better name, the ModeController type is now an
    alias for ItemManager and we have retained the method names.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=737071

 src/Makefile.am                             |    6 +-
 src/photos-application.c                    |   17 +-
 src/photos-dlna-renderers-dialog.c          |    6 +-
 src/photos-embed.c                          |  260 +++++++++++++-----------
 src/photos-empty-results-box.h              |    4 +-
 src/photos-enums.c.template                 |    2 +-
 src/photos-item-manager.c                   |  286 ++++++++++++++++++++++++---
 src/photos-item-manager.h                   |   39 ++++
 src/photos-main-toolbar.c                   |    4 +-
 src/photos-main-window.c                    |    9 +-
 src/photos-mode-controller.c                |  253 -----------------------
 src/photos-mode-controller.h                |   77 -------
 src/photos-overview-searchbar.c             |   32 ---
 src/photos-preview-view.c                   |   11 +-
 src/photos-search-context.c                 |    4 +-
 src/photos-search-context.h                 |    3 +-
 src/photos-tracker-collections-controller.c |    3 +-
 src/photos-tracker-controller.c             |   13 +-
 src/photos-tracker-favorites-controller.c   |    3 +-
 src/photos-tracker-overview-controller.c    |    2 +-
 src/photos-tracker-search-controller.c      |    3 +-
 src/photos-view-container.c                 |    2 +-
 src/photos-view-container.h                 |    4 +-
 src/photos-view-model.c                     |    3 +-
 src/photos-view-model.h                     |    4 +-
 25 files changed, 484 insertions(+), 566 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c0538c..d541fd9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -133,8 +133,6 @@ gnome_photos_SOURCES = \
        photos-main-window.h \
        photos-media-server-item.c \
        photos-media-server-item.h \
-       photos-mode-controller.c \
-       photos-mode-controller.h \
        photos-notification-manager.c \
        photos-notification-manager.h \
        photos-offset-collections-controller.c \
@@ -397,7 +395,7 @@ stamp-photos-enums.h: photos-enums.h.template
        $(AM_V_GEN) ( \
                ( glib-mkenums \
                        --template $(srcdir)/photos-enums.h.template \
-                        $(srcdir)/photos-mode-controller.h \
+                        $(srcdir)/photos-item-manager.h \
                         $(srcdir)/photos-preview-nav-buttons.h \
                 ) >> xgen-etbh \
                && ( cmp -s xgen-etbh photos-enums.h || cp xgen-etbh photos-enums.h ) \
@@ -409,7 +407,7 @@ photos-enums.c: photos-enums.c.template
        $(AM_V_GEN) ( \
                ( glib-mkenums \
                        --template $(srcdir)/photos-enums.c.template \
-                        $(srcdir)/photos-mode-controller.h \
+                        $(srcdir)/photos-item-manager.h \
                         $(srcdir)/photos-preview-nav-buttons.h \
                 ) >> xgen-etbc \
                && ( cmp -s xgen-etbc photos-enums.c || cp xgen-etbc photos-enums.c ) \
diff --git a/src/photos-application.c b/src/photos-application.c
index 17d0760..eb1026f 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -43,7 +43,6 @@
 #include "photos-gom-miner.h"
 #include "photos-item-manager.h"
 #include "photos-main-window.h"
-#include "photos-mode-controller.h"
 #include "photos-properties-dialog.h"
 #include "photos-query.h"
 #include "photos-resources.h"
@@ -82,7 +81,6 @@ struct _PhotosApplicationPrivate
   GSimpleAction *remote_display_action;
   GtkWidget *main_window;
   PhotosCameraCache *camera_cache;
-  PhotosModeController *mode_cntrlr;
   PhotosSearchContextState *state;
   PhotosSearchProvider *search_provider;
   TrackerExtractPriority *extract_priority;
@@ -282,7 +280,7 @@ photos_application_can_fullscreen_changed (PhotosApplication *self)
   PhotosApplicationPrivate *priv = self->priv;
   gboolean can_fullscreen;
 
-  can_fullscreen = photos_mode_controller_get_can_fullscreen (priv->mode_cntrlr);
+  can_fullscreen = photos_mode_controller_get_can_fullscreen (priv->state->mode_cntrlr);
   g_simple_action_set_enabled (priv->fs_action, can_fullscreen);
 }
 
@@ -292,7 +290,7 @@ photos_application_fullscreen (PhotosApplication *self, GVariant *parameter)
 {
   PhotosApplicationPrivate *priv = self->priv;
 
-  photos_mode_controller_toggle_fullscreen (priv->mode_cntrlr);
+  photos_mode_controller_toggle_fullscreen (priv->state->mode_cntrlr);
 }
 
 
@@ -312,7 +310,7 @@ photos_application_launch_search (PhotosApplication *self, const gchar* const *t
   gchar *str;
 
   photos_application_create_window (self);
-  photos_mode_controller_set_window_mode (priv->mode_cntrlr, PHOTOS_WINDOW_MODE_OVERVIEW);
+  photos_mode_controller_set_window_mode (priv->state->mode_cntrlr, PHOTOS_WINDOW_MODE_OVERVIEW);
 
   str = g_strjoinv (" ", (gchar **) terms);
   photos_search_controller_set_string (priv->state->srch_cntrlr, str);
@@ -710,7 +708,7 @@ photos_application_activate (GApplication *application)
   if (priv->main_window == NULL)
     {
       photos_application_create_window (self);
-      photos_mode_controller_set_window_mode (priv->mode_cntrlr, PHOTOS_WINDOW_MODE_OVERVIEW);
+      photos_mode_controller_set_window_mode (priv->state->mode_cntrlr, PHOTOS_WINDOW_MODE_OVERVIEW);
     }
 
   gtk_window_present_with_time (GTK_WINDOW (priv->main_window), priv->activation_timestamp);
@@ -882,8 +880,6 @@ photos_application_startup (GApplication *application)
    */
   priv->camera_cache = photos_camera_cache_dup_singleton ();
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
-
   action = g_simple_action_new ("about", NULL);
   g_signal_connect_swapped (action, "activate", G_CALLBACK (photos_application_about), self);
   g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (action));
@@ -893,7 +889,7 @@ photos_application_startup (GApplication *application)
   g_signal_connect_swapped (priv->fs_action, "activate", G_CALLBACK (photos_application_fullscreen), self);
   g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (priv->fs_action));
 
-  g_signal_connect_swapped (priv->mode_cntrlr,
+  g_signal_connect_swapped (priv->state->mode_cntrlr,
                             "can-fullscreen-changed",
                             G_CALLBACK (photos_application_can_fullscreen_changed),
                             self);
@@ -972,7 +968,7 @@ photos_application_startup (GApplication *application)
   g_signal_connect_swapped (priv->set_ss_action, "activate", G_CALLBACK (photos_application_set_bg_common), 
self);
   g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (priv->set_ss_action));
 
-  g_signal_connect_swapped (priv->mode_cntrlr,
+  g_signal_connect_swapped (priv->state->mode_cntrlr,
                             "window-mode-changed",
                             G_CALLBACK (photos_application_window_mode_changed),
                             self);
@@ -1050,7 +1046,6 @@ photos_application_dispose (GObject *object)
   g_clear_object (&priv->set_bg_action);
   g_clear_object (&priv->set_ss_action);
   g_clear_object (&priv->camera_cache);
-  g_clear_object (&priv->mode_cntrlr);
   g_clear_object (&priv->extract_priority);
 
   if (priv->state != NULL)
diff --git a/src/photos-dlna-renderers-dialog.c b/src/photos-dlna-renderers-dialog.c
index 7498c5c..a7f2662 100644
--- a/src/photos-dlna-renderers-dialog.c
+++ b/src/photos-dlna-renderers-dialog.c
@@ -1,7 +1,7 @@
 /*
  * Photos - access, organize and share your photos on GNOME
  * Copyright © 2013 Intel Corporation. All rights reserved.
- * Copyright © 2013, 2014 Red Hat, Inc.
+ * Copyright © 2013, 2014, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -33,8 +33,8 @@
 #include "photos-dlna-renderer.h"
 #include "photos-dlna-renderers-manager.h"
 #include "photos-icons.h"
+#include "photos-item-manager.h"
 #include "photos-local-item.h"
-#include "photos-mode-controller.h"
 #include "photos-remote-display-manager.h"
 #include "photos-search-context.h"
 
@@ -233,7 +233,7 @@ photos_dlna_renderers_dialog_init (PhotosDlnaRenderersDialog *self)
   priv->item_mngr = g_object_ref (state->item_mngr);
   priv->renderers_mngr = photos_dlna_renderers_manager_dup_singleton ();
   priv->remote_mngr = photos_remote_display_manager_dup_singleton ();
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
diff --git a/src/photos-embed.c b/src/photos-embed.c
index a45b342..59d8413 100644
--- a/src/photos-embed.c
+++ b/src/photos-embed.c
@@ -35,7 +35,6 @@
 #include "photos-embed.h"
 #include "photos-filterable.h"
 #include "photos-item-manager.h"
-#include "photos-mode-controller.h"
 #include "photos-notification-manager.h"
 #include "photos-search-controller.h"
 #include "photos-selection-toolbar.h"
@@ -203,90 +202,10 @@ photos_embed_activate_result (PhotosEmbed *self)
 
 
 static void
-photos_embed_prepare_for_preview (PhotosEmbed *self)
-{
-  PhotosEmbedPrivate *priv = self->priv;
-
-  /* TODO: SearchController,
-   *       ErrorHandler
-   */
-
-  photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
-  photos_preview_view_set_node (PHOTOS_PREVIEW_VIEW (priv->preview), NULL);
-  gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "preview");
-}
-
-
-static void
-photos_embed_load_finished (PhotosEmbed *self, PhotosBaseItem *item, GeglNode *node)
-{
-  PhotosEmbedPrivate *priv = self->priv;
-
-  photos_main_toolbar_set_cancellable (PHOTOS_MAIN_TOOLBAR (priv->toolbar), NULL);
-  photos_embed_clear_load_timer (self);
-  photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
-
-  if (node == NULL)
-    return;
-
-  photos_preview_view_set_node (PHOTOS_PREVIEW_VIEW (priv->preview), node);
-
-  /* TODO: set toolbar model */
-}
-
-
-static gboolean
-photos_embed_load_show_timeout (gpointer user_data)
-{
-  PhotosEmbed *self = PHOTOS_EMBED (user_data);
-  PhotosEmbedPrivate *priv = self->priv;
-
-  priv->load_show_id = 0;
-  photos_spinner_box_start (PHOTOS_SPINNER_BOX (priv->spinner_box));
-  g_object_unref (self);
-  return G_SOURCE_REMOVE;
-}
-
-
-static void
-photos_embed_load_started (PhotosEmbed *self, PhotosBaseItem *item, GCancellable *cancellable)
-{
-  PhotosEmbedPrivate *priv = self->priv;
-  PhotosWindowMode mode;
-
-  mode = photos_mode_controller_get_window_mode (priv->mode_cntrlr);
-
-  /* This is not needed when:
-   *  - activated from the search provider
-   *  - already in the preview and navigating using the buttons
-   */
-  if (mode == PHOTOS_WINDOW_MODE_COLLECTIONS
-      || mode == PHOTOS_WINDOW_MODE_FAVORITES
-      || mode == PHOTOS_WINDOW_MODE_OVERVIEW
-      || mode == PHOTOS_WINDOW_MODE_SEARCH)
-    {
-      GtkListStore *model;
-      GtkTreePath *current_path;
-      GtkWidget *view_container;
-
-      view_container = photos_embed_get_view_container_from_mode (self, mode);
-      current_path = photos_view_container_get_current_path (PHOTOS_VIEW_CONTAINER (view_container));
-      model = photos_view_container_get_model (PHOTOS_VIEW_CONTAINER (view_container));
-      photos_preview_view_set_model (PHOTOS_PREVIEW_VIEW (priv->preview), GTK_TREE_MODEL (model), 
current_path);
-    }
-
-  photos_mode_controller_set_window_mode (priv->mode_cntrlr, PHOTOS_WINDOW_MODE_PREVIEW);
-  photos_main_toolbar_set_cancellable (PHOTOS_MAIN_TOOLBAR (priv->toolbar), cancellable);
-
-  photos_embed_clear_load_timer (self);
-  self->priv->load_show_id = g_timeout_add (400, photos_embed_load_show_timeout, g_object_ref (self));
-}
-
-
-static void
 photos_embed_restore_search (PhotosEmbed *self)
 {
   PhotosEmbedPrivate *priv = self->priv;
+  GVariant *state;
 
   if (!priv->search_state.saved)
     return;
@@ -297,6 +216,9 @@ photos_embed_restore_search (PhotosEmbed *self)
   priv->search_state.saved = FALSE;
 
   photos_embed_clear_search (self);
+
+  state = g_variant_new ("b", TRUE);
+  g_action_change_state (priv->search_action, state);
 }
 
 
@@ -304,6 +226,7 @@ static void
 photos_embed_save_search (PhotosEmbed *self)
 {
   PhotosEmbedPrivate *priv = self->priv;
+  GVariant *state;
 
   if (priv->search_state.saved)
     return;
@@ -314,6 +237,9 @@ photos_embed_save_search (PhotosEmbed *self)
   priv->search_state.search_type = g_object_ref (photos_base_manager_get_active_object (priv->srch_mngr));
   priv->search_state.str = g_strdup (photos_search_controller_get_string (priv->srch_cntrlr));
   priv->search_state.saved = TRUE;
+
+  state = g_variant_new ("b", FALSE);
+  g_action_change_state (priv->search_action, state);
 }
 
 
@@ -344,18 +270,14 @@ photos_embed_tracker_controllers_set_frozen (PhotosEmbed *self, gboolean frozen)
 
 
 static void
-photos_embed_active_changed (PhotosBaseManager *manager, GObject *object, gpointer user_data)
+photos_embed_prepare_for_preview (PhotosEmbed *self, PhotosWindowMode old_mode)
 {
-  PhotosEmbed *self = PHOTOS_EMBED (user_data);
   PhotosEmbedPrivate *priv = self->priv;
   PhotosBaseItem *active_collection;
-  PhotosWindowMode mode;
-  GObject *active_item;
-  GVariant *state;
-  gboolean show_search;
 
-  active_collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (priv->item_mngr));
-  active_item = photos_base_manager_get_active_object (priv->item_mngr);
+  /* TODO: SearchController,
+   *       ErrorHandler
+   */
 
   /* We want to freeze before saving the search state and to thaw
    * after restoring it. We could thaw it earlier too, but that would
@@ -363,28 +285,106 @@ photos_embed_active_changed (PhotosBaseManager *manager, GObject *object, gpoint
    *
    * Note that we don't want to freeze when showing a collection.
    */
-  if (active_item != (GObject *) active_collection) /* active_item != NULL */
-    photos_embed_tracker_controllers_set_frozen (self, TRUE);
+  photos_embed_tracker_controllers_set_frozen (self, TRUE);
 
-  /* Hide the search bar when we are moving from the search to the
-   * preview or collection viewin. Restore it when we are back.
-   */
+  active_collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (priv->item_mngr));
+  if (old_mode == PHOTOS_WINDOW_MODE_SEARCH && active_collection == NULL)
+    photos_embed_save_search (self);
+
+  /* This is not needed when activated from the search provider. */
+  if (old_mode != PHOTOS_WINDOW_MODE_NONE)
+    {
+      GtkListStore *model;
+      GtkTreePath *current_path;
+      GtkWidget *view_container;
+
+      view_container = photos_embed_get_view_container_from_mode (self, old_mode);
+      current_path = photos_view_container_get_current_path (PHOTOS_VIEW_CONTAINER (view_container));
+      model = photos_view_container_get_model (PHOTOS_VIEW_CONTAINER (view_container));
+      photos_preview_view_set_model (PHOTOS_PREVIEW_VIEW (priv->preview), GTK_TREE_MODEL (model), 
current_path);
+    }
+
+  photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
+  photos_preview_view_set_node (PHOTOS_PREVIEW_VIEW (priv->preview), NULL);
+  gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "preview");
+}
+
+
+static void
+photos_embed_load_finished (PhotosEmbed *self, PhotosBaseItem *item, GeglNode *node)
+{
+  PhotosEmbedPrivate *priv = self->priv;
+
+  photos_main_toolbar_set_cancellable (PHOTOS_MAIN_TOOLBAR (priv->toolbar), NULL);
+  photos_embed_clear_load_timer (self);
+  photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
+
+  if (node == NULL)
+    return;
+
+  photos_preview_view_set_node (PHOTOS_PREVIEW_VIEW (priv->preview), node);
+
+  /* TODO: set toolbar model */
+}
+
+
+static gboolean
+photos_embed_load_show_timeout (gpointer user_data)
+{
+  PhotosEmbed *self = PHOTOS_EMBED (user_data);
+  PhotosEmbedPrivate *priv = self->priv;
+
+  priv->load_show_id = 0;
+  photos_spinner_box_start (PHOTOS_SPINNER_BOX (priv->spinner_box));
+  g_object_unref (self);
+  return G_SOURCE_REMOVE;
+}
+
+
+static void
+photos_embed_load_started (PhotosEmbed *self, PhotosBaseItem *item, GCancellable *cancellable)
+{
+  PhotosEmbedPrivate *priv = self->priv;
+
+  photos_main_toolbar_set_cancellable (PHOTOS_MAIN_TOOLBAR (priv->toolbar), cancellable);
+  photos_embed_clear_load_timer (self);
+  self->priv->load_show_id = g_timeout_add (400, photos_embed_load_show_timeout, g_object_ref (self));
+}
+
+
+static void
+photos_embed_active_collection_changed (PhotosBaseManager *manager, PhotosBaseItem *collection, gpointer 
user_data)
+{
+  PhotosEmbed *self = PHOTOS_EMBED (user_data);
+  PhotosEmbedPrivate *priv = self->priv;
+  PhotosWindowMode mode;
 
   mode = photos_mode_controller_get_window_mode (priv->mode_cntrlr);
-  show_search = (mode == PHOTOS_WINDOW_MODE_PREVIEW && active_item == NULL && active_collection == NULL)
-                || (mode == PHOTOS_WINDOW_MODE_SEARCH && active_item == NULL);
+  if (mode != PHOTOS_WINDOW_MODE_SEARCH)
+    return;
 
-  if (show_search)
-    photos_embed_restore_search (self);
+  if (collection == NULL)
+    {
+      photos_embed_restore_search (self);
+    }
   else
-    photos_embed_save_search (self);
+    {
+      PhotosSearchType *search_type;
+      const gchar *str;
+      const gchar *id;
 
-  state = g_variant_new ("b", show_search);
-  g_action_change_state (priv->search_action, state);
+      photos_embed_save_search (self);
 
-  /* See above. */
-  if (active_item == (GObject *) active_collection)
-    photos_embed_tracker_controllers_set_frozen (self, FALSE);
+      search_type = PHOTOS_SEARCH_TYPE (photos_base_manager_get_active_object (priv->srch_mngr));
+      str = photos_search_controller_get_string (priv->srch_cntrlr);
+      id = photos_filterable_get_id (PHOTOS_FILTERABLE (search_type));
+
+      if (g_strcmp0 (str, "") != 0 || g_strcmp0 (id, "all") != 0)
+        {
+          photos_base_manager_set_active_object_by_id (priv->srch_mngr, "all");
+          photos_search_controller_set_string (priv->srch_cntrlr, "");
+        }
+    }
 }
 
 
@@ -426,44 +426,60 @@ photos_embed_notify_visible_child (PhotosEmbed *self)
 
 
 static void
-photos_embed_prepare_for_collections (PhotosEmbed *self)
+photos_embed_prepare_for_collections (PhotosEmbed *self, PhotosWindowMode old_mode)
 {
   PhotosEmbedPrivate *priv = self->priv;
 
-  photos_base_manager_set_active_object (priv->item_mngr, NULL);
+  if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
+    photos_embed_tracker_controllers_set_frozen (self, FALSE);
+
   photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
   gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "collections");
 }
 
 
 static void
-photos_embed_prepare_for_favorites (PhotosEmbed *self)
+photos_embed_prepare_for_favorites (PhotosEmbed *self, PhotosWindowMode old_mode)
 {
   PhotosEmbedPrivate *priv = self->priv;
 
-  photos_base_manager_set_active_object (priv->item_mngr, NULL);
+  if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
+    photos_embed_tracker_controllers_set_frozen (self, FALSE);
+
   photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
   gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "favorites");
 }
 
 
 static void
-photos_embed_prepare_for_overview (PhotosEmbed *self)
+photos_embed_prepare_for_overview (PhotosEmbed *self, PhotosWindowMode old_mode)
 {
   PhotosEmbedPrivate *priv = self->priv;
 
-  photos_base_manager_set_active_object (priv->item_mngr, NULL);
+  if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
+    photos_embed_tracker_controllers_set_frozen (self, FALSE);
+
   photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
   gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "overview");
 }
 
 
 static void
-photos_embed_prepare_for_search (PhotosEmbed *self)
+photos_embed_prepare_for_search (PhotosEmbed *self, PhotosWindowMode old_mode)
 {
   PhotosEmbedPrivate *priv = self->priv;
 
-  photos_base_manager_set_active_object (priv->item_mngr, NULL);
+  if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
+    {
+      PhotosBaseItem *active_collection;
+
+      active_collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (priv->item_mngr));
+      if (active_collection == NULL)
+        photos_embed_restore_search (self);
+
+      photos_embed_tracker_controllers_set_frozen (self, FALSE);
+    }
+
   photos_spinner_box_stop (PHOTOS_SPINNER_BOX (priv->spinner_box));
   gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "search");
 }
@@ -564,23 +580,23 @@ photos_embed_window_mode_changed (PhotosModeController *mode_cntrlr,
   switch (mode)
     {
     case PHOTOS_WINDOW_MODE_COLLECTIONS:
-      photos_embed_prepare_for_collections (self);
+      photos_embed_prepare_for_collections (self, old_mode);
       goto set_toolbar_model;
 
     case PHOTOS_WINDOW_MODE_FAVORITES:
-      photos_embed_prepare_for_favorites (self);
+      photos_embed_prepare_for_favorites (self, old_mode);
       goto set_toolbar_model;
 
     case PHOTOS_WINDOW_MODE_OVERVIEW:
-      photos_embed_prepare_for_overview (self);
+      photos_embed_prepare_for_overview (self, old_mode);
       goto set_toolbar_model;
 
     case PHOTOS_WINDOW_MODE_PREVIEW:
-      photos_embed_prepare_for_preview (self);
+      photos_embed_prepare_for_preview (self, old_mode);
       break;
 
     case PHOTOS_WINDOW_MODE_SEARCH:
-      photos_embed_prepare_for_search (self);
+      photos_embed_prepare_for_search (self, old_mode);
       goto set_toolbar_model;
 
     case PHOTOS_WINDOW_MODE_NONE:
@@ -719,7 +735,7 @@ photos_embed_init (PhotosEmbed *self)
                            self,
                            G_CONNECT_SWAPPED);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   g_signal_connect_object (priv->mode_cntrlr,
                            "window-mode-changed",
                            G_CALLBACK (photos_embed_window_mode_changed),
@@ -739,7 +755,11 @@ photos_embed_init (PhotosEmbed *self)
                            G_CONNECT_SWAPPED);
 
   priv->item_mngr = g_object_ref (state->item_mngr);
-  g_signal_connect_object (priv->item_mngr, "active-changed", G_CALLBACK (photos_embed_active_changed), 
self, 0);
+  g_signal_connect_object (priv->item_mngr,
+                           "active-collection-changed",
+                           G_CALLBACK (photos_embed_active_collection_changed),
+                           self,
+                           0);
   g_signal_connect_object (priv->item_mngr,
                            "load-finished",
                            G_CALLBACK (photos_embed_load_finished),
diff --git a/src/photos-empty-results-box.h b/src/photos-empty-results-box.h
index 2913a55..7e80985 100644
--- a/src/photos-empty-results-box.h
+++ b/src/photos-empty-results-box.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2012, 2013, 2014 Red Hat, Inc.
+ * Copyright © 2012, 2013, 2014, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,7 +27,7 @@
 
 #include <gtk/gtk.h>
 
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/photos-enums.c.template b/src/photos-enums.c.template
index 2033eca..0a6e789 100644
--- a/src/photos-enums.c.template
+++ b/src/photos-enums.c.template
@@ -3,7 +3,7 @@
 #include "config.h"
 
 #include "photos-enums.h"
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 #include "photos-preview-nav-buttons.h"
 
 /*** END file-header ***/
diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c
index e2978a4..cf3570b 100644
--- a/src/photos-item-manager.c
+++ b/src/photos-item-manager.c
@@ -29,9 +29,11 @@
 #include <glib.h>
 #include <tracker-sparql.h>
 
+#include "photos-enums.h"
 #include "photos-filterable.h"
 #include "photos-item-manager.h"
 #include "photos-local-item.h"
+#include "photos-marshalers.h"
 #include "photos-query.h"
 #include "photos-search-context.h"
 #include "photos-single-item-job.h"
@@ -47,8 +49,11 @@ struct _PhotosItemManager
   GHashTable *collections;
   GIOExtensionPoint *extension_point;
   GQueue *collection_path;
+  GQueue *history;
   PhotosBaseItem *active_collection;
   PhotosTrackerChangeMonitor *monitor;
+  PhotosWindowMode mode;
+  gboolean fullscreen;
 };
 
 struct _PhotosItemManagerClass
@@ -57,15 +62,21 @@ struct _PhotosItemManagerClass
 
   /* signals */
   void (*active_collection_changed) (PhotosItemManager *self, PhotosBaseItem *collection);
+  void (*can_fullscreen_changed)    (PhotosItemManager *self);
+  void (*fullscreen_changed)        (PhotosItemManager *self, gboolean fullscreen);
   void (*load_finished)             (PhotosItemManager *self, PhotosBaseItem *item, GeglNode *node);
   void (*load_started)              (PhotosItemManager *self, PhotosBaseItem *item, GCancellable 
*cancellable);
+  void (*window_mode_changed)       (PhotosItemManager *self, PhotosWindowMode mode, PhotosWindowMode 
old_mode);
 };
 
 enum
 {
   ACTIVE_COLLECTION_CHANGED,
+  CAN_FULLSCREEN_CHANGED,
+  FULLSCREEN_CHANGED,
   LOAD_FINISHED,
   LOAD_STARTED,
+  WINDOW_MODE_CHANGED,
   LAST_SIGNAL
 };
 
@@ -202,6 +213,14 @@ photos_item_manager_collection_path_free_foreach (gpointer data, gpointer user_d
 }
 
 
+static void
+photos_item_manager_collection_path_free (PhotosItemManager *self)
+{
+  g_queue_foreach (self->collection_path, photos_item_manager_collection_path_free_foreach, NULL);
+  g_queue_free (self->collection_path);
+}
+
+
 static gchar *
 photos_item_manager_get_where (PhotosBaseManager *mngr, gint flags)
 {
@@ -260,47 +279,66 @@ photos_item_manager_remove_object_by_id (PhotosBaseManager *mngr, const gchar *i
 }
 
 
+static void
+photos_item_manager_update_fullscreen (PhotosItemManager *self)
+{
+  /* Should be called after priv->mode has been updated. */
+
+  if (!photos_mode_controller_get_can_fullscreen (self) && self->fullscreen)
+    photos_mode_controller_set_fullscreen (self, FALSE);
+
+  g_signal_emit (self, signals[CAN_FULLSCREEN_CHANGED], 0);
+}
+
+
+static gboolean
+photos_item_manager_set_window_mode_internal (PhotosItemManager *self,
+                                              PhotosWindowMode mode,
+                                              PhotosWindowMode *out_old_mode)
+{
+  PhotosWindowMode old_mode;
+  gboolean ret_val = FALSE;
+
+  old_mode = self->mode;
+
+  if (old_mode == mode)
+    goto out;
+
+  g_queue_push_head (self->history, GINT_TO_POINTER (old_mode));
+  self->mode = mode;
+
+  if (out_old_mode != NULL)
+    *out_old_mode = old_mode;
+
+  ret_val = TRUE;
+
+ out:
+  return ret_val;
+}
+
+
 static gboolean
 photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *object)
 {
   PhotosItemManager *self = PHOTOS_ITEM_MANAGER (manager);
   GObject *active_item;
+  PhotosWindowMode old_mode;
   gboolean active_collection_changed = FALSE;
   gboolean ret_val = FALSE;
   gboolean start_loading = FALSE;
+  gboolean window_mode_changed = FALSE;
 
-  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (object) || object == NULL, FALSE);
+  g_return_val_if_fail (object != NULL, FALSE);
+  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (object), FALSE);
 
   active_item = photos_base_manager_get_active_object (manager);
   if (object == active_item)
     goto out;
 
-  /* Passing NULL is a way to go back to the current collection or
-   * overview from the preview. However, you can't do that when you
-   * are looking at a collection.
-   */
-  if (object == NULL)
-    {
-      if (active_item != (GObject *) self->active_collection)
-        object = (GObject *) self->active_collection;
-      else
-        goto out;
-    }
-
   photos_item_manager_clear_active_item_load (self);
 
-  /* This is when we are going back to the overview from the preview. */
-  if (object == NULL)
-    goto end;
-
   if (photos_base_item_is_collection (PHOTOS_BASE_ITEM (object)))
     {
-      /* This is when we are going back to the collection from the
-       * preview.
-       */
-      if (object == (GObject *) self->active_collection)
-        goto end;
-
       g_queue_push_head (self->collection_path,
                          (self->active_collection != NULL) ? g_object_ref (self->active_collection) : NULL);
 
@@ -309,15 +347,26 @@ photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *obje
       active_collection_changed = TRUE;
     }
   else
-    start_loading = TRUE;
+    {
+      window_mode_changed = photos_item_manager_set_window_mode_internal (self,
+                                                                          PHOTOS_WINDOW_MODE_PREVIEW,
+                                                                          &old_mode);
+      photos_item_manager_update_fullscreen (self);
+      start_loading = TRUE;
+    }
 
- end:
   ret_val = PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->set_active_object (manager, 
object);
   /* We have already eliminated the possibility of failure. */
   g_assert (ret_val == TRUE);
 
+  active_item = photos_base_manager_get_active_object (manager);
+  g_assert (active_item == object);
+
   if (active_collection_changed)
-    g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
+    {
+      g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
+      g_assert (active_item == (GObject *) self->active_collection);
+    }
 
   if (start_loading)
     {
@@ -335,6 +384,11 @@ photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *obje
                                    g_object_ref (self));
 
       g_signal_emit (self, signals[LOAD_STARTED], 0, PHOTOS_BASE_ITEM (object), self->loader_cancellable);
+
+      if (window_mode_changed)
+        g_signal_emit (self, signals[WINDOW_MODE_CHANGED], 0, PHOTOS_WINDOW_MODE_PREVIEW, old_mode);
+
+      g_assert (active_item != (GObject *) self->active_collection);
     }
 
  out:
@@ -349,8 +403,7 @@ photos_item_manager_dispose (GObject *object)
 
   if (self->collection_path != NULL)
     {
-      g_queue_foreach (self->collection_path, photos_item_manager_collection_path_free_foreach, NULL);
-      g_queue_free (self->collection_path);
+      photos_item_manager_collection_path_free (self);
       self->collection_path = NULL;
     }
 
@@ -364,11 +417,24 @@ photos_item_manager_dispose (GObject *object)
 
 
 static void
+photos_item_manager_finalize (GObject *object)
+{
+  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (object);
+
+  g_queue_free (self->history);
+
+  G_OBJECT_CLASS (photos_item_manager_parent_class)->finalize (object);
+}
+
+
+static void
 photos_item_manager_init (PhotosItemManager *self)
 {
   self->collections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   self->extension_point = g_io_extension_point_lookup (PHOTOS_BASE_ITEM_EXTENSION_POINT_NAME);
   self->collection_path = g_queue_new ();
+  self->history = g_queue_new ();
+  self->mode = PHOTOS_WINDOW_MODE_NONE;
 
   self->monitor = photos_tracker_change_monitor_dup_singleton (NULL, NULL);
   if (G_LIKELY (self->monitor != NULL))
@@ -376,6 +442,8 @@ photos_item_manager_init (PhotosItemManager *self)
                               "changes-pending",
                               G_CALLBACK (photos_item_manager_changes_pending),
                               self);
+
+  self->fullscreen = FALSE;
 }
 
 
@@ -386,6 +454,7 @@ photos_item_manager_class_init (PhotosItemManagerClass *class)
   PhotosBaseManagerClass *base_manager_class = PHOTOS_BASE_MANAGER_CLASS (class);
 
   object_class->dispose = photos_item_manager_dispose;
+  object_class->finalize = photos_item_manager_finalize;
   base_manager_class->add_object = photos_item_manager_add_object;
   base_manager_class->get_where = photos_item_manager_get_where;
   base_manager_class->set_active_object = photos_item_manager_set_active_object;
@@ -403,6 +472,29 @@ photos_item_manager_class_init (PhotosItemManagerClass *class)
                                                      1,
                                                      PHOTOS_TYPE_BASE_ITEM);
 
+  signals[CAN_FULLSCREEN_CHANGED] = g_signal_new ("can-fullscreen-changed",
+                                                  G_TYPE_FROM_CLASS (class),
+                                                  G_SIGNAL_RUN_LAST,
+                                                  G_STRUCT_OFFSET (PhotosItemManagerClass,
+                                                                   can_fullscreen_changed),
+                                                  NULL, /*accumulator */
+                                                  NULL, /*accu_data */
+                                                  g_cclosure_marshal_VOID__VOID,
+                                                  G_TYPE_NONE,
+                                                  0);
+
+  signals[FULLSCREEN_CHANGED] = g_signal_new ("fullscreen-changed",
+                                              G_TYPE_FROM_CLASS (class),
+                                              G_SIGNAL_RUN_LAST,
+                                              G_STRUCT_OFFSET (PhotosItemManagerClass,
+                                                               fullscreen_changed),
+                                              NULL, /*accumulator */
+                                              NULL, /* accu_data */
+                                              g_cclosure_marshal_VOID__BOOLEAN,
+                                              G_TYPE_NONE,
+                                              1,
+                                              G_TYPE_BOOLEAN);
+
   signals[LOAD_FINISHED] = g_signal_new ("load-finished",
                                          G_TYPE_FROM_CLASS (class),
                                          G_SIGNAL_RUN_LAST,
@@ -428,6 +520,19 @@ photos_item_manager_class_init (PhotosItemManagerClass *class)
                                         2,
                                         PHOTOS_TYPE_BASE_ITEM,
                                         G_TYPE_CANCELLABLE);
+
+  signals[WINDOW_MODE_CHANGED] = g_signal_new ("window-mode-changed",
+                                               G_TYPE_FROM_CLASS (class),
+                                               G_SIGNAL_RUN_LAST,
+                                               G_STRUCT_OFFSET (PhotosItemManagerClass,
+                                                                window_mode_changed),
+                                               NULL, /*accumulator */
+                                               NULL, /*accu_data */
+                                               _photos_marshal_VOID__ENUM_ENUM,
+                                               G_TYPE_NONE,
+                                               2,
+                                               PHOTOS_TYPE_WINDOW_MODE,
+                                               PHOTOS_TYPE_WINDOW_MODE);
 }
 
 
@@ -547,3 +652,128 @@ photos_item_manager_get_collections (PhotosItemManager *self)
 {
   return self->collections;
 }
+
+
+gboolean
+photos_mode_controller_get_can_fullscreen (PhotosModeController *self)
+{
+  return self->mode == PHOTOS_WINDOW_MODE_PREVIEW;
+}
+
+
+gboolean
+photos_mode_controller_get_fullscreen (PhotosModeController *self)
+{
+  return self->fullscreen;
+}
+
+
+PhotosWindowMode
+photos_mode_controller_get_window_mode (PhotosModeController *self)
+{
+  return self->mode;
+}
+
+
+void
+photos_mode_controller_go_back (PhotosModeController *self)
+{
+  PhotosWindowMode old_mode;
+  PhotosWindowMode tmp;
+
+  g_return_if_fail (!g_queue_is_empty (self->history));
+
+  old_mode = (PhotosWindowMode) GPOINTER_TO_INT (g_queue_peek_head (self->history));
+
+  /* Always go back to the overview when activated from the search
+   * provider. It is easier to special case it here instead of all
+   * over the code.
+   */
+  if (self->mode == PHOTOS_WINDOW_MODE_PREVIEW && old_mode == PHOTOS_WINDOW_MODE_NONE)
+    old_mode = PHOTOS_WINDOW_MODE_OVERVIEW;
+
+  g_return_if_fail (old_mode != PHOTOS_WINDOW_MODE_NONE);
+  g_return_if_fail (old_mode != PHOTOS_WINDOW_MODE_PREVIEW);
+
+  g_queue_pop_head (self->history);
+
+  /* Swap the old and current modes */
+  tmp = old_mode;
+  old_mode = self->mode;
+  self->mode = tmp;
+
+  photos_item_manager_update_fullscreen (self);
+  photos_item_manager_clear_active_item_load (self);
+
+  if (old_mode == PHOTOS_WINDOW_MODE_PREVIEW)
+    {
+      PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
+        ->set_active_object (PHOTOS_BASE_MANAGER (self), (GObject *) self->active_collection);
+    }
+  else
+    {
+      photos_item_manager_collection_path_free (self);
+      self->collection_path = g_queue_new ();
+
+      g_clear_object (&self->active_collection);
+
+      PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
+        ->set_active_object (PHOTOS_BASE_MANAGER (self), NULL);
+
+      g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
+    }
+
+  g_signal_emit (self, signals[WINDOW_MODE_CHANGED], 0, self->mode, old_mode);
+}
+
+
+void
+photos_mode_controller_toggle_fullscreen (PhotosModeController *self)
+{
+  photos_mode_controller_set_fullscreen (self, !self->fullscreen);
+}
+
+
+void
+photos_mode_controller_set_fullscreen (PhotosModeController *self, gboolean fullscreen)
+{
+  if (self->fullscreen == fullscreen)
+    return;
+
+  self->fullscreen = fullscreen;
+  g_signal_emit (self, signals[FULLSCREEN_CHANGED], 0, self->fullscreen);
+}
+
+
+void
+photos_mode_controller_set_window_mode (PhotosModeController *self, PhotosWindowMode mode)
+{
+  PhotosWindowMode old_mode;
+  gboolean active_collection_changed = FALSE;
+
+  g_return_if_fail (mode != PHOTOS_WINDOW_MODE_NONE);
+  g_return_if_fail (mode != PHOTOS_WINDOW_MODE_PREVIEW);
+
+  if (!photos_item_manager_set_window_mode_internal (self, mode, &old_mode))
+    return;
+
+  photos_item_manager_update_fullscreen (self);
+  photos_item_manager_clear_active_item_load (self);
+
+  photos_item_manager_collection_path_free (self);
+  self->collection_path = g_queue_new ();
+
+  if (self->active_collection != NULL)
+    {
+      g_clear_object (&self->active_collection);
+      active_collection_changed = TRUE;
+    }
+
+  PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)
+    ->set_active_object (PHOTOS_BASE_MANAGER (self), NULL);
+
+  if (active_collection_changed)
+    g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
+
+  g_signal_emit (self, signals[WINDOW_MODE_CHANGED], 0, mode, old_mode);
+}
diff --git a/src/photos-item-manager.h b/src/photos-item-manager.h
index 62b3214..69a8fe8 100644
--- a/src/photos-item-manager.h
+++ b/src/photos-item-manager.h
@@ -44,9 +44,32 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
    PHOTOS_TYPE_ITEM_MANAGER))
 
+#define PHOTOS_TYPE_MODE_CONTROLLER (photos_item_manager_get_type ())
+
+#define PHOTOS_MODE_CONTROLLER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+   PHOTOS_TYPE_MODE_CONTROLLER, PhotosModeController))
+
+#define PHOTOS_IS_MODE_CONTROLLER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+   PHOTOS_TYPE_MODE_CONTROLLER))
+
+typedef enum
+{
+  PHOTOS_WINDOW_MODE_NONE,
+  PHOTOS_WINDOW_MODE_COLLECTIONS,
+  PHOTOS_WINDOW_MODE_FAVORITES,
+  PHOTOS_WINDOW_MODE_OVERVIEW,
+  PHOTOS_WINDOW_MODE_PREVIEW,
+  PHOTOS_WINDOW_MODE_SEARCH
+} PhotosWindowMode;
+
 typedef struct _PhotosItemManager      PhotosItemManager;
 typedef struct _PhotosItemManagerClass PhotosItemManagerClass;
 
+typedef struct _PhotosItemManager      PhotosModeController;
+typedef struct _PhotosItemManagerClass PhotosModeControllerClass;
+
 GType                     photos_item_manager_get_type           (void) G_GNUC_CONST;
 
 PhotosBaseManager        *photos_item_manager_new                (void);
@@ -63,6 +86,22 @@ PhotosBaseItem           *photos_item_manager_get_active_collection (PhotosItemM
 
 GHashTable               *photos_item_manager_get_collections       (PhotosItemManager *self);
 
+gboolean                  photos_mode_controller_get_can_fullscreen (PhotosModeController *self);
+
+gboolean                  photos_mode_controller_get_fullscreen     (PhotosModeController *self);
+
+PhotosWindowMode          photos_mode_controller_get_window_mode    (PhotosModeController *self);
+
+void                      photos_mode_controller_go_back            (PhotosModeController *self);
+
+void                      photos_mode_controller_toggle_fullscreen  (PhotosModeController *self);
+
+void                      photos_mode_controller_set_fullscreen     (PhotosModeController *self,
+                                                                     gboolean              fullscreen);
+
+void                      photos_mode_controller_set_window_mode    (PhotosModeController *self,
+                                                                     PhotosWindowMode      mode);
+
 G_END_DECLS
 
 #endif /* PHOTOS_ITEM_MANAGER_H */
diff --git a/src/photos-main-toolbar.c b/src/photos-main-toolbar.c
index db1ddcb..c46d06c 100644
--- a/src/photos-main-toolbar.c
+++ b/src/photos-main-toolbar.c
@@ -36,7 +36,6 @@
 #include "photos-icons.h"
 #include "photos-item-manager.h"
 #include "photos-main-toolbar.h"
-#include "photos-mode-controller.h"
 #include "photos-overview-searchbar.h"
 #include "photos-remote-display-manager.h"
 #include "photos-search-context.h"
@@ -327,7 +326,6 @@ photos_main_toolbar_back_button_clicked (PhotosMainToolbar *self)
   if (priv->loader_cancellable != NULL)
     g_cancellable_cancel (priv->loader_cancellable);
 
-  photos_base_manager_set_active_object (priv->item_mngr, NULL);
   photos_mode_controller_go_back (priv->mode_cntrlr);
 }
 
@@ -774,7 +772,7 @@ photos_main_toolbar_init (PhotosMainToolbar *self)
 
   priv->item_mngr = g_object_ref (state->item_mngr);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
 
   priv->sel_cntrlr = photos_selection_controller_dup_singleton ();
   g_signal_connect_object (priv->sel_cntrlr,
diff --git a/src/photos-main-window.c b/src/photos-main-window.c
index 1463b2b..e865f40 100644
--- a/src/photos-main-window.c
+++ b/src/photos-main-window.c
@@ -33,7 +33,6 @@
 #include "photos-embed.h"
 #include "photos-item-manager.h"
 #include "photos-main-window.h"
-#include "photos-mode-controller.h"
 #include "photos-preview-view.h"
 #include "photos-search-context.h"
 #include "photos-selection-controller.h"
@@ -163,7 +162,6 @@ photos_main_window_go_back (PhotosMainWindow *self)
   switch (mode)
     {
     case PHOTOS_WINDOW_MODE_PREVIEW:
-      photos_base_manager_set_active_object (priv->item_mngr, NULL);
       photos_mode_controller_go_back (priv->mode_cntrlr);
       break;
 
@@ -242,10 +240,7 @@ photos_main_window_handle_key_preview (PhotosMainWindow *self, GdkEventKey *even
     {
     case GDK_KEY_Escape:
       if (fullscreen)
-        {
-          photos_base_manager_set_active_object (priv->item_mngr, NULL);
-          photos_mode_controller_go_back (priv->mode_cntrlr);
-        }
+        photos_mode_controller_go_back (priv->mode_cntrlr);
       break;
 
     case GDK_KEY_Left:
@@ -429,7 +424,7 @@ photos_main_window_init (PhotosMainWindow *self)
 
   priv->item_mngr = g_object_ref (state->item_mngr);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   g_signal_connect_swapped (priv->mode_cntrlr,
                             "fullscreen-changed",
                             G_CALLBACK (photos_main_window_fullscreen_changed),
diff --git a/src/photos-overview-searchbar.c b/src/photos-overview-searchbar.c
index 201e995..a2c7de2 100644
--- a/src/photos-overview-searchbar.c
+++ b/src/photos-overview-searchbar.c
@@ -49,7 +49,6 @@ struct _PhotosOverviewSearchbarPrivate
   GtkWidget *dropdown;
   GtkWidget *dropdown_button;
   GtkWidget *search_container;
-  PhotosBaseManager *item_mngr;
   PhotosBaseManager *src_mngr;
   PhotosBaseManager *srch_mtch_mngr;
   PhotosBaseManager *srch_typ_mngr;
@@ -92,29 +91,6 @@ photos_overview_searchbar_active_changed (PhotosOverviewSearchbar *self,
 
 
 static void
-photos_overview_searchbar_collection_active_changed (PhotosOverviewSearchbar *self, PhotosBaseItem 
*collection)
-{
-  PhotosOverviewSearchbarPrivate *priv = self->priv;
-  PhotosSearchType *search_type;
-  const gchar *id;
-  const gchar *str;
-
-  if (collection == NULL)
-    return;
-
-  search_type = PHOTOS_SEARCH_TYPE (photos_base_manager_get_active_object (priv->srch_typ_mngr));
-  str = photos_search_controller_get_string (priv->srch_cntrlr);
-  id = photos_filterable_get_id (PHOTOS_FILTERABLE (search_type));
-
-  if (g_strcmp0 (str, "") != 0 || g_strcmp0 (id, "all") != 0)
-    {
-      photos_base_manager_set_active_object_by_id (priv->srch_typ_mngr, "all");
-      gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
-    }
-}
-
-
-static void
 photos_overview_searchbar_closed (PhotosOverviewSearchbar *self)
 {
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->dropdown_button), FALSE);
@@ -303,7 +279,6 @@ photos_overview_searchbar_dispose (GObject *object)
   PhotosOverviewSearchbar *self = PHOTOS_OVERVIEW_SEARCHBAR (object);
   PhotosOverviewSearchbarPrivate *priv = self->priv;
 
-  g_clear_object (&priv->item_mngr);
   g_clear_object (&priv->src_mngr);
   g_clear_object (&priv->srch_mtch_mngr);
   g_clear_object (&priv->srch_typ_mngr);
@@ -349,13 +324,6 @@ photos_overview_searchbar_init (PhotosOverviewSearchbar *self)
                            self,
                            G_CONNECT_SWAPPED);
 
-  priv->item_mngr = g_object_ref (state->item_mngr);
-  g_signal_connect_object (priv->item_mngr,
-                           "active-collection-changed",
-                           G_CALLBACK (photos_overview_searchbar_collection_active_changed),
-                           self,
-                           G_CONNECT_SWAPPED);
-
   priv->srch_cntrlr = g_object_ref (state->srch_cntrlr);
 }
 
diff --git a/src/photos-preview-view.c b/src/photos-preview-view.c
index 51c00cc..5edaab8 100644
--- a/src/photos-preview-view.c
+++ b/src/photos-preview-view.c
@@ -26,12 +26,14 @@
 #include "config.h"
 
 #include <glib.h>
+#include <gio/gio.h>
 #include <glib/gi18n.h>
 
 #include "gegl-gtk-view.h"
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 #include "photos-preview-nav-buttons.h"
 #include "photos-preview-view.h"
+#include "photos-search-context.h"
 
 
 struct _PhotosPreviewViewPrivate
@@ -243,13 +245,18 @@ static void
 photos_preview_view_init (PhotosPreviewView *self)
 {
   PhotosPreviewViewPrivate *priv;
+  GApplication *app;
   GtkStyleContext *context;
   GtkWidget *view;
+  PhotosSearchContextState *state;
 
   self->priv = photos_preview_view_get_instance_private (self);
   priv = self->priv;
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  app = g_application_get_default ();
+  state = photos_search_context_get_state (PHOTOS_SEARCH_CONTEXT (app));
+
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   g_signal_connect_object (priv->mode_cntrlr,
                            "window-mode-changed",
                            G_CALLBACK (photos_preview_view_window_mode_changed),
diff --git a/src/photos-search-context.c b/src/photos-search-context.c
index 864227d..19fc2a2 100644
--- a/src/photos-search-context.c
+++ b/src/photos-search-context.c
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2013, 2014 Red Hat, Inc.
+ * Copyright © 2013, 2014, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -51,6 +51,7 @@ photos_search_context_state_new (PhotosSearchContext *self)
 
   state = g_slice_new0 (PhotosSearchContextState);
   state->item_mngr = photos_item_manager_new ();
+  state->mode_cntrlr = g_object_ref (state->item_mngr);
   state->src_mngr = photos_source_manager_new ();
   state->srch_cntrlr = photos_search_controller_new ();
   state->srch_mtch_mngr = photos_search_match_manager_new (state->srch_cntrlr);
@@ -64,6 +65,7 @@ void
 photos_search_context_state_free (PhotosSearchContextState *state)
 {
   g_object_unref (state->item_mngr);
+  g_object_unref (state->mode_cntrlr);
   g_object_unref (state->src_mngr);
   g_object_unref (state->srch_mtch_mngr);
   g_object_unref (state->srch_typ_mngr);
diff --git a/src/photos-search-context.h b/src/photos-search-context.h
index 7b6e4fa..c72adc0 100644
--- a/src/photos-search-context.h
+++ b/src/photos-search-context.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2013, 2014 Red Hat, Inc.
+ * Copyright © 2013, 2014, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -51,6 +51,7 @@ typedef struct _PhotosSearchContextInterface PhotosSearchContextInterface;
 struct _PhotosSearchContextState
 {
   gpointer item_mngr;
+  gpointer mode_cntrlr;
   gpointer src_mngr;
   gpointer srch_mtch_mngr;
   gpointer srch_typ_mngr;
diff --git a/src/photos-tracker-collections-controller.c b/src/photos-tracker-collections-controller.c
index 6230a45..23d0607 100644
--- a/src/photos-tracker-collections-controller.c
+++ b/src/photos-tracker-collections-controller.c
@@ -24,7 +24,6 @@
 #include <gio/gio.h>
 
 #include "photos-item-manager.h"
-#include "photos-mode-controller.h"
 #include "photos-offset-collections-controller.h"
 #include "photos-query-builder.h"
 #include "photos-search-context.h"
@@ -148,7 +147,7 @@ photos_tracker_collections_controller_init (PhotosTrackerCollectionsController *
                             G_CALLBACK (photos_tracker_collections_controller_col_active_changed),
                             self);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   priv->offset_cntrlr = photos_offset_collections_controller_dup_singleton ();
 }
 
diff --git a/src/photos-tracker-controller.c b/src/photos-tracker-controller.c
index 7519bac..3aae435 100644
--- a/src/photos-tracker-controller.c
+++ b/src/photos-tracker-controller.c
@@ -36,7 +36,6 @@
 #include "photos-filterable.h"
 #include "photos-item-manager.h"
 #include "photos-marshalers.h"
-#include "photos-mode-controller.h"
 #include "photos-query-builder.h"
 #include "photos-search-context.h"
 #include "photos-tracker-controller.h"
@@ -317,12 +316,6 @@ photos_tracker_controller_constructed (GObject *object)
 
   G_OBJECT_CLASS (photos_tracker_controller_parent_class)->constructed (object);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
-  g_signal_connect_swapped (priv->mode_cntrlr,
-                            "window-mode-changed",
-                            G_CALLBACK (photos_tracker_controller_window_mode_changed),
-                            self);
-
   priv->offset_cntrlr = PHOTOS_TRACKER_CONTROLLER_GET_CLASS (self)->get_offset_controller (self);
   g_signal_connect_swapped (priv->offset_cntrlr,
                             "offset-changed",
@@ -406,6 +399,12 @@ photos_tracker_controller_init (PhotosTrackerController *self)
                             G_CALLBACK (photos_tracker_controller_source_object_added_removed),
                             self);
 
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
+  g_signal_connect_swapped (priv->mode_cntrlr,
+                            "window-mode-changed",
+                            G_CALLBACK (photos_tracker_controller_window_mode_changed),
+                            self);
+
   priv->queue = photos_tracker_queue_dup_singleton (NULL, &priv->queue_error);
 }
 
diff --git a/src/photos-tracker-favorites-controller.c b/src/photos-tracker-favorites-controller.c
index dfcfee5..9a5c6fd 100644
--- a/src/photos-tracker-favorites-controller.c
+++ b/src/photos-tracker-favorites-controller.c
@@ -24,7 +24,6 @@
 #include <gio/gio.h>
 
 #include "photos-item-manager.h"
-#include "photos-mode-controller.h"
 #include "photos-offset-favorites-controller.h"
 #include "photos-query-builder.h"
 #include "photos-search-context.h"
@@ -148,7 +147,7 @@ photos_tracker_favorites_controller_init (PhotosTrackerFavoritesController *self
                             G_CALLBACK (photos_tracker_favorites_controller_col_active_changed),
                             self);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   priv->offset_cntrlr = photos_offset_favorites_controller_dup_singleton ();
 }
 
diff --git a/src/photos-tracker-overview-controller.c b/src/photos-tracker-overview-controller.c
index 591fc50..6cca009 100644
--- a/src/photos-tracker-overview-controller.c
+++ b/src/photos-tracker-overview-controller.c
@@ -27,7 +27,7 @@
 
 #include <gio/gio.h>
 
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 #include "photos-offset-overview-controller.h"
 #include "photos-query-builder.h"
 #include "photos-search-context.h"
diff --git a/src/photos-tracker-search-controller.c b/src/photos-tracker-search-controller.c
index 5938d24..7f85ef4 100644
--- a/src/photos-tracker-search-controller.c
+++ b/src/photos-tracker-search-controller.c
@@ -29,7 +29,6 @@
 
 #include "photos-base-manager.h"
 #include "photos-item-manager.h"
-#include "photos-mode-controller.h"
 #include "photos-offset-search-controller.h"
 #include "photos-query-builder.h"
 #include "photos-search-context.h"
@@ -184,7 +183,7 @@ photos_tracker_search_controller_init (PhotosTrackerSearchController *self)
                             G_CALLBACK (photos_tracker_controller_refresh_for_object),
                             self);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   priv->offset_cntrlr = photos_offset_search_controller_dup_singleton ();
 
   priv->srch_cntrlr = g_object_ref (state->srch_cntrlr);
diff --git a/src/photos-view-container.c b/src/photos-view-container.c
index 822556e..d562c31 100644
--- a/src/photos-view-container.c
+++ b/src/photos-view-container.c
@@ -302,7 +302,7 @@ photos_view_container_constructed (GObject *object)
                                                 photos_selection_controller_get_selection_mode 
(priv->sel_cntrlr),
                                                 self);
 
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
   g_signal_connect_object (priv->mode_cntrlr,
                            "window-mode-changed",
                            G_CALLBACK (photos_view_container_window_mode_changed),
diff --git a/src/photos-view-container.h b/src/photos-view-container.h
index 35bd183..9f87ff7 100644
--- a/src/photos-view-container.h
+++ b/src/photos-view-container.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2012, 2014 Red Hat, Inc.
+ * Copyright © 2012, 2014, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,7 +27,7 @@
 
 #include <gtk/gtk.h>
 
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/photos-view-model.c b/src/photos-view-model.c
index 2e4a0e6..c708e0a 100644
--- a/src/photos-view-model.c
+++ b/src/photos-view-model.c
@@ -31,7 +31,6 @@
 #include "photos-base-manager.h"
 #include "photos-enums.h"
 #include "photos-filterable.h"
-#include "photos-item-manager.h"
 #include "photos-offset-collections-controller.h"
 #include "photos-offset-favorites-controller.h"
 #include "photos-offset-overview-controller.h"
@@ -466,7 +465,7 @@ photos_view_model_init (PhotosViewModel *self)
   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self), PHOTOS_VIEW_MODEL_MTIME, 
GTK_SORT_DESCENDING);
 
   priv->item_mngr = g_object_ref (state->item_mngr);
-  priv->mode_cntrlr = photos_mode_controller_dup_singleton ();
+  priv->mode_cntrlr = g_object_ref (state->mode_cntrlr);
 
   priv->oldest_mtime = G_MAXINT64;
 }
diff --git a/src/photos-view-model.h b/src/photos-view-model.h
index 5fd84a2..76e216b 100644
--- a/src/photos-view-model.h
+++ b/src/photos-view-model.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2012 Red Hat, Inc.
+ * Copyright © 2012, 2015 Red Hat, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -28,7 +28,7 @@
 #include <gtk/gtk.h>
 
 #include "photos-base-item.h"
-#include "photos-mode-controller.h"
+#include "photos-item-manager.h"
 
 G_BEGIN_DECLS
 


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