[gnome-photos] Notify when indexing remote items takes a long time



commit d7712db3961386152af0c157027ed3ee807553e6
Author: Debarshi Ray <debarshir gnome org>
Date:   Sun Mar 16 02:26:39 2014 +0100

    Notify when indexing remote items takes a long time
    
    When indexing remote items takes more than 10 seconds show an in-app
    notification to signal the user we are refreshing our local index.
    
    Original patch from Cosimo Cecchi for gnome-documents.

 src/photos-application.c           |   27 ++++++-
 src/photos-application.h           |    7 ++-
 src/photos-indexing-notification.c |  161 +++++++++++++++++++++++++++++++-----
 3 files changed, 172 insertions(+), 23 deletions(-)
---
diff --git a/src/photos-application.c b/src/photos-application.c
index 4a05a49..1a90d34 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -78,6 +78,14 @@ struct _PhotosApplicationPrivate
   guint32 activation_timestamp;
 };
 
+enum
+{
+  MINERS_CHANGED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 static void photos_application_search_context_iface_init (PhotosSearchContextInterface *iface);
 
 
@@ -378,6 +386,7 @@ photos_application_refresh_db (GObject *source_object, GAsyncResult *res, gpoint
   PhotosApplicationRefreshData *data;
 
   priv->miners_running = g_list_remove (priv->miners_running, miner);
+  g_signal_emit (self, signals[MINERS_CHANGED], 0, priv->miners_running);
 
   error = NULL;
   if (!gom_miner_call_refresh_db_finish (miner, res, &error))
@@ -411,6 +420,7 @@ photos_application_refresh_miner_now (PhotosApplication *self, GomMiner *miner)
     goto out;
 
   priv->miners_running = g_list_prepend (priv->miners_running, g_object_ref (miner));
+  g_signal_emit (self, signals[MINERS_CHANGED], 0, priv->miners_running);
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (miner), "cancellable", cancellable, g_object_unref);
@@ -849,7 +859,15 @@ photos_application_class_init (PhotosApplicationClass *class)
   application_class->dbus_unregister = photos_application_dbus_unregister;
   application_class->startup = photos_application_startup;
 
-  /* TODO: Add miners-changed signal */
+  signals[MINERS_CHANGED] = g_signal_new ("miners-changed",
+                                          G_TYPE_FROM_CLASS (class),
+                                          G_SIGNAL_RUN_LAST,
+                                          G_STRUCT_OFFSET (PhotosApplicationClass, miners_changed),
+                                          NULL, /* accumulator */
+                                          NULL, /* accu_data */
+                                          g_cclosure_marshal_VOID__POINTER,
+                                          G_TYPE_NONE,
+                                          0);
 }
 
 
@@ -868,3 +886,10 @@ photos_application_new (void)
                        "flags", G_APPLICATION_IS_SERVICE,
                        NULL);
 }
+
+
+GList *
+photos_application_get_miners_running (PhotosApplication *self)
+{
+  return self->priv->miners_running;
+}
diff --git a/src/photos-application.h b/src/photos-application.h
index 6b0c30e..f75f94e 100644
--- a/src/photos-application.h
+++ b/src/photos-application.h
@@ -1,6 +1,6 @@
 /*
  * Photos - access, organize and share your photos on GNOME
- * Copyright © 2012 Red Hat, Inc.
+ * Copyright © 2012, 2014 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
@@ -64,12 +64,17 @@ struct _PhotosApplication
 struct _PhotosApplicationClass
 {
   GtkApplicationClass parent_class;
+
+  /* signals */
+  void (*miners_changed) (PhotosApplication *self, GList *miners_running);
 };
 
 GType                  photos_application_get_type               (void) G_GNUC_CONST;
 
 GtkApplication        *photos_application_new                    (void);
 
+GList                 *photos_application_get_miners_running     (PhotosApplication *self);
+
 G_END_DECLS
 
 #endif /* PHOTOS_APPLICATION_H */
diff --git a/src/photos-indexing-notification.c b/src/photos-indexing-notification.c
index edb7c06..989625d 100644
--- a/src/photos-indexing-notification.c
+++ b/src/photos-indexing-notification.c
@@ -25,10 +25,13 @@
 
 #include "config.h"
 
+#include <gio/gio.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <libtracker-control/tracker-control.h>
 
+#include "photos-application.h"
+#include "photos-gom-miner.h"
 #include "photos-icons.h"
 #include "photos-indexing-notification.h"
 #include "photos-notification-manager.h"
@@ -37,57 +40,145 @@
 struct _PhotosIndexingNotificationPrivate
 {
   GtkWidget *ntfctn_mngr;
+  GtkWidget *primary_label;
+  GtkWidget *secondary_label;
   GtkWidget *spinner;
   TrackerMinerManager *manager;
-  gboolean manually_closed;
+  gboolean closed;
   gboolean on_display;
+  guint timeout_id;
 };
 
 
 G_DEFINE_TYPE_WITH_PRIVATE (PhotosIndexingNotification, photos_indexing_notification, GTK_TYPE_GRID);
 
 
+enum
+{
+  REMOTE_MINER_TIMEOUT = 10 /* s */
+};
+
 static const gchar *MINER_FILES = "org.freedesktop.Tracker1.Miner.Files";
 
 
 static void
-photos_indexing_notification_destroy_notification (PhotosIndexingNotification *self)
+photos_indexing_notification_remove_timeout (PhotosIndexingNotification *self)
+{
+  PhotosIndexingNotificationPrivate *priv = self->priv;
+
+  if (priv->timeout_id != 0)
+    {
+      g_source_remove (priv->timeout_id);
+      priv->timeout_id = 0;
+    }
+}
+
+
+static void
+photos_indexing_notification_destroy (PhotosIndexingNotification *self, gboolean closed)
 {
   PhotosIndexingNotificationPrivate *priv = self->priv;
   GtkWidget *parent;
 
+  photos_indexing_notification_remove_timeout (self);
+
   priv->on_display = FALSE;
   gtk_spinner_stop (GTK_SPINNER (priv->spinner));
 
   parent = gtk_widget_get_parent (GTK_WIDGET (self));
   if (parent != NULL)
     gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (self));
+
+  priv->closed = closed;
 }
 
 
 static void
 photos_indexing_notification_clicked (PhotosIndexingNotification *self)
 {
-  self->priv->manually_closed = TRUE;
-  photos_indexing_notification_destroy_notification (self);
+  photos_indexing_notification_destroy (self, TRUE);
 }
 
 
 static void
-photos_indexing_notification_display_notification (PhotosIndexingNotification *self)
+photos_indexing_notification_update (PhotosIndexingNotification *self,
+                                     const gchar *primary_text,
+                                     const gchar *secondary_text)
+{
+  PhotosIndexingNotificationPrivate *priv = self->priv;
+
+  gtk_label_set_label (GTK_LABEL (priv->primary_label), primary_text);
+  gtk_label_set_label (GTK_LABEL (priv->secondary_label), secondary_text);
+
+  if (secondary_text != NULL)
+    {
+      gtk_widget_set_vexpand (priv->primary_label, FALSE);
+      gtk_widget_show (priv->secondary_label);
+    }
+  else
+    {
+      gtk_widget_set_vexpand (priv->primary_label, TRUE);
+      gtk_widget_hide (priv->secondary_label);
+    }
+}
+
+
+static void
+photos_indexing_notification_display (PhotosIndexingNotification *self,
+                                      const gchar *primary_text,
+                                      const gchar *secondary_text)
 {
   PhotosIndexingNotificationPrivate *priv = self->priv;
 
   if (priv->on_display)
     return;
 
-  if (priv->manually_closed)
+  if (priv->closed)
     return;
 
   photos_notification_manager_add_notification (PHOTOS_NOTIFICATION_MANAGER (priv->ntfctn_mngr),
                                                 GTK_WIDGET (self));
   gtk_spinner_start (GTK_SPINNER (priv->spinner));
   priv->on_display = TRUE;
+
+  photos_indexing_notification_update (self, primary_text, secondary_text);
+}
+
+
+static gboolean
+photos_indexing_notification_timeout (gpointer user_data)
+{
+  PhotosIndexingNotification *self = PHOTOS_INDEXING_NOTIFICATION (user_data);
+  GApplication *app;
+  GList *miners_running;
+  GomMiner *miner = NULL;
+  const gchar *display_name = NULL;
+  gchar *primary = NULL;
+
+  self->priv->timeout_id = 0;
+
+  app = g_application_get_default ();
+  miners_running = photos_application_get_miners_running (PHOTOS_APPLICATION (app));
+  if (miners_running != NULL && miners_running->next == NULL) /* length == 1 */
+    miner = GOM_MINER (miners_running->data);
+
+  if (miner != NULL)
+    display_name = gom_miner_get_display_name (miner);
+
+  if (display_name != NULL)
+    {
+      /* Translators: %s refers to an online account provider, e.g.,
+       * "Facebook" or "Flickr.
+       */
+      primary = g_strdup_printf (_("Fetching photos from %s"), display_name);
+    }
+  else
+    primary = g_strdup (_("Fetching photos from online accounts"));
+
+  photos_indexing_notification_display (self, primary, NULL);
+  g_free (primary);
+
+  return G_SOURCE_REMOVE;
 }
 
 
@@ -95,7 +186,11 @@ static void
 photos_indexing_notification_check_notification (PhotosIndexingNotification *self)
 {
   PhotosIndexingNotificationPrivate *priv = self->priv;
+  GApplication *app;
+  GList *miners_running;
   GSList *running;
+  gboolean is_indexing_local = FALSE;
+  gboolean is_indexing_remote = FALSE;
 
   running = tracker_miner_manager_get_running (priv->manager);
   if (g_slist_find_custom (running, (gconstpointer) MINER_FILES, (GCompareFunc) g_strcmp0) != NULL)
@@ -104,13 +199,31 @@ photos_indexing_notification_check_notification (PhotosIndexingNotification *sel
 
       tracker_miner_manager_get_status (priv->manager, MINER_FILES, NULL, &progress, NULL);
       if (progress < 1)
-        photos_indexing_notification_display_notification (self);
-      else
-        {
-          priv->manually_closed = FALSE;
-          photos_indexing_notification_destroy_notification (self);
-        }
+        is_indexing_local = TRUE;
+    }
+
+  app = g_application_get_default ();
+  miners_running = photos_application_get_miners_running (PHOTOS_APPLICATION (app));
+  if (miners_running != NULL) /* length > 0 */
+    is_indexing_remote = TRUE;
+
+  if (is_indexing_local)
+    {
+      photos_indexing_notification_display (self,
+                                            _("Your photos are being indexed"),
+                                            _("Some photos might not be available during this process"));
     }
+  else if (is_indexing_remote)
+    {
+      photos_indexing_notification_remove_timeout (self);
+      priv->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+                                                     REMOTE_MINER_TIMEOUT,
+                                                     photos_indexing_notification_timeout,
+                                                     g_object_ref (self),
+                                                     g_object_unref);
+    }
+  else
+    photos_indexing_notification_destroy (self, FALSE);
 
   if (running != NULL)
     g_slist_free_full (running, g_free);
@@ -134,17 +247,18 @@ static void
 photos_indexing_notification_init (PhotosIndexingNotification *self)
 {
   PhotosIndexingNotificationPrivate *priv;
+  GApplication *app;
   GError *error;
   GtkStyleContext *context;
   GtkWidget *close;
   GtkWidget *image;
   GtkWidget *labels;
-  GtkWidget *primary;
-  GtkWidget *secondary;
 
   self->priv = photos_indexing_notification_get_instance_private (self);
   priv = self->priv;
 
+  app = g_application_get_default ();
+
   error = NULL;
   priv->manager = tracker_miner_manager_new_full (FALSE, &error);
   if (error != NULL)
@@ -166,15 +280,15 @@ photos_indexing_notification_init (PhotosIndexingNotification *self)
   gtk_grid_set_row_spacing (GTK_GRID (labels), 3);
   gtk_container_add (GTK_CONTAINER (self), labels);
 
-  primary = gtk_label_new (_("Your photos are being indexed"));
-  gtk_widget_set_halign (primary, GTK_ALIGN_START);
-  gtk_container_add (GTK_CONTAINER (labels), primary);
+  priv->primary_label = gtk_label_new (NULL);
+  gtk_widget_set_halign (priv->primary_label, GTK_ALIGN_START);
+  gtk_container_add (GTK_CONTAINER (labels), priv->primary_label);
 
-  secondary = gtk_label_new (_("Some photos might not be available during this process"));
-  gtk_widget_set_halign (secondary, GTK_ALIGN_START);
-  context = gtk_widget_get_style_context (secondary);
+  priv->secondary_label = gtk_label_new (NULL);
+  gtk_widget_set_halign (priv->secondary_label, GTK_ALIGN_START);
+  context = gtk_widget_get_style_context (priv->secondary_label);
   gtk_style_context_add_class (context, "dim-label");
-  gtk_container_add (GTK_CONTAINER (labels), secondary);
+  gtk_container_add (GTK_CONTAINER (labels), priv->secondary_label);
 
   image = gtk_image_new_from_icon_name (PHOTOS_ICON_WINDOW_CLOSE_SYMBOLIC, GTK_ICON_SIZE_INVALID);
   gtk_widget_set_margin_bottom (image, 2);
@@ -188,6 +302,11 @@ photos_indexing_notification_init (PhotosIndexingNotification *self)
 
   g_signal_connect_swapped (close, "clicked", G_CALLBACK (photos_indexing_notification_clicked), self);
 
+  g_signal_connect_swapped (app,
+                            "miners-changed",
+                            G_CALLBACK (photos_indexing_notification_check_notification),
+                            self);
+
   g_signal_connect_swapped (priv->manager,
                             "miner-progress",
                             G_CALLBACK (photos_indexing_notification_check_notification),


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