75
74
GtkWidget *description;
76
75
GtkWidget *file_name;
77
76
GtkWidget *base_path;
78
GtkWidget *make_in_base_path;
80
77
GtkWidget *patterns;
78
BuildTableData build_properties;
81
79
} PropertyDialogElements;
85
83
static gboolean update_config(const PropertyDialogElements *e);
86
84
static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e);
87
static void on_file_open_button_clicked(GtkButton *button, PropertyDialogElements *e);
88
85
static gboolean load_config(const gchar *filename);
89
86
static gboolean write_config(gboolean emit_signal);
90
87
static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e);
91
88
static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e);
89
static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line);
90
static void apply_editor_prefs(void);
94
93
#define SHOW_ERR(args) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args)
95
#define SHOW_ERR1(args,more) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args, more)
94
#define SHOW_ERR1(args, more) dialogs_show_msgbox(GTK_MESSAGE_ERROR, args, more)
96
95
#define MAX_NAME_LEN 50
97
96
/* "projects" is part of the default project base path so be careful when translating
98
97
* please avoid special characters and spaces, look at the source for details or ask Frank */
316
309
/* Called when creating, opening, closing and updating projects. */
317
310
static void update_ui(void)
312
if (main_status.quitting)
319
315
ui_set_window_title(NULL);
320
316
build_menu_update(NULL);
321
treeviews_openfiles_update_all();
317
sidebar_openfiles_update_all();
321
static void remove_foreach_project_filetype(gpointer data, gpointer user_data)
323
GeanyFiletype *ft = (GeanyFiletype*)data;
326
setptr(ft->projfilecmds, NULL);
327
setptr(ft->projexeccmds, NULL);
328
setptr(ft->projerror_regex_string, NULL);
329
ft->project_list_entry = -1;
332
341
/* use write_config() to save project session files */
333
342
write_config(FALSE);
344
/* remove project filetypes build entries */
345
if (app->project->build_filetypes_list != NULL)
347
g_ptr_array_foreach(app->project->build_filetypes_list, remove_foreach_project_filetype, NULL);
348
g_ptr_array_free(app->project->build_filetypes_list, FALSE);
351
/* remove project non filetype build menu items */
352
build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_NON_FT, -1);
353
build_remove_menu_item(GEANY_BCS_PROJ, GEANY_GBG_EXEC, -1);
335
355
g_free(app->project->name);
336
356
g_free(app->project->description);
337
357
g_free(app->project->file_name);
338
358
g_free(app->project->base_path);
339
g_free(app->project->run_cmd);
341
360
g_free(app->project);
342
361
app->project = NULL;
363
apply_editor_prefs(); /* ensure that global settings are restored */
344
365
if (project_prefs.project_session)
346
367
/* close all existing tabs first */
385
static void on_set_use_base_path_clicked(GtkWidget *unused1, gpointer user_data)
387
build_set_non_ft_wd_to_proj((BuildTableData)user_data);
364
391
static void create_properties_dialog(PropertyDialogElements *e)
366
GtkWidget *table, *notebook;
393
GtkWidget *table, *notebook, *build_table;
368
394
GtkWidget *button;
370
396
GtkWidget *label;
398
GeanyDocument *doc = document_get_current();
399
GeanyFiletype *ft = NULL;
373
401
e->dialog = create_project_dialog();
374
402
gtk_window_set_transient_for(GTK_WINDOW(e->dialog), GTK_WINDOW(main_widgets.window));
375
403
gtk_window_set_destroy_with_parent(GTK_WINDOW(e->dialog), TRUE);
376
404
gtk_widget_set_name(e->dialog, "GeanyDialogProject");
378
ui_entry_add_clear_icon(ui_lookup_widget(e->dialog, "spin_indent_width"));
379
ui_entry_add_clear_icon(ui_lookup_widget(e->dialog, "spin_tab_width"));
406
ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(e->dialog, "spin_indent_width")));
381
408
table = gtk_table_new(6, 2, FALSE);
382
409
gtk_container_set_border_width(GTK_CONTAINER(table), 6);
387
414
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
388
415
(GtkAttachOptions) (GTK_FILL),
389
416
(GtkAttachOptions) (0), 0, 0);
390
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
417
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
392
419
e->name = gtk_entry_new();
393
ui_entry_add_clear_icon(e->name);
420
ui_entry_add_clear_icon(GTK_ENTRY(e->name));
394
421
gtk_entry_set_max_length(GTK_ENTRY(e->name), MAX_NAME_LEN);
395
422
gtk_table_attach(GTK_TABLE(table), e->name, 1, 2, 0, 1,
396
423
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
400
427
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
401
428
(GtkAttachOptions) (GTK_FILL),
402
429
(GtkAttachOptions) (0), 0, 0);
403
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
430
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
405
432
e->file_name = gtk_entry_new();
406
ui_entry_add_clear_icon(e->file_name);
433
ui_entry_add_clear_icon(GTK_ENTRY(e->file_name));
407
434
gtk_editable_set_editable(GTK_EDITABLE(e->file_name), FALSE); /* read-only */
408
435
gtk_table_attach(GTK_TABLE(table), e->file_name, 1, 2, 1, 2,
409
436
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
413
440
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
414
441
(GtkAttachOptions) (GTK_FILL),
415
442
(GtkAttachOptions) (GTK_FILL), 0, 0);
416
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
443
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
418
445
e->description = gtk_text_view_new();
419
446
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(e->description), GTK_WRAP_WORD);
430
457
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4,
431
458
(GtkAttachOptions) (GTK_FILL),
432
459
(GtkAttachOptions) (0), 0, 0);
433
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
460
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
435
462
e->base_path = gtk_entry_new();
436
ui_entry_add_clear_icon(e->base_path);
463
ui_entry_add_clear_icon(GTK_ENTRY(e->base_path));
437
464
ui_widget_set_tooltip_text(e->base_path,
438
465
_("Base directory of all files that make up the project. "
439
466
"This can be a new path, or an existing directory tree. "
444
471
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
445
472
(GtkAttachOptions) (0), 0, 0);
447
e->make_in_base_path = gtk_check_button_new_with_label(_("Make in base path"));
448
gtk_table_attach(GTK_TABLE(table), e->make_in_base_path, 0, 3, 4, 5,
449
(GtkAttachOptions) (GTK_FILL),
450
(GtkAttachOptions) (0), 0, 0);
452
label = gtk_label_new(_("Run command:"));
453
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6,
454
(GtkAttachOptions) (GTK_FILL),
455
(GtkAttachOptions) (0), 0, 0);
456
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
458
e->run_cmd = gtk_entry_new();
459
ui_entry_add_clear_icon(e->run_cmd);
460
ui_widget_set_tooltip_text(e->run_cmd,
461
_("Command-line to run in the project base directory. "
462
"Options can be appended to the command. "
463
"Leave blank to use the default run command."));
464
button = gtk_button_new();
465
g_signal_connect(button, "clicked", G_CALLBACK(on_file_open_button_clicked), e);
466
image = gtk_image_new_from_stock("gtk-open", GTK_ICON_SIZE_BUTTON);
467
gtk_container_add(GTK_CONTAINER(button), image);
474
if (doc != NULL) ft = doc->file_type;
475
build_table = build_commands_table(doc, GEANY_BCS_PROJ, &(e->build_properties), ft);
476
gtk_container_set_border_width(GTK_CONTAINER(build_table), 6);
477
label = gtk_label_new(_("Build"));
478
notebook = ui_lookup_widget(e->dialog, "project_notebook");
479
gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), build_table, label, 2);
481
label = gtk_label_new(_("Set the Build non-filetype working directories to use base path:"));
482
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
484
button = gtk_button_new_with_label(_("Set"));
485
ui_widget_set_tooltip_text(button,
486
_("Set the working directories (on the Build tab) "
487
"for the non-filetype build commands to use the base path"));
488
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
489
g_signal_connect(button, "clicked", G_CALLBACK(on_set_use_base_path_clicked), e->build_properties);
468
490
bbox = gtk_hbox_new(FALSE, 6);
469
gtk_box_pack_start_defaults(GTK_BOX(bbox), e->run_cmd);
491
gtk_box_pack_start(GTK_BOX(bbox), label, TRUE, TRUE, 0);
470
492
gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
471
gtk_table_attach(GTK_TABLE(table), bbox, 1, 2, 5, 6,
493
gtk_table_attach(GTK_TABLE(table), bbox, 0, 2, 4, 5,
472
494
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
473
(GtkAttachOptions) (0), 0, 0);
495
(GtkAttachOptions) (GTK_FILL), 0, 0);
497
g_signal_connect(ui_lookup_widget(e->dialog, "radio_long_line_custom"), "toggled",
498
G_CALLBACK(on_radio_long_line_custom_toggled), ui_lookup_widget(e->dialog, "spin_long_line"));
476
501
label = gtk_label_new(_("File patterns:"));
516
541
/* fill the elements with the appropriate data */
517
542
gtk_entry_set_text(GTK_ENTRY(e->name), p->name);
543
gtk_entry_set_text(GTK_ENTRY(e->file_name), p->file_name);
544
gtk_entry_set_text(GTK_ENTRY(e->base_path), p->base_path);
546
radio_long_line_custom = ui_lookup_widget(e->dialog, "radio_long_line_custom");
547
switch (p->long_line_behaviour)
549
case 0: widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled"); break;
550
case 1: widget = ui_lookup_widget(e->dialog, "radio_long_line_default"); break;
551
case 2: widget = radio_long_line_custom; break;
553
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
555
widget = ui_lookup_widget(e->dialog, "spin_long_line");
556
gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (gdouble)p->long_line_column);
557
on_radio_long_line_custom_toggled(GTK_TOGGLE_BUTTON(radio_long_line_custom), widget);
519
559
if (p->description != NULL)
546
gtk_entry_set_text(GTK_ENTRY(e->file_name), p->file_name);
547
gtk_entry_set_text(GTK_ENTRY(e->base_path), p->base_path);
548
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->make_in_base_path),
549
p->make_in_base_path);
550
if (p->run_cmd != NULL)
551
gtk_entry_set_text(GTK_ENTRY(e->run_cmd), p->run_cmd);
553
586
gtk_widget_show_all(e->dialog);
556
response = gtk_dialog_run(GTK_DIALOG(e->dialog));
557
if (response == GTK_RESPONSE_OK)
588
while (gtk_dialog_run(GTK_DIALOG(e->dialog)) == GTK_RESPONSE_OK)
559
if (! update_config(e))
562
stash_group_update(indent_group, e->dialog);
590
if (update_config(e))
592
stash_group_update(indent_group, e->dialog);
596
build_free_fields(e->build_properties);
565
597
gtk_widget_destroy(e->dialog);
714
748
gtk_text_buffer_get_end_iter(buffer, &end);
715
749
setptr(p->description, g_strdup(gtk_text_buffer_get_text(buffer, &start, &end, FALSE)));
751
/* read the project build menu */
752
oldvalue = ft ? ft->projfilecmds : NULL;
753
build_read_project(ft, e->build_properties);
755
if (ft != NULL && ft->projfilecmds != oldvalue && ft->project_list_entry < 0)
757
if (p->build_filetypes_list == NULL)
758
p->build_filetypes_list = g_ptr_array_new();
759
ft->project_list_entry = p->build_filetypes_list->len;
760
g_ptr_array_add(p->build_filetypes_list, ft);
762
build_menu_update(doc);
764
widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled");
765
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
766
p->long_line_behaviour = 0;
769
widget = ui_lookup_widget(e->dialog, "radio_long_line_default");
770
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
771
p->long_line_behaviour = 1;
773
/* "Custom" radio button must be checked */
774
p->long_line_behaviour = 2;
777
widget = ui_lookup_widget(e->dialog, "spin_long_line");
778
p->long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
779
apply_editor_prefs();
718
782
/* get and set the project file patterns */
719
783
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->patterns));
824
static void on_file_open_button_clicked(GtkButton *button, PropertyDialogElements *e)
827
gchar *path = win32_show_project_open_dialog(e->dialog, _("Choose Project Run Command"),
828
gtk_entry_get_text(GTK_ENTRY(e->run_cmd)), FALSE, FALSE);
831
gtk_entry_set_text(GTK_ENTRY(e->run_cmd), path);
837
/* initialise the dialog */
838
dialog = gtk_file_chooser_dialog_new(_("Choose Project Run Command"), NULL,
839
GTK_FILE_CHOOSER_ACTION_OPEN,
840
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
841
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
842
gtk_widget_set_name(dialog, "GeanyDialog");
843
gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
844
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE);
845
gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
846
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
848
run_dialog(dialog, e->run_cmd);
853
887
/* sets the project base path and the project file name according to the project name */
854
888
static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e)
948
988
p->description = utils_get_setting_string(config, "project", "description", "");
949
989
p->file_name = utils_get_utf8_from_locale(filename);
950
990
p->base_path = utils_get_setting_string(config, "project", "base_path", "");
951
p->make_in_base_path = utils_get_setting_boolean(config, "project", "make_in_base_path", TRUE);
952
p->run_cmd = utils_get_setting_string(config, "project", "run_cmd", "");
953
991
p->file_patterns = g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL);
993
p->long_line_behaviour = utils_get_setting_integer(config, "long line marker",
994
"long_line_behaviour", 1 /* follow global */);
995
p->long_line_column = utils_get_setting_integer(config, "long line marker",
996
"long_line_column", editor_prefs.long_line_global_column);
997
apply_editor_prefs();
999
build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p);
955
1000
if (project_prefs.project_session)
957
1002
/* save current (non-project) session (it could has been changed since program startup) */
999
1053
if (p->description)
1000
1054
g_key_file_set_string(config, "project", "description", p->description);
1001
g_key_file_set_boolean(config, "project", "make_in_base_path", p->make_in_base_path);
1003
g_key_file_set_string(config, "project", "run_cmd", p->run_cmd);
1004
1055
if (p->file_patterns)
1005
1056
g_key_file_set_string_list(config, "project", "file_patterns",
1006
1057
(const gchar**) p->file_patterns, g_strv_length(p->file_patterns));
1059
g_key_file_set_integer(config, "long line marker", "long_line_behaviour", p->long_line_behaviour);
1060
g_key_file_set_integer(config, "long line marker", "long_line_column", p->long_line_column);
1008
1062
/* store the session files into the project too */
1009
1063
if (project_prefs.project_session)
1010
1064
configuration_save_session_files(config);
1065
build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ);
1012
1066
if (emit_signal)
1014
1068
g_signal_emit_by_name(geany_object, "project-save", config);
1149
1190
"radio_indent_tabs", GEANY_INDENT_TYPE_TABS,
1150
1191
"radio_indent_both", GEANY_INDENT_TYPE_BOTH,
1152
stash_group_add_spin_button_integer(group, &indentation.hard_tab_width,
1153
"indent_hard_tab_width", 8, "spin_tab_width");
1193
/* This is a 'hidden' pref for backwards-compatibility */
1194
stash_group_add_integer(group, &indentation.hard_tab_width,
1195
"indent_hard_tab_width", 8);
1154
1196
stash_group_add_toggle_button(group, &indentation.detect_type,
1155
1197
"detect_indent", FALSE, "check_detect_indent");
1156
1198
stash_group_add_combo_box(group, (gint*)(gpointer)&indentation.auto_indent_mode,