1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /* (c) Johannes Schmid 2003
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Library General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #include <libanjuta/anjuta-utils.h>
19 #include <libanjuta/anjuta-debug.h>
20 #include <libanjuta/anjuta-preferences.h>
21 #include <libanjuta/interfaces/ianjuta-message-view.h>
23 #include "message-view.h"
24 #define MESSAGE_TYPE message_get_type()
26 #define PREFERENCES_SCHEMA "org.gnome.anjuta.plugins.message-manager"
27 #define COLOR_ERROR "color-error"
28 #define COLOR_WARNING "color-warning"
30 struct _MessageViewPrivate
39 GtkWidget
*popup_menu
;
44 MessageViewFlags flags
;
60 IAnjutaMessageViewType type
;
83 static gpointer parent_class
;
85 static void prefs_init (MessageView
*mview
);
86 static void prefs_finalize (MessageView
*mview
);
89 message_view_tree_view_filter (GtkTreeModel
*model
,
93 /* Message object creation, copy and freeing */
95 message_new (IAnjutaMessageViewType type
, const gchar
*summary
,
98 /* DEBUG_PRINT ("%s", "Creating message"); */
99 Message
*message
= g_new0 (Message
, 1);
100 message
->type
= type
;
102 message
->summary
= g_strdup (summary
);
104 message
->details
= g_strdup (details
);
109 message_copy (const Message
*src
)
111 return message_new (src
->type
, src
->summary
, src
->details
);
115 message_free (Message
*message
)
117 /* DEBUG_PRINT ("%s", "Freeing message"); */
118 g_free (message
->summary
);
119 g_free (message
->details
);
124 message_serialize (Message
*message
, AnjutaSerializer
*serializer
)
126 if (!anjuta_serializer_write_int (serializer
, "type",
129 if (!anjuta_serializer_write_string (serializer
, "summary",
132 if (!anjuta_serializer_write_string (serializer
, "details",
139 message_deserialize (Message
*message
, AnjutaSerializer
*serializer
)
142 if (!anjuta_serializer_read_int (serializer
, "type",
145 message
->type
= type
;
146 if (!anjuta_serializer_read_string (serializer
, "summary",
147 &message
->summary
, TRUE
))
149 if (!anjuta_serializer_read_string (serializer
, "details",
150 &message
->details
, TRUE
))
156 message_get_type (void)
158 static GType type
= 0;
161 type
= g_boxed_type_register_static ("MessageViewMessage",
162 (GBoxedCopyFunc
) message_copy
,
163 (GBoxedFreeFunc
) message_free
);
168 /* Utility functions */
169 /* Adds the char c to the string str */
171 add_char(gchar
** str
, gchar c
)
175 g_return_if_fail(str
!= NULL
);
177 buffer
= g_strdup_printf("%s%c", *str
, c
);
183 escape_string (const gchar
*str
)
188 gstr
= g_string_new ("");
190 while (*iter
!= '\0')
193 gstr
= g_string_append (gstr
, ">");
194 else if (*iter
== '<')
195 gstr
= g_string_append (gstr
, "<");
196 else if (*iter
== '&')
197 gstr
= g_string_append (gstr
, "&");
199 gstr
= g_string_append_c (gstr
, *iter
);
202 return g_string_free (gstr
, FALSE
);
206 message_view_query_tooltip (GtkWidget
* widget
, gint x
, gint y
, gboolean keyboard
,
212 MessageView
* view
= MESSAGE_VIEW(widget
);
214 model
= view
->privat
->model
;
216 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(view
->privat
->tree_view
),
217 x
, y
, &path
, NULL
, NULL
, NULL
))
220 gchar
*text
, *title
, *desc
;
222 gtk_tree_model_get_iter (model
, &iter
, path
);
223 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
, &message
, -1);
224 gtk_tree_path_free(path
);
226 if (!message
->details
|| !message
->summary
||
227 strlen (message
->details
) <= 0 ||
228 strlen (message
->summary
) <= 0)
231 title
= escape_string (message
->summary
);
232 desc
= escape_string (message
->details
);
233 text
= g_strdup_printf ("<b>%s</b>\n%s", title
, desc
);
238 gtk_tooltip_set_markup (tooltip
, text
);
245 /* MessageView signal callbacks */
246 /* Send a signal if a message was double-clicked or ENTER or SPACE was pressed */
248 on_message_event (GObject
* object
, GdkEvent
* event
, gpointer data
)
250 g_return_val_if_fail(object
!= NULL
, FALSE
);
251 g_return_val_if_fail(event
!= NULL
, FALSE
);
252 g_return_val_if_fail(data
!= NULL
, FALSE
);
254 MessageView
* view
= MESSAGE_VIEW(data
);
259 if (event
->type
== GDK_KEY_PRESS
)
261 switch(((GdkEventKey
*)event
)->keyval
)
266 const gchar
* message
=
267 ianjuta_message_view_get_current_message(IANJUTA_MESSAGE_VIEW (view
), NULL
);
270 g_signal_emit_by_name (G_OBJECT (view
), "message_clicked",
280 else if (event
->type
== GDK_2BUTTON_PRESS
)
282 if (((GdkEventButton
*) event
)->button
== 1)
284 const gchar
* message
=
285 ianjuta_message_view_get_current_message(IANJUTA_MESSAGE_VIEW (view
), NULL
);
288 g_signal_emit_by_name (G_OBJECT (view
), "message_clicked",
295 else if (event
->type
== GDK_BUTTON_PRESS
)
297 if (((GdkEventButton
*) event
)->button
== 3)
299 gtk_menu_popup (GTK_MENU (view
->privat
->popup_menu
), NULL
, NULL
, NULL
, NULL
,
300 ((GdkEventButton
*) event
)->button
,
301 ((GdkEventButton
*) event
)->time
);
309 on_adjustment_changed (GtkAdjustment
* adj
, gpointer data
)
311 gtk_adjustment_set_value (adj
,
312 gtk_adjustment_get_upper (adj
) - gtk_adjustment_get_page_size (adj
));
316 on_adjustment_value_changed (GtkAdjustment
* adj
, gpointer data
)
318 MessageView
*self
= MESSAGE_VIEW (data
);
319 if (gtk_adjustment_get_value (adj
) > (gtk_adjustment_get_upper (adj
) - gtk_adjustment_get_page_size (adj
)) - 0.1)
321 if (!self
->privat
->adj_chgd_hdlr
)
323 self
->privat
->adj_chgd_hdlr
=
324 g_signal_connect (G_OBJECT (adj
), "changed",
325 G_CALLBACK (on_adjustment_changed
), NULL
);
330 if (self
->privat
->adj_chgd_hdlr
)
332 g_signal_handler_disconnect (G_OBJECT (adj
), self
->privat
->adj_chgd_hdlr
);
333 self
->privat
->adj_chgd_hdlr
= 0;
339 message_view_set_property (GObject
* object
,
341 const GValue
* value
, GParamSpec
* pspec
)
343 MessageView
*self
= MESSAGE_VIEW (object
);
344 g_return_if_fail(value
!= NULL
);
345 g_return_if_fail(pspec
!= NULL
);
351 g_free (self
->privat
->label
);
352 self
->privat
->label
= g_value_dup_string (value
);
357 g_free (self
->privat
->pixmap
);
358 self
->privat
->pixmap
= g_value_dup_string (value
);
361 case MV_PROP_HIGHLITE
:
363 self
->privat
->highlite
= g_value_get_boolean (value
);
368 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
375 message_view_get_property (GObject
* object
,
377 GValue
* value
, GParamSpec
* pspec
)
379 MessageView
*self
= MESSAGE_VIEW (object
);
381 g_return_if_fail(value
!= NULL
);
382 g_return_if_fail(pspec
!= NULL
);
388 g_value_set_string (value
, self
->privat
->label
);
393 g_value_set_string (value
, self
->privat
->pixmap
);
396 case MV_PROP_HIGHLITE
:
398 g_value_set_boolean (value
, self
->privat
->highlite
);
403 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
410 message_view_dispose (GObject
*obj
)
412 MessageView
*mview
= MESSAGE_VIEW (obj
);
413 prefs_finalize (mview
);
414 if (mview
->privat
->tree_view
)
416 mview
->privat
->tree_view
= NULL
;
418 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
422 message_view_finalize (GObject
*obj
)
424 MessageView
*mview
= MESSAGE_VIEW (obj
);
425 g_free (mview
->privat
->line_buffer
);
426 g_free (mview
->privat
->label
);
427 g_free (mview
->privat
->pixmap
);
428 g_free (mview
->privat
);
429 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
433 message_view_instance_init (MessageView
* self
)
435 GtkWidget
*scrolled_win
;
436 GtkCellRenderer
*renderer
;
437 GtkCellRenderer
*renderer_pixbuf
;
438 GtkTreeViewColumn
*column
;
439 GtkTreeViewColumn
*column_pixbuf
;
440 GtkTreeSelection
*select
;
444 g_return_if_fail(self
!= NULL
);
445 self
->privat
= g_new0 (MessageViewPrivate
, 1);
447 /* Init private data */
448 self
->privat
->line_buffer
= g_strdup("");
449 self
->privat
->flags
= 0xF;
451 /* Create the tree widget */
452 model
= gtk_list_store_new (N_COLUMNS
, G_TYPE_STRING
,
453 G_TYPE_STRING
, MESSAGE_TYPE
, G_TYPE_STRING
);
454 self
->privat
->model
= GTK_TREE_MODEL (model
);
457 self
->privat
->filter
= gtk_tree_model_filter_new (GTK_TREE_MODEL (model
), NULL
);
458 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (self
->privat
->filter
),
459 message_view_tree_view_filter
,
462 self
->privat
->tree_view
=
463 gtk_tree_view_new_with_model (GTK_TREE_MODEL (self
->privat
->filter
));
464 gtk_widget_show (self
->privat
->tree_view
);
465 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW
466 (self
->privat
->tree_view
), FALSE
);
468 /* Create pixbuf column */
469 renderer_pixbuf
= gtk_cell_renderer_pixbuf_new ();
470 g_object_set (G_OBJECT(renderer_pixbuf
), "stock-size", GTK_ICON_SIZE_MENU
, NULL
);
471 column_pixbuf
= gtk_tree_view_column_new ();
472 gtk_tree_view_column_set_title (column_pixbuf
, _("Icon"));
473 gtk_tree_view_column_pack_start (column_pixbuf
, renderer_pixbuf
, TRUE
);
474 gtk_tree_view_column_add_attribute
475 (column_pixbuf
, renderer_pixbuf
, "stock-id", COLUMN_PIXBUF
);
476 gtk_tree_view_append_column (GTK_TREE_VIEW (self
->privat
->tree_view
),
478 /* Create columns to hold text and color of a line, this
479 * columns are invisible of course. */
480 renderer
= gtk_cell_renderer_text_new ();
481 g_object_set (renderer
, "yalign", 0.0, "wrap-mode", PANGO_WRAP_WORD
,
482 "wrap-width", 1000, NULL
);
483 column
= gtk_tree_view_column_new ();
485 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
486 gtk_tree_view_column_set_title (column
, _("Messages"));
487 gtk_tree_view_column_add_attribute
488 (column
, renderer
, "foreground", COLUMN_COLOR
);
489 gtk_tree_view_column_add_attribute
490 (column
, renderer
, "markup", COLUMN_SUMMARY
);
491 gtk_tree_view_append_column (GTK_TREE_VIEW (self
->privat
->tree_view
),
494 /* Adjust selection */
495 select
= gtk_tree_view_get_selection
496 (GTK_TREE_VIEW (self
->privat
->tree_view
));
497 gtk_tree_selection_set_mode (select
, GTK_SELECTION_BROWSE
);
499 /* Add tree view to a scrolled window */
500 scrolled_win
= gtk_scrolled_window_new (NULL
, NULL
);
501 gtk_container_add (GTK_CONTAINER (scrolled_win
),
502 self
->privat
->tree_view
);
503 gtk_widget_show (scrolled_win
);
504 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win
),
505 GTK_POLICY_AUTOMATIC
,
506 GTK_POLICY_AUTOMATIC
);
507 adj
= gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW
509 self
->privat
->adj_chgd_hdlr
= g_signal_connect(G_OBJECT(adj
), "changed",
510 G_CALLBACK (on_adjustment_changed
), self
);
511 g_signal_connect(G_OBJECT(adj
), "value_changed",
512 G_CALLBACK(on_adjustment_value_changed
), self
);
514 gtk_container_add (GTK_CONTAINER (self
), scrolled_win
);
516 /* Connect signals */
517 g_signal_connect (G_OBJECT(self
->privat
->tree_view
), "event",
518 G_CALLBACK (on_message_event
), self
);
520 g_object_set (G_OBJECT(self
), "has-tooltip", TRUE
, NULL
);
525 message_view_class_init (MessageViewClass
* klass
)
527 GParamSpec
*message_view_spec_label
;
528 GParamSpec
*message_view_spec_pixmap
;
529 GParamSpec
*message_view_spec_highlite
;
530 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
531 GtkWidgetClass
* widget_class
= GTK_WIDGET_CLASS (klass
);
533 parent_class
= g_type_class_peek_parent (klass
);
534 gobject_class
->set_property
= message_view_set_property
;
535 gobject_class
->get_property
= message_view_get_property
;
536 gobject_class
->finalize
= message_view_finalize
;
537 gobject_class
->dispose
= message_view_dispose
;
539 widget_class
->query_tooltip
= message_view_query_tooltip
;
542 message_view_spec_label
= g_param_spec_string ("label",
544 "Used to decorate the view,"
548 g_object_class_install_property (gobject_class
,
550 message_view_spec_label
);
552 message_view_spec_pixmap
= g_param_spec_string ("pixmap",
553 "Pixmap of the view",
554 "Used to decorate the view tab,"
558 g_object_class_install_property (gobject_class
,
560 message_view_spec_pixmap
);
562 message_view_spec_highlite
= g_param_spec_boolean ("highlite",
563 "Highlite build messages",
564 "If TRUE, specify colors",
567 g_object_class_install_property (gobject_class
,
569 message_view_spec_highlite
);
572 /* Returns a new message-view instance */
574 message_view_new (GtkWidget
* popup_menu
)
576 MessageView
* mv
= MESSAGE_VIEW (g_object_new (message_view_get_type (), NULL
));
577 mv
->privat
->popup_menu
= popup_menu
;
579 return GTK_WIDGET(mv
);
583 message_view_serialize (MessageView
*view
, AnjutaSerializer
*serializer
)
588 g_return_val_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
), FALSE
);
590 if (!anjuta_serializer_write_string (serializer
, "label",
591 view
->privat
->label
))
593 if (!anjuta_serializer_write_string (serializer
, "pixmap",
594 view
->privat
->pixmap
))
596 if (!anjuta_serializer_write_int (serializer
, "highlite",
597 view
->privat
->highlite
))
600 /* Serialize individual messages */
601 model
= view
->privat
->model
;
603 if (!anjuta_serializer_write_int (serializer
, "messages",
604 gtk_tree_model_iter_n_children (model
, NULL
)))
607 if (gtk_tree_model_get_iter_first (model
, &iter
))
612 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
, &message
, -1);
615 if (!message_serialize (message
, serializer
))
619 while (gtk_tree_model_iter_next (model
, &iter
));
625 message_view_deserialize (MessageView
*view
, AnjutaSerializer
*serializer
)
630 g_return_val_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
), FALSE
);
632 if (!anjuta_serializer_read_string (serializer
, "label",
633 &view
->privat
->label
, TRUE
))
635 if (!anjuta_serializer_read_string (serializer
, "pixmap",
636 &view
->privat
->pixmap
, TRUE
))
638 if (!anjuta_serializer_read_int (serializer
, "highlite",
639 &view
->privat
->highlite
))
642 /* Create individual messages */
643 model
= view
->privat
->model
;
644 gtk_list_store_clear (GTK_LIST_STORE (model
));
646 if (!anjuta_serializer_read_int (serializer
, "messages", &messages
))
649 for (i
= 0; i
< messages
; i
++)
653 message
= message_new (0, NULL
, NULL
);
654 if (!message_deserialize (message
, serializer
))
656 message_free (message
);
659 ianjuta_message_view_append (IANJUTA_MESSAGE_VIEW (view
), message
->type
,
660 message
->summary
, message
->details
, NULL
);
661 message_free (message
);
666 void message_view_next(MessageView
* view
)
670 GtkTreeSelection
*select
;
672 g_return_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
));
674 model
= view
->privat
->model
;
675 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW
676 (view
->privat
->tree_view
));
678 if (!gtk_tree_selection_get_selected (select
, &model
, &iter
))
680 if (gtk_tree_model_get_iter_first (model
, &iter
))
681 gtk_tree_selection_select_iter (select
, &iter
);
683 while (gtk_tree_model_iter_next (model
, &iter
))
686 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
,
688 if (message
->type
== IANJUTA_MESSAGE_VIEW_TYPE_WARNING
689 || message
->type
== IANJUTA_MESSAGE_VIEW_TYPE_ERROR
)
691 const gchar
* message
;
692 gtk_tree_selection_select_iter (select
, &iter
);
694 ianjuta_message_view_get_current_message(IANJUTA_MESSAGE_VIEW (view
), NULL
);
698 path
= gtk_tree_model_get_path (model
, &iter
);
699 gtk_tree_view_set_cursor (GTK_TREE_VIEW
700 (view
->privat
->tree_view
),
702 gtk_tree_path_free (path
);
703 g_signal_emit_by_name (G_OBJECT (view
), "message_clicked",
711 void message_view_previous(MessageView
* view
)
715 GtkTreeSelection
*select
;
718 g_return_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
));
720 model
= view
->privat
->model
;
721 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW
722 (view
->privat
->tree_view
));
724 if (!gtk_tree_selection_get_selected (select
, &model
, &iter
))
726 if (gtk_tree_model_get_iter_first (model
, &iter
))
727 gtk_tree_selection_select_iter (select
, &iter
);
730 /* gtk_tree_model_iter_previous does not exist, use path */
731 path
= gtk_tree_model_get_path (model
, &iter
);
733 while (gtk_tree_path_prev(path
))
736 gtk_tree_model_get_iter(model
, &iter
, path
);
737 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
,
739 if (message
->type
== IANJUTA_MESSAGE_VIEW_TYPE_WARNING
740 || message
->type
== IANJUTA_MESSAGE_VIEW_TYPE_ERROR
)
742 const gchar
* message
;
744 gtk_tree_selection_select_iter (select
, &iter
);
746 ianjuta_message_view_get_current_message(IANJUTA_MESSAGE_VIEW (view
), NULL
);
750 path
= gtk_tree_model_get_path (model
, &iter
);
751 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW
752 (view
->privat
->tree_view
),
753 path
, NULL
, FALSE
, 0, 0);
754 gtk_tree_path_free (path
);
755 g_signal_emit_by_name (G_OBJECT (view
), "message_clicked",
761 gtk_tree_path_free (path
);
764 void message_view_copy_all(MessageView
* view
)
770 g_return_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
));
772 /* Copy all lines of message view */
773 model
= view
->privat
->model
;
775 messages
= g_string_new (NULL
);
776 gtk_tree_model_get_iter_first (model
, &iter
);
781 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
, &message
, -1);
784 if (message
->details
&& (strlen (message
->details
) > 0))
786 g_string_append (messages
, message
->details
);
787 g_string_append_c (messages
, '\n');
791 g_string_append (messages
, message
->summary
);
792 g_string_append_c (messages
, '\n');
795 } while (gtk_tree_model_iter_next (model
, &iter
));
797 if (messages
->len
!= 0)
799 GtkClipboard
*clipboard
;
801 clipboard
= gtk_widget_get_clipboard (GTK_WIDGET (view
), GDK_SELECTION_CLIPBOARD
);
803 gtk_clipboard_set_text (clipboard
, messages
->str
, messages
->len
);
806 g_string_free (messages
, TRUE
);
809 void message_view_copy(MessageView
* view
)
813 GtkTreeSelection
*select
;
815 g_return_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
));
817 model
= view
->privat
->model
;
818 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW
819 (view
->privat
->tree_view
));
821 if (gtk_tree_selection_get_selected (select
, &model
, &iter
))
825 GtkClipboard
*clipboard
;
827 gtk_tree_model_get (model
, &iter
, COLUMN_MESSAGE
, &message
, -1);
829 if (message
->details
&& (*message
->details
!= '\0'))
831 text
= message
->details
;
833 else if (message
->summary
&& (*message
->summary
!= '\0'))
835 text
= message
->summary
;
843 clipboard
= gtk_widget_get_clipboard (GTK_WIDGET (view
), GDK_SELECTION_CLIPBOARD
);
845 gtk_clipboard_set_text (clipboard
, text
, -1);
849 /* Preferences notifications */
851 pref_change_color (MessageView
*mview
, IAnjutaMessageViewType type
,
852 const gchar
*color_pref_key
)
859 color
= g_settings_get_string (mview
->privat
->settings
, color_pref_key
);
860 store
= GTK_LIST_STORE (mview
->privat
->model
);
861 success
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store
), &iter
);
865 gtk_tree_model_get (GTK_TREE_MODEL (store
), &iter
, COLUMN_MESSAGE
,
867 if (message
&& message
->type
== type
)
869 gtk_list_store_set (store
, &iter
, COLUMN_COLOR
, color
, -1);
871 success
= gtk_tree_model_iter_next (GTK_TREE_MODEL (store
), &iter
);
878 on_notify_color (GSettings
* settings
, const gchar
* key
,
881 if (g_str_equal (key
, COLOR_ERROR
))
882 pref_change_color (MESSAGE_VIEW (user_data
),
883 IANJUTA_MESSAGE_VIEW_TYPE_ERROR
,
886 pref_change_color (MESSAGE_VIEW (user_data
),
887 IANJUTA_MESSAGE_VIEW_TYPE_WARNING
,
892 prefs_init (MessageView
*mview
)
894 mview
->privat
->settings
= g_settings_new (PREFERENCES_SCHEMA
);
895 g_signal_connect (mview
->privat
->settings
, "changed::" COLOR_ERROR
,
896 G_CALLBACK (on_notify_color
), mview
);
897 g_signal_connect (mview
->privat
->settings
, "changed::" COLOR_WARNING
,
898 G_CALLBACK (on_notify_color
), mview
);
902 prefs_finalize (MessageView
*mview
)
904 if (mview
->privat
->settings
)
905 g_object_unref (mview
->privat
->settings
);
906 mview
->privat
->settings
= NULL
;
909 /* IAnjutaMessageView interface implementation */
911 /* Appends the text in buffer. Flushes the buffer where a newline is found.
912 * by emiiting buffer_flushed signal. The string is expected to be utf8.
915 imessage_view_buffer_append (IAnjutaMessageView
* message_view
,
916 const gchar
* message
, GError
** e
)
922 g_return_if_fail (MESSAGE_IS_VIEW (message_view
));
927 len
= strlen(message
);
929 view
= MESSAGE_VIEW (message_view
);
931 /* Check if message contains newlines */
932 for (cur_char
= 0; cur_char
< len
; cur_char
++)
934 /* Is newline => print line */
935 if (message
[cur_char
] != '\n')
937 add_char(&view
->privat
->line_buffer
, message
[cur_char
]);
941 g_signal_emit_by_name (G_OBJECT (view
), "buffer_flushed",
942 view
->privat
->line_buffer
);
943 g_free(view
->privat
->line_buffer
);
944 view
->privat
->line_buffer
= g_strdup("");
950 imessage_view_append (IAnjutaMessageView
*message_view
,
951 IAnjutaMessageViewType type
,
952 const gchar
*summary
,
953 const gchar
*details
,
962 gchar
* stock_id
= NULL
;
967 g_return_if_fail (MESSAGE_IS_VIEW (message_view
));
969 view
= MESSAGE_VIEW (message_view
);
971 message
= message_new (type
, summary
, details
);
973 g_object_get (G_OBJECT (view
), "highlite", &highlite
, NULL
);
977 switch (message
->type
)
979 case IANJUTA_MESSAGE_VIEW_TYPE_INFO
:
980 view
->privat
->info_count
++;
981 stock_id
= GTK_STOCK_INFO
;
983 case IANJUTA_MESSAGE_VIEW_TYPE_WARNING
:
984 color
= g_settings_get_string (view
->privat
->settings
, COLOR_WARNING
);
985 /* FIXME: There is no GTK_STOCK_WARNING which would fit better here */
986 view
->privat
->warn_count
++;
987 stock_id
= GTK_STOCK_DIALOG_WARNING
;
989 case IANJUTA_MESSAGE_VIEW_TYPE_ERROR
:
990 color
= g_settings_get_string (view
->privat
->settings
, COLOR_ERROR
);
991 view
->privat
->error_count
++;
992 stock_id
= GTK_STOCK_STOP
;
996 view
->privat
->normal_count
++;
1000 /* Add the message to the tree */
1001 store
= GTK_LIST_STORE (view
->privat
->model
);
1002 gtk_list_store_append (store
, &iter
);
1005 * Must be normalized to compose representation to be
1006 * displayed correctly (Bug in gtk_list???)
1008 utf8_msg
= g_utf8_normalize (message
->summary
, -1,
1009 G_NORMALIZE_DEFAULT_COMPOSE
);
1010 if (message
->details
&& strlen (message
->details
) > 0)
1013 summary
= escape_string (message
->summary
);
1014 escaped_str
= g_strdup_printf ("<b>%s</b>", summary
);
1017 escaped_str
= escape_string (message
->summary
);
1019 gtk_list_store_set (store
, &iter
,
1020 COLUMN_SUMMARY
, escaped_str
,
1021 COLUMN_MESSAGE
, message
,
1025 gtk_list_store_set (store
, &iter
,
1026 COLUMN_COLOR
, color
, -1);
1030 gtk_list_store_set (store
, &iter
,
1031 COLUMN_PIXBUF
, stock_id
, -1);
1034 message_free (message
);
1036 g_free (escaped_str
);
1039 /* Clear all messages from the message view */
1041 imessage_view_clear (IAnjutaMessageView
*message_view
, GError
**e
)
1043 GtkListStore
*store
;
1046 g_return_if_fail (MESSAGE_IS_VIEW (message_view
));
1047 view
= MESSAGE_VIEW (message_view
);
1049 /* filter settings restart */
1050 view
->privat
->normal_count
= 0;
1051 view
->privat
->info_count
= 0;
1052 view
->privat
->warn_count
= 0;
1053 view
->privat
->error_count
= 0;
1055 store
= GTK_LIST_STORE (view
->privat
->model
);
1056 gtk_list_store_clear (store
);
1059 /* Move the selection to the next line. */
1061 imessage_view_select_next (IAnjutaMessageView
* message_view
,
1064 MessageView
* view
= MESSAGE_VIEW(message_view
);
1065 message_view_next(view
);
1068 /* Move the selection to the previous line. */
1070 imessage_view_select_previous (IAnjutaMessageView
* message_view
,
1073 MessageView
*view
= MESSAGE_VIEW(message_view
);
1074 message_view_previous(view
);
1077 /* Return the currently selected messages or the first message if no
1078 * message is selected or NULL if no messages are availible. The
1079 * returned message must not be freed.
1081 static const gchar
*
1082 imessage_view_get_current_message (IAnjutaMessageView
* message_view
,
1087 GtkTreeSelection
*select
;
1088 GtkTreeModel
*model
;
1089 const Message
*message
;
1091 g_return_val_if_fail (MESSAGE_IS_VIEW (message_view
), NULL
);
1093 view
= MESSAGE_VIEW (message_view
);
1094 select
= gtk_tree_view_get_selection (GTK_TREE_VIEW
1095 (view
->privat
->tree_view
));
1097 if (!gtk_tree_selection_get_selected (select
, &model
, &iter
))
1099 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model
), &iter
))
1101 gtk_tree_model_get (GTK_TREE_MODEL (model
),
1102 &iter
, COLUMN_MESSAGE
, &message
, -1);
1105 if (message
->details
&& strlen (message
->details
) > 0)
1106 return message
->details
;
1108 return message
->summary
;
1114 gtk_tree_model_get (GTK_TREE_MODEL (model
),
1115 &iter
, COLUMN_MESSAGE
, &message
, -1);
1118 if (message
->details
&& strlen (message
->details
) > 0)
1119 return message
->details
;
1121 return message
->summary
;
1127 /* Returns a GList which contains all messages, the GList itself
1128 * must be freed, the messages are managed by the message view and
1129 * must not be freed. NULL is return if no messages are availible.
1132 imessage_view_get_all_messages (IAnjutaMessageView
* message_view
,
1136 GtkListStore
*store
;
1139 GList
*messages
= NULL
;
1141 g_return_val_if_fail (MESSAGE_IS_VIEW (message_view
), NULL
);
1143 view
= MESSAGE_VIEW (message_view
);
1144 store
= GTK_LIST_STORE (view
->privat
->model
);
1146 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store
), &iter
))
1150 gtk_tree_model_get (GTK_TREE_MODEL (store
), &iter
,
1151 COLUMN_MESSAGE
, &message
);
1152 messages
= g_list_prepend (messages
, message
->details
);
1154 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store
), &iter
));
1160 imessage_view_iface_init (IAnjutaMessageViewIface
*iface
)
1162 iface
->buffer_append
= imessage_view_buffer_append
;
1163 iface
->append
= imessage_view_append
;
1164 iface
->clear
= imessage_view_clear
;
1165 iface
->select_next
= imessage_view_select_next
;
1166 iface
->select_previous
= imessage_view_select_previous
;
1167 iface
->get_current_message
= imessage_view_get_current_message
;
1168 iface
->get_all_messages
= imessage_view_get_all_messages
;
1172 message_view_tree_view_filter (GtkTreeModel
*model
, GtkTreeIter
*iter
,
1176 MessageView
*msgview
;
1178 msgview
= MESSAGE_VIEW (data
);
1179 gtk_tree_model_get (msgview
->privat
->model
, iter
, COLUMN_MESSAGE
, &msg
, -1);
1182 if (msg
->type
== IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
) {
1183 return msgview
->privat
->flags
& MESSAGE_VIEW_SHOW_NORMAL
;
1184 } else if (msg
->type
== IANJUTA_MESSAGE_VIEW_TYPE_INFO
) {
1185 return msgview
->privat
->flags
& MESSAGE_VIEW_SHOW_INFO
;
1186 } else if (msg
->type
== IANJUTA_MESSAGE_VIEW_TYPE_WARNING
) {
1187 return msgview
->privat
->flags
& MESSAGE_VIEW_SHOW_WARNING
;
1188 } else if (msg
->type
== IANJUTA_MESSAGE_VIEW_TYPE_ERROR
) {
1189 return msgview
->privat
->flags
& MESSAGE_VIEW_SHOW_ERROR
;
1191 } else return FALSE
;
1195 message_view_get_flags (MessageView
* view
)
1197 g_return_val_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
), MESSAGE_VIEW_SHOW_NORMAL
);
1199 return view
->privat
->flags
;
1202 void message_view_set_flags (MessageView
* view
, MessageViewFlags flags
)
1204 g_return_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
));
1206 view
->privat
->flags
= flags
;
1207 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER(view
->privat
->filter
));
1210 gint
message_view_get_count (MessageView
* view
, MessageViewFlags flags
)
1212 g_return_val_if_fail (view
!= NULL
&& MESSAGE_IS_VIEW (view
), 0);
1216 case MESSAGE_VIEW_SHOW_NORMAL
:
1217 return view
->privat
->normal_count
;
1218 case MESSAGE_VIEW_SHOW_INFO
:
1219 return view
->privat
->info_count
;
1220 case MESSAGE_VIEW_SHOW_WARNING
:
1221 return view
->privat
->warn_count
;
1222 case MESSAGE_VIEW_SHOW_ERROR
:
1223 return view
->privat
->error_count
;
1225 g_assert_not_reached ();
1229 ANJUTA_TYPE_BEGIN(MessageView
, message_view
, GTK_TYPE_HBOX
);
1230 ANJUTA_TYPE_ADD_INTERFACE(imessage_view
, IANJUTA_TYPE_MESSAGE_VIEW
);