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); }
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); }
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); }
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; }