static gboolean
photos_main_window_go_back (PhotosMainWindow *self)
{
  PhotosMainWindowPrivate *priv = self->priv;
  PhotosBaseItem *active_collection;
  PhotosWindowMode mode;
  gboolean handled = TRUE;

  mode = photos_mode_controller_get_window_mode (priv->mode_cntrlr);
  active_collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (priv->item_mngr));

  switch (mode)
    {
    case PHOTOS_WINDOW_MODE_PREVIEW:
      photos_base_manager_set_active_object (priv->item_mngr, NULL);
      photos_mode_controller_go_back (priv->mode_cntrlr);
      break;

    case PHOTOS_WINDOW_MODE_COLLECTIONS:
    case PHOTOS_WINDOW_MODE_FAVORITES:
    case PHOTOS_WINDOW_MODE_SEARCH:
      if (active_collection != NULL)
        photos_item_manager_activate_previous_collection (PHOTOS_ITEM_MANAGER (self->priv->item_mngr));
      break;

    case PHOTOS_WINDOW_MODE_NONE:
    case PHOTOS_WINDOW_MODE_OVERVIEW:
    default:
      handled = FALSE;
      break;
    }

  return handled;
}
static void
photos_item_manager_changes_pending_foreach (gpointer key, gpointer value, gpointer user_data)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (user_data);
  PhotosTrackerChangeEvent *change_event = (PhotosTrackerChangeEvent *) value;
  PhotosTrackerChangeEventType change_type;
  const gchar *change_urn;

  change_type = photos_tracker_change_event_get_type (change_event);
  change_urn = photos_tracker_change_event_get_urn (change_event);

  if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_CHANGED)
    {
      GObject *object;

      object = photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn);
      if (object != NULL)
        photos_base_item_refresh (PHOTOS_BASE_ITEM (object));
    }
  else if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_CREATED)
    {
      photos_item_manager_item_created (self, change_urn);
    }
  else if (change_type == PHOTOS_TRACKER_CHANGE_EVENT_DELETED)
    {
      GObject *object;

      object = photos_base_manager_get_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn);
      if (object != NULL)
        {
          photos_base_item_destroy (PHOTOS_BASE_ITEM (object));
          photos_base_manager_remove_object_by_id (PHOTOS_BASE_MANAGER (self), change_urn);
        }
    }
}
static void
photos_item_manager_add_object (PhotosBaseManager *mngr, GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (mngr);
  PhotosBaseItem *item;
  const gchar *id;
  gpointer *old_collection;

  g_return_if_fail (PHOTOS_IS_BASE_ITEM (object));

  item = PHOTOS_BASE_ITEM (object);

  if (!photos_base_item_is_collection (item))
    goto end;

  id = photos_filterable_get_id (PHOTOS_FILTERABLE (item));
  if (id == NULL)
    goto end;

  old_collection = g_hash_table_lookup (self->collections, id);
  if (old_collection != NULL)
    goto end;

  g_hash_table_insert (self->collections, g_strdup (id), g_object_ref (item));

 end:
  PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->add_object (mngr, object);
}
static void
photos_tracker_controller_cursor_next (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  PhotosTrackerController *self = PHOTOS_TRACKER_CONTROLLER (user_data);
  PhotosTrackerControllerPrivate *priv = self->priv;
  TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source_object);
  gboolean valid;
  gint64 now;

  valid = tracker_sparql_cursor_next_finish (cursor, res, NULL); /* TODO: use GError */
  if (!valid)
    {
      tracker_sparql_cursor_close (cursor);
      photos_tracker_controller_query_finished (self, NULL);
      g_object_unref (self);
      return;
    }

  now = g_get_monotonic_time ();
  photos_debug (PHOTOS_DEBUG_TRACKER, "Query Cursor: %" G_GINT64_FORMAT, (now - priv->last_query_time) / 1000000);

  photos_item_manager_add_item (PHOTOS_ITEM_MANAGER (priv->item_mngr), cursor);
  tracker_sparql_cursor_next_async (cursor,
                                    priv->cancellable,
                                    photos_tracker_controller_cursor_next,
                                    self);
}
static void
photos_item_manager_item_load (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (user_data);
  GError *error;
  GeglNode *node = NULL;
  PhotosBaseItem *item = PHOTOS_BASE_ITEM (source_object);

  g_clear_object (&self->loader_cancellable);

  error = NULL;
  node = photos_base_item_load_finish (item, res, &error);
  if (error != NULL)
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Unable to load the item: %s", error->message);

      self->load_state = PHOTOS_LOAD_STATE_ERROR;
      g_error_free (error);
    }
  else
    {
      self->load_state = PHOTOS_LOAD_STATE_FINISHED;
    }

  g_signal_emit (self, signals[LOAD_FINISHED], 0, item, node);

  g_clear_object (&node);
  g_object_unref (self);
}
Example #6
0
static void
photos_preview_nav_buttons_delete (PhotosPreviewNavButtons *self)
{
  GList *items = NULL;
  PhotosBaseItem *item;
  PhotosWindowMode mode;

  mode = photos_mode_controller_get_window_mode (self->mode_cntrlr);
  if (mode != PHOTOS_WINDOW_MODE_PREVIEW)
    return;

  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (self->item_mngr));
  if (item == NULL)
    return;

  if (self->enable_next)
    g_action_activate (self->load_next, NULL);
  else if (self->enable_prev)
    g_action_activate (self->load_previous, NULL);
  else
    photos_mode_controller_go_back (self->mode_cntrlr);

  items = g_list_prepend (items, g_object_ref (item));
  photos_item_manager_hide_item (PHOTOS_ITEM_MANAGER (self->item_mngr), item);
  photos_delete_notification_new (items);
  g_list_free_full (items, g_object_unref);
}
static void
photos_import_dialog_fetch_collections_local_cursor_next (GObject *source_object,
                                                          GAsyncResult *res,
                                                          gpointer user_data)
{
  PhotosImportDialog *self;
  g_autoptr (PhotosBaseItem) collection = NULL;
  TrackerSparqlCursor *cursor = TRACKER_SPARQL_CURSOR (source_object);
  gboolean success;
  const gchar *identifier;
  g_autofree gchar *identifier_time = NULL;

  {
    g_autoptr (GError) error = NULL;

    /* Note that tracker_sparql_cursor_next_finish can return FALSE even
     * without an error.
     */
    success = tracker_sparql_cursor_next_finish (cursor, res, &error);
    if (error != NULL)
      {
        if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
          g_warning ("Unable to fetch local collections: %s", error->message);

        goto out;
      }
  }

  self = PHOTOS_IMPORT_DIALOG (user_data);

  if (!success)
    {
      photos_import_dialog_initialize_index_and_popover (self);
      goto out;
    }

  collection = photos_item_manager_create_item (PHOTOS_ITEM_MANAGER (self->item_mngr), G_TYPE_NONE, cursor, FALSE);
  photos_import_dialog_add_collection (self, collection);

  identifier = photos_base_item_get_identifier (collection);
  identifier_time = g_strdup_printf ("%s%" G_GINT64_FORMAT, PHOTOS_QUERY_LOCAL_COLLECTIONS_IDENTIFIER, self->time);
  if (g_strcmp0 (identifier, identifier_time) == 0)
    {
      const gchar *id;

      id = photos_filterable_get_id (PHOTOS_FILTERABLE (collection));
      photos_debug (PHOTOS_DEBUG_IMPORT, "Default collection already exists: %s", id);
      g_set_object (&self->default_collection, collection);
    }

  tracker_sparql_cursor_next_async (cursor,
                                    self->cancellable,
                                    photos_import_dialog_fetch_collections_local_cursor_next,
                                    self);

 out:
  return;
}
static void
photos_item_manager_finalize (GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (object);

  g_queue_free (self->history);

  G_OBJECT_CLASS (photos_item_manager_parent_class)->finalize (object);
}
static gchar *
photos_item_manager_get_where (PhotosBaseManager *mngr, gint flags)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (mngr);

  if (self->active_collection == NULL)
    return g_strdup ("");

  return photos_base_item_get_where (self->active_collection);
}
static void
photos_item_manager_item_created_executed (TrackerSparqlCursor *cursor, gpointer user_data)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (user_data);

  if (cursor == NULL)
    goto out;

  photos_item_manager_add_item (self, cursor);

 out:
  g_object_unref (self);
}
Example #11
0
static PhotosBaseItem *
photos_preview_nav_buttons_get_previous_item (PhotosPreviewNavButtons *self)
{
  PhotosBaseItem *item;
  PhotosBaseItem *previous_item;
  PhotosBaseManager *item_mngr_chld;

  item = PHOTOS_BASE_ITEM (photos_base_manager_get_active_object (self->item_mngr));
  item_mngr_chld = photos_item_manager_get_for_mode (PHOTOS_ITEM_MANAGER (self->item_mngr), self->old_mode);

  do
    {
      previous_item = PHOTOS_BASE_ITEM (photos_base_manager_get_previous_object (item_mngr_chld, G_OBJECT (item)));
      item = previous_item;
    } while (item != NULL && photos_base_item_is_collection (item));

  return previous_item;
}
static void
photos_item_manager_dispose (GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (object);

  if (self->collection_path != NULL)
    {
      photos_item_manager_collection_path_free (self);
      self->collection_path = NULL;
    }

  g_clear_pointer (&self->collections, (GDestroyNotify) g_hash_table_unref);
  g_clear_object (&self->loader_cancellable);
  g_clear_object (&self->active_collection);
  g_clear_object (&self->monitor);

  G_OBJECT_CLASS (photos_item_manager_parent_class)->dispose (object);
}
static void
photos_item_manager_remove_object_by_id (PhotosBaseManager *mngr, const gchar *id)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (mngr);
  gpointer *collection;

  if (id == NULL)
    goto end;

  collection = g_hash_table_lookup (self->collections, id);
  if (collection == NULL)
    goto end;

  g_hash_table_remove (self->collections, id);

 end:
  PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->remove_object_by_id (mngr, id);
}
static PhotosQuery *
photos_offset_collection_view_controller_get_query (PhotosOffsetController *offset_cntrlr)
{
  PhotosOffsetCollectionViewController *self = PHOTOS_OFFSET_COLLECTION_VIEW_CONTROLLER (offset_cntrlr);
  GApplication *app;
  PhotosBaseItem *collection;
  PhotosSearchContextState *state;

  g_return_val_if_fail (self->item_mngr != NULL, NULL);

  collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (self->item_mngr));
  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (collection), NULL);

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

  return photos_query_builder_count_query (state, PHOTOS_QUERY_FLAGS_NONE);
}
static void
photos_item_manager_dispose (GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (object);
  PhotosItemManagerPrivate *priv = self->priv;

  if (priv->collection_path != NULL)
    {
      g_queue_foreach (priv->collection_path, photos_item_manager_collection_path_free_foreach, NULL);
      g_queue_free (priv->collection_path);
      priv->collection_path = NULL;
    }

  g_clear_object (&priv->col_mngr);
  g_clear_object (&priv->monitor);

  G_OBJECT_CLASS (photos_item_manager_parent_class)->dispose (object);
}
Example #16
0
static void
photos_application_activate_query_executed (TrackerSparqlCursor *cursor, gpointer user_data)
{
  PhotosApplication *self = PHOTOS_APPLICATION (user_data);
  PhotosApplicationPrivate *priv = self->priv;
  GObject *item;
  const gchar *identifier;

  if (cursor == NULL)
    goto out;

  photos_item_manager_add_item (PHOTOS_ITEM_MANAGER (priv->item_mngr), cursor);

  identifier = tracker_sparql_cursor_get_string (cursor, PHOTOS_QUERY_COLUMNS_URN, NULL);
  item = photos_base_manager_get_object_by_id (priv->item_mngr, identifier);

  photos_application_activate_item (self, item);

 out:
  g_object_unref (self);
}
static PhotosQuery *
photos_offset_favorites_controller_get_query (PhotosOffsetController *offset_cntrlr)
{
  PhotosOffsetFavoritesController *self = PHOTOS_OFFSET_FAVORITES_CONTROLLER (offset_cntrlr);
  GApplication *app;
  PhotosBaseItem *collection;
  PhotosSearchContextState *state;
  gint flags;

  g_return_val_if_fail (self->item_mngr != NULL, NULL);

  collection = photos_item_manager_get_active_collection (PHOTOS_ITEM_MANAGER (self->item_mngr));
  if (collection != NULL)
    flags = PHOTOS_QUERY_FLAGS_NONE;
  else
    flags = PHOTOS_QUERY_FLAGS_FAVORITES;

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

  return photos_query_builder_count_query (state, flags);
}
static gboolean
photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (manager);
  PhotosItemManagerPrivate *priv = self->priv;
  GtkRecentManager *recent;
  gboolean ret_val;
  const gchar *uri;

  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (object) || object == NULL, FALSE);

  ret_val = PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->set_active_object (manager, object);

  if (!ret_val)
    goto out;

  if (object == NULL)
    goto out;

  if (photos_base_item_is_collection (PHOTOS_BASE_ITEM (object)))
    {
      GObject *collection;

      collection = photos_base_manager_get_active_object (priv->col_mngr);
      g_queue_push_head (priv->collection_path, (collection != NULL) ? g_object_ref (collection) : NULL);
      photos_base_manager_set_active_object (priv->col_mngr, object);
      goto out;
    }

  recent = gtk_recent_manager_get_default ();
  uri = photos_base_item_get_uri (PHOTOS_BASE_ITEM (object));
  gtk_recent_manager_add_item (recent, uri);

 out:
  return ret_val;
}
static void
photos_fetch_collection_state_job_emit_callback (PhotosFetchCollectionStateJob *self)
{
  GHashTable *collection_state;
  GHashTable *collections;
  GHashTableIter iter1;
  PhotosBaseItem *collection;
  const gchar *coll_idx;

  collection_state = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  collections = photos_item_manager_get_collections (PHOTOS_ITEM_MANAGER (self->item_mngr));

  /* For all the registered collections… */
  g_hash_table_iter_init (&iter1, collections);
  while (g_hash_table_iter_next (&iter1, (gpointer *) &coll_idx, (gpointer *) &collection))
    {
      GHashTableIter iter2;
      GList *collections_for_item;
      GList *keys;
      PhotosBaseItem *item;
      gboolean found = FALSE;
      gboolean hidden = FALSE;
      gboolean not_found = FALSE;
      const gchar *item_idx;
      gint state = PHOTOS_COLLECTION_STATE_NORMAL;

      /* If the only object we are fetching collection state for is a
       * collection itself, hide this if it is the same collection.
       */
      keys = g_hash_table_get_keys (self->collections_for_items);
      if (g_list_length (keys) == 1)
        {
          item_idx = (gchar *) keys->data;
          item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (self->item_mngr, item_idx));
          if (g_strcmp0 (photos_filterable_get_id (PHOTOS_FILTERABLE (item)),
                         photos_filterable_get_id (PHOTOS_FILTERABLE (collection))) == 0)
            hidden = TRUE;
        }
      g_list_free (keys);

      g_hash_table_iter_init (&iter2, self->collections_for_items);
      while (g_hash_table_iter_next (&iter2, (gpointer *) &item_idx, (gpointer *) &collections_for_item))
        {
          const gchar *identifier;

          item = PHOTOS_BASE_ITEM (photos_base_manager_get_object_by_id (self->item_mngr, item_idx));

          /* If one of the selected items is part of this collection… */
          if (g_list_find_custom (collections_for_item, coll_idx, (GCompareFunc) g_strcmp0) != NULL)
            found = TRUE;
          else
            not_found = TRUE;

          identifier = photos_base_item_get_identifier (collection);
          if (g_strcmp0 (photos_base_item_get_resource_urn (item),
                         photos_base_item_get_resource_urn (collection)) != 0
              && identifier != NULL
              && !g_str_has_prefix (identifier, PHOTOS_QUERY_LOCAL_COLLECTIONS_IDENTIFIER))
            hidden = TRUE;
        }

      if (found && not_found)
        state |= PHOTOS_COLLECTION_STATE_INCONSISTENT;
      else if (found)
        state |= PHOTOS_COLLECTION_STATE_ACTIVE;

      if (hidden)
        state |= PHOTOS_COLLECTION_STATE_HIDDEN;

      g_hash_table_insert (collection_state, g_strdup (coll_idx), GINT_TO_POINTER (state));
    }

  if (self->callback != NULL)
    (*self->callback) (collection_state, self->user_data);

  g_hash_table_unref (collection_state);
}
static gboolean
photos_item_manager_set_active_object (PhotosBaseManager *manager, GObject *object)
{
  PhotosItemManager *self = PHOTOS_ITEM_MANAGER (manager);
  GObject *active_item;
  PhotosWindowMode old_mode;
  gboolean active_collection_changed = FALSE;
  gboolean ret_val = FALSE;
  gboolean start_loading = FALSE;
  gboolean window_mode_changed = FALSE;

  g_return_val_if_fail (object != NULL, FALSE);
  g_return_val_if_fail (PHOTOS_IS_BASE_ITEM (object), FALSE);

  active_item = photos_base_manager_get_active_object (manager);
  if (object == active_item)
    goto out;

  photos_item_manager_clear_active_item_load (self);

  if (photos_base_item_is_collection (PHOTOS_BASE_ITEM (object)))
    {
      g_queue_push_head (self->collection_path,
                         (self->active_collection != NULL) ? g_object_ref (self->active_collection) : NULL);

      g_clear_object (&self->active_collection);
      self->active_collection = g_object_ref (object);
      self->load_state = PHOTOS_LOAD_STATE_NONE;
      active_collection_changed = TRUE;
    }
  else
    {
      window_mode_changed = photos_item_manager_set_window_mode_internal (self,
                                                                          PHOTOS_WINDOW_MODE_PREVIEW,
                                                                          &old_mode);
      photos_item_manager_update_fullscreen (self);
      self->load_state = PHOTOS_LOAD_STATE_STARTED;
      start_loading = TRUE;
    }

  ret_val = PHOTOS_BASE_MANAGER_CLASS (photos_item_manager_parent_class)->set_active_object (manager, object);
  /* We have already eliminated the possibility of failure. */
  g_assert (ret_val == TRUE);

  active_item = photos_base_manager_get_active_object (manager);
  g_assert (active_item == object);

  if (active_collection_changed)
    {
      g_signal_emit (self, signals[ACTIVE_COLLECTION_CHANGED], 0, self->active_collection);
      g_assert (active_item == (GObject *) self->active_collection);
    }

  if (start_loading)
    {
      GtkRecentManager *recent;
      const gchar *uri;

      recent = gtk_recent_manager_get_default ();
      uri = photos_base_item_get_uri (PHOTOS_BASE_ITEM (object));
      gtk_recent_manager_add_item (recent, uri);

      self->loader_cancellable = g_cancellable_new ();
      photos_base_item_load_async (PHOTOS_BASE_ITEM (object),
                                   self->loader_cancellable,
                                   photos_item_manager_item_load,
                                   g_object_ref (self));

      g_signal_emit (self, signals[LOAD_STARTED], 0, PHOTOS_BASE_ITEM (object));

      if (window_mode_changed)
        g_signal_emit (self, signals[WINDOW_MODE_CHANGED], 0, PHOTOS_WINDOW_MODE_PREVIEW, old_mode);

      g_assert (active_item != (GObject *) self->active_collection);
    }

 out:
  return ret_val;
}