/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Pix
*
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include "gth-load-image-info-task.h"
struct _GthLoadImageInfoTaskPrivate {
GthImageInfo **images;
int n_images;
int current;
char *attributes;
GthImageLoader *loader;
};
G_DEFINE_TYPE_WITH_CODE (GthLoadImageInfoTask,
gth_load_image_info_task,
GTH_TYPE_TASK,
G_ADD_PRIVATE (GthLoadImageInfoTask))
static void
gth_load_image_info_task_finalize (GObject *object)
{
GthLoadImageInfoTask *self;
int i;
self = GTH_LOAD_IMAGE_INFO_TASK (object);
for (i = 0; i < self->priv->n_images; i++)
gth_image_info_unref (self->priv->images[i]);
g_free (self->priv->images);
g_free (self->priv->attributes);
g_object_unref (self->priv->loader);
G_OBJECT_CLASS (gth_load_image_info_task_parent_class)->finalize (object);
}
static void load_current_image (GthLoadImageInfoTask *self);
static void
load_next_image (GthLoadImageInfoTask *self)
{
self->priv->current++;
load_current_image (self);
}
static void
metadata_ready_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GthLoadImageInfoTask *self = user_data;
GError *error = NULL;
_g_query_metadata_finish (result, &error);
if (error != NULL) {
gth_task_completed (GTH_TASK (self), error);
return;
}
load_next_image (self);
}
static void
continue_loading_image (GthLoadImageInfoTask *self)
{
if (strcmp (self->priv->attributes, "") != 0) {
GthImageInfo *image_info;
GList *files;
image_info = self->priv->images[self->priv->current];
files = g_list_prepend (NULL, image_info->file_data);
_g_query_metadata_async (files,
self->priv->attributes,
gth_task_get_cancellable (GTH_TASK (self)),
metadata_ready_cb,
self);
g_list_free (files);
}
else
load_next_image (self);
}
static void
image_loader_ready_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GthLoadImageInfoTask *self = user_data;
GthImageInfo *image_info;
GthImage *image = NULL;
GError *error = NULL;
gth_image_loader_load_finish (GTH_IMAGE_LOADER (source_object),
result,
&image,
NULL,
NULL,
NULL,
&error);
if (error == NULL)
g_cancellable_set_error_if_cancelled (gth_task_get_cancellable (GTH_TASK (self)), &error);
if (error == NULL) {
cairo_surface_t *surface;
image_info = self->priv->images[self->priv->current];
surface = gth_image_get_cairo_surface (image);
if (surface != NULL) {
gth_image_info_set_image (image_info, surface);
cairo_surface_destroy (surface);
}
}
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
g_object_unref (image);
gth_task_completed (GTH_TASK (self), error);
return;
}
else
g_clear_error (&error);
_g_object_unref (image);
continue_loading_image (self);
}
static void
load_current_image (GthLoadImageInfoTask *self)
{
GthImageInfo *image_info;
char *details;
if (self->priv->current >= self->priv->n_images) {
gth_task_completed (GTH_TASK (self), NULL);
return;
}
image_info = self->priv->images[self->priv->current];
/* translators: %s is a filename */
details = g_strdup_printf (_("Loading ā%sā"), g_file_info_get_display_name (image_info->file_data->info));
gth_task_progress (GTH_TASK (self),
_("Loading images"),
details,
FALSE,
((double) self->priv->current + 0.5) / self->priv->n_images);
if (image_info->image == NULL)
gth_image_loader_load (self->priv->loader,
image_info->file_data,
-1,
G_PRIORITY_DEFAULT,
gth_task_get_cancellable (GTH_TASK (self)),
image_loader_ready_cb,
self);
else
call_when_idle ((DataFunc) continue_loading_image, self);
g_free (details);
}
static void
gth_load_image_info_task_exec (GthTask *task)
{
GthLoadImageInfoTask *self;
g_return_if_fail (GTH_IS_LOAD_IMAGE_INFO_TASK (task));
self = GTH_LOAD_IMAGE_INFO_TASK (task);
load_current_image (self);
}
static void
gth_load_image_info_task_cancelled (GthTask *task)
{
/* FIXME */
}
static void
gth_load_image_info_task_class_init (GthLoadImageInfoTaskClass *klass)
{
GObjectClass *object_class;
GthTaskClass *task_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gth_load_image_info_task_finalize;
task_class = GTH_TASK_CLASS (klass);
task_class->exec = gth_load_image_info_task_exec;
task_class->cancelled = gth_load_image_info_task_cancelled;
}
static void
gth_load_image_info_task_init (GthLoadImageInfoTask *self)
{
self->priv = gth_load_image_info_task_get_instance_private (self);
self->priv->loader = gth_image_loader_new (NULL, NULL);
}
GthTask *
gth_load_image_info_task_new (GthImageInfo **images,
int n_images,
const char *attributes)
{
GthLoadImageInfoTask *self;
int n;
self = (GthLoadImageInfoTask *) g_object_new (GTH_TYPE_LOAD_IMAGE_INFO_TASK, NULL);
self->priv->images = g_new0 (GthImageInfo *, n_images + 1);
for (n = 0; n < n_images; n++)
self->priv->images[n] = gth_image_info_ref (images[n]);
self->priv->images[n] = NULL;
self->priv->n_images = n;
self->priv->attributes = g_strdup (attributes);
self->priv->current = 0;
return (GthTask *) self;
}