Add dialog for event filtering

Created a dialog that shows all events. Still need to implement the
event filtering.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
diff --git a/Makefile b/Makefile
index 0287721..8d4e48d 100644
--- a/Makefile
+++ b/Makefile
@@ -22,15 +22,19 @@
 
 LIB_FILE = libtracecmd.a
 
-HEADERS = parse-events.h trace-cmd.h
+HEADERS = parse-events.h trace-cmd.h trace-local.h
 
 trace-read.o::		$(HEADERS) 
 trace-cmd.o::		$(HEADERS) $(LIB_FILE)
 trace-util.o::		$(HEADERS)
 trace-ftrace.o::	$(HEADERS)
 trace-input.o::		$(HEADERS)
+trace-view.o::		$(HEADERS)
+trace-view-store.o::	$(HEADERS)
+trace-filter.o::	$(HEADERS)
 
-trace-cmd:: trace-cmd.o trace-read.o trace-view.o trace-view-store.o
+trace-cmd:: trace-cmd.o trace-read.o trace-view.o trace-view-store.o \
+	trace-filter.o
 	$(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)
 
 .PHONY: view_depends
diff --git a/trace-filter.c b/trace-filter.c
new file mode 100644
index 0000000..2e69714
--- /dev/null
+++ b/trace-filter.c
@@ -0,0 +1,171 @@
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "trace-cmd.h"
+#include "trace-local.h"
+#include "trace-view-store.h"
+
+#define EVENT_DIALOG_WIDTH	400
+#define EVENT_DIALOG_HEIGHT	600
+
+struct dialog_helper {
+	GtkWidget		*dialog;
+	GtkWidget		*trace_tree;
+};
+
+enum {
+	COL_EVENT,
+	NUM_EVENT_COLS,
+};
+
+static GtkTreeModel *
+create_tree_event_model(GtkWidget *tree_view)
+{
+	GtkTreeModel *model;
+	TraceViewStore *trace_view;
+	GtkTreeStore *treestore;
+	GtkTreeIter iter_all, iter_sys, iter_events;
+	struct pevent *pevent;
+	struct event **events;
+	struct event *event;
+	char *last_system = NULL;
+	gint i;
+
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
+	trace_view = TRACE_VIEW_STORE(model);
+
+	pevent = tracecmd_get_pevent(trace_view->handle);
+
+	treestore = gtk_tree_store_new(NUM_EVENT_COLS, G_TYPE_STRING);
+
+	gtk_tree_store_append(treestore, &iter_all, NULL);
+	gtk_tree_store_set(treestore, &iter_all,
+			   COL_EVENT,	"All",
+			   -1);
+
+	events = pevent_list_events(pevent, EVENT_SORT_SYSTEM);
+	if (!event)
+		return GTK_TREE_MODEL(treestore);
+
+	for (i = 0; events[i]; i++) {
+		event = events[i];
+		if (!last_system || strcmp(last_system, event->system) != 0) {
+			gtk_tree_store_append(treestore, &iter_sys, &iter_all);
+			gtk_tree_store_set(treestore, &iter_sys,
+					   COL_EVENT, event->system,
+					   -1);
+			last_system = event->system;
+		}
+
+		gtk_tree_store_append(treestore, &iter_events, &iter_sys);
+		gtk_tree_store_set(treestore, &iter_events,
+				   COL_EVENT, event->name,
+				   -1);
+
+	}
+
+	return GTK_TREE_MODEL(treestore);
+}
+
+static GtkWidget *create_event_list_view(GtkWidget *tree_view)
+{
+	GtkTreeViewColumn *col;
+	GtkCellRenderer *renderer;
+	GtkWidget *view;
+	GtkTreeModel *model;
+
+	view = gtk_tree_view_new();
+
+	/* --- events column --- */
+
+	col = gtk_tree_view_column_new();
+
+	gtk_tree_view_column_set_title(col, "Events");
+
+	gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
+
+	renderer  = gtk_cell_renderer_text_new();
+
+	gtk_tree_view_column_pack_start(col, renderer, TRUE);
+
+	gtk_tree_view_column_add_attribute(col, renderer, "text", COL_EVENT);
+
+	model = create_tree_event_model(tree_view);
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+
+	g_object_unref(model);
+
+	gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
+				    GTK_SELECTION_MULTIPLE);
+
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
+
+	return view;
+}
+
+
+/* Callback for the clicked signal of the Events filter button */
+static void
+event_dialog_response (gpointer data, gint response_id)
+{
+	struct dialog_helper *helper = data;
+
+	switch (response_id) {
+	case GTK_RESPONSE_ACCEPT:
+		printf("accept!\n");
+		break;
+	case GTK_RESPONSE_REJECT:
+		printf("reject!\n");
+		break;
+	default:
+		break;
+	};
+
+	gtk_widget_destroy(GTK_WIDGET(helper->dialog));
+
+	g_free(helper);
+}
+
+void trace_filter_event_dialog(void *trace_tree)
+{
+	GtkWidget *tree_view = GTK_WIDGET(trace_tree);
+	struct dialog_helper *helper;
+	GtkWidget *dialog;
+	GtkWidget *scrollwin;
+	GtkWidget *view;
+
+//	trace_view = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
+
+	helper = g_malloc(sizeof(*helper));
+
+	/* --- Make dialog window --- */
+
+	dialog = gtk_dialog_new_with_buttons("Filter Events",
+					     NULL,
+					     GTK_DIALOG_MODAL,
+					     "Accept",
+					     GTK_RESPONSE_ACCEPT,
+					     GTK_STOCK_CANCEL,
+					     GTK_RESPONSE_REJECT,
+					     NULL);
+
+	helper->dialog = dialog;
+	helper->trace_tree = tree_view;
+
+	/* We can attach the Quit menu item to our exit function */
+	g_signal_connect_swapped (dialog, "response",
+				  G_CALLBACK (event_dialog_response),
+				  (gpointer) helper);
+
+	scrollwin = gtk_scrolled_window_new(NULL, NULL);
+	view = create_event_list_view(tree_view);
+
+	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0);
+	gtk_container_add(GTK_CONTAINER(scrollwin), view);
+
+	gtk_widget_set_size_request(GTK_WIDGET(dialog),
+				    EVENT_DIALOG_WIDTH, EVENT_DIALOG_HEIGHT);
+
+	gtk_widget_show_all(dialog);
+}
diff --git a/trace-local.h b/trace-local.h
index 4b3deff..94b61c3 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -13,4 +13,10 @@
 void trace_report(int argc, char **argv);
 void trace_view(int argc, char **argv);
 
+
+/* GUI */
+
+/* We use void because this can be used by non gtk files */
+void trace_filter_event_dialog(void *traceview);
+
 #endif /* __TRACE_LOCAL_H */
diff --git a/trace-view.c b/trace-view.c
index e7e1c99..d756533 100644
--- a/trace-view.c
+++ b/trace-view.c
@@ -43,8 +43,6 @@
 	NUM_COLS
 };
 
-struct tracecmd_input *trace_handle;
-
 GtkWidget *trace_tree;
 
 /* Callback for the clicked signal of the Exit button */
@@ -64,6 +62,15 @@
 	return TRUE;
 }
 
+/* Callback for the clicked signal of the Events filter button */
+static void
+events_clicked (gpointer data)
+{
+	GtkWidget *trace_tree = data;
+
+	trace_filter_event_dialog(trace_tree);
+}
+
 static GtkTreeModel *
 create_trace_view_model(struct tracecmd_input *handle)
 {
@@ -74,15 +81,13 @@
 	return GTK_TREE_MODEL(store);
 }
 
-static GtkWidget *
-create_trace_view(struct tracecmd_input *handle)
+static void
+load_trace_view(GtkWidget *view, struct tracecmd_input *handle)
 {
 	GtkTreeViewColumn *col;
 	GtkCellRenderer *renderer;
-	GtkWidget *view;
 	GtkTreeModel *model;
 
-	view = gtk_tree_view_new();
 
 	/* --- CPU column --- */
 
@@ -144,8 +149,6 @@
 	gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
 
 	g_object_unref(model); /* destroy model automatically with view */
-
-	return view;
 }
 
 void trace_view(int argc, char **argv)
@@ -157,7 +160,7 @@
 	GtkWidget *menu_bar;
 	GtkWidget *menu;
 	GtkWidget *menu_item;
-	GtkWidget *quit_item;
+	GtkWidget *sub_item;
 	GtkWidget *scrollwin;
 
 	handle = read_trace_header();
@@ -170,14 +173,16 @@
 	if (tracecmd_init_data(handle) < 0)
 		die("failed to init data");
 
-	trace_handle = handle;
-
 	gnome_init("trace-cmd", version, argc, argv);
 
 	/* --- Main window --- */
 
 	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
+	/* --- Get handle for trace view first --- */
+
+	trace_tree = gtk_tree_view_new();
+
 	/* --- Top Level Vbox --- */
 
 	vbox = gtk_vbox_new(FALSE, 0);
@@ -200,23 +205,53 @@
 	menu = gtk_menu_new();    /* Don't need to show menus */
 
 
-	/* --- Quit Option --- */
+	/* --- File - Quit Option --- */
 
-	quit_item = gtk_menu_item_new_with_label("Quit");
+	sub_item = gtk_menu_item_new_with_label("Quit");
 
 	/* Add them to the menu */
-	gtk_menu_shell_append(GTK_MENU_SHELL (menu), quit_item);
+	gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
 
 	/* We can attach the Quit menu item to our exit function */
-	g_signal_connect_swapped (G_OBJECT (quit_item), "activate",
+	g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
 				  G_CALLBACK (exit_clicked),
 				  (gpointer) window);
 
 	/* We do need to show menu items */
-	gtk_widget_show(quit_item);
-
+	gtk_widget_show(sub_item);
 
 	gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
+
+	/* --- end File options --- */
+
+
+	/* --- Filter Option --- */
+
+	menu_item = gtk_menu_item_new_with_label("Filter");
+	gtk_widget_show(menu_item);
+
+	gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), menu_item);
+
+	menu = gtk_menu_new();    /* Don't need to show menus */
+
+
+	/* --- Filter - Events Option --- */
+
+	sub_item = gtk_menu_item_new_with_label("events");
+
+	/* Add them to the menu */
+	gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
+
+	/* We can attach the Quit menu item to our exit function */
+	g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
+				  G_CALLBACK (events_clicked),
+				  (gpointer) trace_tree);
+
+	/* We do need to show menu items */
+	gtk_widget_show(sub_item);
+
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
+
 	/* --- Top Level Hbox --- */
 
 	hbox = gtk_hbox_new(FALSE, 0);
@@ -231,9 +266,9 @@
 	gtk_box_pack_start(GTK_BOX (hbox), scrollwin, TRUE, TRUE, 0);
 	gtk_widget_show(scrollwin);
 
-	/* --- Trace Tree --- */
+	/* --- Set up Trace Tree --- */
 
-	trace_tree = create_trace_view(handle);
+	load_trace_view(trace_tree, handle);
 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
 					      trace_tree);
 	gtk_widget_show(trace_tree);