18
18
* along with this program; if not, write to the Free Software
19
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
* $Id: msgwindow.c 4630 2010-01-31 21:54:47Z eht16 $
21
* $Id: msgwindow.c 4959 2010-05-29 18:36:17Z eht16 $
75
75
static void on_scribble_populate(GtkTextView *textview, GtkMenu *arg1, gpointer user_data);
78
void msgwin_show_hide_tabs(void)
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);
87
void msgwin_init(void)
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;
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);
93
ui_widget_modify_font_from_string(
94
ui_lookup_widget(main_widgets.window, "textview_scribble"), interface_prefs.msgwin_font);
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);
101
void msgwin_finalize()
108
void msgwin_finalize(void)
103
110
g_free(msgwindow.find_in_files_dir);
107
114
static gboolean on_msgwin_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
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)
114
GdkEventButton button_event;
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))
121
{ /* single click in the compiler treeview */
122
msgwin_goto_compiler_file_line(event->keyval);
126
{ /* single click in the message treeview (results of 'Find usage') */
127
msgwin_goto_messages_file_line(event->keyval);
241
253
void msgwin_compiler_add(gint msg_color, const gchar *format, ...)
246
258
va_start(args, format);
247
g_vsnprintf(string, 512, format, args);
259
string = g_strdup_vprintf(format, args);
249
261
msgwin_compiler_add_string(msg_color, string);
255
268
GtkTreeIter iter;
256
269
GtkTreePath *path;
257
270
const GdkColor *color = get_color(msg_color);
273
if (! g_utf8_validate(msg, -1, NULL))
274
utf8_msg = utils_get_utf8_from_locale(msg);
276
utf8_msg = (gchar *) msg;
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);
262
if (ui_prefs.msgwindow_visible)
281
if (ui_prefs.msgwindow_visible && interface_prefs.compiler_tab_autoscroll)
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);
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);
303
325
void msgwin_msg_add(gint msg_color, gint line, GeanyDocument *doc, const gchar *format, ...)
308
330
va_start(args, format);
309
g_vsnprintf(string, 512, format, args);
331
string = g_strdup_vprintf(format, args);
312
334
msgwin_msg_add_string(msg_color, line, doc, string);
320
343
const GdkColor *color = get_color(msg_color);
324
if (! ui_prefs.msgwindow_visible) msgwin_show_hide(TRUE);
348
if (! ui_prefs.msgwindow_visible)
349
msgwin_show_hide(TRUE);
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 */
333
358
tmp = g_strdup(string);
360
if (! g_utf8_validate(tmp, -1, NULL))
361
utf8_msg = utils_get_utf8_from_locale(tmp);
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);
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)
346
378
* @param format @c printf()-style format string.
349
381
void msgwin_status_add(const gchar *format, ...)
351
383
GtkTreeIter iter;
353
385
gchar *statusmsg, *time_str;
356
388
va_start(args, format);
357
g_vsnprintf(string, 512, format, args);
389
string = g_strdup_vprintf(format, args);
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);
365
398
/* add message to Status window */
366
399
gtk_list_store_append(msgwindow.store_status, &iter);
497
530
static GtkWidget *create_message_popup_menu(gint type)
499
GtkWidget *message_popup_menu, *clear, *copy, *image;
532
GtkWidget *message_popup_menu, *clear, *copy, *copy_all, *image;
501
534
message_popup_menu = gtk_menu_new();
506
539
g_signal_connect(clear, "activate",
507
540
G_CALLBACK(on_message_treeview_clear_activate), GINT_TO_POINTER(type));
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));
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));
524
560
msgwin_menu_add_common_items(GTK_MENU(message_popup_menu));
578
gboolean msgwin_goto_compiler_file_line()
614
static gboolean goto_compiler_file_line(const gchar *filename, gint line, guint keyval)
616
if (!filename || line <= -1)
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))
624
gchar *cur_dir = utils_get_current_file_dir_utf8();
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));
635
if (g_file_test(name, G_FILE_TEST_EXISTS))
637
ui_set_statusbar(FALSE, _("Could not find file '%s' - trying the current document path."),
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();
651
g_free(utf8_filename);
653
if (doc == NULL) /* file not already open */
654
doc = document_open_file(filename, FALSE, NULL, NULL);
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);
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));
674
gboolean msgwin_goto_compiler_file_line(guint keyval)
580
676
GtkTreeIter iter;
581
677
GtkTreeModel *model;
582
678
GtkTreeSelection *selection;
584
gboolean ret = FALSE;
587
682
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(msgwindow.tree_compiler));
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;
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);
617
if (filename != NULL && line > -1)
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();
623
g_free(utf8_filename);
625
if (doc == NULL) /* file not already open */
626
doc = document_open_file(filename, FALSE, NULL, NULL);
630
if (! doc->changed) /* if modified, line may be wrong */
631
editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1);
633
ret = navqueue_goto_line(old_doc, doc, line);
710
ret = goto_compiler_file_line(filename, line, keyval);
636
711
g_free(filename);
637
g_free(string_start);
929
1004
if (line >= 0 && DOC_VALID(doc))
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));
933
1010
else if (line < 0 && string != NULL)
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)
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));
944
1025
g_free(filename);
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);
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);
1043
1124
switch (tabnum)
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;