aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-04-05 17:28:12 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-04-09 11:56:18 -0400
commit81b404df1d425f146527dc3da253365071e68bea (patch)
treeb5d1c23d118f41505e7c896837ef27bf489c5e9c
parentb2a9cd2f38f6c3c30e9ef4c47eb004b41b50fe5e (diff)
trace-view: Add pop-up task menu for filtering tasks
Add pop-up menu over the rows that will allow to filter on tasks in trace-view. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-view-main.c227
1 files changed, 214 insertions, 13 deletions
diff --git a/trace-view-main.c b/trace-view-main.c
index 22b9e32..74922fb 100644
--- a/trace-view-main.c
+++ b/trace-view-main.c
@@ -30,6 +30,7 @@
30#include "trace-view.h" 30#include "trace-view.h"
31#include "trace-xml.h" 31#include "trace-xml.h"
32#include "trace-gui.h" 32#include "trace-gui.h"
33#include "trace-compat.h"
33 34
34#define version "0.1.1" 35#define version "0.1.1"
35 36
@@ -40,8 +41,13 @@
40static char *input_file; 41static char *input_file;
41 42
42struct trace_tree_info { 43struct trace_tree_info {
43 GtkWidget *trace_tree; 44 struct tracecmd_input *handle;
44 GtkWidget *spin; 45 GtkWidget *trace_tree;
46 GtkWidget *spin;
47 gint filter_enabled;
48 gint filter_task_selected;
49 struct filter_task *task_filter;
50 struct filter_task *hide_tasks;
45}; 51};
46 52
47void usage(char *prog) 53void usage(char *prog)
@@ -68,6 +74,7 @@ load_clicked (gpointer data)
68 trace_view_reload(info->trace_tree, handle, info->spin); 74 trace_view_reload(info->trace_tree, handle, info->spin);
69 /* Free handle when freeing the trace tree */ 75 /* Free handle when freeing the trace tree */
70 tracecmd_close(handle); 76 tracecmd_close(handle);
77 info->handle = handle;
71 } 78 }
72 g_free(filename); 79 g_free(filename);
73} 80}
@@ -203,24 +210,209 @@ cpus_clicked (gpointer data)
203 trace_view_cpu_filter_callback, trace_tree); 210 trace_view_cpu_filter_callback, trace_tree);
204} 211}
205 212
206#if 0 213static void
207static GtkTreeModel * 214filter_list_clicked (gpointer data)
208create_combo_box_model(void) 215{
216 struct trace_tree_info *info = data;
217
218 if (!filter_task_count(info->task_filter) &&
219 !filter_task_count(info->hide_tasks))
220 return;
221
222 info->filter_enabled ^= 1;
223
224 if (info->filter_enabled)
225 trace_view_update_filters(info->trace_tree,
226 info->task_filter,
227 info->hide_tasks);
228 else
229 trace_view_update_filters(info->trace_tree, NULL, NULL);
230}
231
232static void update_task_filter(struct trace_tree_info *info,
233 struct filter_task *filter)
234{
235 struct filter_task_item *task;
236 gint pid = info->filter_task_selected;
237
238 task = filter_task_find_pid(filter, pid);
239
240 if (task)
241 filter_task_remove_pid(filter, pid);
242 else
243 filter_task_add_pid(filter, pid);
244
245 if (info->filter_enabled)
246 trace_view_update_filters(info->trace_tree,
247 info->task_filter,
248 info->hide_tasks);
249}
250
251static void filter_add_task_clicked(gpointer data)
252{
253 struct trace_tree_info *info = data;
254
255 update_task_filter(info, info->task_filter);
256}
257
258static void filter_hide_task_clicked(gpointer data)
209{ 259{
210 GtkListStore *store; 260 struct trace_tree_info *info = data;
211 GtkTreeIter iter;
212 261
213 store = gtk_list_store_new(1, G_TYPE_STRING); 262 update_task_filter(info, info->hide_tasks);
214 gtk_list_store_append(store, &iter); 263}
215 gtk_list_store_set(store, &iter, 0, "1", -1); 264
265static void
266filter_clear_tasks_clicked (gpointer data)
267{
268 struct trace_tree_info *info = data;
216 269
217 return GTK_TREE_MODEL(store); 270 trace_view_update_filters(info->trace_tree, NULL, NULL);
271 info->filter_enabled = 0;
272}
273
274static gboolean
275do_tree_popup(GtkWidget *widget, GdkEventButton *event, gpointer data)
276{
277 struct trace_tree_info *info = data;
278 static GtkWidget *menu;
279 static GtkWidget *menu_filter_enable;
280 static GtkWidget *menu_filter_add_task;
281 static GtkWidget *menu_filter_hide_task;
282 static GtkWidget *menu_filter_clear_tasks;
283 struct pevent *pevent;
284 struct record *record;
285 TraceViewRecord *vrec;
286 GtkTreeModel *model;
287 const char *comm;
288 gchar *text;
289 gint pid;
290 gint len;
291 guint64 offset;
292 gint row;
293 gint cpu;
294
295 if (!menu) {
296 menu = gtk_menu_new();
297
298 menu_filter_enable = gtk_menu_item_new_with_label("Enable Filter");
299 gtk_widget_show(menu_filter_enable);
300 gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_enable);
301
302 g_signal_connect_swapped (G_OBJECT (menu_filter_enable), "activate",
303 G_CALLBACK (filter_list_clicked),
304 data);
305
306 menu_filter_add_task = gtk_menu_item_new_with_label("Add Task");
307 gtk_widget_show(menu_filter_add_task);
308 gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_add_task);
309
310 g_signal_connect_swapped (G_OBJECT (menu_filter_add_task), "activate",
311 G_CALLBACK (filter_add_task_clicked),
312 data);
313
314 menu_filter_hide_task = gtk_menu_item_new_with_label("Hide Task");
315 gtk_widget_show(menu_filter_hide_task);
316 gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_hide_task);
317
318 g_signal_connect_swapped (G_OBJECT (menu_filter_hide_task), "activate",
319 G_CALLBACK (filter_hide_task_clicked),
320 data);
321
322 menu_filter_clear_tasks = gtk_menu_item_new_with_label("Clear Task Filter");
323 gtk_widget_show(menu_filter_clear_tasks);
324 gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_filter_clear_tasks);
325
326 g_signal_connect_swapped (G_OBJECT (menu_filter_clear_tasks), "activate",
327 G_CALLBACK (filter_clear_tasks_clicked),
328 data);
329
330 }
331
332 row = trace_view_get_selected_row(GTK_WIDGET(info->trace_tree));
333 if (row >= 0) {
334
335 model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->trace_tree));
336 vrec = trace_view_store_get_row(TRACE_VIEW_STORE(model), row);
337 offset = vrec->offset;
338
339 record = tracecmd_read_at(info->handle, offset, &cpu);
340
341 if (record) {
342 pevent = tracecmd_get_pevent(info->handle);
343 pid = pevent_data_pid(pevent, record);
344 comm = pevent_data_comm_from_pid(pevent, pid);
345
346 len = strlen(comm) + 50;
347
348 text = g_malloc(len);
349 g_assert(text);
350
351 if (filter_task_find_pid(info->task_filter, pid))
352 snprintf(text, len, "Remove %s-%d to filter", comm, pid);
353 else
354 snprintf(text, len, "Add %s-%d to filter", comm, pid);
355
356 info->filter_task_selected = pid;
357
358 gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_add_task),
359 text);
360
361 if (filter_task_find_pid(info->hide_tasks, pid))
362 snprintf(text, len, "Show %s-%d", comm, pid);
363 else
364 snprintf(text, len, "Hide %s-%d", comm, pid);
365
366 gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_hide_task),
367 text);
368
369 g_free(text);
370
371 info->filter_task_selected = pid;
372
373 gtk_widget_show(menu_filter_add_task);
374 gtk_widget_show(menu_filter_hide_task);
375 free_record(record);
376 }
377 } else {
378 gtk_widget_hide(menu_filter_add_task);
379 gtk_widget_hide(menu_filter_hide_task);
380 }
381
382 if (info->filter_enabled)
383 gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_enable),
384 "Disable List Filter");
385 else
386 gtk_menu_item_set_label(GTK_MENU_ITEM(menu_filter_enable),
387 "Enable List Filter");
388
389 if (filter_task_count(info->task_filter) ||
390 filter_task_count(info->hide_tasks)) {
391 gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE);
392 gtk_widget_set_sensitive(menu_filter_enable, TRUE);
393 } else {
394 gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE);
395 gtk_widget_set_sensitive(menu_filter_enable, FALSE);
396 }
397
398 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3,
399 gtk_get_current_event_time());
400
401 return TRUE;
402}
403
404static gboolean
405button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
406{
407 if (event->button == 3)
408 return do_tree_popup(widget, event, data);
409
410 return FALSE;
218} 411}
219#endif
220 412
221void trace_view(int argc, char **argv) 413void trace_view(int argc, char **argv)
222{ 414{
223 static struct tracecmd_input *handle; 415 static struct tracecmd_input *handle = NULL;
224 struct trace_tree_info tree_info; 416 struct trace_tree_info tree_info;
225 struct stat st; 417 struct stat st;
226 GtkWidget *trace_tree; 418 GtkWidget *trace_tree;
@@ -268,6 +460,11 @@ void trace_view(int argc, char **argv)
268 if (input_file) 460 if (input_file)
269 handle = tracecmd_open(input_file); 461 handle = tracecmd_open(input_file);
270 462
463 memset(&tree_info, 0, sizeof(tree_info));
464 tree_info.handle = handle;
465 tree_info.task_filter = filter_task_hash_alloc();
466 tree_info.hide_tasks = filter_task_hash_alloc();
467
271 /* --- Main window --- */ 468 /* --- Main window --- */
272 469
273 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 470 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -455,6 +652,10 @@ void trace_view(int argc, char **argv)
455 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); 652 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
456 gtk_widget_show(label); 653 gtk_widget_show(label);
457 654
655 gtk_signal_connect(GTK_OBJECT(trace_tree), "button_press_event",
656 (GtkSignalFunc) button_press_event,
657 (gpointer) &tree_info);
658
458 trace_view_search_setup(GTK_BOX(hbox), GTK_TREE_VIEW(trace_tree)); 659 trace_view_search_setup(GTK_BOX(hbox), GTK_TREE_VIEW(trace_tree));
459 660
460 /* --- Top Level Hbox --- */ 661 /* --- Top Level Hbox --- */