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

« back to all changes in this revision

Viewing changes to src/project.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: project.c 4630 2010-01-31 21:54:47Z eht16 $
 
21
 * $Id: project.c 4921 2010-05-16 17:43:24Z eht16 $
22
22
 */
23
23
 
24
24
/** @file project.h
41
41
#include "msgwindow.h"
42
42
#include "main.h"
43
43
#include "keyfile.h"
44
 
#ifdef G_OS_WIN32
45
 
# include "win32.h"
46
 
#endif
 
44
#include "win32.h"
47
45
#include "build.h"
48
46
#include "interface.h"
49
47
#include "editor.h"
50
48
#include "stash.h"
51
 
#include "treeviews.h"
 
49
#include "sidebar.h"
 
50
#include "filetypes.h"
52
51
 
53
52
 
54
53
ProjectPrefs project_prefs = { NULL, FALSE, FALSE };
57
56
static GeanyProjectPrivate priv;
58
57
static GeanyIndentPrefs indentation;
59
58
 
60
 
static GeanyPrefGroup *indent_group = NULL;
 
59
static StashGroup *indent_group = NULL;
61
60
 
62
61
static struct
63
62
{
64
63
        gchar *project_file_path; /* in UTF-8 */
65
 
} local_prefs = {NULL};
 
64
} local_prefs = { NULL };
66
65
 
67
66
 
68
67
static gboolean entries_modified;
75
74
        GtkWidget *description;
76
75
        GtkWidget *file_name;
77
76
        GtkWidget *base_path;
78
 
        GtkWidget *make_in_base_path;
79
 
        GtkWidget *run_cmd;
80
77
        GtkWidget *patterns;
 
78
        BuildTableData  build_properties;
81
79
} PropertyDialogElements;
82
80
 
83
81
 
84
82
 
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);
92
91
 
93
92
 
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 */
108
107
        GtkWidget *bbox;
109
108
        GtkWidget *label;
110
109
        PropertyDialogElements *e;
111
 
        gint response;
112
110
 
113
 
        if (! project_ask_close()) return;
 
111
        if (! project_ask_close())
 
112
                return;
114
113
 
115
114
        g_return_if_fail(app->project == NULL);
116
115
 
141
140
        gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
142
141
 
143
142
        e->name = gtk_entry_new();
144
 
        ui_entry_add_clear_icon(e->name);
 
143
        ui_entry_add_clear_icon(GTK_ENTRY(e->name));
145
144
        gtk_entry_set_max_length(GTK_ENTRY(e->name), MAX_NAME_LEN);
146
145
 
147
146
        ui_table_add_row(GTK_TABLE(table), 0, label, e->name, NULL);
150
149
        gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
151
150
 
152
151
        e->file_name = gtk_entry_new();
153
 
        ui_entry_add_clear_icon(e->file_name);
 
152
        ui_entry_add_clear_icon(GTK_ENTRY(e->file_name));
154
153
        gtk_entry_set_width_chars(GTK_ENTRY(e->file_name), 30);
155
154
        button = gtk_button_new();
156
155
        g_signal_connect(button, "clicked", G_CALLBACK(on_file_save_button_clicked), e);
166
165
        gtk_misc_set_alignment(GTK_MISC(label), 1, 0);
167
166
 
168
167
        e->base_path = gtk_entry_new();
169
 
        ui_entry_add_clear_icon(e->base_path);
 
168
        ui_entry_add_clear_icon(GTK_ENTRY(e->base_path));
170
169
        ui_widget_set_tooltip_text(e->base_path,
171
170
                _("Base directory of all files that make up the project. "
172
171
                "This can be a new path, or an existing directory tree. "
188
187
 
189
188
        gtk_widget_show_all(e->dialog);
190
189
 
191
 
        retry:
192
 
        response = gtk_dialog_run(GTK_DIALOG(e->dialog));
193
 
        if (response == GTK_RESPONSE_OK)
 
190
        while (gtk_dialog_run(GTK_DIALOG(e->dialog)) == GTK_RESPONSE_OK)
194
191
        {
195
 
                if (! update_config(e))
196
 
                        goto retry;
197
 
                else
 
192
                if (update_config(e))
 
193
                {
198
194
                        ui_add_recent_project_file(app->project->file_name);
 
195
                        break;
 
196
                }
199
197
        }
200
 
 
201
198
        gtk_widget_destroy(e->dialog);
202
199
        g_free(e);
203
200
}
222
219
#ifndef G_OS_WIN32
223
220
static void run_open_dialog(GtkDialog *dialog)
224
221
{
225
 
        gint response;
226
 
 
227
 
        retry:
228
 
        response = gtk_dialog_run(dialog);
229
 
 
230
 
        if (response == GTK_RESPONSE_ACCEPT)
 
222
        while (gtk_dialog_run(dialog) == GTK_RESPONSE_ACCEPT)
231
223
        {
232
224
                gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
233
225
 
240
232
                        gtk_widget_grab_focus(GTK_WIDGET(dialog));
241
233
                        g_free(utf8_filename);
242
234
                        g_free(filename);
243
 
                        goto retry;
 
235
                        continue;
244
236
                }
245
237
                g_free(filename);
 
238
                break;
246
239
        }
247
240
}
248
241
#endif
316
309
/* Called when creating, opening, closing and updating projects. */
317
310
static void update_ui(void)
318
311
{
 
312
        if (main_status.quitting)
 
313
                return;
 
314
 
319
315
        ui_set_window_title(NULL);
320
316
        build_menu_update(NULL);
321
 
        treeviews_openfiles_update_all();
 
317
        sidebar_openfiles_update_all();
 
318
}
 
319
 
 
320
 
 
321
static void remove_foreach_project_filetype(gpointer data, gpointer user_data)
 
322
{
 
323
        GeanyFiletype *ft = (GeanyFiletype*)data;
 
324
        if (ft != NULL)
 
325
        {
 
326
                setptr(ft->projfilecmds, NULL);
 
327
                setptr(ft->projexeccmds, NULL);
 
328
                setptr(ft->projerror_regex_string, NULL);
 
329
                ft->project_list_entry = -1;
 
330
        }
322
331
}
323
332
 
324
333
 
332
341
        /* use write_config() to save project session files */
333
342
        write_config(FALSE);
334
343
 
 
344
        /* remove project filetypes build entries */
 
345
        if (app->project->build_filetypes_list != NULL)
 
346
        {
 
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);
 
349
        }
 
350
 
 
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);
 
354
 
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);
340
359
 
341
360
        g_free(app->project);
342
361
        app->project = NULL;
343
362
 
 
363
        apply_editor_prefs(); /* ensure that global settings are restored */
 
364
 
344
365
        if (project_prefs.project_session)
345
366
        {
346
367
                /* close all existing tabs first */
361
382
}
362
383
 
363
384
 
 
385
static void on_set_use_base_path_clicked(GtkWidget *unused1, gpointer user_data)
 
386
{
 
387
        build_set_non_ft_wd_to_proj((BuildTableData)user_data);
 
388
}
 
389
 
 
390
 
364
391
static void create_properties_dialog(PropertyDialogElements *e)
365
392
{
366
 
        GtkWidget *table, *notebook;
367
 
        GtkWidget *image;
 
393
        GtkWidget *table, *notebook, *build_table;
368
394
        GtkWidget *button;
369
395
        GtkWidget *bbox;
370
396
        GtkWidget *label;
371
397
        GtkWidget *swin;
 
398
        GeanyDocument *doc = document_get_current();
 
399
        GeanyFiletype *ft = NULL;
372
400
 
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");
377
405
 
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")));
380
407
 
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);
391
418
 
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);
404
431
 
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);
417
444
 
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);
434
461
 
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);
446
473
 
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);
451
 
 
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);
457
 
 
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);
 
480
 
 
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);
 
483
 
 
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);
 
496
 
 
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"));
474
499
 
475
500
#if 0
476
501
        label = gtk_label_new(_("File patterns:"));
478
503
        gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7,
479
504
                                        (GtkAttachOptions) (GTK_FILL),
480
505
                                        (GtkAttachOptions) (GTK_FILL), 0, 0);
481
 
        gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
 
506
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
482
507
 
483
508
        e->patterns = gtk_text_view_new();
484
509
        swin = gtk_scrolled_window_new(NULL, NULL);
491
516
                                        (GtkAttachOptions) (0), 0, 0);
492
517
#endif
493
518
 
494
 
        notebook = ui_lookup_widget(e->dialog, "project_notebook");
495
519
        label = gtk_label_new(_("Project"));
496
520
        gtk_widget_show(table); /* needed to switch current page */
497
521
        gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), table, label, 0);
503
527
{
504
528
        PropertyDialogElements *e = g_new(PropertyDialogElements, 1);
505
529
        GeanyProject *p = app->project;
506
 
        gint response;
 
530
        GtkWidget *widget = NULL;
 
531
        GtkWidget *radio_long_line_custom;
507
532
 
508
533
        g_return_if_fail(app->project != NULL);
509
534
 
515
540
 
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);
 
545
 
 
546
        radio_long_line_custom = ui_lookup_widget(e->dialog, "radio_long_line_custom");
 
547
        switch (p->long_line_behaviour)
 
548
        {
 
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;
 
552
        }
 
553
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
 
554
 
 
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);
518
558
 
519
559
        if (p->description != NULL)
520
560
        {       /* set text */
543
583
        }
544
584
#endif
545
585
 
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);
552
 
 
553
586
        gtk_widget_show_all(e->dialog);
554
587
 
555
 
        retry:
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)
558
589
        {
559
 
                if (! update_config(e))
560
 
                        goto retry;
561
 
 
562
 
                stash_group_update(indent_group, e->dialog);
 
590
                if (update_config(e))
 
591
                {
 
592
                        stash_group_update(indent_group, e->dialog);
 
593
                        break;
 
594
                }
563
595
        }
564
 
 
 
596
        build_free_fields(e->build_properties);
565
597
        gtk_widget_destroy(e->dialog);
566
598
        g_free(e);
567
599
}
598
630
        priv.indentation = &indentation;
599
631
        project->priv = &priv;
600
632
 
 
633
        project->long_line_behaviour = 1 /* use global settings */;
 
634
        project->long_line_column = editor_prefs.long_line_global_column;
 
635
 
601
636
        app->project = project;
602
637
        return project;
603
638
}
701
736
        if (! new_project)      /* save properties specific fields */
702
737
        {
703
738
                GtkTextIter start, end;
704
 
                /*gchar *tmp;*/
705
739
                GtkTextBuffer *buffer;
706
 
 
707
 
                p->make_in_base_path = gtk_toggle_button_get_active(
708
 
                        GTK_TOGGLE_BUTTON(e->make_in_base_path));
709
 
                setptr(p->run_cmd, g_strdup(gtk_entry_get_text(GTK_ENTRY(e->run_cmd))));
 
740
                GeanyDocument *doc = document_get_current();
 
741
                GeanyBuildCommand *oldvalue;
 
742
                GeanyFiletype *ft = doc ? doc->file_type : NULL;
 
743
                GtkWidget *widget;
710
744
 
711
745
                /* get and set the project description */
712
746
                buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->description));
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)));
716
750
 
 
751
                /* read the project build menu */
 
752
                oldvalue = ft ? ft->projfilecmds : NULL;
 
753
                build_read_project(ft, e->build_properties);
 
754
 
 
755
                if (ft != NULL && ft->projfilecmds != oldvalue && ft->project_list_entry < 0)
 
756
                {
 
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);
 
761
                }
 
762
                build_menu_update(doc);
 
763
 
 
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;
 
767
                else
 
768
                {
 
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;
 
772
                        else
 
773
                                /* "Custom" radio button must be checked */
 
774
                                p->long_line_behaviour = 2;
 
775
                }
 
776
 
 
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();
 
780
 
717
781
#if 0
718
782
                /* get and set the project file patterns */
719
783
                buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->patterns));
769
833
                        g_free(locale_dir);
770
834
                }
771
835
        }
772
 
        else
773
 
        if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN)
 
836
        else if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN)
774
837
        {
775
838
                gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), utf8_filename);
776
839
        }
821
884
}
822
885
 
823
886
 
824
 
static void on_file_open_button_clicked(GtkButton *button, PropertyDialogElements *e)
825
 
{
826
 
#ifdef G_OS_WIN32
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);
829
 
        if (path != NULL)
830
 
        {
831
 
                gtk_entry_set_text(GTK_ENTRY(e->run_cmd), path);
832
 
                g_free(path);
833
 
        }
834
 
#else
835
 
        GtkWidget *dialog;
836
 
 
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);
847
 
 
848
 
        run_dialog(dialog, e->run_cmd);
849
 
#endif
850
 
}
851
 
 
852
 
 
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)
855
889
{
862
896
                return;
863
897
 
864
898
        name = gtk_editable_get_chars(editable, 0, -1);
865
 
        if (name != NULL && strlen(name) > 0)
 
899
        if (NZV(name))
866
900
        {
867
901
                base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S,
868
902
                        name, G_DIR_SEPARATOR_S, NULL);
896
930
}
897
931
 
898
932
 
 
933
static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line)
 
934
{
 
935
        gtk_widget_set_sensitive(spin_long_line, gtk_toggle_button_get_active(radio));
 
936
}
 
937
 
 
938
 
899
939
gboolean project_load_file(const gchar *locale_file_name)
900
940
{
901
941
        g_return_val_if_fail(locale_file_name != NULL, FALSE);
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);
954
992
 
 
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();
 
998
 
 
999
        build_load_menu(config, GEANY_BCS_PROJ, (gpointer)p);
955
1000
        if (project_prefs.project_session)
956
1001
        {
957
1002
                /* save current (non-project) session (it could has been changed since program startup) */
969
1014
}
970
1015
 
971
1016
 
 
1017
static void apply_editor_prefs(void)
 
1018
{
 
1019
        guint i;
 
1020
 
 
1021
        foreach_document(i)
 
1022
                editor_apply_update_prefs(documents[i]->editor);
 
1023
}
 
1024
 
 
1025
 
972
1026
/* Write the project settings as well as the project session files into its configuration files.
973
1027
 * emit_signal defines whether the project-save signal should be emitted. When write_config()
974
1028
 * is called while closing a project, this is used to skip emitting the signal because
998
1052
 
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);
1002
 
        if (p->run_cmd)
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));
1007
1058
 
 
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);
 
1061
 
1008
1062
        /* store the session files into the project too */
1009
1063
        if (project_prefs.project_session)
1010
1064
                configuration_save_session_files(config);
1011
 
 
 
1065
        build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ);
1012
1066
        if (emit_signal)
1013
1067
        {
1014
1068
                g_signal_emit_by_name(geany_object, "project-save", config);
1055
1109
}
1056
1110
 
1057
1111
 
1058
 
/* Returns: NULL if the default path should be used, or a UTF-8 path.
1059
 
 * Maybe in future this will support a separate project make path from base path. */
1060
 
gchar *project_get_make_dir(void)
1061
 
{
1062
 
        GeanyProject *project = app->project;
1063
 
 
1064
 
        if (project && ! project->make_in_base_path)
1065
 
                return NULL;
1066
 
        else
1067
 
                return project_get_base_path();
1068
 
}
1069
 
 
1070
 
 
1071
1112
/* This is to save project-related global settings, NOT project file settings. */
1072
1113
void project_save_prefs(GKeyFile *config)
1073
1114
{
1075
1116
 
1076
1117
        if (cl_options.load_session)
1077
1118
        {
1078
 
                gchar *utf8_filename = (project == NULL) ? "" : project->file_name;
 
1119
                const gchar *utf8_filename = (project == NULL) ? "" : project->file_name;
1079
1120
 
1080
1121
                g_key_file_set_string(config, "project", "session_file", utf8_filename);
1081
1122
        }
1110
1151
        static gboolean callback_setup = FALSE;
1111
1152
 
1112
1153
        g_return_if_fail(local_prefs.project_file_path != NULL);
1113
 
        
 
1154
 
1114
1155
        gtk_entry_set_text(GTK_ENTRY(path_entry), local_prefs.project_file_path);
1115
1156
        if (! callback_setup)
1116
1157
        {       /* connect the callback only once */
1134
1175
 
1135
1176
void project_init(void)
1136
1177
{
1137
 
        GeanyPrefGroup *group;
 
1178
        StashGroup *group;
1138
1179
 
1139
1180
        group = stash_group_new("indentation");
1140
1181
        /* defaults are copied from editor indent prefs */
1149
1190
                "radio_indent_tabs", GEANY_INDENT_TYPE_TABS,
1150
1191
                "radio_indent_both", GEANY_INDENT_TYPE_BOTH,
1151
1192
                NULL);
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,
1162
1204
{
1163
1205
        stash_group_free(indent_group);
1164
1206
}
1165