~ubuntu-branches/ubuntu/natty/geany/natty

« back to all changes in this revision

Viewing changes to src/dialogs.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-08-07 03:23:12 UTC
  • mfrom: (1.4.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20100807032312-ot70ac9d50cn79we
Tags: upstream-0.19
ImportĀ upstreamĀ versionĀ 0.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *      along with this program; if not, write to the Free Software
19
19
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
20
 *
21
 
 * $Id: dialogs.c 4630 2010-01-31 21:54:47Z eht16 $
 
21
 * $Id: dialogs.c 4929 2010-05-16 18:22:24Z eht16 $
22
22
 */
23
23
 
24
24
/*
65
65
        GEANY_RESPONSE_VIEW
66
66
};
67
67
 
68
 
#if ! GEANY_USE_WIN32_DIALOG
 
68
 
 
69
static gboolean handle_save_as(const gchar *utf8_filename, gboolean open_new_tab,
 
70
        gboolean rename_file);
 
71
 
 
72
 
69
73
static GtkWidget *add_file_open_extra_widget(void);
70
74
 
71
75
 
84
88
                gint encoding_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(
85
89
                                                ui_lookup_widget(GTK_WIDGET(dialog), "encoding_combo")));
86
90
                GeanyFiletype *ft = NULL;
87
 
                gchar *charset = NULL;
 
91
                const gchar *charset = NULL;
88
92
                gboolean ro = (response == GEANY_RESPONSE_VIEW);        /* View clicked */
89
93
 
90
94
                /* ignore detect from file item */
91
 
                if (filetype_idx > 0 && filetype_idx < GEANY_MAX_BUILT_IN_FILETYPES)
 
95
                if (filetype_idx > 0)
92
96
                        ft = g_slist_nth_data(filetypes_by_title, filetype_idx);
93
97
                if (encoding_idx >= 0 && encoding_idx < GEANY_ENCODINGS_MAX)
94
98
                        charset = encodings[encoding_idx].charset;
203
207
        g_signal_connect(ui_widgets.open_filesel, "response",
204
208
                                G_CALLBACK(on_file_open_dialog_response), NULL);
205
209
}
206
 
#endif
207
210
 
208
211
 
209
212
/* This shows the file selection dialog to open a file. */
221
224
 
222
225
        setptr(initdir, utils_get_locale_from_utf8(initdir));
223
226
 
224
 
#if GEANY_USE_WIN32_DIALOG
225
 
        win32_show_file_dialog(TRUE, initdir);
226
 
#else /* X11, not win32: use GTK_FILE_CHOOSER */
227
 
 
228
 
        /* We use the same file selection widget each time, so first of all we create it
229
 
         * if it hasn't already been created. */
230
 
        if (ui_widgets.open_filesel == NULL)
231
 
                create_open_file_dialog();
232
 
 
233
 
        if (initdir != NULL)
 
227
#ifdef G_OS_WIN32
 
228
        if (interface_prefs.use_native_windows_dialogs)
 
229
                win32_show_document_open_dialog(GTK_WINDOW(main_widgets.window), _("Open File"), initdir);
 
230
        else
 
231
#endif
234
232
        {
235
 
                if (g_path_is_absolute(initdir))
236
 
                        gtk_file_chooser_set_current_folder(
237
 
                                GTK_FILE_CHOOSER(ui_widgets.open_filesel), initdir);
 
233
                /* We use the same file selection widget each time, so first of all we create it
 
234
                 * if it hasn't already been created. */
 
235
                if (ui_widgets.open_filesel == NULL)
 
236
                        create_open_file_dialog();
 
237
 
 
238
                if (initdir != NULL)
 
239
                {
 
240
                        if (g_path_is_absolute(initdir))
 
241
                                gtk_file_chooser_set_current_folder(
 
242
                                        GTK_FILE_CHOOSER(ui_widgets.open_filesel), initdir);
 
243
                }
 
244
 
 
245
                if (app->project && NZV(app->project->base_path))
 
246
                        gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
 
247
                                app->project->base_path, NULL);
 
248
 
 
249
                gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
 
250
                gtk_window_present(GTK_WINDOW(ui_widgets.open_filesel));
238
251
        }
239
 
 
240
 
        if (app->project && NZV(app->project->base_path))
241
 
                gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
242
 
                        app->project->base_path, NULL);
243
 
 
244
 
        gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
245
 
        gtk_window_present(GTK_WINDOW(ui_widgets.open_filesel));
246
 
#endif
247
252
        g_free(initdir);
248
253
}
249
254
 
250
255
 
251
 
#if ! GEANY_USE_WIN32_DIALOG
252
256
static GtkWidget *add_file_open_extra_widget()
253
257
{
254
258
        GtkWidget *expander, *vbox, *table, *check_hidden;
321
325
 
322
326
        return expander;
323
327
}
324
 
#endif
325
 
 
326
 
 
327
 
#if ! GEANY_USE_WIN32_DIALOG
 
328
 
 
329
 
328
330
static void on_save_as_new_tab_toggled(GtkToggleButton *togglebutton, gpointer user_data)
329
331
{
330
332
        gtk_widget_set_sensitive(GTK_WIDGET(user_data),
331
333
                ! gtk_toggle_button_get_active(togglebutton));
332
334
}
333
 
#endif
334
 
 
335
 
 
336
 
#if ! GEANY_USE_WIN32_DIALOG
 
335
 
 
336
 
337
337
static gboolean handle_save_as(const gchar *utf8_filename, gboolean open_new_tab, gboolean rename_file)
338
338
{
339
339
        GeanyDocument *doc = document_get_current();
412
412
        if (success)
413
413
                gtk_widget_hide(ui_widgets.save_filesel);
414
414
}
415
 
#endif
416
 
 
417
 
 
418
 
#if ! GEANY_USE_WIN32_DIALOG
 
415
 
 
416
 
419
417
static void create_save_file_dialog(void)
420
418
{
421
419
        GtkWidget *vbox, *check_open_new_tab, *rename_btn;
472
470
 
473
471
        gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.save_filesel), GTK_WINDOW(main_widgets.window));
474
472
}
475
 
#endif
476
 
 
477
 
 
478
 
#if ! GEANY_USE_WIN32_DIALOG
 
473
 
 
474
 
479
475
static gboolean gtk_show_save_as(void)
480
476
{
481
477
        GeanyDocument *doc = document_get_current();
482
478
        gint resp;
483
479
 
 
480
        g_return_val_if_fail(doc != NULL, FALSE);
 
481
 
484
482
        if (G_UNLIKELY(ui_widgets.save_filesel == NULL))
485
483
                create_save_file_dialog();
486
484
 
511
509
        {
512
510
                gchar *fname = NULL;
513
511
 
514
 
                if (doc->file_type != NULL && doc->file_type->id != GEANY_FILETYPES_NONE &&
515
 
                        doc->file_type->extension != NULL)
 
512
                if (doc->file_type != NULL && doc->file_type->extension != NULL)
516
513
                        fname = g_strconcat(GEANY_STRING_UNTITLED, ".",
517
514
                                                                doc->file_type->extension, NULL);
518
515
                else
536
533
 
537
534
        return (resp == GTK_RESPONSE_ACCEPT);
538
535
}
539
 
#endif
540
536
 
541
537
 
542
538
/**
543
 
 *  Show the Save As dialog for the current notebook page.
 
539
 *  Shows the Save As dialog for the current notebook page.
544
540
 *
545
541
 *  @return @c TRUE if the file was saved, otherwise @c FALSE.
546
542
 **/
547
543
gboolean dialogs_show_save_as()
548
544
{
549
 
        gboolean result;
 
545
        gboolean result = FALSE;
550
546
 
551
 
#if GEANY_USE_WIN32_DIALOG
552
 
        result = win32_show_file_dialog(FALSE, utils_get_default_dir_utf8());
553
 
#else
 
547
#ifdef G_OS_WIN32
 
548
        if (interface_prefs.use_native_windows_dialogs)
 
549
        {
 
550
                GeanyDocument *doc = document_get_current();
 
551
                gchar *utf8_name = win32_show_document_save_as_dialog(GTK_WINDOW(main_widgets.window),
 
552
                                                _("Save File"), DOC_FILENAME(doc));
 
553
                if (utf8_name != NULL)
 
554
                        result = handle_save_as(utf8_name, FALSE, FALSE);
 
555
        }
 
556
        else
 
557
#endif
554
558
        result = gtk_show_save_as();
555
 
#endif
556
559
        return result;
557
560
}
558
561
 
577
580
                        break;
578
581
        }
579
582
        gtk_window_set_title(GTK_WINDOW(dialog), title);
580
 
        if (parent == NULL)
 
583
        if (parent == NULL || GTK_IS_DIALOG(parent))
581
584
        {
582
585
                GdkPixbuf *pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
583
586
                gtk_window_set_icon(GTK_WINDOW(dialog), pb);
592
595
 
593
596
 
594
597
/**
595
 
 *  Show a message box of the type @a type with @a text.
 
598
 *  Shows a message box of the type @a type with @a text.
596
599
 *  On Unix-like systems a GTK message dialog box is shown, on Win32 systems a native Windows
597
600
 *  message dialog box is shown.
598
601
 *
606
609
#ifndef G_OS_WIN32
607
610
        GtkWidget *dialog;
608
611
#endif
609
 
        gchar string[512];
 
612
        gchar *string;
610
613
        va_list args;
611
614
        GtkWindow *parent = (main_status.main_window_realized) ? GTK_WINDOW(main_widgets.window) : NULL;
612
615
 
613
616
        va_start(args, text);
614
 
        g_vsnprintf(string, 511, text, args);
 
617
        string = g_strdup_vprintf(text, args);
615
618
        va_end(args);
616
619
 
617
620
#ifdef G_OS_WIN32
621
624
                                  type, GTK_BUTTONS_OK, "%s", string);
622
625
        show_msgbox_dialog(dialog, type, parent);
623
626
#endif
 
627
        g_free(string);
624
628
}
625
629
 
626
630
 
697
701
#endif
698
702
        g_free(msg);
699
703
 
700
 
        switch(ret)
 
704
        switch (ret)
701
705
        {
702
706
                case GTK_RESPONSE_YES:
703
707
                {
704
 
                        if (doc->file_name == NULL)
 
708
                        if (document_need_save_as(doc))
705
709
                        {
706
710
                                ret = dialogs_show_save_as();
707
711
                        }
821
825
        if (response == GTK_RESPONSE_ACCEPT)
822
826
        {
823
827
                const gchar *str = gtk_entry_get_text(GTK_ENTRY(entry));
824
 
                InputCallback input_cb =
825
 
                        (InputCallback) g_object_get_data(G_OBJECT(dialog), "input_cb");
 
828
                GeanyInputCallback input_cb =
 
829
                        (GeanyInputCallback) g_object_get_data(G_OBJECT(dialog), "input_cb");
826
830
 
827
831
                if (persistent)
828
832
                {
831
835
                }
832
836
                input_cb(str);
833
837
        }
834
 
 
835
 
        if (persistent)
836
 
                gtk_widget_hide(GTK_WIDGET(dialog));
837
 
        else
838
 
                gtk_widget_destroy(GTK_WIDGET(dialog));
 
838
        gtk_widget_hide(GTK_WIDGET(dialog));
839
839
}
840
840
 
841
841
 
842
842
static void add_input_widgets(GtkWidget *dialog, GtkWidget *vbox,
843
 
                const gchar *label_text, const gchar *default_text, gboolean persistent)
 
843
                const gchar *label_text, const gchar *default_text, gboolean persistent,
 
844
                GCallback insert_text_cb)
844
845
{
845
 
        GtkWidget *label, *entry;
 
846
        GtkWidget *entry;
846
847
 
847
 
        label = gtk_label_new(label_text);
848
 
        gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
849
 
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
850
 
        gtk_container_add(GTK_CONTAINER(vbox), label);
 
848
        if (label_text)
 
849
        {
 
850
                GtkWidget *label = gtk_label_new(label_text);
 
851
                gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 
852
                gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
853
                gtk_container_add(GTK_CONTAINER(vbox), label);
 
854
        }
851
855
 
852
856
        if (persistent) /* remember previous entry text in a combo box */
853
857
        {
854
858
                GtkWidget *combo = gtk_combo_box_entry_new_text();
855
859
 
856
860
                entry = GTK_BIN(combo)->child;
857
 
                ui_entry_add_clear_icon(entry);
 
861
                ui_entry_add_clear_icon(GTK_ENTRY(entry));
858
862
                g_object_set_data(G_OBJECT(dialog), "combo", combo);
859
863
                gtk_container_add(GTK_CONTAINER(vbox), combo);
860
864
        }
861
865
        else
862
866
        {
863
867
                entry = gtk_entry_new();
864
 
                ui_entry_add_clear_icon(entry);
 
868
                ui_entry_add_clear_icon(GTK_ENTRY(entry));
865
869
                gtk_container_add(GTK_CONTAINER(vbox), entry);
866
870
        }
867
871
 
872
876
        gtk_entry_set_max_length(GTK_ENTRY(entry), 255);
873
877
        gtk_entry_set_width_chars(GTK_ENTRY(entry), 30);
874
878
 
 
879
        if (insert_text_cb != NULL)
 
880
                g_signal_connect(entry, "insert-text", insert_text_cb, NULL);
875
881
        g_signal_connect(entry, "activate", G_CALLBACK(on_input_entry_activate), dialog);
876
882
        g_signal_connect(dialog, "show", G_CALLBACK(on_input_dialog_show), entry);
877
883
        g_signal_connect(dialog, "response", G_CALLBACK(on_input_dialog_response), entry);
883
889
 *      in this case the dialog returned is not destroyed on a response,
884
890
 *      and can be reshown.
885
891
 * Returns: the dialog widget. */
886
 
GtkWidget *
887
 
dialogs_show_input(const gchar *title, const gchar *label_text, const gchar *default_text,
888
 
                                                gboolean persistent, InputCallback input_cb)
 
892
static GtkWidget *
 
893
dialogs_show_input_full(const gchar *title, const gchar *label_text, const gchar *default_text,
 
894
                                                gboolean persistent, GeanyInputCallback input_cb, GCallback insert_text_cb)
889
895
{
890
896
        GtkWidget *dialog, *vbox;
891
897
 
899
905
        g_object_set_data(G_OBJECT(dialog), "has_combo", GINT_TO_POINTER(persistent));
900
906
        g_object_set_data(G_OBJECT(dialog), "input_cb", (gpointer) input_cb);
901
907
 
902
 
        add_input_widgets(dialog, vbox, label_text, default_text, persistent);
 
908
        add_input_widgets(dialog, vbox, label_text, default_text, persistent, insert_text_cb);
903
909
 
904
910
        if (persistent)
 
911
        {
 
912
                /* override default handler */
905
913
                g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
906
 
        else
907
 
                g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL);
908
 
 
 
914
                gtk_widget_show_all(dialog);
 
915
                return dialog;
 
916
        }
909
917
        gtk_widget_show_all(dialog);
910
 
        return dialog;
 
918
        gtk_dialog_run(GTK_DIALOG(dialog));
 
919
        gtk_widget_destroy(dialog);
 
920
        return NULL;
 
921
}
 
922
 
 
923
 
 
924
/* Remember previous entry text in a combo box.
 
925
 * Returns: the dialog widget. */
 
926
GtkWidget *
 
927
dialogs_show_input_persistent(const gchar *title, const gchar *label_text, const gchar *default_text,
 
928
                GeanyInputCallback input_cb)
 
929
{
 
930
        return dialogs_show_input_full(title, label_text, default_text, TRUE, input_cb, NULL);
 
931
}
 
932
 
 
933
 
 
934
/* ugly hack - user_data not supported for callback */
 
935
static gchar *dialog_input = NULL;
 
936
 
 
937
static void on_dialog_input(const gchar *str)
 
938
{
 
939
        dialog_input = g_strdup(str);
 
940
}
 
941
 
 
942
 
 
943
/* Returns: newly allocated string - a copy of either the entry text or default_text. */
 
944
gchar *dialogs_show_input(const gchar *title, const gchar *label_text,
 
945
        const gchar *default_text)
 
946
{
 
947
        dialog_input = NULL;
 
948
        dialogs_show_input_full(title, label_text, default_text, FALSE, on_dialog_input, NULL);
 
949
        return NVL(dialog_input, g_strdup(default_text));
 
950
}
 
951
 
 
952
 
 
953
/* Returns: newly allocated copy of the entry text or NULL on cancel.
 
954
 * Specialised variant for Goto Line dialog. */
 
955
gchar *dialogs_show_input_goto_line(const gchar *title, const gchar *label_text,
 
956
        const gchar *default_text)
 
957
{
 
958
        dialog_input = NULL;
 
959
        dialogs_show_input_full(
 
960
                title, label_text, default_text, FALSE, on_dialog_input,
 
961
                G_CALLBACK(ui_editable_insert_text_callback));
 
962
        return dialog_input;
911
963
}
912
964
 
913
965
 
914
966
/**
915
 
 *  Show an input box to enter a numerical value using a GtkSpinButton.
 
967
 *  Shows an input box to enter a numerical value using a GtkSpinButton.
916
968
 *  If the dialog is aborted, @a value remains untouched.
917
969
 *
918
970
 *  @param title The dialog title.
950
1002
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
951
1003
 
952
1004
        spin = gtk_spin_button_new_with_range(min, max, step);
953
 
        ui_entry_add_clear_icon(spin);
 
1005
        ui_entry_add_clear_icon(GTK_ENTRY(spin));
954
1006
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), *value);
955
1007
        g_signal_connect(spin, "activate", G_CALLBACK(on_input_numeric_activate), dialog);
956
1008
 
1050
1102
 
1051
1103
        gtk_window_set_default_size(GTK_WINDOW(dialog), 300, -1);
1052
1104
 
1053
 
        title = g_strdup_printf("<b>%s</b>", base_name);
1054
 
        label = gtk_label_new(title);
 
1105
        label = ui_label_new_bold(base_name);
1055
1106
        gtk_label_set_selectable(GTK_LABEL(label), TRUE);
1056
1107
        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1057
1108
        image = gtk_image_new_from_stock("gtk-file", GTK_ICON_SIZE_BUTTON);
1061
1112
        gtk_container_add(GTK_CONTAINER(hbox), image);
1062
1113
        gtk_container_add(GTK_CONTAINER(hbox), label);
1063
1114
        gtk_container_add(GTK_CONTAINER(vbox), hbox);
1064
 
        g_free(title);
1065
1115
 
1066
1116
        table = gtk_table_new(8, 2, FALSE);
1067
1117
        gtk_table_set_row_spacings(GTK_TABLE(table), 10);
1345
1395
}
1346
1396
 
1347
1397
 
1348
 
static gboolean show_question(GtkWidget *parent, const gchar *yes_btn, const gchar *no_btn,
1349
 
                                                          const gchar *question_text, const gchar *extra_text)
 
1398
/* extra_text can be NULL; otherwise it is displayed below main_text.
 
1399
 * if parent is NULL, main_widgets.window will be used
 
1400
 * btn_1, btn_2, btn_3 can be NULL.
 
1401
 * returns response_1, response_2 or response_3 */
 
1402
static gint show_prompt(GtkWidget *parent,
 
1403
                const gchar *btn_1, GtkResponseType response_1,
 
1404
                const gchar *btn_2, GtkResponseType response_2,
 
1405
                const gchar *btn_3, GtkResponseType response_3,
 
1406
                const gchar *question_text, const gchar *extra_text)
1350
1407
{
1351
1408
        gboolean ret = FALSE;
 
1409
        GtkWidget *dialog;
 
1410
        GtkWidget *btn;
 
1411
 
 
1412
        if (btn_2 == NULL)
 
1413
        {
 
1414
                btn_2 = GTK_STOCK_NO;
 
1415
                response_2 = GTK_RESPONSE_NO;
 
1416
        }
 
1417
        if (btn_3 == NULL)
 
1418
        {
 
1419
                btn_3 = GTK_STOCK_YES;
 
1420
                response_3 = GTK_RESPONSE_YES;
 
1421
        }
 
1422
 
1352
1423
#ifdef G_OS_WIN32
1353
 
        gchar *string = (extra_text == NULL) ? g_strdup(question_text) :
1354
 
                g_strconcat(question_text, "\n\n", extra_text, NULL);
1355
 
 
1356
 
        ret = win32_message_dialog(parent, GTK_MESSAGE_QUESTION, string);
1357
 
        g_free(string);
1358
 
#else
1359
 
        GtkWidget *dialog;
1360
 
 
 
1424
        /* our native dialog code doesn't support custom buttons */
 
1425
        if (btn_3 == GTK_STOCK_YES && btn_2 == GTK_STOCK_NO && btn_1 == NULL)
 
1426
        {
 
1427
                gchar *string = (extra_text == NULL) ? g_strdup(question_text) :
 
1428
                        g_strconcat(question_text, "\n\n", extra_text, NULL);
 
1429
 
 
1430
                ret = win32_message_dialog(parent, GTK_MESSAGE_QUESTION, string);
 
1431
                ret = ret ? response_3 : response_2;
 
1432
                g_free(string);
 
1433
                return ret;
 
1434
        }
 
1435
#endif
1361
1436
        if (parent == NULL && main_status.main_window_realized)
1362
1437
                parent = main_widgets.window;
1363
1438
 
1366
1441
                GTK_BUTTONS_NONE, "%s", question_text);
1367
1442
        gtk_widget_set_name(dialog, "GeanyDialog");
1368
1443
        gtk_window_set_title(GTK_WINDOW(dialog), _("Question"));
1369
 
        if (parent == NULL)
 
1444
        if (parent == NULL || GTK_IS_DIALOG(parent))
1370
1445
        {
1371
1446
                GdkPixbuf *pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
1372
1447
                gtk_window_set_icon(GTK_WINDOW(dialog), pb);
1378
1453
                gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1379
1454
                        "%s", extra_text);
1380
1455
 
 
1456
        if (btn_1 != NULL)
 
1457
                gtk_dialog_add_button(GTK_DIALOG(dialog), btn_1, response_1);
 
1458
 
1381
1459
        /* For a cancel button, use cancel response so user can press escape to cancel */
1382
 
        gtk_dialog_add_button(GTK_DIALOG(dialog), no_btn,
1383
 
                utils_str_equal(no_btn, GTK_STOCK_CANCEL) ? GTK_RESPONSE_CANCEL : GTK_RESPONSE_NO);
1384
 
        gtk_dialog_add_button(GTK_DIALOG(dialog), yes_btn, GTK_RESPONSE_YES);
 
1460
        btn = gtk_dialog_add_button(GTK_DIALOG(dialog), btn_2,
 
1461
                utils_str_equal(btn_2, GTK_STOCK_CANCEL) ? GTK_RESPONSE_CANCEL : response_2);
 
1462
        /* we don't want a default, but we need to override the apply button as default */
 
1463
        gtk_widget_grab_default(btn);
 
1464
        gtk_dialog_add_button(GTK_DIALOG(dialog), btn_3, response_3);
1385
1465
 
1386
 
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES)
1387
 
                ret = TRUE;
 
1466
        ret = gtk_dialog_run(GTK_DIALOG(dialog));
1388
1467
        gtk_widget_destroy(dialog);
1389
 
#endif
 
1468
 
 
1469
        if (ret == GTK_RESPONSE_CANCEL)
 
1470
                ret = response_2;
1390
1471
        return ret;
1391
1472
}
1392
1473
 
1393
1474
 
1394
1475
/**
1395
 
 *  Show a question message box with @a text and Yes/No buttons.
 
1476
 *  Shows a question message box with @a text and Yes/No buttons.
1396
1477
 *  On Unix-like systems a GTK message dialog box is shown, on Win32 systems a native Windows
1397
1478
 *  message dialog box is shown.
1398
1479
 *
1403
1484
 **/
1404
1485
gboolean dialogs_show_question(const gchar *text, ...)
1405
1486
{
1406
 
        gboolean ret = FALSE;
1407
 
        gchar string[512];
 
1487
        gchar *string;
1408
1488
        va_list args;
1409
1489
        GtkWidget *parent = (main_status.main_window_realized) ? main_widgets.window : NULL;
 
1490
        gint result;
1410
1491
 
1411
1492
        va_start(args, text);
1412
 
        g_vsnprintf(string, 511, text, args);
 
1493
        string = g_strdup_vprintf(text, args);
1413
1494
        va_end(args);
1414
 
        ret = show_question(parent, GTK_STOCK_YES, GTK_STOCK_NO, string, NULL);
1415
 
        return ret;
 
1495
        result = show_prompt(parent,
 
1496
                NULL, GTK_RESPONSE_NONE,
 
1497
                GTK_STOCK_NO, GTK_RESPONSE_NO,
 
1498
                GTK_STOCK_YES, GTK_RESPONSE_YES,
 
1499
                string, NULL);
 
1500
        g_free(string);
 
1501
        return (result == GTK_RESPONSE_YES);
1416
1502
}
1417
1503
 
1418
1504
 
1422
1508
gboolean dialogs_show_question_full(GtkWidget *parent, const gchar *yes_btn, const gchar *no_btn,
1423
1509
        const gchar *extra_text, const gchar *main_text, ...)
1424
1510
{
1425
 
        gboolean ret = FALSE;
1426
 
        gchar string[512];
1427
 
        va_list args;
1428
 
 
1429
 
        if (!yes_btn)
1430
 
                yes_btn = GTK_STOCK_YES;
1431
 
        if (!no_btn)
1432
 
                no_btn = GTK_STOCK_NO;
1433
 
 
1434
 
        va_start(args, main_text);
1435
 
        g_vsnprintf(string, 511, main_text, args);
1436
 
        va_end(args);
1437
 
        ret = show_question(parent, yes_btn, no_btn, string, extra_text);
1438
 
        return ret;
 
1511
        gint result;
 
1512
        gchar *string;
 
1513
        va_list args;
 
1514
 
 
1515
        va_start(args, main_text);
 
1516
        string = g_strdup_vprintf(main_text, args);
 
1517
        va_end(args);
 
1518
        result = show_prompt(parent,
 
1519
                NULL, GTK_RESPONSE_NONE,
 
1520
                no_btn, GTK_RESPONSE_NO,
 
1521
                yes_btn, GTK_RESPONSE_YES,
 
1522
                string, extra_text);
 
1523
        g_free(string);
 
1524
        return (result == GTK_RESPONSE_YES);
 
1525
}
 
1526
 
 
1527
 
 
1528
/* extra_text can be NULL; otherwise it is displayed below main_text.
 
1529
 * if parent is NULL, main_widgets.window will be used
 
1530
 * btn_1, btn_2, btn_3 can be NULL.
 
1531
 * returns response_1, response_2 or response_3 */
 
1532
gint dialogs_show_prompt(GtkWidget *parent,
 
1533
                const gchar *btn_1, GtkResponseType response_1,
 
1534
                const gchar *btn_2, GtkResponseType response_2,
 
1535
                const gchar *btn_3, GtkResponseType response_3,
 
1536
                const gchar *extra_text, const gchar *main_text, ...)
 
1537
{
 
1538
        gchar *string;
 
1539
        va_list args;
 
1540
        gint result;
 
1541
 
 
1542
        va_start(args, main_text);
 
1543
        string = g_strdup_vprintf(main_text, args);
 
1544
        va_end(args);
 
1545
        result = show_prompt(parent, btn_1, response_1, btn_2, response_2, btn_3, response_3,
 
1546
                                string, extra_text);
 
1547
        g_free(string);
 
1548
        return result;
1439
1549
}
1440
1550
 
1441
1551