[gnome-photos] Support exporting from selection mode



commit d0c232881c5b4e7d82ceb58b3ef15a60f599cbbf
Author: Rafael Fonseca <r4f4rfs gmail com>
Date:   Wed Jan 27 15:06:39 2016 +0100

    Support exporting from selection mode
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760838

 src/photos-application.c        |   64 ++++++++++++++++++++++++++++++---
 src/photos-export-dialog.c      |   76 +++++++++++++++++++++++++++++----------
 src/photos-selection-toolbar.ui |   10 +++++
 3 files changed, 126 insertions(+), 24 deletions(-)
---
diff --git a/src/photos-application.c b/src/photos-application.c
index 0df2e0c..67aa6ae 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -52,6 +52,7 @@
 #include "photos-search-match.h"
 #include "photos-search-type.h"
 #include "photos-search-provider.h"
+#include "photos-selection-controller.h"
 #include "photos-single-item-job.h"
 #include "photos-source.h"
 #include "photos-source-manager.h"
@@ -98,6 +99,7 @@ struct _PhotosApplicationPrivate
   PhotosCameraCache *camera_cache;
   PhotosSearchContextState *state;
   PhotosSearchProvider *search_provider;
+  PhotosSelectionController *sel_cntrlr;
   TrackerExtractPriority *extract_priority;
   guint create_miners_count;
   guint32 activation_timestamp;
@@ -259,6 +261,34 @@ photos_application_action_toggle (GSimpleAction *simple, GVariant *parameter, gp
 }
 
 
+static PhotosBaseItem *
+photos_application_get_selection_or_active_item (PhotosApplication *self)
+{
+  PhotosApplicationPrivate *priv = self->priv;
+  PhotosBaseItem *item = NULL;
+
+  if (photos_selection_controller_get_selection_mode (priv->sel_cntrlr))
+    {
+      GList *selection;
+      const gchar *urn;
+
+      selection = photos_selection_controller_get_selection (priv->sel_cntrlr);
+      if (selection == NULL || selection->next != NULL) /* length != NULL */
+        goto out;
+
+      urn = (gchar *) selection->data;
+      item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (priv->state->item_mngr, urn));
+    }
+  else
+    {
+      item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (priv->state->item_mngr));
+    }
+
+ out:
+  return item;
+}
+
+
 static void
 photos_application_actions_update (PhotosApplication *self)
 {
@@ -268,7 +298,7 @@ photos_application_actions_update (PhotosApplication *self)
   PhotosWindowMode mode;
   gboolean enable;
 
-  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (priv->state->item_mngr));
+  item = photos_application_get_selection_or_active_item (self);
   load_state = photos_item_manager_get_load_state (priv->state->item_mngr);
   mode = photos_mode_controller_get_window_mode (priv->state->mode_cntrlr);
 
@@ -306,10 +336,15 @@ photos_application_actions_update (PhotosApplication *self)
   g_simple_action_set_enabled (priv->open_action, enable);
   g_simple_action_set_enabled (priv->print_action, enable);
   g_simple_action_set_enabled (priv->properties_action, enable);
-  g_simple_action_set_enabled (priv->save_action, enable);
   g_simple_action_set_enabled (priv->set_bg_action, enable);
   g_simple_action_set_enabled (priv->set_ss_action, enable);
 
+  enable = ((load_state == PHOTOS_LOAD_STATE_FINISHED && mode == PHOTOS_WINDOW_MODE_PREVIEW)
+            || (photos_selection_controller_get_selection_mode (priv->sel_cntrlr)
+                && item != NULL
+                && !photos_base_item_is_collection (item)));
+  g_simple_action_set_enabled (priv->save_action, enable);
+
   enable = (load_state == PHOTOS_LOAD_STATE_FINISHED
             && mode == PHOTOS_WINDOW_MODE_PREVIEW
             && photos_base_item_can_edit (item));
@@ -948,6 +983,7 @@ photos_application_save_save (GObject *source_object, GAsyncResult *res, gpointe
     }
 
  out:
+  photos_selection_controller_set_selection_mode (self->priv->sel_cntrlr, FALSE);
   g_application_release (G_APPLICATION (self));
 }
 
@@ -956,7 +992,6 @@ static void
 photos_application_save_response (GtkDialog *dialog, gint response_id, gpointer user_data)
 {
   PhotosApplication *self = PHOTOS_APPLICATION (user_data);
-  PhotosApplicationPrivate *priv = self->priv;
   GError *error;
   GFile *export = NULL;
   GFile *tmp;
@@ -969,7 +1004,7 @@ photos_application_save_response (GtkDialog *dialog, gint response_id, gpointer
   if (response_id != GTK_RESPONSE_OK)
     goto out;
 
-  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (priv->state->item_mngr));
+  item = photos_application_get_selection_or_active_item (self);
   g_return_if_fail (item != NULL);
 
   pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
@@ -1025,7 +1060,7 @@ photos_application_save (PhotosApplication *self)
   GtkWidget *dialog;
   PhotosBaseItem *item;
 
-  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (priv->state->item_mngr));
+  item = photos_application_get_selection_or_active_item (self);
   g_return_if_fail (item != NULL);
   g_return_if_fail (!photos_base_item_is_collection (item));
 
@@ -1186,6 +1221,13 @@ photos_application_window_mode_changed (PhotosApplication *self)
 
 
 static void
+photos_application_selection_changed (PhotosApplication *self)
+{
+  photos_application_actions_update (self);
+}
+
+
+static void
 photos_application_activate (GApplication *application)
 {
   PhotosApplication *self = PHOTOS_APPLICATION (application);
@@ -1341,6 +1383,17 @@ photos_application_startup (GApplication *application)
    */
   priv->camera_cache = photos_camera_cache_dup_singleton ();
 
+  priv->sel_cntrlr = photos_selection_controller_dup_singleton ();
+  g_signal_connect_swapped (priv->sel_cntrlr,
+                            "selection-changed",
+                            G_CALLBACK (photos_application_selection_changed),
+                            self);
+
+  g_signal_connect_swapped (priv->sel_cntrlr,
+                            "selection-mode-changed",
+                            G_CALLBACK (photos_application_selection_changed),
+                            self);
+
   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));
@@ -1587,6 +1640,7 @@ photos_application_dispose (GObject *object)
   g_clear_object (&priv->sharpen_action);
   g_clear_object (&priv->undo_action);
   g_clear_object (&priv->camera_cache);
+  g_clear_object (&priv->sel_cntrlr);
   g_clear_object (&priv->extract_priority);
 
   if (priv->state != NULL)
diff --git a/src/photos-export-dialog.c b/src/photos-export-dialog.c
index 028ea34..d6d70fa 100644
--- a/src/photos-export-dialog.c
+++ b/src/photos-export-dialog.c
@@ -173,25 +173,40 @@ photos_export_dialog_guess_sizes (GObject *source_object, GAsyncResult *res, gpo
 
 
 static void
-photos_export_dialog_constructed (GObject *object)
+photos_export_dialog_load (GObject *source_object, GAsyncResult *result, gpointer user_data)
 {
-  PhotosExportDialog *self = PHOTOS_EXPORT_DIALOG (object);
-
-  G_OBJECT_CLASS (photos_export_dialog_parent_class)->constructed (object);
+  PhotosExportDialog *self;
+  PhotosBaseItem *item = PHOTOS_BASE_ITEM (source_object);
+  GDateTime *now = NULL;
+  GError *error;
+  GeglNode *node = NULL;
+  gboolean success = TRUE;
+  gchar *now_str = NULL;
 
-  if (photos_base_item_is_collection (self->item))
+  error = NULL;
+  node = photos_base_item_load_finish (item, result, &error);
+  if (error != NULL)
     {
-      const gchar *name;
+      success = FALSE;
 
-      name = photos_base_item_get_name_with_fallback (self->item);
-      gtk_entry_set_text (GTK_ENTRY (self->dir_entry), name);
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        {
+          g_error_free (error);
+          goto out;
+        }
+      else
+        {
+          g_warning ("Unable to load the item: %s", error->message);
+          g_error_free (error);
+        }
     }
-  else
+
+  self = PHOTOS_EXPORT_DIALOG (user_data);
+
+  if (success)
     {
-      GDateTime *now;
       GeglRectangle bbox;
       gboolean got_bbox_edited;
-      gchar *now_str;
       gint max_dimension;
       guint i;
 
@@ -212,18 +227,41 @@ photos_export_dialog_constructed (GObject *object)
               break;
             }
         }
+    }
+
+  now = g_date_time_new_now_local ();
+
+  /* Translators: this is the default sub-directory where photos
+   *  will be exported.
+   */
+  now_str = g_date_time_format (now, _("%e %B %Y"));
+
+  gtk_entry_set_text (GTK_ENTRY (self->dir_entry), now_str);
 
-      now = g_date_time_new_now_local ();
+ out:
+  g_free (now_str);
+  g_clear_object (&node);
+  g_clear_pointer (&now, (GDestroyNotify) g_date_time_unref);
+}
 
-      /* Translators: this is the default sub-directory where photos
-       *  will be exported.
-       */
-      now_str = g_date_time_format (now, _("%e %B %Y"));
 
-      gtk_entry_set_text (GTK_ENTRY (self->dir_entry), now_str);
+static void
+photos_export_dialog_constructed (GObject *object)
+{
+  PhotosExportDialog *self = PHOTOS_EXPORT_DIALOG (object);
 
-      g_free (now_str);
-      g_date_time_unref (now);
+  G_OBJECT_CLASS (photos_export_dialog_parent_class)->constructed (object);
+
+  if (photos_base_item_is_collection (self->item))
+    {
+      const gchar *name;
+
+      name = photos_base_item_get_name_with_fallback (self->item);
+      gtk_entry_set_text (GTK_ENTRY (self->dir_entry), name);
+    }
+  else
+    {
+      photos_base_item_load_async (self->item, self->cancellable, photos_export_dialog_load, self);
     }
 }
 
diff --git a/src/photos-selection-toolbar.ui b/src/photos-selection-toolbar.ui
index cce3769..6428fd8 100644
--- a/src/photos-selection-toolbar.ui
+++ b/src/photos-selection-toolbar.ui
@@ -14,6 +14,16 @@
         </packing>
       </child>
       <child>
+        <object class="GtkButton">
+          <property name="visible">1</property>
+          <property name="action_name">app.save-current</property>
+          <property name="label" translatable="yes">Export</property>
+        </object>
+        <packing>
+          <property name="pack_type">start</property>
+        </packing>
+      </child>
+      <child>
         <object class="GtkButton" id="toolbar_open">
           <property name="visible">1</property>
           <property name="label" translatable="yes">Open</property>


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