static void
photos_organize_collection_view_text_editing_canceled (PhotosOrganizeCollectionView *self)
{
  if (self->choice_confirmed)
    {
      GtkCellArea *cell_area;
      GtkCellEditable *entry;
      GtkTreePath *path;

      self->choice_confirmed = FALSE;

      g_object_get (self->view_col, "cell-area", &cell_area, NULL);
      entry = gtk_cell_area_get_edit_widget (cell_area);
      g_object_unref (cell_area);

      path = photos_organize_collection_model_get_placeholder (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model),
                                                               FALSE);

      if (entry != NULL && path != NULL)
        {
          const gchar *text;

          text = gtk_entry_get_text (GTK_ENTRY (entry));
          photos_organize_collection_view_text_edited_real (self,
                                                            GTK_CELL_RENDERER_TEXT (self->renderer_text),
                                                            path,
                                                            text);
        }

      gtk_tree_path_free (path);
    }
  else
    photos_organize_collection_model_remove_placeholder (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model));
}
static void
photos_organize_collection_view_create_collection_executed (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  PhotosOrganizeCollectionView *self;
  PhotosCreateCollectionJob *col_job = PHOTOS_CREATE_COLLECTION_JOB (source_object);
  PhotosSetCollectionJob *set_job = NULL;
  GApplication *app;
  GError *error;
  GList *urns;
  GtkTreeIter iter;
  GtkTreePath *path = NULL;
  PhotosSearchContextState *state;
  gchar *created_urn = NULL;

  error = NULL;
  created_urn = photos_create_collection_job_finish (col_job, res, &error);
  if (error != NULL)
    {
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_error_free (error);
          goto out;
        }
      else
        {
          g_warning ("Unable to create collection: %s", error->message);
          g_error_free (error);
        }
    }

  self = PHOTOS_ORGANIZE_COLLECTION_VIEW (user_data);

  if (created_urn == NULL)
    {
      photos_organize_collection_model_remove_placeholder (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model));
      goto out;
    }

  path = photos_organize_collection_model_get_placeholder (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model), TRUE);
  if (path == NULL)
    goto out;

  app = g_application_get_default ();
  state = photos_search_context_get_state (PHOTOS_SEARCH_CONTEXT (app));

  gtk_tree_model_get_iter (GTK_TREE_MODEL (self->model), &iter, path);
  gtk_list_store_set (self->model, &iter, PHOTOS_ORGANIZE_MODEL_ID, created_urn, -1);

  set_job = photos_set_collection_job_new (created_urn, TRUE);
  urns = photos_selection_controller_get_selection (self->sel_cntrlr);
  photos_set_collection_job_run (set_job, state, urns, NULL, NULL, NULL);

 out:
  g_clear_object (&set_job);
  g_free (created_urn);
  gtk_tree_path_free (path);
}
static void
photos_organize_collection_view_set_collection_executed (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  PhotosOrganizeCollectionView *self;
  GError *error;
  PhotosSetCollectionJob *job = PHOTOS_SET_COLLECTION_JOB (source_object);

  error = NULL;
  if (!photos_set_collection_job_finish (job, res, &error))
    {
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_error_free (error);
          goto out;
        }
      else
        {
          g_warning ("Unable to set collection: %s", error->message);
          g_error_free (error);
        }
    }

  self = PHOTOS_ORGANIZE_COLLECTION_VIEW (user_data);

  photos_organize_collection_model_refresh_collection_state (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model));

 out:
  return;
}
static void
photos_organize_collection_view_text_edited_real (PhotosOrganizeCollectionView *self,
                                                  GtkCellRendererText *cell_renderer,
                                                  GtkTreePath *path,
                                                  const gchar *new_text)
{
  GtkTreeIter iter;
  PhotosCreateCollectionJob *job;

  g_object_set (cell_renderer, "editable", FALSE, NULL);

  if (new_text == NULL || new_text[0] == '\0')
    {
      /* Don't insert collections with empty names. */
      photos_organize_collection_model_remove_placeholder (PHOTOS_ORGANIZE_COLLECTION_MODEL (self->model));
      return;
    }

  gtk_tree_model_get_iter (GTK_TREE_MODEL (self->model), &iter, path);
  gtk_list_store_set (self->model, &iter, PHOTOS_ORGANIZE_MODEL_NAME, new_text, -1);

  job = photos_create_collection_job_new (new_text, NULL);
  photos_create_collection_job_run (job,
                                    self->cancellable,
                                    photos_organize_collection_view_create_collection_executed,
                                    self);
  g_object_unref (job);
}
static void
photos_organize_collection_model_dispose (GObject *object)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (object);

  g_clear_object (&self->manager);

  G_OBJECT_CLASS (photos_organize_collection_model_parent_class)->dispose (object);
}
static void
photos_organize_collection_model_finalize (GObject *object)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (object);

  gtk_tree_path_free (self->coll_path);
  gtk_tree_row_reference_free (self->placeholder_ref);

  G_OBJECT_CLASS (photos_organize_collection_model_parent_class)->finalize (object);
}
static void
photos_organize_collection_model_object_removed (PhotosBaseManager *manager, GObject *object, gpointer user_data)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (user_data);
  GtkTreeIter *iter;

  iter = photos_organize_collection_model_find_collection_iter (self, PHOTOS_BASE_ITEM (object));
  if (iter == NULL)
    return;

  gtk_list_store_remove (GTK_LIST_STORE (self), iter);
  gtk_tree_iter_free (iter);
}
static void
photos_organize_collection_model_fetch_collection_state_executed (GHashTable *collection_state, gpointer user_data)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (user_data);
  GHashTableIter collection_state_iter;
  const gchar *idx;
  gpointer value;

  photos_organize_collection_model_remove_placeholder (self);

  g_hash_table_iter_init (&collection_state_iter, collection_state);
  while (g_hash_table_iter_next (&collection_state_iter, (gpointer) &idx, (gpointer) &value))
    {
      GtkTreeIter *iter;
      PhotosBaseItem *collection;
      gint state = GPOINTER_TO_INT (value);

      if (state & PHOTOS_COLLECTION_STATE_HIDDEN)
        continue;

      collection = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (self->priv->manager, idx));
      iter = photos_organize_collection_model_find_collection_iter (self, collection);
      if (iter == NULL)
        {
          GtkTreeIter tmp;

          gtk_list_store_append (GTK_LIST_STORE (self), &tmp);
          iter = gtk_tree_iter_copy (&tmp);
        }

      gtk_list_store_set (GTK_LIST_STORE (self),
                          iter,
                          PHOTOS_ORGANIZE_MODEL_ID, idx,
                          PHOTOS_ORGANIZE_MODEL_NAME, photos_base_item_get_name (collection),
                          PHOTOS_ORGANIZE_MODEL_STATE, state,
                          -1);
      gtk_tree_iter_free (iter);
    }

  g_object_unref (self);
}
static gboolean
photos_organize_collection_model_foreach (GtkTreeModel *model,
                                          GtkTreePath *path,
                                          GtkTreeIter *iter,
                                          gpointer user_data)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (model);
  PhotosBaseItem *collection = PHOTOS_BASE_ITEM (user_data);
  gboolean ret_val = FALSE;
  gchar *id;

  gtk_tree_model_get (GTK_TREE_MODEL (self), iter, PHOTOS_ORGANIZE_MODEL_ID, &id, -1);
  if (g_strcmp0 (photos_filterable_get_id (PHOTOS_FILTERABLE (collection)), id) == 0)
    {
      self->priv->coll_path = gtk_tree_path_copy (path);
      ret_val = TRUE;
      goto out;
    }

 out:
  g_free (id);
  return ret_val;
}
static void
photos_organize_collection_model_object_added (PhotosBaseManager *manager, GObject *object, gpointer user_data)
{
  PhotosOrganizeCollectionModel *self = PHOTOS_ORGANIZE_COLLECTION_MODEL (user_data);
  photos_organize_collection_model_refresh_state (self);
}