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

« back to all changes in this revision

Viewing changes to src/msgwindow.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., 675 Mass Ave, Cambridge, MA 02139, USA.
20
20
 *
21
 
 * $Id: msgwindow.c 4630 2010-01-31 21:54:47Z eht16 $
 
21
 * $Id: msgwindow.c 4959 2010-05-29 18:36:17Z eht16 $
22
22
 */
23
23
 
24
24
/*
75
75
static void on_scribble_populate(GtkTextView *textview, GtkMenu *arg1, gpointer user_data);
76
76
 
77
77
 
78
 
void msgwin_init()
 
78
void msgwin_show_hide_tabs(void)
 
79
{
 
80
        ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_status), interface_prefs.msgwin_status_visible);
 
81
        ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_compiler), interface_prefs.msgwin_compiler_visible);
 
82
        ui_widget_show_hide(gtk_widget_get_parent(msgwindow.tree_msg), interface_prefs.msgwin_messages_visible);
 
83
        ui_widget_show_hide(gtk_widget_get_parent(msgwindow.scribble), interface_prefs.msgwin_scribble_visible);
 
84
}
 
85
 
 
86
 
 
87
void msgwin_init(void)
79
88
{
80
89
        msgwindow.notebook = ui_lookup_widget(main_widgets.window, "notebook_info");
81
90
        msgwindow.tree_status = ui_lookup_widget(main_widgets.window, "treeview3");
82
91
        msgwindow.tree_msg = ui_lookup_widget(main_widgets.window, "treeview4");
83
92
        msgwindow.tree_compiler = ui_lookup_widget(main_widgets.window, "treeview5");
 
93
        msgwindow.scribble = ui_lookup_widget(main_widgets.window, "textview_scribble");
84
94
        msgwindow.find_in_files_dir = NULL;
85
95
 
86
96
        prepare_status_tree_view();
90
100
        msgwindow.popup_msg_menu = create_message_popup_menu(MSG_MESSAGE);
91
101
        msgwindow.popup_compiler_menu = create_message_popup_menu(MSG_COMPILER);
92
102
 
93
 
        ui_widget_modify_font_from_string(
94
 
                ui_lookup_widget(main_widgets.window, "textview_scribble"), interface_prefs.msgwin_font);
95
 
 
96
 
        g_signal_connect(ui_lookup_widget(main_widgets.window, "textview_scribble"),
97
 
                "populate-popup", G_CALLBACK(on_scribble_populate), NULL);
 
103
        ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font);
 
104
        g_signal_connect(msgwindow.scribble, "populate-popup", G_CALLBACK(on_scribble_populate), NULL);
98
105
}
99
106
 
100
107
 
101
 
void msgwin_finalize()
 
108
void msgwin_finalize(void)
102
109
{
103
110
        g_free(msgwindow.find_in_files_dir);
104
111
}
106
113
 
107
114
static gboolean on_msgwin_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
108
115
{
109
 
        if (event->keyval == GDK_Return ||
110
 
                event->keyval == GDK_ISO_Enter ||
111
 
                event->keyval == GDK_KP_Enter ||
112
 
                event->keyval == GDK_space)
 
116
        if (ui_is_keyval_enter_or_return(event->keyval) || event->keyval == GDK_space)
113
117
        {
114
 
                GdkEventButton button_event;
115
 
 
116
 
                button_event.button = 1;
117
 
                button_event.time = event->time;
118
 
                on_msgwin_button_press_event(NULL, &button_event, data);
 
118
                switch (GPOINTER_TO_INT(data))
 
119
                {
 
120
                        case MSG_COMPILER:
 
121
                        {       /* single click in the compiler treeview */
 
122
                                msgwin_goto_compiler_file_line(event->keyval);
 
123
                                break;
 
124
                        }
 
125
                        case MSG_MESSAGE:
 
126
                        {       /* single click in the message treeview (results of 'Find usage') */
 
127
                                msgwin_goto_messages_file_line(event->keyval);
 
128
                                break;
 
129
                        }
 
130
                }
119
131
        }
120
132
        return FALSE;
121
133
}
240
252
 **/
241
253
void msgwin_compiler_add(gint msg_color, const gchar *format, ...)
242
254
{
243
 
        gchar string[512];
 
255
        gchar *string;
244
256
        va_list args;
245
257
 
246
258
        va_start(args, format);
247
 
        g_vsnprintf(string, 512, format, args);
 
259
        string = g_strdup_vprintf(format, args);
248
260
        va_end(args);
249
261
        msgwin_compiler_add_string(msg_color, string);
 
262
        g_free(string);
250
263
}
251
264
 
252
265
 
255
268
        GtkTreeIter iter;
256
269
        GtkTreePath *path;
257
270
        const GdkColor *color = get_color(msg_color);
 
271
        gchar *utf8_msg;
 
272
 
 
273
        if (! g_utf8_validate(msg, -1, NULL))
 
274
                utf8_msg = utils_get_utf8_from_locale(msg);
 
275
        else
 
276
                utf8_msg = (gchar *) msg;
258
277
 
259
278
        gtk_list_store_append(msgwindow.store_compiler, &iter);
260
 
        gtk_list_store_set(msgwindow.store_compiler, &iter, 0, color, 1, msg, -1);
 
279
        gtk_list_store_set(msgwindow.store_compiler, &iter, 0, color, 1, utf8_msg, -1);
261
280
 
262
 
        if (ui_prefs.msgwindow_visible)
 
281
        if (ui_prefs.msgwindow_visible && interface_prefs.compiler_tab_autoscroll)
263
282
        {
264
283
                path = gtk_tree_model_get_path(
265
284
                        gtk_tree_view_get_model(GTK_TREE_VIEW(msgwindow.tree_compiler)), &iter);
267
286
                gtk_tree_path_free(path);
268
287
        }
269
288
 
270
 
        /* calling build_menu_update for every build message would be overkill */
271
 
        gtk_widget_set_sensitive(build_get_menu_items(-1)->item_next_error, TRUE);
272
 
        gtk_widget_set_sensitive(build_get_menu_items(-1)->item_previous_error, TRUE);
 
289
        /* calling build_menu_update for every build message would be overkill, TODO really should call it once when all done */
 
290
        gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_NEXT_ERROR], TRUE);
 
291
        gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_PREV_ERROR], TRUE);
 
292
 
 
293
        if (utf8_msg != msg)
 
294
                g_free(utf8_msg);
273
295
}
274
296
 
275
297
 
302
324
 **/
303
325
void msgwin_msg_add(gint msg_color, gint line, GeanyDocument *doc, const gchar *format, ...)
304
326
{
305
 
        gchar string[512];
 
327
        gchar *string;
306
328
        va_list args;
307
329
 
308
330
        va_start(args, format);
309
 
        g_vsnprintf(string, 512, format, args);
 
331
        string = g_strdup_vprintf(format, args);
310
332
        va_end(args);
311
333
 
312
334
        msgwin_msg_add_string(msg_color, line, doc, string);
 
335
        g_free(string);
313
336
}
314
337
 
315
338
 
320
343
        const GdkColor *color = get_color(msg_color);
321
344
        gchar *tmp;
322
345
        gsize len;
 
346
        gchar *utf8_msg;
323
347
 
324
 
        if (! ui_prefs.msgwindow_visible) msgwin_show_hide(TRUE);
 
348
        if (! ui_prefs.msgwindow_visible)
 
349
                msgwin_show_hide(TRUE);
325
350
 
326
351
        /* work around a strange problem when adding very long lines(greater than 4000 bytes)
327
352
         * cut the string to a maximum of 1024 bytes and discard the rest */
332
357
        else
333
358
                tmp = g_strdup(string);
334
359
 
 
360
        if (! g_utf8_validate(tmp, -1, NULL))
 
361
                utf8_msg = utils_get_utf8_from_locale(tmp);
 
362
        else
 
363
                utf8_msg = tmp;
 
364
 
335
365
        gtk_list_store_append(msgwindow.store_msg, &iter);
336
 
        gtk_list_store_set(msgwindow.store_msg, &iter, 0, line, 1, doc, 2, color, 3, tmp, -1);
 
366
        gtk_list_store_set(msgwindow.store_msg, &iter, 0, line, 1, doc, 2, color, 3, utf8_msg, -1);
337
367
 
338
368
        g_free(tmp);
 
369
        if (utf8_msg != tmp)
 
370
                g_free(utf8_msg);
339
371
}
340
372
 
341
373
 
342
374
/**
343
 
 *  Log a status message *without* setting the status bar.
 
375
 *  Logs a status message *without* setting the status bar.
344
376
 *  (Use ui_set_statusbar() to display text on the statusbar)
345
377
 *
346
378
 *  @param format @c printf()-style format string.
349
381
void msgwin_status_add(const gchar *format, ...)
350
382
{
351
383
        GtkTreeIter iter;
352
 
        gchar string[512];
 
384
        gchar *string;
353
385
        gchar *statusmsg, *time_str;
354
386
        va_list args;
355
387
 
356
388
        va_start(args, format);
357
 
        g_vsnprintf(string, 512, format, args);
 
389
        string = g_strdup_vprintf(format, args);
358
390
        va_end(args);
359
391
 
360
392
        /* add a timestamp to status messages */
361
393
        time_str = utils_get_current_time_string();
362
394
        statusmsg = g_strconcat(time_str, ": ", string, NULL);
363
395
        g_free(time_str);
 
396
        g_free(string);
364
397
 
365
398
        /* add message to Status window */
366
399
        gtk_list_store_append(msgwindow.store_status, &iter);
496
529
 
497
530
static GtkWidget *create_message_popup_menu(gint type)
498
531
{
499
 
        GtkWidget *message_popup_menu, *clear, *copy, *image;
 
532
        GtkWidget *message_popup_menu, *clear, *copy, *copy_all, *image;
500
533
 
501
534
        message_popup_menu = gtk_menu_new();
502
535
 
506
539
        g_signal_connect(clear, "activate",
507
540
                G_CALLBACK(on_message_treeview_clear_activate), GINT_TO_POINTER(type));
508
541
 
509
 
        copy = gtk_image_menu_item_new_from_stock("gtk-copy", NULL);
 
542
        copy = gtk_image_menu_item_new_with_mnemonic(_("C_opy"));
510
543
        gtk_widget_show(copy);
511
544
        gtk_container_add(GTK_CONTAINER(message_popup_menu), copy);
 
545
        image = gtk_image_new_from_stock("gtk-copy", GTK_ICON_SIZE_MENU);
 
546
        gtk_widget_show(image);
 
547
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(copy), image);
512
548
        g_signal_connect(copy, "activate",
513
549
                G_CALLBACK(on_compiler_treeview_copy_activate), GINT_TO_POINTER(type));
514
550
 
515
 
        copy = gtk_image_menu_item_new_with_mnemonic(_("Copy _All"));
516
 
        gtk_widget_show(copy);
517
 
        gtk_container_add(GTK_CONTAINER(message_popup_menu), copy);
 
551
        copy_all = gtk_image_menu_item_new_with_mnemonic(_("Copy _All"));
 
552
        gtk_widget_show(copy_all);
 
553
        gtk_container_add(GTK_CONTAINER(message_popup_menu), copy_all);
518
554
        image = gtk_image_new_from_stock("gtk-copy", GTK_ICON_SIZE_MENU);
519
555
        gtk_widget_show(image);
520
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(copy), image);
521
 
        g_signal_connect(copy, "activate",
 
556
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(copy_all), image);
 
557
        g_signal_connect(copy_all, "activate",
522
558
                G_CALLBACK(on_compiler_treeview_copy_all_activate), GINT_TO_POINTER(type));
523
559
 
524
560
        msgwin_menu_add_common_items(GTK_MENU(message_popup_menu));
575
611
}
576
612
 
577
613
 
578
 
gboolean msgwin_goto_compiler_file_line()
 
614
static gboolean goto_compiler_file_line(const gchar *filename, gint line, guint keyval)
 
615
{
 
616
        if (!filename || line <= -1)
 
617
                return FALSE;
 
618
 
 
619
        /* If the path doesn't exist, try the current document.
 
620
         * This happens when we receive build messages in the wrong order - after the
 
621
         * 'Leaving directory' messages */
 
622
        if (!g_file_test(filename, G_FILE_TEST_EXISTS))
 
623
        {
 
624
                gchar *cur_dir = utils_get_current_file_dir_utf8();
 
625
                gchar *name;
 
626
 
 
627
                if (cur_dir)
 
628
                {
 
629
                        /* we let the user know we couldn't find the parsed filename from the message window */
 
630
                        setptr(cur_dir, utils_get_locale_from_utf8(cur_dir));
 
631
                        name = g_path_get_basename(filename);
 
632
                        setptr(name, g_build_path(G_DIR_SEPARATOR_S, cur_dir, name, NULL));
 
633
                        g_free(cur_dir);
 
634
 
 
635
                        if (g_file_test(name, G_FILE_TEST_EXISTS))
 
636
                        {
 
637
                                ui_set_statusbar(FALSE, _("Could not find file '%s' - trying the current document path."),
 
638
                                        filename);
 
639
                                filename = name;
 
640
                        }
 
641
                        else
 
642
                                g_free(name);
 
643
                }
 
644
        }
 
645
 
 
646
        {
 
647
                gchar *utf8_filename = utils_get_utf8_from_locale(filename);
 
648
                GeanyDocument *doc = document_find_by_filename(utf8_filename);
 
649
                GeanyDocument *old_doc = document_get_current();
 
650
 
 
651
                g_free(utf8_filename);
 
652
 
 
653
                if (doc == NULL)        /* file not already open */
 
654
                        doc = document_open_file(filename, FALSE, NULL, NULL);
 
655
 
 
656
                if (doc != NULL)
 
657
                {
 
658
                        gboolean ret;
 
659
 
 
660
                        if (! doc->changed && editor_prefs.use_indicators)      /* if modified, line may be wrong */
 
661
                                editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1);
 
662
 
 
663
                        ret = navqueue_goto_line(old_doc, doc, line);
 
664
                        if (ret && ui_is_keyval_enter_or_return(keyval))
 
665
                                gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));
 
666
 
 
667
                        return ret;
 
668
                }
 
669
        }
 
670
        return FALSE;
 
671
}
 
672
 
 
673
 
 
674
gboolean msgwin_goto_compiler_file_line(guint keyval)
579
675
{
580
676
        GtkTreeIter iter;
581
677
        GtkTreeModel *model;
582
678
        GtkTreeSelection *selection;
583
679
        gchar *string;
584
 
        gboolean ret = FALSE;
585
680
        GdkColor *color;
586
681
 
587
682
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_compiler));
603
698
                        gint line;
604
699
                        gchar *filename, *dir;
605
700
                        GtkTreePath *path;
606
 
                        /* save the beginning of the string to use when free'ing it after it was stripped */
607
 
                        gchar *string_start = string;
 
701
                        gboolean ret;
608
702
 
609
703
                        path = gtk_tree_model_get_path(model, &iter);
610
704
                        find_prev_build_dir(path, model, &dir);
611
705
                        gtk_tree_path_free(path);
612
706
                        msgwin_parse_compiler_error_line(string, dir, &filename, &line);
613
 
 
614
 
                        if (dir != NULL)
615
 
                                g_free(dir);
616
 
 
617
 
                        if (filename != NULL && line > -1)
618
 
                        {
619
 
                                gchar *utf8_filename = utils_get_utf8_from_locale(filename);
620
 
                                GeanyDocument *doc = document_find_by_filename(utf8_filename);
621
 
                                GeanyDocument *old_doc = document_get_current();
622
 
 
623
 
                                g_free(utf8_filename);
624
 
 
625
 
                                if (doc == NULL)        /* file not already open */
626
 
                                        doc = document_open_file(filename, FALSE, NULL, NULL);
627
 
 
628
 
                                if (doc != NULL)
629
 
                                {
630
 
                                        if (! doc->changed)     /* if modified, line may be wrong */
631
 
                                                editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1);
632
 
 
633
 
                                        ret = navqueue_goto_line(old_doc, doc, line);
634
 
                                }
635
 
                        }
 
707
                        g_free(string);
 
708
                        g_free(dir);
 
709
 
 
710
                        ret = goto_compiler_file_line(filename, line, keyval);
636
711
                        g_free(filename);
637
 
                        g_free(string_start);
 
712
                        return ret;
638
713
                }
639
714
        }
640
 
        return ret;
 
715
        return FALSE;
641
716
}
642
717
 
643
718
 
909
984
}
910
985
 
911
986
 
912
 
gboolean msgwin_goto_messages_file_line()
 
987
gboolean msgwin_goto_messages_file_line(guint keyval)
913
988
{
914
989
        GtkTreeIter iter;
915
990
        GtkTreeModel *model;
929
1004
                if (line >= 0 && DOC_VALID(doc))
930
1005
                {
931
1006
                        ret = navqueue_goto_line(old_doc, doc, line);
 
1007
                        if (ret && ui_is_keyval_enter_or_return(keyval))
 
1008
                                gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));
932
1009
                }
933
1010
                else if (line < 0 && string != NULL)
934
1011
                {
939
1016
                                /* use document_open_file to find an already open file, or open it in place */
940
1017
                                doc = document_open_file(filename, FALSE, NULL, NULL);
941
1018
                                if (doc != NULL)
 
1019
                                {
942
1020
                                        ret = navqueue_goto_line(old_doc, doc, line);
 
1021
                                        if (ret && ui_is_keyval_enter_or_return(keyval))
 
1022
                                                gtk_widget_grab_focus(GTK_WIDGET(doc->editor->sci));
 
1023
                                }
943
1024
                        }
944
1025
                        g_free(filename);
945
1026
                }
987
1068
                {
988
1069
                        case MSG_COMPILER:
989
1070
                        {       /* single click in the compiler treeview */
990
 
                                msgwin_goto_compiler_file_line();
 
1071
                                msgwin_goto_compiler_file_line(0);
991
1072
                                break;
992
1073
                        }
993
1074
                        case MSG_MESSAGE:
994
1075
                        {       /* single click in the message treeview (results of 'Find usage') */
995
 
                                msgwin_goto_messages_file_line();
 
1076
                                msgwin_goto_messages_file_line(0);
996
1077
                                break;
997
1078
                        }
998
1079
                }
1042
1123
 
1043
1124
        switch (tabnum)
1044
1125
        {
1045
 
                case MSG_SCRATCH: widget = ui_lookup_widget(main_widgets.window, "textview_scribble"); break;
 
1126
                case MSG_SCRATCH: widget = msgwindow.scribble; break;
1046
1127
                case MSG_COMPILER: widget = msgwindow.tree_compiler; break;
1047
1128
                case MSG_STATUS: widget = msgwindow.tree_status; break;
1048
1129
                case MSG_MESSAGE: widget = msgwindow.tree_msg; break;
1061
1142
                gtk_widget_grab_focus(widget);
1062
1143
}
1063
1144
 
 
1145
 
1064
1146
/**
1065
1147
 *  Removes all messages from a tab specified by @a tabnum in the messages window.
1066
1148
 *