image_list.c 17.4 KB
Newer Older
1
/*
2
 *  Copyright (c) Stephan Arts 2009-2011 <stephan@xfce.org>
3 4 5 6 7
 *
 *  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.
Stephan Arts's avatar
Stephan Arts committed
8 9
 *
 *  This program is distributed in the hope that it will be useful,
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <config.h>

#include <gtk/gtk.h>
#include <gtk/gtkmarshal.h>

#include <string.h>

#include <libexif/exif-data.h>

#include "image_list.h"
29
#include "settings.h"
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

static void 
rstto_image_list_init(RsttoImageList *);
static void
rstto_image_list_class_init(RsttoImageListClass *);
static void
rstto_image_list_dispose(GObject *object);

static void 
rstto_image_list_iter_init(RsttoImageListIter *);
static void
rstto_image_list_iter_class_init(RsttoImageListIterClass *);
static void
rstto_image_list_iter_dispose(GObject *object);

static RsttoImageListIter * rstto_image_list_iter_new ();

static gint
48
cb_rstto_image_list_image_name_compare_func (GFile *a, GFile *b);
Stephan Arts's avatar
Stephan Arts committed
49
static gint
50
cb_rstto_image_list_exif_date_compare_func (GFile *a, GFile *b);
Stephan Arts's avatar
Stephan Arts committed
51
static gint
52
cb_rstto_image_list_file_compare_func (GFile *a, GFile *file);
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

static GObjectClass *parent_class = NULL;
static GObjectClass *iter_parent_class = NULL;

enum
{
    RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE = 0,
    RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE,
    RSTTO_IMAGE_LIST_SIGNAL_REMOVE_ALL,
    RSTTO_IMAGE_LIST_SIGNAL_COUNT
};

enum
{
    RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED = 0,
68
    RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE,
69 70 71 72 73 74
    RSTTO_IMAGE_LIST_ITER_SIGNAL_COUNT
};

struct _RsttoImageListIterPriv
{
    RsttoImageList *image_list;
75
    GFile *file;
76 77 78 79 80 81
};

struct _RsttoImageListPriv
{
    GList *images;
    gint n_images;
Stephan Arts's avatar
Stephan Arts committed
82 83

    GSList *iterators;
Stephan Arts's avatar
Stephan Arts committed
84
    GCompareFunc cb_rstto_image_list_compare_func;
85 86 87 88 89 90
};

static gint rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_COUNT];
static gint rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_COUNT];

GType
Stephan Arts's avatar
Stephan Arts committed
91
rstto_image_list_get_type (void)
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
{
    static GType rstto_image_list_type = 0;

    if (!rstto_image_list_type)
    {
        static const GTypeInfo rstto_image_list_info = 
        {
            sizeof (RsttoImageListClass),
            (GBaseInitFunc) NULL,
            (GBaseFinalizeFunc) NULL,
            (GClassInitFunc) rstto_image_list_class_init,
            (GClassFinalizeFunc) NULL,
            NULL,
            sizeof (RsttoImageList),
            0,
            (GInstanceInitFunc) rstto_image_list_init,
            NULL
        };

        rstto_image_list_type = g_type_register_static (G_TYPE_OBJECT, "RsttoImageList", &rstto_image_list_info, 0);
    }
    return rstto_image_list_type;
}

static void
rstto_image_list_init(RsttoImageList *image_list)
{
119

120
    image_list->priv = g_new0 (RsttoImageListPriv, 1);
Stephan Arts's avatar
Stephan Arts committed
121
    image_list->priv->cb_rstto_image_list_compare_func = (GCompareFunc)cb_rstto_image_list_image_name_compare_func;
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
}

static void
rstto_image_list_class_init(RsttoImageListClass *nav_class)
{
    GObjectClass *object_class = G_OBJECT_CLASS(nav_class);

    parent_class = g_type_class_peek_parent(nav_class);

    object_class->dispose = rstto_image_list_dispose;

    rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE] = g_signal_new("new-image",
            G_TYPE_FROM_CLASS(nav_class),
            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
            0,
            NULL,
            NULL,
            g_cclosure_marshal_VOID__OBJECT,
            G_TYPE_NONE,
            1,
            G_TYPE_OBJECT,
            NULL);

    rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE] = g_signal_new("remove-image",
            G_TYPE_FROM_CLASS(nav_class),
            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
            0,
            NULL,
            NULL,
            g_cclosure_marshal_VOID__OBJECT,
            G_TYPE_NONE,
            1,
            G_TYPE_OBJECT,
            NULL);

    rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_REMOVE_ALL] = g_signal_new("remove-all",
            G_TYPE_FROM_CLASS(nav_class),
            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
            0,
            NULL,
            NULL,
            g_cclosure_marshal_VOID__VOID,
            G_TYPE_NONE,
            0,
            NULL);
}

static void
rstto_image_list_dispose(GObject *object)
{
    /*RsttoImageList *image_list = RSTTO_IMAGE_LIST(object);*/
}

RsttoImageList *
Stephan Arts's avatar
Stephan Arts committed
176
rstto_image_list_new (void)
177 178 179 180 181 182 183 184 185 186 187
{
    RsttoImageList *image_list;

    image_list = g_object_new(RSTTO_TYPE_IMAGE_LIST, NULL);

    return image_list;
}

gboolean
rstto_image_list_add_file (RsttoImageList *image_list, GFile *file, GError **error)
{
188
    GList *image_iter = g_list_find_custom (image_list->priv->images, file, rstto_image_list_get_compare_func (image_list));
189

Stephan Arts's avatar
Stephan Arts committed
190 191
    if (!image_iter)
    {
192
        if (file)
Stephan Arts's avatar
Stephan Arts committed
193
        {
194 195 196
            image_list->priv->images = g_list_insert_sorted (image_list->priv->images, file, rstto_image_list_get_compare_func (image_list));
            g_object_ref (file);

Stephan Arts's avatar
Stephan Arts committed
197 198
            image_list->priv->n_images++;

199
            g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE], 0, file, NULL);
Stephan Arts's avatar
Stephan Arts committed
200
            if (image_list->priv->n_images == 1)
Stephan Arts's avatar
Stephan Arts committed
201
            {
Stephan Arts's avatar
Stephan Arts committed
202 203 204 205 206 207 208
                /** TODO: update all iterators */
                GSList *iter = image_list->priv->iterators;
                while (iter)
                {
                    g_signal_emit (G_OBJECT (iter->data), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
                    iter = g_slist_next (iter);
                }
Stephan Arts's avatar
Stephan Arts committed
209
            }
Stephan Arts's avatar
Stephan Arts committed
210
            return TRUE;
Stephan Arts's avatar
Stephan Arts committed
211
        }
Stephan Arts's avatar
Stephan Arts committed
212
        return FALSE;
213
    }
Stephan Arts's avatar
Stephan Arts committed
214 215 216
    g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE], 0, image_iter->data, NULL);

    return TRUE;
217 218 219 220 221 222 223 224
}

gint
rstto_image_list_get_n_images (RsttoImageList *image_list)
{
    return g_list_length (image_list->priv->images);
}

Stephan Arts's avatar
Stephan Arts committed
225 226 227 228 229 230 231 232
/**
 * rstto_image_list_get_iter:
 * @image_list:
 *
 * TODO: track iterators
 *
 * return iter;
 */
233 234 235
RsttoImageListIter *
rstto_image_list_get_iter (RsttoImageList *image_list)
{
236
    GFile *file = NULL;
Stephan Arts's avatar
Stephan Arts committed
237
    RsttoImageListIter *iter = NULL;
238
    if (image_list->priv->images)
239
        file = image_list->priv->images->data;
240

241
    iter = rstto_image_list_iter_new (image_list, file);
242

Stephan Arts's avatar
Stephan Arts committed
243 244
    image_list->priv->iterators = g_slist_prepend (image_list->priv->iterators, iter);

245 246 247 248 249
    return iter;
}


void
250
rstto_image_list_remove_file (RsttoImageList *image_list, GFile *file)
251
{
Stephan Arts's avatar
Stephan Arts committed
252
    GSList *iter = NULL;
253
    GFile *afile = NULL;
Stephan Arts's avatar
Stephan Arts committed
254

255
    if (g_list_find(image_list->priv->images, file))
256
    {
Stephan Arts's avatar
Stephan Arts committed
257

Stephan Arts's avatar
Stephan Arts committed
258
        iter = image_list->priv->iterators;
Stephan Arts's avatar
Stephan Arts committed
259 260
        while (iter)
        {
261
            if (g_file_equal(rstto_image_list_iter_get_file (iter->data), file))
Stephan Arts's avatar
Stephan Arts committed
262 263
            {
                rstto_image_list_iter_previous (iter->data);
264 265 266 267
                /* If the image is still the same, 
                 * it's a single item list,
                 * and we should force the image in this iter to NULL
                 */
268
                if (g_file_equal(rstto_image_list_iter_get_file (iter->data), file))
269
                {
270
                    ((RsttoImageListIter *)(iter->data))->priv->file = NULL;
271
                    g_signal_emit (G_OBJECT (iter->data), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
272
                }
Stephan Arts's avatar
Stephan Arts committed
273 274 275
            }
            iter = g_slist_next (iter);
        }
276

277
        image_list->priv->images = g_list_remove (image_list->priv->images, file);
278
        iter = image_list->priv->iterators;
279
        g_object_ref(file);
280 281
        while (iter)
        {
282 283
            afile = rstto_image_list_iter_get_file(iter->data);
            if (NULL != afile)
284
            {
285 286 287 288
                if (g_file_equal(afile, file))
                {
                    rstto_image_list_iter_previous (iter->data);
                }
289 290 291 292
            }
            iter = g_slist_next (iter);
        }

293 294
        g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE], 0, file, NULL);
        g_object_unref(file);
295 296 297 298 299 300
    }
}

void
rstto_image_list_remove_all (RsttoImageList *image_list)
{
Stephan Arts's avatar
Stephan Arts committed
301
    GSList *iter = NULL;
302 303 304
    g_list_foreach (image_list->priv->images, (GFunc)g_object_unref, NULL);
    g_list_free (image_list->priv->images);
    image_list->priv->images = NULL;
Stephan Arts's avatar
Stephan Arts committed
305

Stephan Arts's avatar
Stephan Arts committed
306
    iter = image_list->priv->iterators;
Stephan Arts's avatar
Stephan Arts committed
307 308
    while (iter)
    {
Stephan Arts's avatar
Stephan Arts committed
309
        rstto_image_list_iter_set_position (iter->data, -1);
Stephan Arts's avatar
Stephan Arts committed
310 311 312
        iter = g_slist_next (iter);
    }
    g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_REMOVE_ALL], 0, NULL);
313 314 315 316 317
}



GType
Stephan Arts's avatar
Stephan Arts committed
318
rstto_image_list_iter_get_type (void)
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
{
    static GType rstto_image_list_iter_type = 0;

    if (!rstto_image_list_iter_type)
    {
        static const GTypeInfo rstto_image_list_iter_info = 
        {
            sizeof (RsttoImageListIterClass),
            (GBaseInitFunc) NULL,
            (GBaseFinalizeFunc) NULL,
            (GClassInitFunc) rstto_image_list_iter_class_init,
            (GClassFinalizeFunc) NULL,
            NULL,
            sizeof (RsttoImageListIter),
            0,
            (GInstanceInitFunc) rstto_image_list_iter_init,
            NULL
        };

        rstto_image_list_iter_type = g_type_register_static (G_TYPE_OBJECT, "RsttoImageListIter", &rstto_image_list_iter_info, 0);
    }
    return rstto_image_list_iter_type;
}

static void
rstto_image_list_iter_init (RsttoImageListIter *iter)
{
    iter->priv = g_new0 (RsttoImageListIterPriv, 1);
}

static void
rstto_image_list_iter_class_init(RsttoImageListIterClass *iter_class)
{
    GObjectClass *object_class = G_OBJECT_CLASS(iter_class);

    iter_parent_class = g_type_class_peek_parent(iter_class);

    object_class->dispose = rstto_image_list_iter_dispose;

358 359 360 361 362 363 364 365 366 367 368
    rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE] = g_signal_new("prepare-change",
            G_TYPE_FROM_CLASS(iter_class),
            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
            0,
            NULL,
            NULL,
            g_cclosure_marshal_VOID__VOID,
            G_TYPE_NONE,
            0,
            NULL);

369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED] = g_signal_new("changed",
            G_TYPE_FROM_CLASS(iter_class),
            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
            0,
            NULL,
            NULL,
            g_cclosure_marshal_VOID__VOID,
            G_TYPE_NONE,
            0,
            NULL);

}

static void
rstto_image_list_iter_dispose (GObject *object)
{
    RsttoImageListIter *iter = RSTTO_IMAGE_LIST_ITER(object);
386
    if (iter->priv->file)
387
    {
388
        iter->priv->file = NULL;
389
    }
Stephan Arts's avatar
Stephan Arts committed
390 391 392 393 394 395

    if (iter->priv->image_list)
    {
        iter->priv->image_list->priv->iterators = g_slist_remove (iter->priv->image_list->priv->iterators, iter);
        iter->priv->image_list= NULL;
    }
396 397 398
}

static RsttoImageListIter *
399
rstto_image_list_iter_new (RsttoImageList *nav, GFile *file)
400 401 402 403
{
    RsttoImageListIter *iter;

    iter = g_object_new(RSTTO_TYPE_IMAGE_LIST_ITER, NULL);
404
    iter->priv->file = file;
405 406 407 408 409 410
    iter->priv->image_list = nav;

    return iter;
}

gboolean
411
rstto_image_list_iter_find_file (RsttoImageListIter *iter, GFile *file)
412
{
413
    gint pos = g_list_index (iter->priv->image_list->priv->images, file);
414 415
    if (pos > -1)
    {
416 417
        g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE], 0, NULL);

418
        if (iter->priv->file)
419
        {
420
            iter->priv->file = NULL;
421
        }
422
        iter->priv->file = file;
423 424 425 426 427 428 429 430 431 432 433

        g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);

        return TRUE;
    }
    return FALSE;
}

gint
rstto_image_list_iter_get_position (RsttoImageListIter *iter)
{
434
    if ( NULL == iter->priv->file )
435
    {
436
        return -1;
437
    }
438
    return g_list_index (iter->priv->image_list->priv->images, iter->priv->file);
439 440
}

441 442
GFile *
rstto_image_list_iter_get_file (RsttoImageListIter *iter)
443
{
444
    return iter->priv->file;
445 446 447
}


Stephan Arts's avatar
Stephan Arts committed
448
void
449 450
rstto_image_list_iter_set_position (RsttoImageListIter *iter, gint pos)
{
451 452
    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE], 0, NULL);

453
    if (iter->priv->file)
454
    {
455
        iter->priv->file = NULL;
456 457
    }

Stephan Arts's avatar
Stephan Arts committed
458
    if (pos >= 0)
Stephan Arts's avatar
Stephan Arts committed
459
    {
460
        iter->priv->file = g_list_nth_data (iter->priv->image_list->priv->images, pos); 
Stephan Arts's avatar
Stephan Arts committed
461
    }
462

463 464 465
    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
}

Stephan Arts's avatar
Stephan Arts committed
466
void
467 468
rstto_image_list_iter_next (RsttoImageListIter *iter)
{
469
    GList *position = NULL;
Stephan Arts's avatar
Stephan Arts committed
470
    RsttoSettings *settings = NULL;
471 472 473

    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE], 0, NULL);

474
    if (iter->priv->file)
475
    {
476 477
        position = g_list_find (iter->priv->image_list->priv->images, iter->priv->file);
        iter->priv->file = NULL;
478 479
    }

480 481
    position = g_list_next (position);
    if (position)
482
        iter->priv->file = position->data; 
483 484
    else
    {
Stephan Arts's avatar
Stephan Arts committed
485 486 487
        settings = rstto_settings_new();

        if (rstto_settings_get_boolean_property (settings, "wrap-images"))
488 489 490 491
            position = g_list_first (iter->priv->image_list->priv->images);
        else
            position = g_list_last (iter->priv->image_list->priv->images);

492
        if (position)
493
            iter->priv->file = position->data; 
494
        else
495
            iter->priv->file = NULL;
Stephan Arts's avatar
Stephan Arts committed
496 497

        g_object_unref (settings);
498 499 500 501 502
    }

    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
}

Stephan Arts's avatar
Stephan Arts committed
503
void
504 505
rstto_image_list_iter_previous (RsttoImageListIter *iter)
{
506
    GList *position = NULL;
Stephan Arts's avatar
Stephan Arts committed
507
    RsttoSettings *settings = NULL;
508 509 510

    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_PREPARE_CHANGE], 0, NULL);

511
    if (iter->priv->file)
512
    {
513 514
        position = g_list_find (iter->priv->image_list->priv->images, iter->priv->file);
        iter->priv->file = NULL;
515 516
    }

517 518
    position = g_list_previous (position);
    if (position)
519
    {
520
        iter->priv->file = position->data; 
521
    }
522 523
    else
    {
Stephan Arts's avatar
Stephan Arts committed
524 525 526
        settings = rstto_settings_new();

        if (rstto_settings_get_boolean_property (settings, "wrap-images"))
527 528 529 530
            position = g_list_last (iter->priv->image_list->priv->images);
        else
            position = g_list_first (iter->priv->image_list->priv->images);

531
        if (position)
532
            iter->priv->file = position->data; 
533
        else
534
            iter->priv->file = NULL;
Stephan Arts's avatar
Stephan Arts committed
535 536

        g_object_unref (settings);
537
    }
538

539 540 541 542 543 544
    g_signal_emit (G_OBJECT (iter), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
}

RsttoImageListIter *
rstto_image_list_iter_clone (RsttoImageListIter *iter)
{
545
    RsttoImageListIter *new_iter = rstto_image_list_iter_new (iter->priv->image_list, iter->priv->file);
Stephan Arts's avatar
Stephan Arts committed
546
    rstto_image_list_iter_set_position (new_iter, rstto_image_list_iter_get_position(iter));
547 548 549

    return new_iter;
}
550 551 552 553

GCompareFunc
rstto_image_list_get_compare_func (RsttoImageList *image_list)
{
Stephan Arts's avatar
Stephan Arts committed
554 555 556
    return (GCompareFunc)image_list->priv->cb_rstto_image_list_compare_func;
}

557 558 559
void
rstto_image_list_set_compare_func (RsttoImageList *image_list, GCompareFunc func)
{
560
    GSList *iter = NULL;
561
    image_list->priv->cb_rstto_image_list_compare_func = func;
562
    image_list->priv->images = g_list_sort (image_list->priv->images,  func);
563

564 565 566 567
    for (iter = image_list->priv->iterators; iter != NULL; iter = g_slist_next (iter))
    {
        g_signal_emit (G_OBJECT (iter->data), rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_CHANGED], 0, NULL);
    }
568 569
}

Stephan Arts's avatar
Stephan Arts committed
570 571 572 573
/***********************/
/*  Compare Functions  */
/***********************/

574 575 576
void
rstto_image_list_set_sort_by_name (RsttoImageList *image_list)
{
577
    rstto_image_list_set_compare_func (image_list, (GCompareFunc)cb_rstto_image_list_image_name_compare_func);
578 579 580 581 582
}

void
rstto_image_list_set_sort_by_date (RsttoImageList *image_list)
{
583
    rstto_image_list_set_compare_func (image_list, (GCompareFunc)cb_rstto_image_list_exif_date_compare_func);
584 585
}

Stephan Arts's avatar
Stephan Arts committed
586 587 588 589 590 591 592 593 594
/**
 * cb_rstto_image_list_image_name_compare_func:
 * @a:
 * @b:
 *
 *
 * Return value: (see strcmp)
 */
static gint
595
cb_rstto_image_list_image_name_compare_func (GFile *a, GFile *b)
Stephan Arts's avatar
Stephan Arts committed
596
{
597 598
    gchar *a_base = g_file_get_basename (a);  
    gchar *b_base = g_file_get_basename (b);  
Stephan Arts's avatar
Stephan Arts committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612
    gint result = 0;

    result = g_strcasecmp (a_base, b_base);

    g_free (a_base);
    g_free (b_base);
    return result;
}

/**
 * cb_rstto_image_list_exif_date_compare_func:
 * @a:
 * @b:
 *
613
 * TODO: Use EXIF data if available, not the last-modification-time.
Stephan Arts's avatar
Stephan Arts committed
614 615 616 617
 *
 * Return value: (see strcmp)
 */
static gint
618
cb_rstto_image_list_exif_date_compare_func (GFile *a, GFile *b)
Stephan Arts's avatar
Stephan Arts committed
619 620
{
    gint result = 0;
621
    
622 623
    GFileInfo *file_info_a = g_file_query_info (a, "time::modified", 0, NULL, NULL);
    GFileInfo *file_info_b = g_file_query_info (b, "time::modified", 0, NULL, NULL);
624 625 626 627 628 629 630 631 632 633

    guint64 a_i = g_file_info_get_attribute_uint64(file_info_a, "time::modified");
    guint64 b_i = g_file_info_get_attribute_uint64(file_info_b, "time::modified");
    if (a_i > b_i)
        result = 1;
    else
        result = 0;

    g_object_unref (file_info_a);
    g_object_unref (file_info_b);
Stephan Arts's avatar
Stephan Arts committed
634
    return result;
635
}