]> Pileus Git - ~andy/gtk/blob - gtk/gtkfilechooserdialog.c
Set the HIG spacings directly instead of using style-set handlers. Fix the
[~andy/gtk] / gtk / gtkfilechooserdialog.c
1 /* GTK - The GIMP Toolkit
2  * gtkfilechooserdialog.c: File selector dialog
3  * Copyright (C) 2003, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22 #include "gtkfilechooserprivate.h"
23 #include "gtkfilechooserdialog.h"
24 #include "gtkfilechooserwidget.h"
25 #include "gtkfilechooserutils.h"
26 #include "gtkfilechooserembed.h"
27 #include "gtkfilesystem.h"
28 #include "gtktypebuiltins.h"
29 #include "gtkintl.h"
30 #include "gtkalias.h"
31
32 #include <stdarg.h>
33
34 #define GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE(o)  (GTK_FILE_CHOOSER_DIALOG (o)->priv)
35
36 static void gtk_file_chooser_dialog_finalize   (GObject                   *object);
37
38 static GObject* gtk_file_chooser_dialog_constructor  (GType                  type,
39                                                       guint                  n_construct_properties,
40                                                       GObjectConstructParam *construct_params);
41 static void     gtk_file_chooser_dialog_set_property (GObject               *object,
42                                                       guint                  prop_id,
43                                                       const GValue          *value,
44                                                       GParamSpec            *pspec);
45 static void     gtk_file_chooser_dialog_get_property (GObject               *object,
46                                                       guint                  prop_id,
47                                                       GValue                *value,
48                                                       GParamSpec            *pspec);
49
50 static void     gtk_file_chooser_dialog_map          (GtkWidget             *widget);
51 static void     gtk_file_chooser_dialog_unmap        (GtkWidget             *widget);
52
53 static void response_cb (GtkDialog *dialog,
54                          gint       response_id);
55
56 G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDialog, gtk_file_chooser_dialog, GTK_TYPE_DIALOG,
57                          G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
58                                                 _gtk_file_chooser_delegate_iface_init))
59
60 static void
61 gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class)
62 {
63   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
64   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
65
66   gobject_class->constructor = gtk_file_chooser_dialog_constructor;
67   gobject_class->set_property = gtk_file_chooser_dialog_set_property;
68   gobject_class->get_property = gtk_file_chooser_dialog_get_property;
69   gobject_class->finalize = gtk_file_chooser_dialog_finalize;
70
71   widget_class->map       = gtk_file_chooser_dialog_map;
72   widget_class->unmap     = gtk_file_chooser_dialog_unmap;
73
74   _gtk_file_chooser_install_properties (gobject_class);
75
76   g_type_class_add_private (class, sizeof (GtkFileChooserDialogPrivate));
77 }
78
79 static void
80 gtk_file_chooser_dialog_init (GtkFileChooserDialog *dialog)
81 {
82   GtkFileChooserDialogPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (dialog,
83                                                                    GTK_TYPE_FILE_CHOOSER_DIALOG,
84                                                                    GtkFileChooserDialogPrivate);
85   GtkDialog *fc_dialog = GTK_DIALOG (dialog);
86
87   dialog->priv = priv;
88   dialog->priv->default_width = -1;
89   dialog->priv->default_height = -1;
90   dialog->priv->resize_horizontally = TRUE;
91   dialog->priv->resize_vertically = TRUE;
92   dialog->priv->response_requested = FALSE;
93
94   gtk_dialog_set_has_separator (fc_dialog, FALSE);
95   gtk_container_set_border_width (GTK_CONTAINER (fc_dialog), 5);
96   gtk_box_set_spacing (GTK_BOX (fc_dialog->vbox), 2); /* 2 * 5 + 2 = 12 */
97   gtk_container_set_border_width (GTK_CONTAINER (fc_dialog->action_area), 5);
98
99   /* We do a signal connection here rather than overriding the method in
100    * class_init because GtkDialog::response is a RUN_LAST signal.  We want *our*
101    * handler to be run *first*, regardless of whether the user installs response
102    * handlers of his own.
103    */
104   g_signal_connect (dialog, "response",
105                     G_CALLBACK (response_cb), NULL);
106 }
107
108 static void
109 gtk_file_chooser_dialog_finalize (GObject *object)
110 {
111   GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (object);
112
113   g_free (dialog->priv->file_system);
114
115   G_OBJECT_CLASS (gtk_file_chooser_dialog_parent_class)->finalize (object);  
116 }
117
118 /* Callback used when the user activates a file in the file chooser widget */
119 static void
120 file_chooser_widget_file_activated (GtkFileChooser       *chooser,
121                                     GtkFileChooserDialog *dialog)
122 {
123   GList *children, *l;
124
125   if (gtk_window_activate_default (GTK_WINDOW (dialog)))
126     return;
127
128   /* There probably isn't a default widget, so make things easier for the
129    * programmer by looking for a reasonable button on our own.
130    */
131
132   children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
133
134   for (l = children; l; l = l->next)
135     {
136       GtkWidget *widget;
137       int response_id;
138
139       widget = GTK_WIDGET (l->data);
140       response_id = gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
141       if (response_id == GTK_RESPONSE_ACCEPT
142           || response_id == GTK_RESPONSE_OK
143           || response_id == GTK_RESPONSE_YES
144           || response_id == GTK_RESPONSE_APPLY)
145         {
146           gtk_widget_activate (widget); /* Should we gtk_dialog_response (dialog, response_id) instead? */
147           break;
148         }
149     }
150
151   g_list_free (children);
152 }
153
154 static void
155 file_chooser_widget_update_hints (GtkFileChooserDialog *dialog)
156 {
157   GtkFileChooserDialogPrivate *priv;
158   GdkGeometry geometry;
159
160   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
161
162   geometry.min_width = -1;
163   geometry.min_height = -1;
164   geometry.max_width = (priv->resize_horizontally?G_MAXSHORT:-1);
165   geometry.max_height = (priv->resize_vertically?G_MAXSHORT:-1);
166
167   gtk_window_set_geometry_hints (GTK_WINDOW (dialog), NULL,
168                                  &geometry,
169                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
170 }
171
172 static void
173 clamp_to_screen (GtkWidget *widget,
174                  gint      *width,
175                  gint      *height)
176 {
177   GdkScreen *screen;
178   int monitor_num;
179   GdkRectangle monitor;
180
181   g_return_if_fail (GTK_WIDGET_REALIZED (widget));
182   
183   screen = gtk_widget_get_screen (widget);
184   monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
185
186   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
187
188   if (width)
189     *width = MIN (*width, (monitor.width * 3) / 4);
190
191   if (height)
192     *height = MIN (*height, (monitor.height * 3) / 4);
193 }
194
195 static void
196 file_chooser_widget_default_realized_size_changed (GtkWidget            *widget,
197                                                    GtkFileChooserDialog *dialog)
198 {
199   GtkFileChooserDialogPrivate *priv;
200   gint width;
201   gint height;
202   gint default_width, default_height;
203   GtkRequisition req;
204   gboolean resize_horizontally;
205   gboolean resize_vertically;
206   gboolean update_hints;
207   gint dx = 0, dy = 0;
208   gint cur_width, cur_height;
209
210   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
211
212   /* Force a size request of everything before we start.  This will make sure
213    * that widget->requisition is meaningful. */
214   gtk_widget_size_request (GTK_WIDGET (dialog), &req);
215   gtk_window_get_size (GTK_WINDOW (dialog), &cur_width, &cur_height);
216   width = GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width;
217   height = GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height;
218   _gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget),
219                                             &default_width, &default_height);
220
221   /* Ideal target size modulo any resizing */
222   width = default_width + width;
223   height = default_height + height;
224
225   /* Now, we test for resizability */
226   update_hints = FALSE;
227   _gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget),
228                                                &resize_horizontally,
229                                                &resize_vertically);
230   resize_vertically = (!! resize_vertically);     /* normalize */
231   resize_horizontally = (!! resize_horizontally);
232
233   if (resize_horizontally && priv->resize_horizontally)
234     {
235       dx = default_width - priv->default_width;
236       priv->default_width = default_width;
237     }
238   else if (resize_horizontally && ! priv->resize_horizontally)
239     {
240       /* We restore to the ideal size + any change in default_size (which is not
241        * expected).  It would be nicer to store the older size to restore to in
242        * the future. */
243       dx = default_width - priv->default_width;
244       dx += width - cur_width;
245       priv->default_width = default_width;
246       update_hints = TRUE;
247     }
248   else
249     {
250       update_hints = TRUE;
251     }
252   
253   if (resize_vertically && priv->resize_vertically)
254     {
255       dy = default_height - priv->default_height;
256       priv->default_height = default_height;
257     }
258   else if (resize_vertically && ! priv->resize_vertically)
259     {
260       dy = default_height - priv->default_height;
261       dy += height - cur_height;
262       priv->default_height = default_height;
263       update_hints = TRUE;
264     }
265   else
266     {
267       update_hints = TRUE;
268     }
269
270   priv->resize_horizontally = resize_horizontally;
271   priv->resize_vertically = resize_vertically;
272
273   if (dx != 0 || dy != 0)
274     {
275       gint new_width = cur_width + dx;
276       gint new_height = cur_height + dy;
277
278       clamp_to_screen (GTK_WIDGET (dialog), &new_width, &new_height);
279       
280       gtk_window_resize (GTK_WINDOW (dialog), new_width, new_height);
281     }
282
283   /* Only store the size if we can resize in that direction. */
284   if (update_hints)
285     file_chooser_widget_update_hints (dialog);
286 }
287
288 static void
289 file_chooser_widget_default_unrealized_size_changed (GtkWidget            *widget,
290                                                      GtkFileChooserDialog *dialog)
291 {
292   GtkFileChooserDialogPrivate *priv;
293   GtkRequisition req;
294   gint width, height;
295
296   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
297   gtk_widget_size_request (GTK_WIDGET (dialog), &req);
298
299   _gtk_file_chooser_embed_get_resizable_hints (GTK_FILE_CHOOSER_EMBED (priv->widget),
300                                                &(priv->resize_horizontally),
301                                                &(priv->resize_vertically));
302   _gtk_file_chooser_embed_get_default_size (GTK_FILE_CHOOSER_EMBED (priv->widget),
303                                             &(priv->default_width), &(priv->default_height));
304   
305   /* Determine how much space the rest of the dialog uses compared to priv->widget */
306   width = priv->default_width + GTK_WIDGET (dialog)->requisition.width - priv->widget->requisition.width;
307   height = priv->default_height + GTK_WIDGET (dialog)->requisition.height - priv->widget->requisition.height;
308
309   gtk_window_set_default_size (GTK_WINDOW (dialog), width, height);
310   file_chooser_widget_update_hints (dialog);
311 }
312
313 static void
314 file_chooser_widget_default_size_changed (GtkWidget            *widget,
315                                           GtkFileChooserDialog *dialog)
316 {
317   if (GTK_WIDGET_REALIZED (dialog))
318     file_chooser_widget_default_realized_size_changed (widget, dialog);
319   else
320     file_chooser_widget_default_unrealized_size_changed (widget, dialog);
321 }
322
323 static void
324 file_chooser_widget_response_requested (GtkWidget            *widget,
325                                         GtkFileChooserDialog *dialog)
326 {
327   GList *children, *l;
328
329   /* There probably isn't a default widget, so make things easier for the
330    * programmer by looking for a reasonable button on our own.
331    */
332
333   children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
334
335   for (l = children; l; l = l->next)
336     {
337       GtkWidget *widget;
338       int response_id;
339
340       widget = GTK_WIDGET (l->data);
341       response_id = gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget);
342       if (response_id == GTK_RESPONSE_ACCEPT
343           || response_id == GTK_RESPONSE_OK
344           || response_id == GTK_RESPONSE_YES
345           || response_id == GTK_RESPONSE_APPLY)
346         {
347           dialog->priv->response_requested = TRUE;
348           gtk_widget_activate (widget); /* Should we gtk_dialog_response (dialog, response_id) instead? */
349           break;
350         }
351     }
352
353   g_list_free (children);
354 }
355   
356 static GObject*
357 gtk_file_chooser_dialog_constructor (GType                  type,
358                                      guint                  n_construct_properties,
359                                      GObjectConstructParam *construct_params)
360 {
361   GtkFileChooserDialogPrivate *priv;
362   GObject *object;
363
364   object = G_OBJECT_CLASS (gtk_file_chooser_dialog_parent_class)->constructor (type,
365                                                                                n_construct_properties,
366                                                                                construct_params);
367   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (object);
368
369   gtk_widget_push_composite_child ();
370
371   if (priv->file_system)
372     priv->widget = g_object_new (GTK_TYPE_FILE_CHOOSER_WIDGET,
373                                  "file-system-backend", priv->file_system,
374                                  NULL);
375   else
376     priv->widget = g_object_new (GTK_TYPE_FILE_CHOOSER_WIDGET, NULL);
377
378   g_signal_connect (priv->widget, "file-activated",
379                     G_CALLBACK (file_chooser_widget_file_activated), object);
380   g_signal_connect (priv->widget, "default-size-changed",
381                     G_CALLBACK (file_chooser_widget_default_size_changed), object);
382   g_signal_connect (priv->widget, "response-requested",
383                     G_CALLBACK (file_chooser_widget_response_requested), object);
384
385   gtk_container_set_border_width (GTK_CONTAINER (priv->widget), 5);
386   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (object)->vbox), priv->widget, TRUE, TRUE, 0);
387
388   gtk_widget_show (priv->widget);
389
390   _gtk_file_chooser_set_delegate (GTK_FILE_CHOOSER (object),
391                                   GTK_FILE_CHOOSER (priv->widget));
392
393   gtk_widget_pop_composite_child ();
394
395   return object;
396 }
397
398 static void
399 gtk_file_chooser_dialog_set_property (GObject         *object,
400                                       guint            prop_id,
401                                       const GValue    *value,
402                                       GParamSpec      *pspec)
403
404 {
405   GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (object);
406
407   switch (prop_id)
408     {
409     case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND:
410       g_free (priv->file_system);
411       priv->file_system = g_value_dup_string (value);
412       break;
413     default:
414       g_object_set_property (G_OBJECT (priv->widget), pspec->name, value);
415       break;
416     }
417 }
418
419 static void
420 gtk_file_chooser_dialog_get_property (GObject         *object,
421                                       guint            prop_id,
422                                       GValue          *value,
423                                       GParamSpec      *pspec)
424 {
425   GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (object);
426
427   g_object_get_property (G_OBJECT (priv->widget), pspec->name, value);
428 }
429
430 #if 0
431 static void
432 set_default_size (GtkFileChooserDialog *dialog)
433 {
434   GtkWidget *widget;
435   GtkWindow *window;
436   int default_width, default_height;
437   int width, height;
438   int font_size;
439   GdkScreen *screen;
440   int monitor_num;
441   GtkRequisition req;
442   GdkRectangle monitor;
443
444   widget = GTK_WIDGET (dialog);
445   window = GTK_WINDOW (dialog);
446
447   /* Size based on characters */
448
449   font_size = pango_font_description_get_size (widget->style->font_desc);
450   font_size = PANGO_PIXELS (font_size);
451
452   width = font_size * NUM_CHARS;
453   height = font_size * NUM_LINES;
454
455   /* Use at least the requisition size... */
456
457   gtk_widget_size_request (widget, &req);
458   width = MAX (width, req.width);
459   height = MAX (height, req.height);
460
461   /* ... but no larger than the monitor */
462
463   screen = gtk_widget_get_screen (widget);
464   monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
465
466   gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
467
468   width = MIN (width, monitor.width * 3 / 4);
469   height = MIN (height, monitor.height * 3 / 4);
470
471   /* Set size */
472
473   gtk_window_get_default_size (window, &default_width, &default_height);
474
475   gtk_window_set_default_size (window,
476                                (default_width == -1) ? width : default_width,
477                                (default_height == -1) ? height : default_height);
478 }
479 #endif
480
481 /* GtkWidget::map handler */
482 static void
483 gtk_file_chooser_dialog_map (GtkWidget *widget)
484 {
485   GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
486   GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
487
488   if (!GTK_WIDGET_MAPPED (priv->widget))
489     gtk_widget_map (priv->widget);
490
491   _gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
492
493   GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
494 }
495
496 /* GtkWidget::unmap handler */
497 static void
498 gtk_file_chooser_dialog_unmap (GtkWidget *widget)
499 {
500   GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
501   GtkFileChooserDialogPrivate *priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
502
503   GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->unmap (widget);
504
505   /* See bug #145470.  We unmap the GtkFileChooserWidget so that if the dialog
506    * is remapped, the widget will be remapped as well.  Implementations should
507    * refresh their contents when this happens, as some applications keep a
508    * single file chooser alive and map/unmap it as needed, rather than creating
509    * a new file chooser every time they need one.
510    */
511   gtk_widget_unmap (priv->widget);
512 }
513
514 /* GtkDialog::response handler */
515 static void
516 response_cb (GtkDialog *dialog,
517              gint       response_id)
518 {
519   GtkFileChooserDialogPrivate *priv;
520
521   priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
522
523   /* Act only on response IDs we recognize */
524   if (!(response_id == GTK_RESPONSE_ACCEPT
525         || response_id == GTK_RESPONSE_OK
526         || response_id == GTK_RESPONSE_YES
527         || response_id == GTK_RESPONSE_APPLY))
528     return;
529
530   if (!priv->response_requested && !_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
531     {
532       g_signal_stop_emission_by_name (dialog, "response");
533       priv->response_requested = FALSE;
534     }
535 }
536
537 static GtkWidget *
538 gtk_file_chooser_dialog_new_valist (const gchar          *title,
539                                     GtkWindow            *parent,
540                                     GtkFileChooserAction  action,
541                                     const gchar          *backend,
542                                     const gchar          *first_button_text,
543                                     va_list               varargs)
544 {
545   GtkWidget *result;
546   const char *button_text = first_button_text;
547   gint response_id;
548
549   result = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
550                          "title", title,
551                          "action", action,
552                          "file-system-backend", backend,
553                          NULL);
554
555   if (parent)
556     gtk_window_set_transient_for (GTK_WINDOW (result), parent);
557
558   while (button_text)
559     {
560       response_id = va_arg (varargs, gint);
561       gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id);
562       button_text = va_arg (varargs, const gchar *);
563     }
564
565   return result;
566 }
567
568 /**
569  * gtk_file_chooser_dialog_new:
570  * @title: Title of the dialog, or %NULL
571  * @parent: Transient parent of the dialog, or %NULL
572  * @action: Open or save mode for the dialog
573  * @first_button_text: stock ID or text to go in the first button, or %NULL
574  * @Varargs: response ID for the first button, then additional (button, id) pairs, ending with %NULL
575  *
576  * Creates a new #GtkFileChooserDialog.  This function is analogous to
577  * gtk_dialog_new_with_buttons().
578  *
579  * Return value: a new #GtkFileChooserDialog
580  *
581  * Since: 2.4
582  **/
583 GtkWidget *
584 gtk_file_chooser_dialog_new (const gchar         *title,
585                              GtkWindow           *parent,
586                              GtkFileChooserAction action,
587                              const gchar         *first_button_text,
588                              ...)
589 {
590   GtkWidget *result;
591   va_list varargs;
592   
593   va_start (varargs, first_button_text);
594   result = gtk_file_chooser_dialog_new_valist (title, parent, action,
595                                                NULL, first_button_text,
596                                                varargs);
597   va_end (varargs);
598
599   return result;
600 }
601
602 /**
603  * gtk_file_chooser_dialog_new_with_backend:
604  * @title: Title of the dialog, or %NULL
605  * @parent: Transient parent of the dialog, or %NULL
606  * @action: Open or save mode for the dialog
607  * @backend: The name of the specific filesystem backend to use.
608  * @first_button_text: stock ID or text to go in the first button, or %NULL
609  * @Varargs: response ID for the first button, then additional (button, id) pairs, ending with %NULL
610  *
611  * Creates a new #GtkFileChooserDialog with a specified backend. This is
612  * especially useful if you use gtk_file_chooser_set_local_only() to allow
613  * non-local files and you use a more expressive vfs, such as gnome-vfs,
614  * to load files.
615  *
616  * Return value: a new #GtkFileChooserDialog
617  *
618  * Since: 2.4
619  **/
620 GtkWidget *
621 gtk_file_chooser_dialog_new_with_backend (const gchar          *title,
622                                           GtkWindow            *parent,
623                                           GtkFileChooserAction  action,
624                                           const gchar          *backend,
625                                           const gchar          *first_button_text,
626                                           ...)
627 {
628   GtkWidget *result;
629   va_list varargs;
630   
631   va_start (varargs, first_button_text);
632   result = gtk_file_chooser_dialog_new_valist (title, parent, action,
633                                                backend, first_button_text,
634                                                varargs);
635   va_end (varargs);
636
637   return result;
638 }
639
640 #define __GTK_FILE_CHOOSER_DIALOG_C__
641 #include "gtkaliasdef.c"