[gnome-photos/wip/rishi/collection: 12/14] source-manager: ...



commit 0b6c72141467f8382b01ed34996bb3feb4751159
Author: Petr Štětka <stetka peta gmail com>
Date:   Wed Sep 6 09:29:08 2017 +0200

    source-manager: ...
    
    https://bugzilla.gnome.org/show_bug.cgi?id=751212

 src/photos-source-manager.c | 217 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 168 insertions(+), 49 deletions(-)
---
diff --git a/src/photos-source-manager.c b/src/photos-source-manager.c
index 59f427f9..7da6ceef 100644
--- a/src/photos-source-manager.c
+++ b/src/photos-source-manager.c
@@ -42,7 +42,9 @@ struct _PhotosSourceManager
   PhotosBaseManager parent_instance;
   GCancellable *cancellable;
   GHashTable *sources_notified;
+  GVolumeMonitor *volume_monitor;
   GoaClient *client;
+  guint refresh_mounts_timeout_id;
 };
 
 enum
@@ -58,6 +60,12 @@ static guint signals[LAST_SIGNAL] = { 0 };
 G_DEFINE_TYPE (PhotosSourceManager, photos_source_manager, PHOTOS_TYPE_BASE_MANAGER);
 
 
+enum
+{
+  REFRESH_MOUNTS_TIMEOUT = 2 /* s */
+};
+
+
 static gchar *
 photos_source_manager_get_filter (PhotosBaseManager *mngr, gint flags)
 {
@@ -109,71 +117,55 @@ photos_source_manager_remove_object_by_id (PhotosBaseManager *mngr, const gchar
 }
 
 
-static void
-photos_source_manager_refresh_accounts (PhotosSourceManager *self)
+static gboolean
+photos_source_manager_online_source_needs_notification (PhotosSource *source)
 {
-  GApplication *app;
-  g_autoptr (GHashTable) new_sources = NULL;
-  GList *accounts = NULL;
-  GList *l;
-  guint i;
-  guint n_items;
+  GoaAccount *account;
+  GoaObject *object;
+  gboolean attention_needed;
 
-  app = g_application_get_default ();
-  if (photos_application_get_empty_results (PHOTOS_APPLICATION (app)))
-    goto out;
-
-  accounts = goa_client_get_accounts (self->client);
-  new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-
-  for (l = accounts; l != NULL; l = l->next)
-    {
-      GoaAccount *account;
-      GoaObject *object = GOA_OBJECT (l->data);
-      g_autoptr (PhotosSource) source = NULL;
-      const gchar *id;
-
-      account = goa_object_peek_account (object);
-      if (account == NULL)
-        continue;
+  object = photos_source_get_goa_object (source);
+  g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
 
-      if (goa_account_get_photos_disabled (account))
-        continue;
+  account = goa_object_peek_account (object);
+  g_return_val_if_fail (GOA_IS_ACCOUNT (account), FALSE);
 
-      if (goa_object_peek_photos (object) == NULL)
-        continue;
+  attention_needed = goa_account_get_attention_needed (account);
+  return attention_needed;
+}
 
-      source = photos_source_new_from_goa_object (GOA_OBJECT (l->data));
-      id = photos_filterable_get_id (PHOTOS_FILTERABLE (source));
-      g_hash_table_insert (new_sources, g_strdup (id), g_object_ref (source));
-    }
 
-  photos_base_manager_process_new_objects (PHOTOS_BASE_MANAGER (self), new_sources);
+static void
+photos_source_manager_notify_sources (PhotosSourceManager *self)
+{
+  guint i;
+  guint n_items;
 
   n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
   for (i = 0; i < n_items; i++)
     {
-      GoaAccount *account;
+      GMount *mount;
       GoaObject *object;
       g_autoptr (PhotosSource) source = NULL;
-      gboolean attention_needed;
+      gboolean needs_notification;
       gboolean source_notified;
       const gchar *id;
 
       source = PHOTOS_SOURCE (g_list_model_get_object (G_LIST_MODEL (self), i));
+      mount = photos_source_get_mount (source);
       object = photos_source_get_goa_object (source);
-      if (object == NULL)
-        continue;
 
-      account = goa_object_peek_account (object);
-      if (account == NULL)
-        continue;
+      if (object != NULL)
+        needs_notification = photos_source_manager_online_source_needs_notification (source);
+      else if (mount != NULL)
+        needs_notification = TRUE;
+      else
+        needs_notification = FALSE;
 
-      attention_needed = goa_account_get_attention_needed (account);
       id = photos_filterable_get_id (PHOTOS_FILTERABLE (source));
       source_notified = g_hash_table_contains (self->sources_notified, id);
 
-      if (!attention_needed && source_notified)
+      if (!needs_notification && source_notified)
         {
           gboolean removed;
 
@@ -181,7 +173,7 @@ photos_source_manager_refresh_accounts (PhotosSourceManager *self)
           removed = g_hash_table_remove (self->sources_notified, id);
           g_assert_true (removed);
         }
-      else if (attention_needed && !source_notified)
+      else if (needs_notification && !source_notified)
         {
           gboolean inserted;
 
@@ -190,9 +182,114 @@ photos_source_manager_refresh_accounts (PhotosSourceManager *self)
           g_assert_true (inserted);
         }
     }
+}
+
+
+static void
+photos_source_manager_refresh_sources (PhotosSourceManager *self)
+{
+  GApplication *app;
+  g_autoptr (GHashTable) new_sources = NULL;
+  GList *l;
+  GList *mounts = NULL;
+
+  app = g_application_get_default ();
+  if (photos_application_get_empty_results (PHOTOS_APPLICATION (app)))
+    goto out;
+
+  new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+  mounts = g_volume_monitor_get_mounts (self->volume_monitor);
+
+  for (l = mounts; l != NULL; l = l->next)
+    {
+      g_autoptr (GFile) root = NULL;
+      GMount *mount = G_MOUNT (l->data);
+      g_autoptr (PhotosSource) source = NULL;
+      const gchar *id;
+      g_autofree gchar *root_scheme = NULL;
+
+      if (g_mount_is_shadowed (mount))
+        continue;
+
+      root = g_mount_get_root (mount);
+      root_scheme = g_file_get_uri_scheme (root);
+      if (g_strcmp0 (root_scheme, "file") != 0 && g_strcmp0 (root_scheme, "gphoto2") != 0)
+        continue;
+
+      source = photos_source_new_from_mount (mount);
+      id = photos_filterable_get_id (PHOTOS_FILTERABLE (source));
+      g_hash_table_insert (new_sources, g_strdup (id), g_object_ref (source));
+    }
+
+  if (self->client != NULL)
+    {
+      GList *accounts = NULL;
+
+      accounts = goa_client_get_accounts (self->client);
+
+      for (l = accounts; l != NULL; l = l->next)
+        {
+          GoaAccount *account;
+          GoaObject *object = GOA_OBJECT (l->data);
+          g_autoptr (PhotosSource) source = NULL;
+          const gchar *id;
+
+          account = goa_object_peek_account (object);
+          if (account == NULL)
+            continue;
+
+          if (goa_account_get_photos_disabled (account))
+            continue;
+
+          if (goa_object_peek_photos (object) == NULL)
+            continue;
+
+          source = photos_source_new_from_goa_object (GOA_OBJECT (l->data));
+          id = photos_filterable_get_id (PHOTOS_FILTERABLE (source));
+          g_hash_table_insert (new_sources, g_strdup (id), g_object_ref (source));
+        }
+
+      g_list_free_full (accounts, g_object_unref);
+    }
+
+  photos_base_manager_process_new_objects (PHOTOS_BASE_MANAGER (self), new_sources);
+  photos_source_manager_notify_sources (self);
 
  out:
-  g_list_free_full (accounts, g_object_unref);
+  return;
+}
+
+
+static gboolean
+photos_source_manager_refresh_mounts_timeout (gpointer user_data)
+{
+  PhotosSourceManager *self = PHOTOS_SOURCE_MANAGER (user_data);
+
+  self->refresh_mounts_timeout_id = 0;
+  photos_source_manager_refresh_sources (self);
+  return G_SOURCE_REMOVE;
+}
+
+
+static void
+photos_source_manager_remove_refresh_mounts_timeout (PhotosSourceManager *self)
+{
+  if (self->refresh_mounts_timeout_id != 0)
+    {
+      g_source_remove (self->refresh_mounts_timeout_id);
+      self->refresh_mounts_timeout_id = 0;
+    }
+}
+
+
+static void
+photos_source_manager_queue_refresh_mounts (PhotosSourceManager *self)
+{
+  photos_source_manager_remove_refresh_mounts_timeout (self);
+  self->refresh_mounts_timeout_id = g_timeout_add_seconds (REFRESH_MOUNTS_TIMEOUT,
+                                                           photos_source_manager_refresh_mounts_timeout,
+                                                           self);
 }
 
 
@@ -220,18 +317,18 @@ photos_source_manager_goa_client (GObject *source_object, GAsyncResult *res, gpo
   self->client = client;
   g_signal_connect_swapped (self->client,
                             "account-added",
-                            G_CALLBACK (photos_source_manager_refresh_accounts),
+                            G_CALLBACK (photos_source_manager_refresh_sources),
                             self);
   g_signal_connect_swapped (self->client,
                             "account-changed",
-                            G_CALLBACK (photos_source_manager_refresh_accounts),
+                            G_CALLBACK (photos_source_manager_refresh_sources),
                             self);
   g_signal_connect_swapped (self->client,
                             "account-removed",
-                            G_CALLBACK (photos_source_manager_refresh_accounts),
+                            G_CALLBACK (photos_source_manager_refresh_sources),
                             self);
 
-  photos_source_manager_refresh_accounts (self);
+  photos_source_manager_refresh_sources (self);
 }
 
 
@@ -240,11 +337,14 @@ photos_source_manager_dispose (GObject *object)
 {
   PhotosSourceManager *self = PHOTOS_SOURCE_MANAGER (object);
 
+  photos_source_manager_remove_refresh_mounts_timeout (self);
+
   if (self->cancellable != NULL)
     g_cancellable_cancel (self->cancellable);
 
   g_clear_object (&self->cancellable);
   g_clear_object (&self->client);
+  g_clear_object (&self->volume_monitor);
   g_clear_pointer (&self->sources_notified, (GDestroyNotify) g_hash_table_unref);
 
   G_OBJECT_CLASS (photos_source_manager_parent_class)->dispose (object);
@@ -265,8 +365,27 @@ photos_source_manager_init (PhotosSourceManager *self)
 
   self->cancellable = g_cancellable_new ();
   self->sources_notified = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+  self->volume_monitor = g_volume_monitor_get ();
+  g_signal_connect_object (self->volume_monitor,
+                           "mount-added",
+                           G_CALLBACK (photos_source_manager_queue_refresh_mounts),
+                           self,
+                           G_CONNECT_SWAPPED);
+  g_signal_connect_object (self->volume_monitor,
+                           "mount-changed",
+                           G_CALLBACK (photos_source_manager_queue_refresh_mounts),
+                           self,
+                           G_CONNECT_SWAPPED);
+  g_signal_connect_object (self->volume_monitor,
+                           "mount-removed",
+                           G_CALLBACK (photos_source_manager_queue_refresh_mounts),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   goa_client_new (self->cancellable, photos_source_manager_goa_client, self);
 
+  photos_source_manager_refresh_sources (self);
   photos_base_manager_set_active_object_by_id (PHOTOS_BASE_MANAGER (self), PHOTOS_SOURCE_STOCK_ALL);
 }
 


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