gimpthumbbox.c 23.1 KB
Newer Older
1
/* GIMP - The GNU Image Manipulation Program
2 3
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7 8 9 10 11 12 13 14
 * (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
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17 18 19 20 21
 */

#include "config.h"

#include <string.h>

22
#include <gegl.h>
23 24
#include <gtk/gtk.h>

25
#include "libgimpbase/gimpbase.h"
26 27 28 29 30 31 32 33
#include "libgimpthumb/gimpthumb.h"
#include "libgimpwidgets/gimpwidgets.h"

#include "widgets-types.h"

#include "config/gimpcoreconfig.h"

#include "core/gimp.h"
34
#include "core/gimpcontext.h"
35
#include "core/gimpimagefile.h"
36
#include "core/gimpprogress.h"
37
#include "core/gimpsubprogress.h"
38

39
#include "plug-in/gimppluginmanager-file.h"
40

41
#include "gimpfiledialog.h" /* eek */
42
#include "gimpthumbbox.h"
43 44
#include "gimpview.h"
#include "gimpviewrenderer-frame.h"
45 46 47 48 49 50 51
#include "gimpwidgets-utils.h"

#include "gimp-intl.h"


/*  local function prototypes  */

52
static void     gimp_thumb_box_progress_iface_init (GimpProgressInterface *iface);
53

54 55
static void     gimp_thumb_box_dispose            (GObject           *object);
static void     gimp_thumb_box_finalize           (GObject           *object);
56

57
static GimpProgress *
58
                gimp_thumb_box_progress_start     (GimpProgress      *progress,
59 60
                                                   gboolean           cancellable,
                                                   const gchar       *message);
61 62 63 64 65
static void     gimp_thumb_box_progress_end       (GimpProgress      *progress);
static gboolean gimp_thumb_box_progress_is_active (GimpProgress      *progress);
static void     gimp_thumb_box_progress_set_value (GimpProgress      *progress,
                                                   gdouble            percentage);
static gdouble  gimp_thumb_box_progress_get_value (GimpProgress      *progress);
Sven Neumann's avatar
Sven Neumann committed
66
static void     gimp_thumb_box_progress_pulse     (GimpProgress      *progress);
67

68
static gboolean gimp_thumb_box_progress_message   (GimpProgress      *progress,
69
                                                   Gimp              *gimp,
70
                                                   GimpMessageSeverity  severity,
71 72 73
                                                   const gchar       *domain,
                                                   const gchar       *message);

74
static gboolean gimp_thumb_box_ebox_button_press  (GtkWidget         *widget,
75 76 77 78 79 80 81
                                                   GdkEventButton    *bevent,
                                                   GimpThumbBox      *box);
static void gimp_thumb_box_thumbnail_clicked      (GtkWidget         *widget,
                                                   GdkModifierType    state,
                                                   GimpThumbBox      *box);
static void gimp_thumb_box_imagefile_info_changed (GimpImagefile     *imagefile,
                                                   GimpThumbBox      *box);
82 83 84
static void gimp_thumb_box_thumb_state_notify     (GimpThumbnail     *thumb,
                                                   GParamSpec        *pspec,
                                                   GimpThumbBox      *box);
85
static void gimp_thumb_box_create_thumbnails      (GimpThumbBox      *box,
86
                                                   gboolean           force);
87
static void gimp_thumb_box_create_thumbnail       (GimpThumbBox      *box,
88
                                                   GFile             *file,
89
                                                   GimpThumbnailSize  size,
90 91
                                                   gboolean           force,
                                                   GimpProgress      *progress);
92
static gboolean gimp_thumb_box_auto_thumbnail     (GimpThumbBox      *box);
93 94


95 96
G_DEFINE_TYPE_WITH_CODE (GimpThumbBox, gimp_thumb_box, GTK_TYPE_FRAME,
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
97
                                                gimp_thumb_box_progress_iface_init))
98

99
#define parent_class gimp_thumb_box_parent_class
100 101 102 103 104


static void
gimp_thumb_box_class_init (GimpThumbBoxClass *klass)
{
105 106
  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
107

108 109
  object_class->dispose  = gimp_thumb_box_dispose;
  object_class->finalize = gimp_thumb_box_finalize;
110

111
  gtk_widget_class_set_css_name (widget_class, "treeview");
112 113 114 115 116 117
}

static void
gimp_thumb_box_init (GimpThumbBox *box)
{
  gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_IN);
118 119

  box->idle_id = 0;
120 121
}

122
static void
123
gimp_thumb_box_progress_iface_init (GimpProgressInterface *iface)
124
{
125 126 127 128 129 130 131
  iface->start     = gimp_thumb_box_progress_start;
  iface->end       = gimp_thumb_box_progress_end;
  iface->is_active = gimp_thumb_box_progress_is_active;
  iface->set_value = gimp_thumb_box_progress_set_value;
  iface->get_value = gimp_thumb_box_progress_get_value;
  iface->pulse     = gimp_thumb_box_progress_pulse;
  iface->message   = gimp_thumb_box_progress_message;
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145
static void
gimp_thumb_box_dispose (GObject *object)
{
  GimpThumbBox *box = GIMP_THUMB_BOX (object);

  if (box->idle_id)
    {
      g_source_remove (box->idle_id);
      box->idle_id = 0;
    }

  G_OBJECT_CLASS (parent_class)->dispose (object);
146 147

  box->progress = NULL;
148 149
}

150 151 152 153 154
static void
gimp_thumb_box_finalize (GObject *object)
{
  GimpThumbBox *box = GIMP_THUMB_BOX (object);

155
  gimp_thumb_box_take_files (box, NULL);
156

157
  g_clear_object (&box->imagefile);
158 159 160 161

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

162 163
static GimpProgress *
gimp_thumb_box_progress_start (GimpProgress *progress,
164 165
                               gboolean      cancellable,
                               const gchar  *message)
166
{
167
  GimpThumbBox *box = GIMP_THUMB_BOX (progress);
168

169 170 171
  if (! box->progress)
    return NULL;

172
  if (! box->progress_active)
173
    {
174
      GtkProgressBar *bar = GTK_PROGRESS_BAR (box->progress);
175
      GtkWidget      *toplevel;
176 177 178

      gtk_progress_bar_set_fraction (bar, 0.0);

179
      box->progress_active = TRUE;
180

181 182 183 184
      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (box));

      if (GIMP_IS_FILE_DIALOG (toplevel))
        gtk_dialog_set_response_sensitive (GTK_DIALOG (toplevel),
185
                                           GTK_RESPONSE_CANCEL, cancellable);
186

187 188 189 190 191 192 193 194 195
      return progress;
    }

  return NULL;
}

static void
gimp_thumb_box_progress_end (GimpProgress *progress)
{
196
  if (gimp_thumb_box_progress_is_active (progress))
197
    {
198
      GimpThumbBox   *box = GIMP_THUMB_BOX (progress);
199
      GtkProgressBar *bar = GTK_PROGRESS_BAR (box->progress);
200 201 202

      gtk_progress_bar_set_fraction (bar, 0.0);

203
      box->progress_active = FALSE;
204 205 206
    }
}

207 208 209
static gboolean
gimp_thumb_box_progress_is_active (GimpProgress *progress)
{
210
  GimpThumbBox *box = GIMP_THUMB_BOX (progress);
211

212
  return (box->progress && box->progress_active);
213 214
}

215 216 217 218
static void
gimp_thumb_box_progress_set_value (GimpProgress *progress,
                                   gdouble       percentage)
{
219
  if (gimp_thumb_box_progress_is_active (progress))
Sven Neumann's avatar
Sven Neumann committed
220
    {
221
      GimpThumbBox   *box = GIMP_THUMB_BOX (progress);
Sven Neumann's avatar
Sven Neumann committed
222 223 224 225
      GtkProgressBar *bar = GTK_PROGRESS_BAR (box->progress);

      gtk_progress_bar_set_fraction (bar, percentage);
    }
226 227 228 229 230
}

static gdouble
gimp_thumb_box_progress_get_value (GimpProgress *progress)
{
231
  if (gimp_thumb_box_progress_is_active (progress))
232
    {
233
      GimpThumbBox   *box = GIMP_THUMB_BOX (progress);
234
      GtkProgressBar *bar = GTK_PROGRESS_BAR (box->progress);
235 236 237 238 239 240 241

      return gtk_progress_bar_get_fraction (bar);
    }

  return 0.0;
}

Sven Neumann's avatar
Sven Neumann committed
242 243 244
static void
gimp_thumb_box_progress_pulse (GimpProgress *progress)
{
245
  if (gimp_thumb_box_progress_is_active (progress))
Sven Neumann's avatar
Sven Neumann committed
246
    {
247
      GimpThumbBox   *box = GIMP_THUMB_BOX (progress);
Sven Neumann's avatar
Sven Neumann committed
248 249 250 251 252 253
      GtkProgressBar *bar = GTK_PROGRESS_BAR (box->progress);

      gtk_progress_bar_pulse (bar);
    }
}

254 255 256 257 258 259
static gboolean
gimp_thumb_box_progress_message (GimpProgress        *progress,
                                 Gimp                *gimp,
                                 GimpMessageSeverity  severity,
                                 const gchar         *domain,
                                 const gchar         *message)
260 261
{
  /*  GimpThumbBox never shows any messages  */
262 263

  return TRUE;
264 265
}

266

267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
/*  stupid GimpHeader class just so we get a "header" CSS node  */

#define GIMP_TYPE_HEADER (gimp_header_get_type ())

typedef struct _GtkBox      GimpHeader;
typedef struct _GtkBoxClass GimpHeaderClass;

static GType gimp_header_get_type (void) G_GNUC_CONST;

G_DEFINE_TYPE (GimpHeader, gimp_header, GTK_TYPE_BOX)

static void
gimp_header_class_init (GimpHeaderClass *klass)
{
  gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "header");
}

static void
gimp_header_init (GimpHeader *header)
{
  gtk_orientable_set_orientation (GTK_ORIENTABLE (header),
                                  GTK_ORIENTATION_VERTICAL);
}


292 293
/*  public functions  */

294
GtkWidget *
295
gimp_thumb_box_new (GimpContext *context)
296
{
297 298 299 300 301 302 303
  GimpThumbBox   *box;
  GtkWidget      *vbox;
  GtkWidget      *vbox2;
  GtkWidget      *ebox;
  GtkWidget      *button;
  GtkWidget      *label;
  gchar          *str;
304
  gint            h, v;
305

306
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
307 308 309

  box = g_object_new (GIMP_TYPE_THUMB_BOX, NULL);

310 311 312
  gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (box)),
                               GTK_STYLE_CLASS_VIEW);

313 314
  box->context = context;

315 316 317 318
  ebox = gtk_event_box_new ();
  gtk_container_add (GTK_CONTAINER (box), ebox);
  gtk_widget_show (ebox);

319
  g_signal_connect (ebox, "button-press-event",
320 321 322 323
                    G_CALLBACK (gimp_thumb_box_ebox_button_press),
                    box);

  str = g_strdup_printf (_("Click to update preview\n"
324
                           "%s-Click to force update even "
325
                           "if preview is up-to-date"),
326
                         gimp_get_mod_string (gimp_get_toggle_behavior_mask ()));
327 328 329 330 331

  gimp_help_set_help_data (ebox, str, NULL);

  g_free (str);

Michael Natterer's avatar
Michael Natterer committed
332
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
333 334 335
  gtk_container_add (GTK_CONTAINER (ebox), vbox);
  gtk_widget_show (vbox);

336 337 338 339
  vbox2 = g_object_new (GIMP_TYPE_HEADER, NULL);
  gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
  gtk_widget_show (vbox2);

340
  button = gtk_button_new ();
341
  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
342 343
  gtk_widget_show (button);

344
  label = gtk_label_new_with_mnemonic (_("Pr_eview"));
345
  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
346 347 348
  gtk_container_add (GTK_CONTAINER (button), label);
  gtk_widget_show (label);

349
  g_signal_connect (button, "button-press-event",
350 351
                    G_CALLBACK (gtk_true),
                    NULL);
352
  g_signal_connect (button, "button-release-event",
353 354
                    G_CALLBACK (gtk_true),
                    NULL);
355
  g_signal_connect (button, "enter-notify-event",
356 357
                    G_CALLBACK (gtk_true),
                    NULL);
358
  g_signal_connect (button, "leave-notify-event",
359 360 361
                    G_CALLBACK (gtk_true),
                    NULL);

Michael Natterer's avatar
Michael Natterer committed
362
  vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
363
  gtk_container_set_border_width (GTK_CONTAINER (vbox2), 4);
Michael Natterer's avatar
Michael Natterer committed
364
  gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
365 366
  gtk_widget_show (vbox2);

367
  box->imagefile = gimp_imagefile_new (context->gimp, NULL);
368

369
  g_signal_connect (box->imagefile, "info-changed",
370 371 372
                    G_CALLBACK (gimp_thumb_box_imagefile_info_changed),
                    box);

373 374
  g_signal_connect (gimp_imagefile_get_thumbnail (box->imagefile),
                    "notify::thumb-state",
375 376 377
                    G_CALLBACK (gimp_thumb_box_thumb_state_notify),
                    box);

378 379
  gimp_view_renderer_get_frame_size (&h, &v);

380 381
  box->preview = gimp_view_new (context,
                                GIMP_VIEWABLE (box->imagefile),
382
                                /* add padding for the shadow frame */
383 384
                                context->gimp->config->thumbnail_size +
                                MAX (h, v),
385
                                0, FALSE);
386

387 388
  gtk_style_context_add_class (gtk_widget_get_style_context (box->preview),
                               GTK_STYLE_CLASS_VIEW);
389
  gtk_box_pack_start (GTK_BOX (vbox2), box->preview, FALSE, FALSE, 0);
390 391 392 393 394 395 396 397
  gtk_widget_show (box->preview);

  gtk_label_set_mnemonic_widget (GTK_LABEL (label), box->preview);

  g_signal_connect (box->preview, "clicked",
                    G_CALLBACK (gimp_thumb_box_thumbnail_clicked),
                    box);

398
  box->filename = gtk_label_new (_("No selection"));
399
  gtk_label_set_max_width_chars (GTK_LABEL (box->filename), 1);
Sven Neumann's avatar
Sven Neumann committed
400
  gtk_label_set_ellipsize (GTK_LABEL (box->filename), PANGO_ELLIPSIZE_MIDDLE);
401
  gtk_label_set_justify (GTK_LABEL (box->filename), GTK_JUSTIFY_CENTER);
402
  gimp_label_set_attributes (GTK_LABEL (box->filename),
403 404
                             PANGO_ATTR_STYLE, PANGO_STYLE_OBLIQUE,
                             -1);
405 406
  gtk_box_pack_start (GTK_BOX (vbox2), box->filename, FALSE, FALSE, 0);
  gtk_widget_show (box->filename);
407

408
  box->info = gtk_label_new (" \n \n \n ");
409
  gtk_label_set_justify (GTK_LABEL (box->info), GTK_JUSTIFY_CENTER);
410
  gtk_label_set_line_wrap (GTK_LABEL (box->info), TRUE);
411
  gimp_label_set_attributes (GTK_LABEL (box->info),
412 413
                             PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
                             -1);
414 415
  gtk_box_pack_start (GTK_BOX (vbox2), box->info, FALSE, FALSE, 0);
  gtk_widget_show (box->info);
416 417

  box->progress = gtk_progress_bar_new ();
418
  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), "Fog");
419
  gtk_box_pack_end (GTK_BOX (vbox2), box->progress, FALSE, FALSE, 0);
420
  gtk_widget_set_no_show_all (box->progress, TRUE);
421 422
  /* don't gtk_widget_show (box->progress); */

423 424 425 426 427
  gtk_widget_set_size_request (GTK_WIDGET (box),
                               MAX ((gint) GIMP_THUMB_SIZE_NORMAL,
                                    (gint) context->gimp->config->thumbnail_size) +
                               2 * MAX (h, v),
                               -1);
428

429 430 431 432
  return GTK_WIDGET (box);
}

void
433 434
gimp_thumb_box_take_file (GimpThumbBox *box,
                          GFile        *file)
435 436
{
  g_return_if_fail (GIMP_IS_THUMB_BOX (box));
437
  g_return_if_fail (file == NULL || G_IS_FILE (file));
438

439 440 441 442 443 444
  if (box->idle_id)
    {
      g_source_remove (box->idle_id);
      box->idle_id = 0;
    }

445
  gimp_imagefile_set_file (box->imagefile, file);
446

447
  if (file)
448
    {
449
      gchar *basename = g_path_get_basename (gimp_file_get_utf8_name (file));
450
      gtk_label_set_text (GTK_LABEL (box->filename), basename);
451 452 453 454
      g_free (basename);
    }
  else
    {
455
      gtk_label_set_text (GTK_LABEL (box->filename), _("No selection"));
456 457
    }

458
  gtk_widget_set_sensitive (GTK_WIDGET (box), file != NULL);
459 460 461 462
  gimp_imagefile_update (box->imagefile);
}

void
463 464
gimp_thumb_box_take_files (GimpThumbBox *box,
                           GSList       *files)
465 466 467
{
  g_return_if_fail (GIMP_IS_THUMB_BOX (box));

468
  if (box->files)
469
    {
470 471
      g_slist_free_full (box->files, (GDestroyNotify) g_object_unref);
      box->files = NULL;
472 473
    }

474
  box->files = files;
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
}


/*  private functions  */

static gboolean
gimp_thumb_box_ebox_button_press (GtkWidget      *widget,
                                  GdkEventButton *bevent,
                                  GimpThumbBox   *box)
{
  gimp_thumb_box_thumbnail_clicked (widget, bevent->state, box);

  return TRUE;
}

static void
gimp_thumb_box_thumbnail_clicked (GtkWidget       *widget,
                                  GdkModifierType  state,
                                  GimpThumbBox    *box)
{
  gimp_thumb_box_create_thumbnails (box,
496 497
                                    (state & gimp_get_toggle_behavior_mask ()) ?
                                    TRUE : FALSE);
498 499
}

500 501 502 503 504 505 506 507 508 509 510 511
static void
this_is_ugly (GtkWidget     *widget,
              GtkAllocation *allocation,
              gpointer       data)
{
  gtk_widget_queue_resize (widget);

  g_signal_handlers_disconnect_by_func (widget,
                                        this_is_ugly,
                                        data);
}

512 513 514 515
static void
gimp_thumb_box_imagefile_info_changed (GimpImagefile *imagefile,
                                       GimpThumbBox  *box)
{
516
  gtk_label_set_text (GTK_LABEL (box->info),
517
                      gimp_imagefile_get_desc_string (imagefile));
518 519 520 521

  g_signal_connect_after (box->info, "size-allocate",
                          G_CALLBACK (this_is_ugly),
                          "this too");
522 523
}

524 525 526 527 528 529 530 531
static void
gimp_thumb_box_thumb_state_notify (GimpThumbnail *thumb,
                                   GParamSpec    *pspec,
                                   GimpThumbBox  *box)
{
  if (box->idle_id)
    return;

532 533 534
  if (thumb->image_state == GIMP_THUMB_STATE_REMOTE)
    return;

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
  switch (thumb->thumb_state)
    {
    case GIMP_THUMB_STATE_NOT_FOUND:
    case GIMP_THUMB_STATE_OLD:
      box->idle_id =
        g_idle_add_full (G_PRIORITY_LOW,
                         (GSourceFunc) gimp_thumb_box_auto_thumbnail,
                         box, NULL);
      break;

    default:
      break;
    }
}

550 551
static void
gimp_thumb_box_create_thumbnails (GimpThumbBox *box,
552
                                  gboolean      force)
553
{
554
  Gimp           *gimp     = box->context->gimp;
555 556
  GimpProgress   *progress = GIMP_PROGRESS (box);
  GimpFileDialog *dialog   = NULL;
557
  GtkWidget      *toplevel;
558
  GSList         *list;
559
  gint            n_files;
560
  gint            i;
561

562
  if (gimp->config->thumbnail_size == GIMP_THUMBNAIL_SIZE_NONE)
563
    return;
564

565
  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (box));
566

567 568
  if (GIMP_IS_FILE_DIALOG (toplevel))
    dialog = GIMP_FILE_DIALOG (toplevel);
569

570
  gimp_set_busy (gimp);
571

572 573 574 575
  if (dialog)
    gimp_file_dialog_set_sensitive (dialog, FALSE);
  else
    gtk_widget_set_sensitive (toplevel, FALSE);
576

577
  if (box->files)
578 579 580 581
    {
      gtk_widget_hide (box->info);
      gtk_widget_show (box->progress);
    }
582

583
  n_files = g_slist_length (box->files);
584

585
  if (n_files > 1)
586 587
    {
      gchar *str;
588

589
      gimp_progress_start (GIMP_PROGRESS (box), TRUE, "%s", "");
Sven Neumann's avatar
Sven Neumann committed
590 591

      progress = gimp_sub_progress_new (GIMP_PROGRESS (box));
592

593
      gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress), 0, n_files);
594

595
      for (list = box->files->next, i = 1;
596 597 598
           list;
           list = g_slist_next (list), i++)
        {
599
          str = g_strdup_printf (_("Thumbnail %d of %d"), i, n_files);
600
          gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), str);
601 602
          g_free (str);

603 604
          gimp_progress_set_value (progress, 0.0);

605 606
          while (gtk_events_pending ())
            gtk_main_iteration ();
607 608

          gimp_thumb_box_create_thumbnail (box,
609
                                           list->data,
610
                                           gimp->config->thumbnail_size,
611 612
                                           force,
                                           progress);
613

614 615
          if (dialog && dialog->canceled)
            goto canceled;
616

617
          gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (progress), i, n_files);
618 619
        }

620
      str = g_strdup_printf (_("Thumbnail %d of %d"), n_files, n_files);
621
      gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), str);
622 623
      g_free (str);

624 625
      gimp_progress_set_value (progress, 0.0);

626 627
      while (gtk_events_pending ())
        gtk_main_iteration ();
628 629
    }

630
  if (box->files)
631 632
    {
      gimp_thumb_box_create_thumbnail (box,
633
                                       box->files->data,
634
                                       gimp->config->thumbnail_size,
635 636
                                       force,
                                       progress);
637

638
      gimp_progress_set_value (progress, 1.0);
639
    }
640

641
 canceled:
642

643
  if (n_files > 1)
Sven Neumann's avatar
Sven Neumann committed
644 645 646 647 648 649
    {
      g_object_unref (progress);

      gimp_progress_end (GIMP_PROGRESS (box));
      gtk_progress_bar_set_text (GTK_PROGRESS_BAR (box->progress), "");
    }
650

651
  if (box->files)
652
    {
653
      gtk_widget_hide (box->progress);
654
      gtk_widget_show (box->info);
655
    }
656 657 658 659 660 661 662

  if (dialog)
    gimp_file_dialog_set_sensitive (dialog, TRUE);
  else
    gtk_widget_set_sensitive (toplevel, TRUE);

  gimp_unset_busy (gimp);
663 664 665 666
}

static void
gimp_thumb_box_create_thumbnail (GimpThumbBox      *box,
667
                                 GFile             *file,
668
                                 GimpThumbnailSize  size,
669 670
                                 gboolean           force,
                                 GimpProgress      *progress)
671
{
672
  GimpThumbnail *thumb = gimp_imagefile_get_thumbnail (box->imagefile);
673
  gchar         *basename;
674

675
  basename = g_path_get_basename (gimp_file_get_utf8_name (file));
676 677 678
  gtk_label_set_text (GTK_LABEL (box->filename), basename);
  g_free (basename);

679
  gimp_imagefile_set_file (box->imagefile, file);
680

681
  if (force ||
682
      (gimp_thumbnail_peek_thumb (thumb, (GimpThumbSize) size) < GIMP_THUMB_STATE_FAILED &&
683 684
       ! gimp_thumbnail_has_failed (thumb)))
    {
685 686 687 688 689 690 691
      GError *error = NULL;

      if (! gimp_imagefile_create_thumbnail (box->imagefile, box->context,
                                             progress,
                                             size, ! force, &error))
        {
          gimp_message_literal (box->context->gimp,
692 693
                                G_OBJECT (progress), GIMP_MESSAGE_ERROR,
                                error->message);
694 695
          g_clear_error (&error);
        }
696
    }
697
}
698 699

static gboolean
700
gimp_thumb_box_auto_thumbnail (GimpThumbBox *box)
701
{
702 703
  Gimp          *gimp  = box->context->gimp;
  GimpThumbnail *thumb = gimp_imagefile_get_thumbnail (box->imagefile);
704
  GFile         *file  = gimp_imagefile_get_file (box->imagefile);
705

706
  box->idle_id = 0;
707

708 709 710
  if (thumb->image_state == GIMP_THUMB_STATE_NOT_FOUND)
    return FALSE;

711 712 713 714 715
  switch (thumb->thumb_state)
    {
    case GIMP_THUMB_STATE_NOT_FOUND:
    case GIMP_THUMB_STATE_OLD:
      if (thumb->image_filesize < gimp->config->thumbnail_filesize_limit &&
716
          ! gimp_thumbnail_has_failed (thumb)                            &&
717 718 719
          gimp_plug_in_manager_file_procedure_find_by_extension (gimp->plug_in_manager,
                                                                 GIMP_FILE_PROCEDURE_GROUP_OPEN,
                                                                 file))
720
        {
721 722 723 724 725
          if (thumb->image_filesize > 0)
            {
              gchar *size;
              gchar *text;

726
              size = g_format_size (thumb->image_filesize);
727
              text = g_strdup_printf ("%s\n%s",
728
                                      size, _("Creating preview..."));
729 730 731 732 733 734 735 736 737

              gtk_label_set_text (GTK_LABEL (box->info), text);

              g_free (text);
              g_free (size);
            }
          else
            {
              gtk_label_set_text (GTK_LABEL (box->info),
738
                                  _("Creating preview..."));
739 740
            }

741
          gimp_imagefile_create_thumbnail_weak (box->imagefile, box->context,
742
                                                GIMP_PROGRESS (box),
743 744
                                                gimp->config->thumbnail_size,
                                                TRUE);
745 746 747 748 749 750 751 752 753
        }
      break;

    default:
      break;
    }

  return FALSE;
}