Added Russian translation (by Sergei Ivanov and Vitaly Petrov)
[vagalume:vagalume.git] / src / uimisc.c
1 /*
2  * uimisc.c -- Misc UI-related functions
3  *
4  * Copyright (C) 2007-2010 Igalia, S.L.
5  * Authors: Alberto Garcia <agarcia@igalia.com>
6  *
7  * This file is part of Vagalume and is published under the GNU GPLv3.
8  * See the README file for more details.
9  */
10
11 #include <glib/gi18n.h>
12 #include "config.h"
13 #include "uimisc.h"
14 #include "util.h"
15 #include "compat.h"
16
17 #include <string.h>
18 #include <gtk/gtk.h>
19
20 #ifdef MAEMO5
21 #        include <hildon/hildon.h>
22 #endif
23
24 #if defined(HILDON_LIBS)
25 #        include <hildon-widgets/hildon-program.h>
26 #        include <hildon-widgets/hildon-banner.h>
27 #elif defined(HILDON_1)
28 #        include <hildon/hildon-program.h>
29 #        include <hildon/hildon-banner.h>
30 #endif
31
32 #if defined(HILDON_FM)
33 #        include <hildon-widgets/hildon-file-chooser-dialog.h>
34 #elif defined(HILDON_FM_2)
35 #        include <hildon/hildon-file-chooser-dialog.h>
36 #endif
37
38 #define MENU_ITEM_ICON_SIZE 16
39
40 typedef struct {
41         GtkDialog *dialog;
42         GtkWidget *combo;
43         GtkEntry *entry;
44         GtkToggleButton *radio3;
45 } StopAfterDialog;
46
47 static const char *authors[] = {
48         "Alberto Garcia Gonzalez\n<agarcia@igalia.com>\n",
49         "Mario Sanchez Prada\n<msanchez@igalia.com>",
50         NULL
51 };
52 static const char *artists[] = {
53         "Otto Krüja\n<ottokrueja@gmx.net>",
54         NULL
55 };
56
57 static const char appdescr[] = N_("Client for Last.fm and compatible services");
58 static const char copyright[] = "(c) 2007-2010 Igalia, S.L.";
59 static const char website[] = "http://vagalume.igalia.com/";
60 static const char license[] =
61 "Vagalume is free software: you can redistribute\n"
62 "it and/or modify it under the terms of the GNU\n"
63 "General Public License version 3 as published by\n"
64 "the Free Software Foundation.\n"
65 "\n"
66 "Vagalume is distributed in the hope that it will\n"
67 "be useful, but WITHOUT ANY WARRANTY; without even\n"
68 "the implied warranty of MERCHANTABILITY or FITNESS\n"
69 "FOR A PARTICULAR PURPOSE. See the GNU General\n"
70 "Public License for more details.\n"
71 "\n"
72 "You should have received a copy of the GNU General\n"
73 "Public License along with Vagalume. If not, see\n"
74 "http://www.gnu.org/licenses/\n";
75 static const char translators_tpl[] =
76 "%s (de)\n* Stephan Reichholf <stephan@reichholf.net>\n"
77          "* Oskar Welzl <mail@welzl.info>\n\n"
78 "%s (es)\n* Oscar A. Mata T. <omata_mac@yahoo.com>\n\n"
79 "%s (fi)\n* Janne Mäkinen <janne.makinen@surffi.fi>\n"
80          "* Mika Tapojärvi <mika.tapojarvi@sse.fi>\n"
81          "* Tommi Franttila <tommif@gmail.com>\n\n"
82 "%s (fr)\n* Julien Duponchelle <julien@duponchelle.info>\n"
83          "* Jean-Alexandre Angles d'Auriac <jeanalexandre.angles_dauriac@ens-lyon.fr>\n\n"
84 "%s (gl)\n* Ignacio Casal Quinteiro <nacho.resa@gmail.com>\n"
85          "* Amador Loureiro Blanco <dorfun@adorfunteca.org>\n\n"
86 "%s (it)\n* Andrea Grandi <a.grandi@gmail.com>\n\n"
87 "%s (lv)\n* Pēteris Caune <cuu508@gmail.com>\n\n"
88 "%s (pl)\n* Dawid Pakuła (ZuLuS) <zulus@w3des.net>\n\n"
89 "%s (pt)\n* Marcos Garcia <marcosgg@gmail.com>\n\n"
90 "%s (pt_BR)\n* Rodrigo Flores <rodrigomarquesflores@gmail.com>\n\n"
91 "%s (ru)\n* Sergei Ivanov <isn@vu.spb.ru>\n"
92          "* Vitaly Petrov <vit.petrov@vu.spb.ru>";
93
94 /* Don't use gtk_button_new() in Nokia 770 or icons won't appear */
95 GtkWidget *
96 compat_gtk_button_new                   (void)
97 {
98 #ifdef MAEMO2
99         return gtk_button_new_with_label("");
100 #else
101         return gtk_button_new();
102 #endif
103 }
104
105 static void
106 ui_show_dialog                          (GtkWindow      *parent,
107                                          const char     *text,
108                                          GtkMessageType  type)
109 {
110         g_return_if_fail(text != NULL);
111         GtkDialogFlags flags = GTK_DIALOG_MODAL |
112                 GTK_DIALOG_DESTROY_WITH_PARENT;
113         GtkWidget *dialog = gtk_message_dialog_new(parent, flags, type,
114                                                    GTK_BUTTONS_OK,
115                                                    "%s", text);
116         gtk_dialog_run (GTK_DIALOG (dialog));
117         gtk_widget_destroy (dialog);
118 }
119
120 void
121 ui_info_dialog                          (GtkWindow  *parent,
122                                          const char *text)
123 {
124         ui_show_dialog(parent, text, GTK_MESSAGE_INFO);
125 }
126
127 void
128 ui_warning_dialog                       (GtkWindow  *parent,
129                                          const char *text)
130 {
131         ui_show_dialog(parent, text, GTK_MESSAGE_WARNING);
132 }
133
134 void
135 ui_error_dialog                         (GtkWindow  *parent,
136                                          const char *text)
137 {
138         ui_show_dialog(parent, text, GTK_MESSAGE_ERROR);
139 }
140
141 void
142 ui_info_banner                          (GtkWindow  *parent,
143                                          const char *text)
144 {
145         g_return_if_fail(parent != NULL && text != NULL);
146 #ifdef MAEMO
147         hildon_banner_show_information(NULL, NULL, text);
148 #else
149         /* TODO: Implement a notification banner for Gnome */
150         g_warning("Info banner not implemented!!");
151 #endif
152 }
153
154 #ifdef HAVE_GIO
155 static void
156 about_dialog_uri_hook                   (GtkAboutDialog *about,
157                                          const gchar    *link,
158                                          gpointer        data)
159 {
160         gchar *uri = g_strconcat (data, link, NULL);
161         launch_url (uri, NULL);
162         g_free (uri);
163 }
164 #endif
165
166 void
167 ui_about_dialog                         (GtkWindow *parent)
168 {
169         GdkPixbuf *logo = gdk_pixbuf_new_from_file (APP_ICON_BIG, NULL);
170         char *translators = g_strdup_printf (translators_tpl, _("German"),
171                                              _("Spanish"), _("Finnish"),
172                                              _("French"),
173                                              _("Galician"), _("Italian"),
174                                              _("Latvian"), _("Polish"),
175                                              _("Portuguese"), _("Portuguese"),
176                                              _("Russian"));
177 #ifdef HAVE_GIO
178         gtk_about_dialog_set_url_hook (about_dialog_uri_hook, "", NULL);
179         gtk_about_dialog_set_email_hook (about_dialog_uri_hook, "mailto:",
180                                          NULL);
181 #endif
182         gtk_show_about_dialog (parent, "authors", authors,
183                                "comments", _(appdescr), "copyright", copyright,
184                                "license", license, "version", APP_VERSION,
185                                "website", website, "artists", artists,
186                                "translator-credits", translators,
187 #ifdef HAVE_GTK_ABOUT_DIALOG_PROGRAM_NAME
188                                "program-name", APP_NAME,
189 #else
190                                "name", APP_NAME,
191 #endif /* HAVE_GTK_ABOUT_DIALOG_PROGRAM_NAME */
192                                "logo", logo, NULL);
193         g_object_unref (logo);
194         g_free (translators);
195 }
196
197 GtkDialog *
198 ui_base_dialog                          (GtkWindow  *parent,
199                                          const char *title)
200 {
201         GtkWidget *dialog;
202         dialog = gtk_dialog_new_with_buttons(title, parent,
203                                              GTK_DIALOG_MODAL |
204                                              GTK_DIALOG_DESTROY_WITH_PARENT,
205                                              GTK_STOCK_CANCEL,
206                                              GTK_RESPONSE_REJECT,
207                                              GTK_STOCK_OK,
208                                              GTK_RESPONSE_ACCEPT,
209                                              NULL);
210         gtk_dialog_set_default_response(GTK_DIALOG(dialog),
211                                         GTK_RESPONSE_ACCEPT);
212         return GTK_DIALOG(dialog);
213 }
214
215 gboolean
216 ui_confirm_dialog                       (GtkWindow  *parent,
217                                          const char *text)
218 {
219         g_return_val_if_fail(text != NULL, FALSE);
220         gint response;
221         GtkDialog *dialog = ui_base_dialog(parent, _("Confirmation"));
222         GtkWidget *label = gtk_label_new(text);
223         gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 10);
224         gtk_widget_show_all(GTK_WIDGET(dialog));
225         response = gtk_dialog_run(dialog);
226         gtk_widget_destroy(GTK_WIDGET(dialog));
227         return (response == GTK_RESPONSE_ACCEPT);
228 }
229
230 char *
231 ui_input_dialog                         (GtkWindow  *parent,
232                                          const char *title,
233                                          const char *text,
234                                          const char *value)
235 {
236         GtkDialog *dialog;
237         GtkWidget *label;
238         GtkEntry *entry;
239         char *retvalue = NULL;
240         dialog = ui_base_dialog(parent, title);
241         label = gtk_label_new(text);
242 #ifdef MAEMO5
243         entry = GTK_ENTRY(hildon_entry_new(FINGER_SIZE));
244 #else
245         entry = GTK_ENTRY(gtk_entry_new());
246 #endif
247         gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 10);
248         gtk_box_pack_start(GTK_BOX(dialog->vbox),
249                            GTK_WIDGET(entry), FALSE, FALSE, 10);
250         if (value != NULL) gtk_entry_set_text(entry, value);
251         gtk_entry_set_activates_default(entry, TRUE);
252         gtk_widget_show_all(GTK_WIDGET(dialog));
253         if (gtk_dialog_run(dialog) == GTK_RESPONSE_ACCEPT) {
254                 retvalue = g_strstrip(g_strdup(gtk_entry_get_text(entry)));
255         }
256         gtk_widget_destroy(GTK_WIDGET(dialog));
257         return retvalue;
258 }
259
260 gboolean
261 ui_edit_bookmark_dialog                 (GtkWindow  *parent,
262                                          char      **name,
263                                          char      **url,
264                                          gboolean    add)
265 {
266         GtkDialog *dialog;
267         GtkWidget *namelabel, *urllabel;
268         GtkEntry *nameentry, *urlentry;
269         GtkBox *vbox;
270         gboolean done, retvalue;
271         dialog = ui_base_dialog(parent,
272                                 add ? _("Add bookmark") : _("Edit bookmark"));
273         namelabel = gtk_label_new(_("Bookmark name"));
274         urllabel = gtk_label_new(_("Last.fm radio address"));
275 #ifdef MAEMO5
276         nameentry = GTK_ENTRY (hildon_entry_new (FINGER_SIZE));
277         urlentry = GTK_ENTRY (hildon_entry_new (FINGER_SIZE));
278 #else
279         nameentry = GTK_ENTRY(gtk_entry_new());
280         urlentry = GTK_ENTRY(gtk_entry_new());
281 #endif /* MAEMO5 */
282
283         if (*name != NULL) gtk_entry_set_text(nameentry, *name);
284         if (*url != NULL) gtk_entry_set_text(urlentry, *url);
285
286         vbox = GTK_BOX (dialog->vbox);
287         gtk_box_pack_start(vbox, namelabel, FALSE, FALSE, 4);
288         gtk_box_pack_start(vbox, GTK_WIDGET(nameentry), FALSE, FALSE, 4);
289         gtk_box_pack_start(vbox, urllabel, FALSE, FALSE, 4);
290         gtk_box_pack_start(vbox, GTK_WIDGET(urlentry), FALSE, FALSE, 4);
291         gtk_entry_set_activates_default(nameentry, TRUE);
292         gtk_entry_set_activates_default(urlentry, TRUE);
293         gtk_widget_show_all(GTK_WIDGET(dialog));
294         done = FALSE;
295         while (!done) {
296                 if (gtk_dialog_run(dialog) == GTK_RESPONSE_ACCEPT) {
297                         char *tmpname, *tmpurl;
298                         tmpname = g_strdup(gtk_entry_get_text(nameentry));
299                         tmpurl = g_strdup(gtk_entry_get_text(urlentry));
300                         g_strstrip(tmpname);
301                         g_strstrip(tmpurl);
302                         if (tmpname[0] == '\0') {
303                                 ui_info_dialog(GTK_WINDOW(dialog),
304                                                _("Invalid bookmark name"));
305                                 gtk_widget_grab_focus(GTK_WIDGET(nameentry));
306                         } else if (strncmp(tmpurl, "lastfm://", 9)) {
307                                 ui_info_dialog(GTK_WINDOW(dialog),
308                                                _("Last.fm radio URLs must "
309                                                  "start with lastfm://"));
310                                 gtk_widget_grab_focus(GTK_WIDGET(urlentry));
311                         } else {
312                                 retvalue = done = TRUE;
313                                 g_free(*name);
314                                 g_free(*url);
315                                 *name = tmpname;
316                                 *url = tmpurl;
317                         }
318                         if (!done) {
319                                 g_free(tmpname);
320                                 g_free(tmpurl);
321                         }
322                 } else {
323                         retvalue = FALSE;
324                         done = TRUE;
325                 }
326         }
327         gtk_widget_destroy(GTK_WIDGET(dialog));
328         return retvalue;
329 }
330
331 GtkWidget *
332 ui_menu_item_create_from_icon           (const gchar *icon_name,
333                                          const gchar *label)
334 {
335         g_return_val_if_fail (icon_name != NULL && label != NULL, NULL);
336
337         GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (label);
338         GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
339         GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name,
340                                                       MENU_ITEM_ICON_SIZE, 0,
341                                                       NULL);
342
343         if (pixbuf != NULL) {
344                 GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf);
345                 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
346                                                image);
347                 g_object_unref (pixbuf);
348         }
349
350         return item;
351 }
352
353 static GtkWidget *
354 create_file_chooser_dialog              (GtkWindow            *parent,
355                                          const char           *title,
356                                          GtkFileChooserAction  action)
357 {
358         GtkWidget *dialog;
359 #ifdef MAEMO
360         dialog = hildon_file_chooser_dialog_new (parent, action);
361         gtk_window_set_title (GTK_WINDOW (dialog), title);
362 #else
363         dialog = gtk_file_chooser_dialog_new (
364                 title, parent, action,
365                 GTK_STOCK_OK, GTK_RESPONSE_OK,
366                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
367                 NULL);
368 #endif
369         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
370         return dialog;
371 }
372
373 char *
374 ui_select_servers_file                  (GtkWindow *parent)
375 {
376         GtkWidget *dialog;
377         char *file = NULL;
378         dialog = create_file_chooser_dialog (
379                 parent, _("Select server file to import"),
380                 GTK_FILE_CHOOSER_ACTION_OPEN);
381         if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
382                 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
383         }
384         gtk_widget_destroy (dialog);
385         return file;
386 }
387
388 char *
389 ui_select_download_dir                  (GtkWindow  *parent,
390                                          const char *curdir)
391 {
392         GtkWidget *dialog;
393         char *dir = NULL;
394         dialog = create_file_chooser_dialog (
395                 parent, _("Select download directory"),
396                 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
397         if (curdir != NULL) {
398                 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
399                                               curdir);
400         }
401         if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
402                 dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
403         }
404         gtk_widget_destroy(dialog);
405         return dir;
406 }
407
408 GtkTreeModel *
409 ui_create_options_list                  (const GList *elems)
410 {
411         GtkTreeIter iter;
412         const GList *current = elems;
413         GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
414
415         for (; current != NULL; current = g_list_next(current)) {
416                 gtk_list_store_append(store, &iter);
417                 gtk_list_store_set(store, &iter, 0, current->data, -1);
418         }
419         return GTK_TREE_MODEL(store);
420 }
421
422 static void
423 stop_after_dialog_update_sensitivity    (StopAfterDialog *win)
424 {
425         gboolean radio3_active = gtk_toggle_button_get_active (win->radio3);
426         gboolean ok_button_sensitive = TRUE;
427         if (radio3_active) {
428                 const char *text = gtk_entry_get_text (win->entry);
429                 guint64 value = g_ascii_strtoull (text, NULL, 10);
430                 ok_button_sensitive = (value > 0 && value < 10080);
431         }
432         gtk_widget_set_sensitive (win->combo, radio3_active);
433         gtk_dialog_set_response_sensitive (win->dialog,
434                                            GTK_RESPONSE_ACCEPT,
435                                            ok_button_sensitive);
436 }
437
438 static void
439 stop_after_entry_changed                (GtkWidget       *w,
440                                          GParamSpec      *arg,
441                                          StopAfterDialog *win)
442 {
443         stop_after_dialog_update_sensitivity (win);
444 }
445
446 static void
447 stop_after_radio_button_toggled         (GtkWidget       *button,
448                                          StopAfterDialog *win)
449 {
450         stop_after_dialog_update_sensitivity (win);
451 }
452
453 gboolean
454 ui_stop_after_dialog                    (GtkWindow     *parent,
455                                          StopAfterType *stopafter,
456                                          int           *minutes)
457 {
458         GtkDialog *dialog;
459         GtkWidget *alignment;
460         GtkWidget *hbox, *vbox;
461         GtkWidget *descrlabel, *minuteslabel;
462         GtkWidget *combo;
463         GtkEntry *entry;
464         GtkListStore *model;
465         GtkWidget *radio1, *radio2, *radio3;
466         StopAfterDialog win;
467         int default_times[] = { 5, 15, 30, 45, 60, 90, 120, 240, -1 };
468         int i;
469         gboolean retvalue = FALSE;
470
471         g_return_val_if_fail (minutes != NULL && stopafter != NULL, FALSE);
472
473         /* Create all widgets */
474         dialog = ui_base_dialog (parent, _("Stop automatically"));
475         descrlabel = gtk_label_new (_("When do you want to stop playback?"));
476         minuteslabel = gtk_label_new (_("minutes"));
477         alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
478         hbox = gtk_hbox_new (FALSE, 5);
479         vbox = gtk_vbox_new (TRUE, 5);
480         radio1 = gtk_radio_button_new (NULL);
481         radio2 = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio1));
482         radio3 = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (radio1));
483
484         gtk_button_set_label (GTK_BUTTON (radio1), _("Don't stop"));
485         gtk_button_set_label (GTK_BUTTON (radio2), _("Stop after this track"));
486         /* Translators: the full text is "Stop after ____ minutes" */
487         gtk_button_set_label (GTK_BUTTON (radio3), _("Stop after"));
488
489         /* Create and fill model */
490         model = gtk_list_store_new (1, G_TYPE_STRING);
491         for (i = 0; default_times[i] != -1; i++) {
492                 GtkTreeIter iter;
493                 char str[4];
494                 g_snprintf (str, 4, "%d", default_times[i]);
495                 gtk_list_store_append (model, &iter);
496                 gtk_list_store_set (model, &iter, 0, str, -1);
497         }
498
499         /* Create combo box */
500         combo = gtk_combo_box_entry_new_with_model (GTK_TREE_MODEL (model), 0);
501         g_object_unref (model);
502         entry = GTK_ENTRY (GTK_BIN (combo)->child);
503         gtk_entry_set_width_chars (entry, 4);
504 #ifdef MAEMO
505         hildon_gtk_entry_set_input_mode (entry, HILDON_GTK_INPUT_MODE_NUMERIC);
506 #endif
507
508         /* Set default values */
509         if (*stopafter == STOP_AFTER_DONT_STOP) {
510                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
511                                               TRUE);
512         } else if (*stopafter == STOP_AFTER_THIS_TRACK) {
513                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2),
514                                               TRUE);
515         } else if (*stopafter == STOP_AFTER_N_MINUTES) {
516                 char *str;
517                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio3),
518                                               TRUE);
519                 if (*minutes > 0) {
520                         str = g_strdup_printf ("%d", *minutes);
521                         gtk_entry_set_text (entry, str);
522                         g_free (str);
523                 }
524         } else {
525                 g_return_val_if_reached (FALSE);
526         }
527
528         /* Pack widgets */
529         gtk_box_pack_start (GTK_BOX (hbox), radio3, FALSE, FALSE, 0);
530         gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
531         gtk_box_pack_start (GTK_BOX (hbox), minuteslabel, FALSE, FALSE, 0);
532         gtk_box_pack_start (GTK_BOX (vbox), descrlabel, FALSE, FALSE, 5);
533         gtk_box_pack_start (GTK_BOX (vbox), radio1, FALSE, FALSE, 0);
534         gtk_box_pack_start (GTK_BOX (vbox), radio2, FALSE, FALSE, 0);
535         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
536         gtk_container_add (GTK_CONTAINER (alignment), vbox);
537         gtk_box_pack_start (GTK_BOX (dialog->vbox), alignment, TRUE, TRUE, 10);
538
539         /* Fill StopAfterDialog struct */
540         win.dialog = dialog;
541         win.combo = combo;
542         win.entry = entry;
543         win.radio3 = GTK_TOGGLE_BUTTON (radio3);
544
545         /* Set sensitivity of combo box and OK button */
546         stop_after_dialog_update_sensitivity (&win);
547
548         /* Connect signals */
549         g_signal_connect (radio3, "toggled",
550                           G_CALLBACK (stop_after_radio_button_toggled), &win);
551         g_signal_connect (entry, "notify::text",
552                           G_CALLBACK (stop_after_entry_changed), &win);
553
554         /* Run dialog */
555         gtk_widget_show_all (GTK_WIDGET (dialog));
556         if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) {
557                 if (gtk_toggle_button_get_active (
558                             GTK_TOGGLE_BUTTON (radio1))) {
559                         *stopafter = STOP_AFTER_DONT_STOP;
560                 } else if (gtk_toggle_button_get_active (
561                                    GTK_TOGGLE_BUTTON (radio2))) {
562                         *stopafter = STOP_AFTER_THIS_TRACK;
563                 } else {
564                         const char *str = gtk_entry_get_text (entry);
565                         *minutes = g_ascii_strtoull (str, NULL, 10);
566                         *stopafter = STOP_AFTER_N_MINUTES;
567                 }
568                 retvalue = TRUE;
569         }
570         gtk_widget_destroy (GTK_WIDGET (dialog));
571
572         return retvalue;
573 }