aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-16 22:13:47 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-16 22:13:47 -0500
commit39b1cdf4a8e7e256420a1dc8769d8849f185fe3b (patch)
tree0eb94a11f58a204a9c228fc07da60b146172ff1d
parentad813ef9fb16cf4510be274a04dfb37c9fadf6e3 (diff)
trace-cmd: Add advanced filtering
Add a "Advanced event filter" option that opens a text dialog that lets you write an advanced filter. This is still very primitive and needs to be cleaned up. Not only that, it needs to show previous filters. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-filter.c113
-rw-r--r--trace-filter.h17
-rw-r--r--trace-view-main.c38
-rw-r--r--trace-view.c46
-rw-r--r--trace-view.h4
5 files changed, 218 insertions, 0 deletions
diff --git a/trace-filter.c b/trace-filter.c
index 7e5d37d..a431fa1 100644
--- a/trace-filter.c
+++ b/trace-filter.c
@@ -32,6 +32,9 @@
32#define DIALOG_WIDTH 400 32#define DIALOG_WIDTH 400
33#define DIALOG_HEIGHT 600 33#define DIALOG_HEIGHT 600
34 34
35#define TEXT_DIALOG_WIDTH 400
36#define TEXT_DIALOG_HEIGHT 200
37
35int str_cmp(const void *a, const void *b) 38int str_cmp(const void *a, const void *b)
36{ 39{
37 char * const * sa = a; 40 char * const * sa = a;
@@ -57,6 +60,116 @@ struct dialog_helper {
57 gpointer data; 60 gpointer data;
58}; 61};
59 62
63struct adv_event_filter_helper {
64 trace_adv_filter_cb_func func;
65 GtkWidget *entry;
66 gpointer data;
67};
68
69/* Callback for the clicked signal of the advanced filter button */
70static void
71adv_filter_dialog_response (gpointer data, gint response_id)
72{
73 struct dialog_helper *helper = data;
74 struct adv_event_filter_helper *event_helper = helper->data;
75 const gchar *text;
76
77 switch (response_id) {
78 case GTK_RESPONSE_ACCEPT:
79 text = gtk_entry_get_text(GTK_ENTRY(event_helper->entry));
80 event_helper->func(TRUE, text, event_helper->data);
81 break;
82 case GTK_RESPONSE_REJECT:
83 event_helper->func(FALSE, NULL, event_helper->data);
84 break;
85 default:
86 break;
87 };
88
89 gtk_widget_destroy(GTK_WIDGET(helper->dialog));
90
91 g_free(event_helper);
92 g_free(helper);
93}
94
95/**
96 * trace_adv_filter_dialog - make dialog for text
97 * @handle: the handle to the tracecmd data file
98 * @event_filter: advanced filters
99 * @func: The function to call when accept or cancel is pressed
100 * @data: data to pass to the function @func
101 */
102void trace_adv_filter_dialog(struct tracecmd_input *handle,
103 struct event_filter *event_filter,
104 trace_adv_filter_cb_func func,
105 gpointer data)
106{
107 struct dialog_helper *helper;
108 struct adv_event_filter_helper *event_helper;
109 GtkWidget *dialog;
110 GtkWidget *hbox;
111 GtkWidget *label;
112 GtkWidget *entry;
113
114 helper = g_malloc(sizeof(*helper));
115 g_assert(helper);
116
117 /* --- Make dialog window --- */
118
119 dialog = gtk_dialog_new_with_buttons("Advanced Filters",
120 NULL,
121 GTK_DIALOG_MODAL,
122 "Apply",
123 GTK_RESPONSE_ACCEPT,
124 GTK_STOCK_CANCEL,
125 GTK_RESPONSE_REJECT,
126 NULL);
127
128 event_helper = g_new0(typeof(*event_helper), 1);
129 g_assert(event_helper);
130
131 helper->dialog = dialog;
132 helper->data = event_helper;
133
134 event_helper->func = func;
135 event_helper->data = data;
136
137 /* We can attach the Quit menu item to our exit function */
138 g_signal_connect_swapped (dialog, "response",
139 G_CALLBACK (adv_filter_dialog_response),
140 (gpointer) helper);
141
142#if 0
143 scrollwin = gtk_scrolled_window_new(NULL, NULL);
144 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
145 GTK_POLICY_AUTOMATIC,
146 GTK_POLICY_AUTOMATIC);
147 view = create_event_list_view(handle, all_events, systems, events);
148 event_helper->view = GTK_TREE_VIEW(view);
149 gtk_container_add(GTK_CONTAINER(scrollwin), view);
150 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrollwin, TRUE, TRUE, 0);
151#endif
152
153 hbox = gtk_hbox_new(FALSE, 0);
154 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
155 gtk_widget_show(hbox);
156
157 label = gtk_label_new("Filter:");
158 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
159 gtk_widget_show(label);
160
161 entry = gtk_entry_new();
162 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
163 gtk_widget_show(entry);
164
165 event_helper->entry = entry;
166
167 gtk_widget_set_size_request(GTK_WIDGET(dialog),
168 TEXT_DIALOG_WIDTH, TEXT_DIALOG_HEIGHT);
169
170 gtk_widget_show_all(dialog);
171}
172
60enum { 173enum {
61 COL_EVENT, 174 COL_EVENT,
62 COL_ACTIVE, 175 COL_ACTIVE,
diff --git a/trace-filter.h b/trace-filter.h
index 73bdb67..80a27ed 100644
--- a/trace-filter.h
+++ b/trace-filter.h
@@ -29,6 +29,18 @@ struct event_filter_list {
29}; 29};
30 30
31/** 31/**
32 * trace_adv_filter_cb_func - callback type for advanced filter dialog
33 * @accept: TRUE if the accept button was pressed, otherwise FALSE
34 * @text: The text that was entered
35 * @data: The data given passed in to the event dialog function
36 *
37 * If @accept is FALSE then @text should be ignored. @data is still valid.
38 */
39typedef void (*trace_adv_filter_cb_func)(gboolean accept,
40 const gchar *text,
41 gpointer data);
42
43/**
32 * trace_filter_event_cb_func - callback type for event dialog 44 * trace_filter_event_cb_func - callback type for event dialog
33 * @accept: TRUE if the accept button was pressed, otherwise FALSE 45 * @accept: TRUE if the accept button was pressed, otherwise FALSE
34 * @all_events: TRUE if "All Events" was checked 46 * @all_events: TRUE if "All Events" was checked
@@ -47,6 +59,11 @@ typedef void (*trace_filter_event_cb_func)(gboolean accept,
47 gint *events, 59 gint *events,
48 gpointer data); 60 gpointer data);
49 61
62void trace_adv_filter_dialog(struct tracecmd_input *handle,
63 struct event_filter *event_filter,
64 trace_adv_filter_cb_func func,
65 gpointer data);
66
50void trace_filter_event_dialog(struct tracecmd_input *handle, 67void trace_filter_event_dialog(struct tracecmd_input *handle,
51 gboolean all_events, 68 gboolean all_events,
52 gchar **systems, 69 gchar **systems,
diff --git a/trace-view-main.c b/trace-view-main.c
index 2bbfd42..268726c 100644
--- a/trace-view-main.c
+++ b/trace-view-main.c
@@ -126,6 +126,28 @@ events_clicked (gpointer data)
126 free(events); 126 free(events);
127} 127}
128 128
129/* Callback for the clicked signal of the Advanced filter button */
130static void
131adv_filter_clicked (gpointer data)
132{
133 struct trace_tree_info *info = data;
134 struct event_filter *event_filter;
135 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->trace_tree);
136 GtkTreeModel *model;
137 TraceViewStore *store;
138
139 model = gtk_tree_view_get_model(trace_tree);
140 if (!model)
141 return;
142
143 store = TRACE_VIEW_STORE(model);
144
145 event_filter = trace_view_store_get_event_filter(store);
146
147 trace_adv_filter_dialog(store->handle, event_filter,
148 trace_view_adv_filter_callback, trace_tree);
149}
150
129/* Callback for the clicked signal of the CPUs filter button */ 151/* Callback for the clicked signal of the CPUs filter button */
130static void 152static void
131cpus_clicked (gpointer data) 153cpus_clicked (gpointer data)
@@ -293,6 +315,22 @@ void trace_view(int argc, char **argv)
293 gtk_widget_show(sub_item); 315 gtk_widget_show(sub_item);
294 316
295 317
318 /* --- Filter - Advanced Events Option --- */
319
320 sub_item = gtk_menu_item_new_with_label("advanced event filter");
321
322 /* Add them to the menu */
323 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
324
325 /* We can attach the Quit menu item to our exit function */
326 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
327 G_CALLBACK (adv_filter_clicked),
328 (gpointer) &tree_info);
329
330 /* We do need to show menu items */
331 gtk_widget_show(sub_item);
332
333
296 /* --- Filter - CPUs Option --- */ 334 /* --- Filter - CPUs Option --- */
297 335
298 sub_item = gtk_menu_item_new_with_label("CPUs"); 336 sub_item = gtk_menu_item_new_with_label("CPUs");
diff --git a/trace-view.c b/trace-view.c
index 5de5f51..13fdb7e 100644
--- a/trace-view.c
+++ b/trace-view.c
@@ -432,6 +432,52 @@ void trace_view_event_filter_callback(gboolean accept,
432 trace_view_select(GTK_WIDGET(trace_tree), time); 432 trace_view_select(GTK_WIDGET(trace_tree), time);
433} 433}
434 434
435void trace_view_adv_filter_callback(gboolean accept,
436 const gchar *text,
437 gpointer data)
438{
439 struct event_filter *event_filter;
440 GtkTreeView *trace_tree = data;
441 GtkTreeModel *model;
442 TraceViewStore *store;
443 TraceViewRecord *vrec;
444 char *error_str;
445 guint64 time;
446 gint row;
447
448 if (!accept)
449 return;
450
451 model = gtk_tree_view_get_model(trace_tree);
452 if (!model)
453 return;
454
455 store = TRACE_VIEW_STORE(model);
456
457 trace_view_store_clear_all_events_enabled(store);
458
459 event_filter = trace_view_store_get_event_filter(store);
460
461 pevent_filter_add_filter_str(event_filter, text, &error_str);
462
463 /* Keep track of the currently selected row */
464 row = trace_view_get_selected_row(GTK_WIDGET(trace_tree));
465 if (row >= 0) {
466 vrec = trace_view_store_get_row(store, row);
467 time = vrec->timestamp;
468 }
469
470 /* Force an update */
471 g_object_ref(store);
472 gtk_tree_view_set_model(trace_tree, NULL);
473 trace_view_store_update_filter(store);
474 gtk_tree_view_set_model(trace_tree, GTK_TREE_MODEL(store));
475 g_object_unref(store);
476
477 if (row >= 0)
478 trace_view_select(GTK_WIDGET(trace_tree), time);
479}
480
435void trace_view_cpu_filter_callback(gboolean accept, 481void trace_view_cpu_filter_callback(gboolean accept,
436 gboolean all_cpus, 482 gboolean all_cpus,
437 guint64 *selected_cpu_mask, 483 guint64 *selected_cpu_mask,
diff --git a/trace-view.h b/trace-view.h
index 6f1357b..f8b85ea 100644
--- a/trace-view.h
+++ b/trace-view.h
@@ -47,6 +47,10 @@ void trace_view_event_filter_callback(gboolean accept,
47 gint *events, 47 gint *events,
48 gpointer data); 48 gpointer data);
49 49
50void trace_view_adv_filter_callback(gboolean accept,
51 const gchar *text,
52 gpointer data);
53
50void trace_view_cpu_filter_callback(gboolean accept, 54void trace_view_cpu_filter_callback(gboolean accept,
51 gboolean all_cpus, 55 gboolean all_cpus,
52 guint64 *selected_cpu_mask, 56 guint64 *selected_cpu_mask,