Initial import
This commit is contained in:
parent
719a3a053d
commit
c6b8ccfb81
306
gnoemoe/widgets/gm-log-view.c
Normal file
306
gnoemoe/widgets/gm-log-view.c
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
#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);
|
||||||
|
}
|
58
gnoemoe/widgets/gm-log-view.h
Normal file
58
gnoemoe/widgets/gm-log-view.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef __GM_LOG_VIEW_H__
|
||||||
|
#define __GM_LOG_VIEW_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type checking and casting macros
|
||||||
|
*/
|
||||||
|
#define GM_TYPE_LOG_VIEW (gm_log_view_get_type())
|
||||||
|
#define GM_LOG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||||
|
GM_TYPE_LOG_VIEW, GmLogView))
|
||||||
|
#define GM_LOG_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
|
||||||
|
GM_TYPE_LOG_VIEW, GmLogView const))
|
||||||
|
#define GM_LOG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||||
|
GM_TYPE_LOG_VIEW, GmLogViewClass))
|
||||||
|
#define GM_IS_LOG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
|
||||||
|
GM_TYPE_LOG_VIEW))
|
||||||
|
#define GM_IS_LOG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||||
|
GM_TYPE_LOG_VIEW))
|
||||||
|
#define GM_LOG_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
|
||||||
|
GM_TYPE_LOG_VIEW, GmLogViewClass))
|
||||||
|
|
||||||
|
/* Private structure type */
|
||||||
|
typedef struct _GmLogViewPrivate GmLogViewPrivate;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main object structure
|
||||||
|
*/
|
||||||
|
typedef struct _GmLogView GmLogView;
|
||||||
|
|
||||||
|
struct _GmLogView {
|
||||||
|
GtkVBox parent;
|
||||||
|
|
||||||
|
/*< private > */
|
||||||
|
GmLogViewPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class definition
|
||||||
|
*/
|
||||||
|
typedef struct _GmLogViewClass GmLogViewClass;
|
||||||
|
|
||||||
|
struct _GmLogViewClass {
|
||||||
|
GtkVBoxClass parent_class;
|
||||||
|
|
||||||
|
/* Signals
|
||||||
|
void (* proto) (GmLogView *obj); */
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gm_log_view_get_type(void) G_GNUC_CONST;
|
||||||
|
GmLogView *gm_log_view_new(void);
|
||||||
|
void gm_log_view_set_text(GmLogView *view, gchar const *text);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* __GM_LOG_VIEW_H__ */
|
Reference in a new issue