[gnome-photos] item-manager: Add mechanism for constraining item additions



commit 3ad413e3dc7b5375efebf4e32bce6c66be24d6a5
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Jan 12 11:22:22 2017 +0100

    item-manager: Add mechanism for constraining item additions
    
    Constraining the addition of new items was an important function of the
    ViewModel class. We want to show content in steps of N items, sorted by
    their mtime in descending order. Normally, this works because the step
    and offset are embedded in our SPARQL queries. However, when reacting
    to out-of-band "graph-updated" signals, we might end up showing too
    manyitems unless the constraints are re-validated.
    
    Once we port to GtkFlowBox, we will lose the ViewModel class.
    Therefore, we need to find a new home for this code.
    
    This commit adds some of the mechanisms needed to perform constrained
    item additions in ItemManager. The constraints aren't actually turned
    on. That will happen in a latter commit.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=690623

 src/photos-item-manager.c |  131 ++++++++++++++++++++++++++++++++++++++++----
 src/photos-item-manager.h |    6 ++-
 2 files changed, 124 insertions(+), 13 deletions(-)
---
diff --git a/src/photos-item-manager.c b/src/photos-item-manager.c
index d87b354..232693b 100644
--- a/src/photos-item-manager.c
+++ b/src/photos-item-manager.c
@@ -62,6 +62,7 @@ struct _PhotosItemManager
   PhotosTrackerChangeMonitor *monitor;
   PhotosWindowMode mode;
   gboolean fullscreen;
+  gboolean *constrain_additions;
 };
 
 struct _PhotosItemManagerClass
@@ -143,6 +144,63 @@ photos_item_manager_add_object (PhotosBaseManager *mngr, GObject *object)
 
 
 static gboolean
+photos_item_manager_can_add_mtime_for_mode (PhotosItemManager *self, gint64 mtime, PhotosWindowMode mode)
+{
+  PhotosBaseItem *oldest_item = NULL;
+  PhotosBaseManager *item_mngr_chld;
+  gboolean ret_val = TRUE;
+  gint64 oldest_mtime;
+  guint n_items;
+
+  if (!self->constrain_additions[mode])
+    goto out;
+
+  item_mngr_chld = self->item_mngr_chldrn[mode];
+  n_items = g_list_model_get_n_items (G_LIST_MODEL (item_mngr_chld));
+  if (n_items == 0)
+    goto out;
+
+  oldest_item = PHOTOS_BASE_ITEM (g_list_model_get_object (G_LIST_MODEL (item_mngr_chld), n_items - 1));
+  oldest_mtime = photos_base_item_get_mtime (oldest_item);
+
+  if (mtime > oldest_mtime)
+    goto out;
+
+  ret_val = FALSE;
+
+ out:
+  g_clear_object (&oldest_item);
+  return ret_val;
+}
+
+
+static gboolean
+photos_item_manager_can_add_cursor_for_mode (PhotosItemManager *self,
+                                             TrackerSparqlCursor *cursor,
+                                             PhotosWindowMode mode)
+{
+  gboolean ret_val = TRUE;
+  gint64 mtime;
+
+  mtime = tracker_sparql_cursor_get_boolean (cursor, PHOTOS_QUERY_COLUMNS_MTIME);
+  ret_val = photos_item_manager_can_add_mtime_for_mode (self, mtime, mode);
+  return ret_val;
+}
+
+
+static gboolean
+photos_item_manager_can_add_item_for_mode (PhotosItemManager *self, PhotosBaseItem *item, PhotosWindowMode 
mode)
+{
+  gboolean ret_val = TRUE;
+  gint64 mtime;
+
+  mtime = photos_base_item_get_mtime (item);
+  ret_val = photos_item_manager_can_add_mtime_for_mode (self, mtime, mode);
+  return ret_val;
+}
+
+
+static gboolean
 photos_item_manager_cursor_is_collection (TrackerSparqlCursor *cursor)
 {
   gboolean ret_val;
@@ -154,6 +212,30 @@ photos_item_manager_cursor_is_collection (TrackerSparqlCursor *cursor)
 }
 
 
+static gboolean
+photos_item_manager_try_to_add_item_for_mode (PhotosItemManager *self,
+                                              PhotosBaseItem *item,
+                                              PhotosWindowMode mode)
+{
+  gboolean ret_val = FALSE;
+
+  g_return_val_if_fail (PHOTOS_IS_ITEM_MANAGER (self), FALSE);
+  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (item), FALSE);
+  g_return_val_if_fail (mode != PHOTOS_WINDOW_MODE_NONE, FALSE);
+  g_return_val_if_fail (mode != PHOTOS_WINDOW_MODE_EDIT, FALSE);
+  g_return_val_if_fail (mode != PHOTOS_WINDOW_MODE_PREVIEW, FALSE);
+
+  if (!photos_item_manager_can_add_item_for_mode (self, item, mode))
+    goto out;
+
+  photos_base_manager_add_object (self->item_mngr_chldrn[mode], G_OBJECT (item));
+  ret_val = TRUE;
+
+ out:
+  return ret_val;
+}
+
+
 static void
 photos_item_manager_info_updated (PhotosBaseItem *item, gpointer user_data)
 {
@@ -178,14 +260,14 @@ photos_item_manager_info_updated (PhotosBaseItem *item, gpointer user_data)
   if (is_collection)
     {
       if (self->active_collection == NULL)
-        photos_base_manager_add_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_COLLECTIONS], G_OBJECT 
(item));
+        photos_item_manager_try_to_add_item_for_mode (self, item, PHOTOS_WINDOW_MODE_COLLECTIONS);
     }
   else
     {
       if (is_favorite)
-        photos_base_manager_add_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_FAVORITES], G_OBJECT 
(item));
+        photos_item_manager_try_to_add_item_for_mode (self, item, PHOTOS_WINDOW_MODE_FAVORITES);
 
-      photos_base_manager_add_object (self->item_mngr_chldrn[PHOTOS_WINDOW_MODE_OVERVIEW], G_OBJECT (item));
+      photos_item_manager_try_to_add_item_for_mode (self, item, PHOTOS_WINDOW_MODE_OVERVIEW);
     }
 
   if (is_collection)
@@ -207,7 +289,8 @@ photos_item_manager_info_updated (PhotosBaseItem *item, gpointer user_data)
 static void
 photos_item_manager_add_cursor_for_mode (PhotosItemManager *self,
                                          TrackerSparqlCursor *cursor,
-                                         PhotosWindowMode mode)
+                                         PhotosWindowMode mode,
+                                         gboolean force)
 {
   PhotosBaseItem *item = NULL;
   PhotosBaseManager *item_mngr_chld;
@@ -224,6 +307,9 @@ photos_item_manager_add_cursor_for_mode (PhotosItemManager *self,
   g_return_if_fail ((is_collection && (mode == PHOTOS_WINDOW_MODE_COLLECTIONS || mode == 
PHOTOS_WINDOW_MODE_SEARCH))
                     || (!is_collection && (mode != PHOTOS_WINDOW_MODE_COLLECTIONS || self->active_collection 
!= NULL)));
 
+  if (!force && !photos_item_manager_can_add_cursor_for_mode (self, cursor, mode))
+    goto out;
+
   item_mngr_chld = self->item_mngr_chldrn[mode];
   id = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
 
@@ -741,6 +827,7 @@ photos_item_manager_finalize (GObject *object)
   PhotosItemManager *self = PHOTOS_ITEM_MANAGER (object);
 
   g_queue_free (self->history);
+  g_free (self->constrain_additions);
 
   G_OBJECT_CLASS (photos_item_manager_parent_class)->finalize (object);
 
@@ -770,6 +857,7 @@ photos_item_manager_init (PhotosItemManager *self)
   self->history = g_queue_new ();
 
   window_mode_class = G_ENUM_CLASS (g_type_class_ref (PHOTOS_TYPE_WINDOW_MODE));
+
   self->item_mngr_chldrn = (PhotosBaseManager **) g_malloc0_n (window_mode_class->n_values + 1,
                                                                sizeof (PhotosBaseManager *));
   for (i = 0; i < window_mode_class->n_values; i++)
@@ -791,6 +879,7 @@ photos_item_manager_init (PhotosItemManager *self)
                              G_CONNECT_SWAPPED);
 
   self->fullscreen = FALSE;
+  self->constrain_additions = (gboolean *) g_malloc0_n (window_mode_class->n_values, sizeof (gboolean));
 
   g_type_class_unref (window_mode_class);
 }
@@ -939,14 +1028,14 @@ photos_item_manager_add_item (PhotosItemManager *self, TrackerSparqlCursor *curs
         photos_item_manager_activate_previous_collection (self);
 
       if (self->active_collection == NULL)
-        photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_COLLECTIONS);
+        photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_COLLECTIONS, force);
     }
   else
     {
       if (photos_item_manager_cursor_is_favorite (cursor))
-        photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_FAVORITES);
+        photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_FAVORITES, force);
 
-      photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_OVERVIEW);
+      photos_item_manager_add_cursor_for_mode (self, cursor, PHOTOS_WINDOW_MODE_OVERVIEW, force);
     }
 }
 
@@ -954,7 +1043,7 @@ photos_item_manager_add_item (PhotosItemManager *self, TrackerSparqlCursor *curs
 void
 photos_item_manager_add_item_for_mode (PhotosItemManager *self, PhotosWindowMode mode, TrackerSparqlCursor 
*cursor)
 {
-  photos_item_manager_add_cursor_for_mode (self, cursor, mode);
+  photos_item_manager_add_cursor_for_mode (self, cursor, mode, FALSE);
 }
 
 
@@ -1133,9 +1222,22 @@ photos_item_manager_hide_item (PhotosItemManager *self, PhotosBaseItem *item)
 
 
 void
+photos_item_manager_set_constraints_for_mode (PhotosItemManager *self, gboolean constrain, PhotosWindowMode 
mode)
+{
+  g_return_if_fail (PHOTOS_IS_ITEM_MANAGER (self));
+  g_return_if_fail (mode != PHOTOS_WINDOW_MODE_NONE);
+  g_return_if_fail (mode != PHOTOS_WINDOW_MODE_EDIT);
+  g_return_if_fail (mode != PHOTOS_WINDOW_MODE_PREVIEW);
+
+  self->constrain_additions[mode] = constrain;
+}
+
+
+void
 photos_item_manager_unhide_item (PhotosItemManager *self, PhotosBaseItem *item)
 {
   PhotosItemManagerHiddenItem *hidden_item;
+  gboolean added_somewhere = FALSE;
   const gchar *id;
   guint i;
 
@@ -1148,17 +1250,22 @@ photos_item_manager_unhide_item (PhotosItemManager *self, PhotosBaseItem *item)
   hidden_item = (PhotosItemManagerHiddenItem *) g_hash_table_lookup (self->hidden_items, id);
   g_return_if_fail (hidden_item->item == item);
 
-  for (i = 0; self->item_mngr_chldrn[i] != NULL; i++)
+  for (i = 1; self->item_mngr_chldrn[i] != NULL; i++)
     {
       g_assert_cmpuint (i, <, hidden_item->n_modes);
 
       if (hidden_item->modes[i])
-        photos_base_manager_add_object (self->item_mngr_chldrn[i], G_OBJECT (item));
+        added_somewhere = added_somewhere || photos_item_manager_try_to_add_item_for_mode (self, item, i);
     }
 
   g_hash_table_remove (self->hidden_items, id);
-  g_signal_connect_object (item, "info-updated", G_CALLBACK (photos_item_manager_info_updated), self, 0);
-  g_signal_emit_by_name (self, "object-added", G_OBJECT (item));
+
+  if (added_somewhere)
+    {
+      photos_base_manager_add_object (self->item_mngr_chldrn[0], G_OBJECT (item));
+      g_signal_connect_object (item, "info-updated", G_CALLBACK (photos_item_manager_info_updated), self, 0);
+      g_signal_emit_by_name (self, "object-added", G_OBJECT (item));
+    }
 }
 
 
diff --git a/src/photos-item-manager.h b/src/photos-item-manager.h
index 1ba0884..6a0c30c 100644
--- a/src/photos-item-manager.h
+++ b/src/photos-item-manager.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2012 – 2016 Red Hat, Inc.
+ * Copyright © 2012 – 2017 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
@@ -111,6 +111,10 @@ PhotosLoadState           photos_item_manager_get_load_state               (Phot
 void                      photos_item_manager_hide_item                    (PhotosItemManager *self,
                                                                             PhotosBaseItem *item);
 
+void                      photos_item_manager_set_constraints_for_mode     (PhotosItemManager *self,
+                                                                            gboolean constrain,
+                                                                            PhotosWindowMode mode);
+
 void                      photos_item_manager_wait_for_changes_async       (PhotosItemManager *self,
                                                                             PhotosBaseItem *item,
                                                                             GCancellable *cancellable,


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