307 lines
9 KiB
C
307 lines
9 KiB
C
#include "gm-log-view.h"
|
|
#include "gm-searchable.h"
|
|
#include "gm-app.h"
|
|
#include "gm-color-table.h"
|
|
#include "gm-support.h"
|
|
#include "gm-options.h"
|
|
#include "gm-debug.h"
|
|
|
|
#define GM_LOG_VIEW_GET_PRIVATE(object)( \
|
|
G_TYPE_INSTANCE_GET_PRIVATE((object), \
|
|
GM_TYPE_LOG_VIEW, GmLogViewPrivate))
|
|
|
|
struct _GmLogViewPrivate {
|
|
GtkTextView *text_view;
|
|
};
|
|
|
|
/* Signals
|
|
|
|
enum {
|
|
PROTO
|
|
NUM_SIGNALS
|
|
};
|
|
|
|
static guint gm_log_view_signals[NUM_SIGNALS] = {0};*/
|
|
static void gm_log_view_searchable_iface_init(
|
|
GmSearchableInterface *iface);
|
|
|
|
static GtkTextView *gm_log_view_searchable_get_text_view(GmSearchable *sea);
|
|
void on_gm_log_view_font_changed(GmColorTable *color_table,
|
|
gchar *font_description, GmLogView *view);
|
|
void on_gm_log_view_filter_toggled(GtkToggleButton *button, GmLogView *view);
|
|
|
|
G_DEFINE_TYPE_EXTENDED(GmLogView, gm_log_view, GTK_TYPE_VBOX, 0, \
|
|
G_IMPLEMENT_INTERFACE(GM_TYPE_SEARCHABLE, \
|
|
gm_log_view_searchable_iface_init))
|
|
|
|
static void
|
|
gm_log_view_searchable_iface_init(GmSearchableInterface *iface) {
|
|
iface->get_text_view = gm_log_view_searchable_get_text_view;
|
|
}
|
|
|
|
static GtkTextView *
|
|
gm_log_view_searchable_get_text_view(GmSearchable *sea) {
|
|
GmLogView *view = (GmLogView *)(sea);
|
|
|
|
g_return_val_if_fail(GM_IS_LOG_VIEW(sea), NULL);
|
|
|
|
return view->priv->text_view;
|
|
}
|
|
|
|
static void
|
|
gm_log_view_finalize(GObject *object) {
|
|
//GmLogView *obj = GM_LOG_VIEW(object);
|
|
|
|
g_signal_handlers_disconnect_by_func(gm_app_color_table(gm_app_instance()),
|
|
on_gm_log_view_font_changed, object);
|
|
G_OBJECT_CLASS(gm_log_view_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
gm_log_view_class_init(GmLogViewClass *klass) {
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
GmOptions *options;
|
|
|
|
object_class->finalize = gm_log_view_finalize;
|
|
|
|
/*gm_log_view_signals[PROTO] =
|
|
g_signal_new("proto",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmLogViewClass, proto),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE,
|
|
0);*/
|
|
|
|
options = gm_app_options(gm_app_instance());
|
|
|
|
g_type_class_add_private(object_class, sizeof(GmLogViewPrivate));
|
|
}
|
|
|
|
static void
|
|
gm_log_view_create_tags(GmLogView *obj) {
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(obj->priv->text_view);
|
|
gtk_text_buffer_create_tag(buffer, "in", NULL);
|
|
gtk_text_buffer_create_tag(buffer, "out", NULL);
|
|
gtk_text_buffer_create_tag(buffer, "status", NULL);
|
|
gtk_text_buffer_create_tag(buffer, "mcp_in", NULL);
|
|
gtk_text_buffer_create_tag(buffer, "mcp_out", NULL);
|
|
gtk_text_buffer_create_tag(buffer, "mcp_status", NULL);
|
|
}
|
|
|
|
void
|
|
gm_log_view_update_font(GmLogView *view) {
|
|
PangoFontDescription *f = pango_font_description_from_string(
|
|
gm_color_table_font_description(gm_app_color_table(
|
|
gm_app_instance())));
|
|
|
|
if (f != NULL) {
|
|
gtk_widget_modify_font(GTK_WIDGET(view->priv->text_view), f);
|
|
pango_font_description_free(f);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gm_log_view_create_text_view(GmLogView *obj) {
|
|
GtkTextView *text_view = GTK_TEXT_VIEW(gtk_text_view_new());
|
|
|
|
gtk_text_view_set_editable(text_view, FALSE);
|
|
|
|
// Margins
|
|
gtk_text_view_set_left_margin(text_view, 3);
|
|
gtk_text_view_set_right_margin(text_view, 3);
|
|
|
|
// Set default wrapping mode
|
|
gtk_text_view_set_wrap_mode(text_view, GTK_WRAP_WORD_CHAR);
|
|
gtk_widget_show(GTK_WIDGET(text_view));
|
|
obj->priv->text_view = text_view;
|
|
|
|
gm_log_view_create_tags(obj);
|
|
gm_log_view_update_font(obj);
|
|
}
|
|
|
|
GtkWidget *
|
|
gm_log_view_create_filter(GmLogView *obj) {
|
|
GtkWidget *box = gtk_hbox_new(FALSE, 6);
|
|
GtkWidget *label = gtk_label_new(_("Filter: "));
|
|
GtkWidget *check;
|
|
GmOptions *options = gm_app_options(gm_app_instance());
|
|
|
|
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Incoming"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("in"), g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_in"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Outgoing"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("out"), g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_out"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Status"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("status"),
|
|
g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_status"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Mcp incoming"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("mcp_in"),
|
|
g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_mcp_in"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Mcp outgoing"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("mcp_out"),
|
|
g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_mcp_out"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
check = gtk_check_button_new_with_label(_("Mcp status"));
|
|
g_object_set_data_full(G_OBJECT(check), "option", g_strdup("mcp_status"),
|
|
g_free);
|
|
g_signal_connect(check, "toggled",
|
|
G_CALLBACK(on_gm_log_view_filter_toggled), obj);
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check),
|
|
gm_options_get_int(options, "logging_filter_mcp_status"));
|
|
gtk_box_pack_start(GTK_BOX(box), check, FALSE, FALSE, 0);
|
|
|
|
gtk_container_set_border_width(GTK_CONTAINER(box), 3);
|
|
|
|
gtk_widget_show_all(box);
|
|
return box;
|
|
}
|
|
|
|
static void
|
|
gm_log_view_init(GmLogView *obj) {
|
|
GtkWidget *srl;
|
|
obj->priv = GM_LOG_VIEW_GET_PRIVATE(obj);
|
|
|
|
gtk_box_set_spacing(GTK_BOX(obj), 6);
|
|
gtk_box_set_homogeneous(GTK_BOX(obj), FALSE);
|
|
|
|
gm_log_view_create_text_view(obj);
|
|
//gtk_box_pack_start(GTK_BOX(obj), gm_log_view_create_filter(obj), FALSE,
|
|
// FALSE, 0);
|
|
|
|
srl = gtk_scrolled_window_new(NULL, NULL);
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(srl),
|
|
GTK_SHADOW_IN);
|
|
|
|
gtk_widget_show(srl);
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(srl),
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_container_add(GTK_CONTAINER(srl), GTK_WIDGET(obj->priv->text_view));
|
|
gtk_box_pack_start(GTK_BOX(obj), srl, TRUE, TRUE, 0);
|
|
|
|
g_signal_connect(gm_app_color_table(gm_app_instance()), "font_changed",
|
|
G_CALLBACK(on_gm_log_view_font_changed), obj);
|
|
}
|
|
|
|
GmLogView *
|
|
gm_log_view_new() {
|
|
GmLogView *obj = GM_LOG_VIEW(g_object_new(GM_TYPE_LOG_VIEW, NULL));
|
|
|
|
return obj;
|
|
}
|
|
|
|
gchar const *
|
|
gm_log_view_get_tag(gchar const *last) {
|
|
switch (last[11]) {
|
|
case '>':
|
|
return "out";
|
|
break;
|
|
case '<':
|
|
return "in";
|
|
break;
|
|
case '#':
|
|
return "status";
|
|
break;
|
|
case '[':
|
|
switch (last[17]) {
|
|
case '>':
|
|
return "mcp_out";
|
|
break;
|
|
case '<':
|
|
return "mcp_in";
|
|
break;
|
|
case '#':
|
|
return "mcp_status";
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
gm_log_view_set_text(GmLogView *view, gchar const *text) {
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(view->priv->text_view);
|
|
gchar *ptr;
|
|
gchar const *last = text, *tag;
|
|
GtkTextIter iter;
|
|
|
|
gtk_text_buffer_get_end_iter(buffer, &iter);
|
|
tag = gm_log_view_get_tag(text);
|
|
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, text, -1, tag, NULL);
|
|
return;
|
|
|
|
// log format: [hh:mm:ss] >|<|#|[MCP] <|[MCP] > text
|
|
while ((ptr = g_utf8_strchr(last, -1, '\n'))) {
|
|
gtk_text_buffer_get_end_iter(buffer, &iter);
|
|
tag = gm_log_view_get_tag(last);
|
|
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, last,
|
|
ptr - last + 1, tag, NULL);
|
|
last = ptr + 1;
|
|
}
|
|
|
|
if (*last != '\0') {
|
|
gtk_text_buffer_get_end_iter(buffer, &iter);
|
|
tag = gm_log_view_get_tag(last);
|
|
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, last,
|
|
ptr - last + 1, tag, NULL);
|
|
}
|
|
}
|
|
|
|
/* Callbacks */
|
|
|
|
void
|
|
on_gm_log_view_font_changed(GmColorTable *color_table,
|
|
gchar *font_description, GmLogView *view) {
|
|
gm_log_view_update_font(view);
|
|
}
|
|
|
|
void
|
|
on_gm_log_view_filter_toggled(GtkToggleButton *button, GmLogView *view) {
|
|
gchar *option = (gchar *)g_object_get_data(G_OBJECT(button), "option");
|
|
gchar *opt = g_strconcat("logging_filter_", option, NULL);
|
|
gboolean active = gtk_toggle_button_get_active(button);
|
|
GmOptions *options = gm_app_options(gm_app_instance());
|
|
|
|
GtkTextTag *tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(
|
|
gtk_text_view_get_buffer(view->priv->text_view)), option);
|
|
|
|
g_object_set(G_OBJECT(tag), "invisible", !active, NULL);
|
|
|
|
gm_options_set_int(options, opt, active);
|
|
g_free(opt);
|
|
}
|