testfilechooser.c 19.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* testfilechooser.c
 * Copyright (C) 2003  Red Hat, Inc.
 * Author: Owen Taylor
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
Javier Jardón's avatar
Javier Jardón committed
16
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
 */
18
#include "config.h"
19

Owen Taylor's avatar
Owen Taylor committed
20
#include <string.h>
21 22 23 24
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
25
#ifdef HAVE_UNISTD_H
26
#include <unistd.h>
27
#endif
Owen Taylor's avatar
Owen Taylor committed
28
#include <gtk/gtk.h>
29 30 31

#ifdef G_OS_WIN32
#  include <io.h>
32
#  define localtime_r(t,b) *(b) = *localtime (t)
33 34 35 36 37
#  ifndef S_ISREG
#    define S_ISREG(m) ((m) & _S_IFREG)
#  endif
#endif

Owen Taylor's avatar
Owen Taylor committed
38 39
#include "prop-editor.h"

40 41
static GtkWidget *preview_label;
static GtkWidget *preview_image;
42
static GtkFileChooserAction action;
43

Owen Taylor's avatar
Owen Taylor committed
44 45 46 47 48 49
static void
print_current_folder (GtkFileChooser *chooser)
{
  gchar *uri;

  uri = gtk_file_chooser_get_current_folder_uri (chooser);
50
  g_print ("Current folder changed :\n  %s\n", uri ? uri : "(null)");
Owen Taylor's avatar
Owen Taylor committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  g_free (uri);
}

static void
print_selected (GtkFileChooser *chooser)
{
  GSList *uris = gtk_file_chooser_get_uris (chooser);
  GSList *tmp_list;

  g_print ("Selection changed :\n");
  for (tmp_list = uris; tmp_list; tmp_list = tmp_list->next)
    {
      gchar *uri = tmp_list->data;
      g_print ("  %s\n", uri);
      g_free (uri);
    }
  g_print ("\n");
  g_slist_free (uris);
}

71 72 73 74
static void
response_cb (GtkDialog *dialog,
	     gint       response_id)
{
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
  if (response_id == GTK_RESPONSE_OK)
    {
      GSList *list;

      list = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));

      if (list)
	{
	  GSList *l;

	  g_print ("Selected files:\n");

	  for (l = list; l; l = l->next)
	    {
	      g_print ("%s\n", (char *) l->data);
	      g_free (l->data);
	    }

	  g_slist_free (list);
	}
      else
	g_print ("No selected files\n");
    }
  else
    g_print ("Dialog was closed\n");
100

101 102 103
  gtk_main_quit ();
}

Owen Taylor's avatar
Owen Taylor committed
104 105 106 107
static gboolean
no_backup_files_filter (const GtkFileFilterInfo *filter_info,
			gpointer                 data)
{
108
  gsize len = filter_info->display_name ? strlen (filter_info->display_name) : 0;
Owen Taylor's avatar
Owen Taylor committed
109 110 111 112 113 114
  if (len > 0 && filter_info->display_name[len - 1] == '~')
    return 0;
  else
    return 1;
}

115 116 117 118 119 120 121
static void
filter_changed (GtkFileChooserDialog *dialog,
		gpointer              data)
{
  g_print ("file filter changed\n");
}

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
static char *
format_time (time_t t)
{
  gchar buf[128];
  struct tm tm_buf;
  time_t now = time (NULL);
  const char *format;

  if (abs (now - t) < 24*60*60)
    format = "%X";
  else
    format = "%x";

  localtime_r (&t, &tm_buf);
  if (strftime (buf, sizeof (buf), format, &tm_buf) == 0)
    return g_strdup ("<unknown>");
  else
    return g_strdup (buf);
}

static char *
format_size (gint64 size)
{
  if (size < (gint64)1024)
    return g_strdup_printf ("%d bytes", (gint)size);
  else if (size < (gint64)1024*1024)
    return g_strdup_printf ("%.1f K", size / (1024.));
  else if (size < (gint64)1024*1024*1024)
    return g_strdup_printf ("%.1f M", size / (1024.*1024.));
  else
    return g_strdup_printf ("%.1f G", size / (1024.*1024.*1024.));
}

#include <stdio.h>
#include <errno.h>
#define _(s) (s)

static void
160
size_prepared_cb (GdkPixbufLoader *loader,
161 162
		  int              width,
		  int              height,
163
		  int             *data)
164
{
165 166 167 168 169 170 171 172
	int des_width = data[0];
	int des_height = data[1];

	if (des_height >= height && des_width >= width) {
		/* Nothing */
	} else if ((double)height * des_width > (double)width * des_height) {
		width = 0.5 + (double)width * des_height / (double)height;
		height = des_height;
173
	} else {
174 175
		height = 0.5 + (double)height * des_width / (double)width;
		width = des_width;
176 177 178 179 180 181 182
	}

	gdk_pixbuf_loader_set_size (loader, width, height);
}

GdkPixbuf *
my_new_from_file_at_size (const char *filename,
183
			  int         width,
184 185 186 187 188
			  int         height,
			  GError    **error)
{
	GdkPixbufLoader *loader;
	GdkPixbuf       *pixbuf;
189
	int              info[2];
190
	struct stat st;
191 192 193 194 195 196 197 198

	guchar buffer [4096];
	int length;
	FILE *f;

	g_return_val_if_fail (filename != NULL, NULL);
        g_return_val_if_fail (width > 0 && height > 0, NULL);

199
	if (stat (filename, &st) != 0) {
200 201
                int errsv = errno;

202 203
		g_set_error (error,
			     G_FILE_ERROR,
204
			     g_file_error_from_errno (errsv),
205
			     _("Could not get information for file '%s': %s"),
206
			     filename, g_strerror (errsv));
207 208 209 210 211 212
		return NULL;
	}

	if (!S_ISREG (st.st_mode))
		return NULL;

213 214
	f = fopen (filename, "rb");
	if (!f) {
215 216
                int errsv = errno;

217 218
                g_set_error (error,
                             G_FILE_ERROR,
219
                             g_file_error_from_errno (errsv),
220
                             _("Failed to open file '%s': %s"),
221
                             filename, g_strerror (errsv));
222 223
		return NULL;
        }
224

225 226 227 228
	loader = gdk_pixbuf_loader_new ();
#ifdef DONT_PRESERVE_ASPECT
	gdk_pixbuf_loader_set_size (loader, width, height);
#else
229 230 231
	info[0] = width;
	info[1] = height;
	g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), info);
232
#endif
233 234 235 236 237 238 239

	while (!feof (f)) {
		length = fread (buffer, 1, sizeof (buffer), f);
		if (length > 0)
			if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) {
			        gdk_pixbuf_loader_close (loader, NULL);
				fclose (f);
240
				g_object_unref (loader);
241 242 243 244 245 246
				return NULL;
			}
	}

	fclose (f);

247
	g_assert (*error == NULL);
248
	if (!gdk_pixbuf_loader_close (loader, error)) {
249
		g_object_unref (loader);
250 251 252 253 254 255
		return NULL;
	}

	pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);

	if (!pixbuf) {
256
		g_object_unref (loader);
257 258 259 260 261

		/* did the loader set an error? */
		if (*error != NULL)
			return NULL;

262 263 264 265 266 267 268 269 270 271
		g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_FAILED,
                             _("Failed to load image '%s': reason not known, probably a corrupt image file"),
                             filename);
		return NULL;
	}

	g_object_ref (pixbuf);

272
	g_object_unref (loader);
273 274 275 276 277 278 279 280 281

	return pixbuf;
}

static void
update_preview_cb (GtkFileChooser *chooser)
{
  gchar *filename = gtk_file_chooser_get_preview_filename (chooser);
  gboolean have_preview = FALSE;
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
  if (filename)
    {
      GdkPixbuf *pixbuf;
      GError *error = NULL;

      pixbuf = my_new_from_file_at_size (filename, 128, 128, &error);
      if (pixbuf)
	{
	  gtk_image_set_from_pixbuf (GTK_IMAGE (preview_image), pixbuf);
	  g_object_unref (pixbuf);
	  gtk_widget_show (preview_image);
	  gtk_widget_hide (preview_label);
	  have_preview = TRUE;
	}
      else
	{
	  struct stat buf;
	  if (stat (filename, &buf) == 0)
	    {
	      gchar *preview_text;
	      gchar *size_str;
	      gchar *modified_time;
305

306 307
	      size_str = format_size (buf.st_size);
	      modified_time = format_time (buf.st_mtime);
308

309 310 311 312 313 314 315 316
	      preview_text = g_strdup_printf ("<i>Modified:</i>\t%s\n"
					      "<i>Size:</i>\t%s\n",
					      modified_time,
					      size_str);
	      gtk_label_set_markup (GTK_LABEL (preview_label), preview_text);
	      g_free (modified_time);
	      g_free (size_str);
	      g_free (preview_text);
317

318 319 320 321 322
	      gtk_widget_hide (preview_image);
	      gtk_widget_show (preview_label);
	      have_preview = TRUE;
	    }
	}
323

324
      g_free (filename);
Morten Welinder's avatar
Morten Welinder committed
325 326 327

      if (error)
	g_error_free (error);
328 329 330 331 332
    }

  gtk_file_chooser_set_preview_widget_active (chooser, have_preview);
}

333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
static void
set_current_folder (GtkFileChooser *chooser,
		    const char     *name)
{
  if (!gtk_file_chooser_set_current_folder (chooser, name))
    {
      GtkWidget *dialog;

      dialog = gtk_message_dialog_new (GTK_WINDOW (chooser),
				       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				       GTK_MESSAGE_ERROR,
				       GTK_BUTTONS_CLOSE,
				       "Could not set the folder to %s",
				       name);
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
    }
}

352
static void
353
set_folder_nonexistent_cb (GtkButton      *button,
354 355
			   GtkFileChooser *chooser)
{
356
  set_current_folder (chooser, "/nonexistent");
357 358 359
}

static void
360
set_folder_existing_nonexistent_cb (GtkButton      *button,
361 362
				    GtkFileChooser *chooser)
{
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
  set_current_folder (chooser, "/usr/nonexistent");
}

static void
set_filename (GtkFileChooser *chooser,
	      const char     *name)
{
  if (!gtk_file_chooser_set_filename (chooser, name))
    {
      GtkWidget *dialog;

      dialog = gtk_message_dialog_new (GTK_WINDOW (chooser),
				       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				       GTK_MESSAGE_ERROR,
				       GTK_BUTTONS_CLOSE,
				       "Could not select %s",
				       name);
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
    }
383 384 385
}

static void
386
set_filename_nonexistent_cb (GtkButton      *button,
387 388
			     GtkFileChooser *chooser)
{
389
  set_filename (chooser, "/nonexistent");
390 391 392
}

static void
393
set_filename_existing_nonexistent_cb (GtkButton      *button,
394 395
				      GtkFileChooser *chooser)
{
396
  set_filename (chooser, "/usr/nonexistent");
397 398
}

399 400 401 402 403 404 405 406
static void
unmap_and_remap_cb (GtkButton *button,
		    GtkFileChooser *chooser)
{
  gtk_widget_hide (GTK_WIDGET (chooser));
  gtk_widget_show (GTK_WIDGET (chooser));
}

407
static void
408
kill_dependent (GtkWindow *win, GtkWidget *dep)
409
{
410
  gtk_widget_destroy (dep);
411 412 413
  g_object_unref (dep);
}

414 415 416 417 418 419 420 421
static void
notify_multiple_cb (GtkWidget  *dialog,
		    GParamSpec *pspec,
		    GtkWidget  *button)
{
  gboolean multiple;

  multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (dialog));
422

423 424 425
  gtk_widget_set_sensitive (button, multiple);
}

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
static GtkFileChooserConfirmation
confirm_overwrite_cb (GtkFileChooser *chooser,
		      gpointer        data)
{
  GtkWidget *dialog;
  GtkWidget *button;
  int response;
  GtkFileChooserConfirmation conf;

  dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))),
				   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
				   GTK_MESSAGE_QUESTION,
				   GTK_BUTTONS_NONE,
				   "What do you want to do?");

  button = gtk_button_new_with_label ("Use the stock confirmation dialog");
  gtk_widget_show (button);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 1);

  button = gtk_button_new_with_label ("Type a new file name");
  gtk_widget_show (button);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 2);

  button = gtk_button_new_with_label ("Accept the file name");
  gtk_widget_show (button);
  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 3);

  response = gtk_dialog_run (GTK_DIALOG (dialog));

  switch (response)
    {
    case 1:
      conf = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM;
      break;

    case 3:
      conf = GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME;
      break;

    default:
      conf = GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN;
      break;
    }

  gtk_widget_destroy (dialog);

  return conf;
}

Owen Taylor's avatar
Owen Taylor committed
475 476 477 478 479 480 481
int
main (int argc, char **argv)
{
  GtkWidget *control_window;
  GtkWidget *vbbox;
  GtkWidget *button;
  GtkWidget *dialog;
482
  GtkWidget *extra;
Owen Taylor's avatar
Owen Taylor committed
483
  GtkFileFilter *filter;
484
  GtkWidget *preview_vbox;
485
  gboolean force_rtl = FALSE;
486
  gboolean multiple = FALSE;
487
  char *action_arg = NULL;
488
  char *initial_filename = NULL;
489
  char *initial_folder = NULL;
490 491
  GError *error = NULL;
  GOptionEntry options[] = {
492
    { "action", 'a', 0, G_OPTION_ARG_STRING, &action_arg, "Filechooser action", "ACTION" },
493 494
    { "multiple", 'm', 0, G_OPTION_ARG_NONE, &multiple, "Select-multiple", NULL },
    { "right-to-left", 'r', 0, G_OPTION_ARG_NONE, &force_rtl, "Force right-to-left layout.", NULL },
495
    { "initial-filename", 'f', 0, G_OPTION_ARG_FILENAME, &initial_filename, "Initial filename to select", "FILENAME" },
496
    { "initial-folder", 'F', 0, G_OPTION_ARG_FILENAME, &initial_folder, "Initial folder to show", "FILENAME" },
497 498 499 500 501 502 503 504 505
    { NULL }
  };

  if (!gtk_init_with_args (&argc, &argv, "", options, NULL, &error))
    {
      g_print ("Failed to parse args: %s\n", error->message);
      g_error_free (error);
      return 1;
    }
506

507 508 509 510 511 512
  if (initial_filename && initial_folder)
    {
      g_print ("Only one of --initial-filename and --initial-folder may be specified");
      return 1;
    }

513
  if (force_rtl)
514
    gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
515

516 517
  action = GTK_FILE_CHOOSER_ACTION_OPEN;

518
  if (action_arg != NULL)
519
    {
520
      if (! strcmp ("open", action_arg))
521
	action = GTK_FILE_CHOOSER_ACTION_OPEN;
522
      else if (! strcmp ("save", action_arg))
523
	action = GTK_FILE_CHOOSER_ACTION_SAVE;
524
      else if (! strcmp ("select_folder", action_arg))
525
	action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
526
      else if (! strcmp ("create_folder", action_arg))
527
	action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
528 529

      g_free (action_arg);
530 531
    }

532
  dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
533
			 "action", action,
534
			 "select-multiple", multiple,
535
			 NULL);
536

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
  switch (action)
    {
    case GTK_FILE_CHOOSER_ACTION_OPEN:
    case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
      gtk_window_set_title (GTK_WINDOW (dialog), "Select a file");
      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
			      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			      GTK_STOCK_OPEN, GTK_RESPONSE_OK,
			      NULL);
      break;
    case GTK_FILE_CHOOSER_ACTION_SAVE:
    case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
      gtk_window_set_title (GTK_WINDOW (dialog), "Save a file");
      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
			      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			      GTK_STOCK_SAVE, GTK_RESPONSE_OK,
			      NULL);
      break;
    }
556
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
557

558
  g_signal_connect (dialog, "selection-changed",
Owen Taylor's avatar
Owen Taylor committed
559
		    G_CALLBACK (print_selected), NULL);
560
  g_signal_connect (dialog, "current-folder-changed",
Owen Taylor's avatar
Owen Taylor committed
561
		    G_CALLBACK (print_current_folder), NULL);
562 563
  g_signal_connect (dialog, "response",
		    G_CALLBACK (response_cb), NULL);
564 565
  g_signal_connect (dialog, "confirm-overwrite",
		    G_CALLBACK (confirm_overwrite_cb), NULL);
Owen Taylor's avatar
Owen Taylor committed
566 567 568 569 570 571

  /* Filters */
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "All Files");
  gtk_file_filter_add_pattern (filter, "*");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
572

Owen Taylor's avatar
Owen Taylor committed
573 574 575 576 577 578 579
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "No backup files");
  gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_DISPLAY_NAME,
			      no_backup_files_filter, NULL, NULL);
  gtk_file_filter_add_mime_type (filter, "image/png");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);

Matthias Clasen's avatar
Matthias Clasen committed
580 581 582 583 584
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "Starts with D");
  gtk_file_filter_add_pattern (filter, "D*");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);

585
  g_signal_connect (dialog, "notify::filter",
586 587
		    G_CALLBACK (filter_changed), NULL);

Owen Taylor's avatar
Owen Taylor committed
588 589
  /* Make this filter the default */
  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
590

Owen Taylor's avatar
Owen Taylor committed
591 592 593 594 595 596
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "PNG and JPEG");
  gtk_file_filter_add_mime_type (filter, "image/jpeg");
  gtk_file_filter_add_mime_type (filter, "image/png");
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);

597 598 599 600
  filter = gtk_file_filter_new ();
  gtk_file_filter_set_name (filter, "Images");
  gtk_file_filter_add_pixbuf_formats (filter);
  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
601

602
  /* Preview widget */
603 604
  /* THIS IS A TERRIBLE PREVIEW WIDGET, AND SHOULD NOT BE COPIED AT ALL.
   */
605
  preview_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
606
  /*gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), preview_vbox);*/
607

608 609
  preview_label = gtk_label_new (NULL);
  gtk_box_pack_start (GTK_BOX (preview_vbox), preview_label, TRUE, TRUE, 0);
610
  g_object_set (preview_label, "margin", 6, NULL);
611

612 613
  preview_image = gtk_image_new ();
  gtk_box_pack_start (GTK_BOX (preview_vbox), preview_image, TRUE, TRUE, 0);
614
  g_object_set (preview_image, "margin", 6, NULL);
615

616 617 618
  update_preview_cb (GTK_FILE_CHOOSER (dialog));
  g_signal_connect (dialog, "update-preview",
		    G_CALLBACK (update_preview_cb), NULL);
619 620

  /* Extra widget */
621

622 623 624
  extra = gtk_check_button_new_with_mnemonic ("Lar_t whoever asks about this button");
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (extra), TRUE);
  gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), extra);
625 626 627 628 629 630 631

  /* Shortcuts */

  gtk_file_chooser_add_shortcut_folder_uri (GTK_FILE_CHOOSER (dialog),
					    "file:///usr/share/pixmaps",
					    NULL);

632
  /* Initial filename or folder */
633 634 635 636

  if (initial_filename)
    set_filename (GTK_FILE_CHOOSER (dialog), initial_filename);

637 638 639
  if (initial_folder)
    set_current_folder (GTK_FILE_CHOOSER (dialog), initial_folder);

Owen Taylor's avatar
Owen Taylor committed
640 641
  /* show_all() to reveal bugs in composite widget handling */
  gtk_widget_show_all (dialog);
Owen Taylor's avatar
Owen Taylor committed
642

643 644
  /* Extra controls for manipulating the test environment
   */
645
  create_prop_editor (G_OBJECT (dialog), GTK_TYPE_FILE_CHOOSER);
Owen Taylor's avatar
Owen Taylor committed
646 647

  control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
648

649
  vbbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
Owen Taylor's avatar
Owen Taylor committed
650 651 652
  gtk_container_add (GTK_CONTAINER (control_window), vbbox);

  button = gtk_button_new_with_mnemonic ("_Select all");
653
  gtk_widget_set_sensitive (button, multiple);
Owen Taylor's avatar
Owen Taylor committed
654 655 656
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect_swapped (button, "clicked",
			    G_CALLBACK (gtk_file_chooser_select_all), dialog);
657
  g_signal_connect (dialog, "notify::select-multiple",
658
		    G_CALLBACK (notify_multiple_cb), button);
659

Owen Taylor's avatar
Owen Taylor committed
660 661 662 663 664
  button = gtk_button_new_with_mnemonic ("_Unselect all");
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect_swapped (button, "clicked",
			    G_CALLBACK (gtk_file_chooser_unselect_all), dialog);

665 666 667 668 669
  button = gtk_button_new_with_label ("set_current_folder (\"/nonexistent\")");
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect (button, "clicked",
		    G_CALLBACK (set_folder_nonexistent_cb), dialog);

670
  button = gtk_button_new_with_label ("set_current_folder (\"/usr/nonexistent\")");
671 672 673 674
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect (button, "clicked",
		    G_CALLBACK (set_folder_existing_nonexistent_cb), dialog);

675
  button = gtk_button_new_with_label ("set_filename (\"/nonexistent\")");
676 677 678 679
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect (button, "clicked",
		    G_CALLBACK (set_filename_nonexistent_cb), dialog);

680
  button = gtk_button_new_with_label ("set_filename (\"/usr/nonexistent\")");
681 682 683 684
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect (button, "clicked",
		    G_CALLBACK (set_filename_existing_nonexistent_cb), dialog);

685 686 687 688 689
  button = gtk_button_new_with_label ("Unmap and remap");
  gtk_container_add (GTK_CONTAINER (vbbox), button);
  g_signal_connect (button, "clicked",
		    G_CALLBACK (unmap_and_remap_cb), dialog);

Owen Taylor's avatar
Owen Taylor committed
690
  gtk_widget_show_all (control_window);
691 692

  g_object_ref (control_window);
693
  g_signal_connect (dialog, "destroy",
694 695 696 697 698 699
		    G_CALLBACK (kill_dependent), control_window);

  /* We need to hold a ref until we have destroyed the widgets, just in case
   * someone else destroys them.  We explicitly destroy windows to catch leaks.
   */
  g_object_ref (dialog);
Owen Taylor's avatar
Owen Taylor committed
700
  gtk_main ();
701 702
  gtk_widget_destroy (dialog);
  g_object_unref (dialog);
Owen Taylor's avatar
Owen Taylor committed
703 704 705

  return 0;
}