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 */
90
94
/* ignore detect from file item */
91
if (filetype_idx > 0 && filetype_idx < GEANY_MAX_BUILT_IN_FILETYPES)
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;
222
225
setptr(initdir, utils_get_locale_from_utf8(initdir));
224
#if GEANY_USE_WIN32_DIALOG
225
win32_show_file_dialog(TRUE, initdir);
226
#else /* X11, not win32: use GTK_FILE_CHOOSER */
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();
228
if (interface_prefs.use_native_windows_dialogs)
229
win32_show_document_open_dialog(GTK_WINDOW(main_widgets.window), _("Open File"), initdir);
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();
240
if (g_path_is_absolute(initdir))
241
gtk_file_chooser_set_current_folder(
242
GTK_FILE_CHOOSER(ui_widgets.open_filesel), initdir);
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);
249
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
250
gtk_window_present(GTK_WINDOW(ui_widgets.open_filesel));
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);
244
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(ui_widgets.open_filesel));
245
gtk_window_present(GTK_WINDOW(ui_widgets.open_filesel));
251
#if ! GEANY_USE_WIN32_DIALOG
252
256
static GtkWidget *add_file_open_extra_widget()
254
258
GtkWidget *expander, *vbox, *table, *check_hidden;
327
#if ! GEANY_USE_WIN32_DIALOG
328
330
static void on_save_as_new_tab_toggled(GtkToggleButton *togglebutton, gpointer user_data)
330
332
gtk_widget_set_sensitive(GTK_WIDGET(user_data),
331
333
! gtk_toggle_button_get_active(togglebutton));
336
#if ! GEANY_USE_WIN32_DIALOG
337
337
static gboolean handle_save_as(const gchar *utf8_filename, gboolean open_new_tab, gboolean rename_file)
339
339
GeanyDocument *doc = document_get_current();
473
471
gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.save_filesel), GTK_WINDOW(main_widgets.window));
478
#if ! GEANY_USE_WIN32_DIALOG
479
475
static gboolean gtk_show_save_as(void)
481
477
GeanyDocument *doc = document_get_current();
480
g_return_val_if_fail(doc != NULL, FALSE);
484
482
if (G_UNLIKELY(ui_widgets.save_filesel == NULL))
485
483
create_save_file_dialog();
537
534
return (resp == GTK_RESPONSE_ACCEPT);
543
* Show the Save As dialog for the current notebook page.
539
* Shows the Save As dialog for the current notebook page.
545
541
* @return @c TRUE if the file was saved, otherwise @c FALSE.
547
543
gboolean dialogs_show_save_as()
545
gboolean result = FALSE;
551
#if GEANY_USE_WIN32_DIALOG
552
result = win32_show_file_dialog(FALSE, utils_get_default_dir_utf8());
548
if (interface_prefs.use_native_windows_dialogs)
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);
554
558
result = gtk_show_save_as();
836
gtk_widget_hide(GTK_WIDGET(dialog));
838
gtk_widget_destroy(GTK_WIDGET(dialog));
838
gtk_widget_hide(GTK_WIDGET(dialog));
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)
845
GtkWidget *label, *entry;
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);
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);
852
856
if (persistent) /* remember previous entry text in a combo box */
854
858
GtkWidget *combo = gtk_combo_box_entry_new_text();
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);
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);
872
876
gtk_entry_set_max_length(GTK_ENTRY(entry), 255);
873
877
gtk_entry_set_width_chars(GTK_ENTRY(entry), 30);
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. */
887
dialogs_show_input(const gchar *title, const gchar *label_text, const gchar *default_text,
888
gboolean persistent, InputCallback input_cb)
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)
890
896
GtkWidget *dialog, *vbox;
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);
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);
912
/* override default handler */
905
913
g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
907
g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL);
914
gtk_widget_show_all(dialog);
909
917
gtk_widget_show_all(dialog);
918
gtk_dialog_run(GTK_DIALOG(dialog));
919
gtk_widget_destroy(dialog);
924
/* Remember previous entry text in a combo box.
925
* Returns: the dialog widget. */
927
dialogs_show_input_persistent(const gchar *title, const gchar *label_text, const gchar *default_text,
928
GeanyInputCallback input_cb)
930
return dialogs_show_input_full(title, label_text, default_text, TRUE, input_cb, NULL);
934
/* ugly hack - user_data not supported for callback */
935
static gchar *dialog_input = NULL;
937
static void on_dialog_input(const gchar *str)
939
dialog_input = g_strdup(str);
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)
948
dialogs_show_input_full(title, label_text, default_text, FALSE, on_dialog_input, NULL);
949
return NVL(dialog_input, g_strdup(default_text));
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)
959
dialogs_show_input_full(
960
title, label_text, default_text, FALSE, on_dialog_input,
961
G_CALLBACK(ui_editable_insert_text_callback));
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.
918
970
* @param title The dialog title.
950
1002
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
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);
1051
1103
gtk_window_set_default_size(GTK_WINDOW(dialog), 300, -1);
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);
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)
1351
1408
gboolean ret = FALSE;
1414
btn_2 = GTK_STOCK_NO;
1415
response_2 = GTK_RESPONSE_NO;
1419
btn_3 = GTK_STOCK_YES;
1420
response_3 = GTK_RESPONSE_YES;
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);
1356
ret = win32_message_dialog(parent, GTK_MESSAGE_QUESTION, string);
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)
1427
gchar *string = (extra_text == NULL) ? g_strdup(question_text) :
1428
g_strconcat(question_text, "\n\n", extra_text, NULL);
1430
ret = win32_message_dialog(parent, GTK_MESSAGE_QUESTION, string);
1431
ret = ret ? response_3 : response_2;
1361
1436
if (parent == NULL && main_status.main_window_realized)
1362
1437
parent = main_widgets.window;
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"));
1444
if (parent == NULL || GTK_IS_DIALOG(parent))
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);
1457
gtk_dialog_add_button(GTK_DIALOG(dialog), btn_1, response_1);
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);
1386
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES)
1466
ret = gtk_dialog_run(GTK_DIALOG(dialog));
1388
1467
gtk_widget_destroy(dialog);
1469
if (ret == GTK_RESPONSE_CANCEL)
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.
1404
1485
gboolean dialogs_show_question(const gchar *text, ...)
1406
gboolean ret = FALSE;
1409
1489
GtkWidget *parent = (main_status.main_window_realized) ? main_widgets.window : NULL;
1411
1492
va_start(args, text);
1412
g_vsnprintf(string, 511, text, args);
1493
string = g_strdup_vprintf(text, args);
1414
ret = show_question(parent, GTK_STOCK_YES, GTK_STOCK_NO, string, NULL);
1495
result = show_prompt(parent,
1496
NULL, GTK_RESPONSE_NONE,
1497
GTK_STOCK_NO, GTK_RESPONSE_NO,
1498
GTK_STOCK_YES, GTK_RESPONSE_YES,
1501
return (result == GTK_RESPONSE_YES);
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, ...)
1425
gboolean ret = FALSE;
1430
yes_btn = GTK_STOCK_YES;
1432
no_btn = GTK_STOCK_NO;
1434
va_start(args, main_text);
1435
g_vsnprintf(string, 511, main_text, args);
1437
ret = show_question(parent, yes_btn, no_btn, string, extra_text);
1515
va_start(args, main_text);
1516
string = g_strdup_vprintf(main_text, 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);
1524
return (result == GTK_RESPONSE_YES);
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, ...)
1542
va_start(args, main_text);
1543
string = g_strdup_vprintf(main_text, args);
1545
result = show_prompt(parent, btn_1, response_1, btn_2, response_2, btn_3, response_3,
1546
string, extra_text);