Initial import
This commit is contained in:
parent
719a3a053d
commit
c6b8ccfb81
2 changed files with 364 additions and 0 deletions
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