This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/widgets/gm-log-view.c

282 lines
8.3 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_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_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);
}
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);
}
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);
gm_register_schemed(GTK_WIDGET(obj->priv->text_view), gm_app_color_table(
gm_app_instance()), GM_SCHEMED_COLORS | GM_SCHEMED_FONT);
}
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_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);
}