gui filter module is now nearly finished
[lttv.git] / ltt / branches / poly / lttv / modules / gui / filter / filter.c
CommitLineData
91ad3f0a 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Simon Bouvier-Zappa
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19#include <glib.h>
20#include <string.h>
21#include <gtk/gtk.h>
22#include <gdk/gdk.h>
23
24#include <lttv/lttv.h>
25#include <lttv/module.h>
26#include <lttv/hook.h>
27#include <lttv/filter.h>
28
29#include <lttvwindow/lttvwindow.h>
30#include <lttvwindow/lttvwindowtraces.h>
31
32#include "hGuiFilterInsert.xpm"
33
4ed9b7ba 34/*
35 * TODO
36 * - connect the gui filter to the core filter
37 */
38
91ad3f0a 39typedef struct _FilterViewerData FilterViewerData;
c2774e9d 40typedef struct _FilterViewerDataLine FilterViewerDataLine;
91ad3f0a 41
4ed9b7ba 42/*
43 * Prototypes
44 */
91ad3f0a 45GtkWidget *guifilter_get_widget(FilterViewerData *fvd);
46FilterViewerData *gui_filter(Tab *tab);
47void gui_filter_destructor(FilterViewerData *fvd);
c2774e9d 48FilterViewerDataLine* gui_filter_add_line(FilterViewerData *fvd);
49void gui_filter_line_set_visible(FilterViewerDataLine *fvdl, gboolean v);
50void gui_filter_line_reset(FilterViewerDataLine *fvdl);
91ad3f0a 51gboolean filter_traceset_changed(void * hook_data, void * call_data);
52gboolean filter_viewer_data(void * hook_data, void * call_data);
2b99ec10 53GtkWidget* h_guifilter(Tab *tab);
c2774e9d 54void filter_destroy_walk(gpointer data, gpointer user_data);
91ad3f0a 55
c2774e9d 56/*
57 * Callback functions
58 */
59void callback_process_button(GtkWidget *widget, gpointer data);
60void callback_add_button(GtkWidget *widget, gpointer data);
61void callback_logical_op_box(GtkWidget *widget, gpointer data);
62void callback_expression_field(GtkWidget *widget, gpointer data);
63
64struct _FilterViewerDataLine {
65 int row;
66 gboolean visible;
67 GtkWidget *f_logical_op_box;
68 GtkWidget *f_struct_box;
69 GtkWidget *f_subfield_box;
70 GtkWidget *f_math_op_box;
71 GtkWidget *f_value_field;
72};
73
74/**
75 * @struct _FilterViewerData
76 * Main struct for the filter gui module
77 */
91ad3f0a 78struct _FilterViewerData {
79 Tab *tab;
80
4ed9b7ba 81 GtkWidget *f_main_box;
82
83 GtkWidget *f_hbox1;
84 GtkWidget *f_hbox2;
85
86 GtkWidget *f_expression_field;
87 GtkWidget *f_process_button;
88
c2774e9d 89 GtkWidget *f_logical_op_junction_box;
4ed9b7ba 90
c2774e9d 91 int rows;
92 GPtrArray *f_lines;
93
94 GtkWidget *f_add_button;
95
2b99ec10 96 GtkWidget *f_textwnd;
97 GtkWidget *f_selectwnd;
98 GtkWidget *f_treewnd;
99
91ad3f0a 100};
101
c2774e9d 102/**
103 * This function returns the current main widget
104 * used by this module
105 * @param fvd the module struct
106 * @return The main widget
107 */
91ad3f0a 108GtkWidget
109*guifilter_get_widget(FilterViewerData *fvd)
110{
4ed9b7ba 111 return fvd->f_main_box;
91ad3f0a 112}
113
114/**
c2774e9d 115 * Constructor is used to create FilterViewerData data structure.
116 * @param the tab structure used by the widget
117 * @return The Filter viewer data created.
91ad3f0a 118 */
119FilterViewerData*
120gui_filter(Tab *tab)
121{
4ed9b7ba 122 g_print("filter::gui_filter()");
123
91ad3f0a 124 GtkCellRenderer *renderer;
125 GtkTreeViewColumn *column;
126
127 FilterViewerData* fvd = g_new(FilterViewerData,1);
128
129 fvd->tab = tab;
130
131 lttvwindow_register_traceset_notify(fvd->tab,
132 filter_traceset_changed,
133 filter_viewer_data);
134// request_background_data(filter_viewer_data);
4ed9b7ba 135
136 /*
137 * Initiating GtkTable layout
138 * starts with 2 rows and 5 columns and
139 * expands when expressions added
140 */
c2774e9d 141 fvd->f_main_box = gtk_table_new(3,6,FALSE);
4ed9b7ba 142 gtk_table_set_row_spacings(GTK_TABLE(fvd->f_main_box),5);
143 gtk_table_set_col_spacings(GTK_TABLE(fvd->f_main_box),5);
91ad3f0a 144
4ed9b7ba 145 /*
146 * First half of the filter window
147 * - textual entry of filter expression
148 * - processing button
149 */
150 fvd->f_expression_field = gtk_entry_new(); //gtk_scrolled_window_new (NULL, NULL);
c2774e9d 151// gtk_entry_set_text(GTK_ENTRY(fvd->f_expression_field),"state.cpu>0");
4ed9b7ba 152 gtk_widget_show (fvd->f_expression_field);
153
c2774e9d 154 g_signal_connect (G_OBJECT (fvd->f_expression_field), "changed",
155 G_CALLBACK (callback_expression_field), (gpointer) fvd);
156
4ed9b7ba 157 fvd->f_process_button = gtk_button_new_with_label("Process");
158 gtk_widget_show (fvd->f_process_button);
159
c2774e9d 160 g_signal_connect (G_OBJECT (fvd->f_process_button), "clicked",
161 G_CALLBACK (callback_process_button), (gpointer) fvd);
162
163 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_expression_field,0,5,0,1,GTK_FILL,GTK_FILL,0,0);
164 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_process_button,5,6,0,1,GTK_FILL,GTK_FILL,0,0);
165
166
4ed9b7ba 167
168 /*
169 * Second half of the filter window
170 * - combo boxes featuring filtering options added to the expression
171 */
c2774e9d 172 fvd->f_add_button = gtk_button_new_with_label("Add Expression");
173 gtk_widget_show (fvd->f_add_button);
174
175 g_signal_connect (G_OBJECT (fvd->f_add_button), "clicked",
176 G_CALLBACK (callback_add_button), (gpointer) fvd);
4ed9b7ba 177
c2774e9d 178 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_add_button,5,6,1,2,GTK_FILL,GTK_FILL,0,0);
179
180 fvd->f_logical_op_junction_box = gtk_combo_box_new_text();
181 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd->f_logical_op_junction_box), "");
182 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd->f_logical_op_junction_box), "&");
183 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd->f_logical_op_junction_box), "|");
184 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd->f_logical_op_junction_box), "^");
185 gtk_combo_box_append_text (GTK_COMBO_BOX (fvd->f_logical_op_junction_box), "!");
186 //gtk_widget_show(fvd->f_logical_op_box);
2b99ec10 187
c2774e9d 188 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvd->f_logical_op_junction_box,0,1,1,2,GTK_SHRINK,GTK_FILL,0,0);
189
190 /* initialize a new line */
191 fvd->f_lines = g_ptr_array_new();
192 fvd->rows = 1;
193 FilterViewerDataLine* fvdl = gui_filter_add_line(fvd);
194 g_ptr_array_add(fvd->f_lines,(gpointer) fvdl);
4ed9b7ba 195
c2774e9d 196 /*
197 * show main container
198 */
4ed9b7ba 199 gtk_widget_show(fvd->f_main_box);
200
91ad3f0a 201
202 g_object_set_data_full(
203 G_OBJECT(guifilter_get_widget(fvd)),
204 "filter_viewer_data",
205 fvd,
206 (GDestroyNotify)gui_filter_destructor);
207
4ed9b7ba 208
91ad3f0a 209 return fvd;
210}
211
c2774e9d 212/**
213 * Adds a filter option line on the module tab
214 * @param fvd The filter module structure
215 * @return The line structure
216 */
217FilterViewerDataLine*
218gui_filter_add_line(FilterViewerData* fvd) {
219
220 FilterViewerDataLine* fvdl = g_new(FilterViewerDataLine,1);
221
222 fvdl->row = fvd->rows;
223 fvdl->visible = TRUE;
224
225 fvdl->f_struct_box = gtk_combo_box_new_text();
226 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_struct_box), "");
227 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_struct_box), "event");
228 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_struct_box), "tracefile");
229 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_struct_box), "trace");
230 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_struct_box), "state");
231 gtk_widget_show(fvdl->f_struct_box);
232
233 fvdl->f_subfield_box = gtk_combo_box_new_text();
234 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "");
235 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "name");
236 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "category");
237 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "time");
238 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "tsc");
239 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "pid");
240 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "ppid");
241 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "creation time");
242 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "insertion time");
243 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "process name");
244 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "execution mode");
245 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "execution submode");
246 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "process status");
247 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_subfield_box), "cpu");
248 gtk_widget_show(fvdl->f_subfield_box);
249
250 fvdl->f_math_op_box = gtk_combo_box_new_text();
251 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), "");
252 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), "=");
253 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), "!=");
254 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), "<");
255 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), "<=");
256 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), ">");
257 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_math_op_box), ">=");
258 gtk_widget_show(fvdl->f_math_op_box);
259
260 fvdl->f_value_field = gtk_entry_new();
261 gtk_widget_show(fvdl->f_value_field);
262
263 fvdl->f_logical_op_box = gtk_combo_box_new_text();
264 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_logical_op_box), "");
265 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_logical_op_box), "&");
266 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_logical_op_box), "|");
267 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_logical_op_box), "^");
268 gtk_combo_box_append_text (GTK_COMBO_BOX (fvdl->f_logical_op_box), "!");
269 gtk_widget_show(fvdl->f_logical_op_box);
270
271 gtk_widget_set_events(fvdl->f_logical_op_box,
272 GDK_ENTER_NOTIFY_MASK |
273 GDK_LEAVE_NOTIFY_MASK |
274 GDK_FOCUS_CHANGE_MASK);
275
276 g_signal_connect (G_OBJECT (fvdl->f_logical_op_box), "changed",
277 G_CALLBACK (callback_logical_op_box), (gpointer) fvd);
278
279 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_struct_box,0,1,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
280 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_subfield_box,1,2,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
281 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_math_op_box,2,3,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
282 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_value_field,3,4,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
283 gtk_table_attach( GTK_TABLE(fvd->f_main_box),fvdl->f_logical_op_box,4,5,fvd->rows+1,fvd->rows+2,GTK_SHRINK,GTK_FILL,0,0);
284
285 return fvdl;
286}
287
288void gui_filter_line_set_visible(FilterViewerDataLine *fvdl, gboolean v) {
289
290 fvdl->visible = v;
291 if(v) {
292 gtk_widget_show(fvdl->f_struct_box);
293 gtk_widget_show(fvdl->f_subfield_box);
294 gtk_widget_show(fvdl->f_math_op_box);
295 gtk_widget_show(fvdl->f_value_field);
296 gtk_widget_show(fvdl->f_logical_op_box);
297 } else {
298 gtk_widget_hide(fvdl->f_struct_box);
299 gtk_widget_hide(fvdl->f_subfield_box);
300 gtk_widget_hide(fvdl->f_math_op_box);
301 gtk_widget_hide(fvdl->f_value_field);
302 gtk_widget_hide(fvdl->f_logical_op_box);
303 }
304
305}
306
307void gui_filter_line_reset(FilterViewerDataLine *fvdl) {
308
309 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_struct_box),0);
310 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_subfield_box),0);
311 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_math_op_box),0);
312 gtk_entry_set_text(GTK_COMBO_BOX(fvdl->f_value_field),"");
313 gtk_combo_box_set_active(GTK_COMBO_BOX(fvdl->f_logical_op_box),0);
314}
315
316/**
317 * Destructor for the filter gui module
318 * @param fvd The module structure
319 */
91ad3f0a 320void
321gui_filter_destructor(FilterViewerData *fvd)
322{
323 Tab *tab = fvd->tab;
324
325 /* May already been done by GTK window closing */
326 if(GTK_IS_WIDGET(guifilter_get_widget(fvd))){
327 g_info("widget still exists");
328 }
329 if(tab != NULL) {
330 lttvwindow_unregister_traceset_notify(fvd->tab,
331 filter_traceset_changed,
332 filter_viewer_data);
333 }
334 lttvwindowtraces_background_notify_remove(fvd);
335
336 g_free(fvd);
337}
338
c2774e9d 339/**
340 * Hook function
341 * @param hook_data The hook data
342 * @param call_data The call data
343 * @return Success/Failure of operation
344 */
91ad3f0a 345gboolean
346filter_traceset_changed(void * hook_data, void * call_data) {
347
348 return FALSE;
349}
350
c2774e9d 351/**
352 * Hook function
353 * @param hook_data The hook data
354 * @param call_data The call data
355 * @return Success/Failure of operation
356 */
91ad3f0a 357gboolean
358filter_viewer_data(void * hook_data, void * call_data) {
359
360 return FALSE;
361}
362
363/**
364 * Filter Module's constructor hook
365 *
366 * This constructor is given as a parameter to the menuitem and toolbar button
367 * registration. It creates the list.
c2774e9d 368 * @param tab A pointer to the parent window.
91ad3f0a 369 * @return The widget created.
370 */
371GtkWidget *
2b99ec10 372h_guifilter(Tab *tab)
91ad3f0a 373{
374 FilterViewerData* f = gui_filter(tab) ;
375
2b99ec10 376 g_print("FilterViewerData:%p\n",f);
91ad3f0a 377 if(f)
378 return guifilter_get_widget(f);
379 else return NULL;
380
381}
382
91ad3f0a 383/**
c2774e9d 384 * This function initializes the Filter Viewer functionnality through the
91ad3f0a 385 * gtkTraceSet API.
386 */
387static void init() {
388
389 lttvwindow_register_constructor("guifilter",
390 "/",
391 "Insert Filter Module",
392 hGuiFilterInsert_xpm,
393 "Insert Filter Module",
2b99ec10 394 h_guifilter);
91ad3f0a 395}
396
c2774e9d 397/**
398 * Initiate the destruction of the current gui module
399 * on the GTK Interface
400 */
91ad3f0a 401void filter_destroy_walk(gpointer data, gpointer user_data)
402{
403 FilterViewerData *fvd = (FilterViewerData*)data;
404
c2774e9d 405 g_debug("CFV.c : filter_destroy_walk, %p", fvd);
91ad3f0a 406 /* May already have been done by GTK window closing */
407 if(GTK_IS_WIDGET(guifilter_get_widget(fvd)))
408 gtk_widget_destroy(guifilter_get_widget(fvd));
409}
410
411/**
412 * plugin's destroy function
413 *
414 * This function releases the memory reserved by the module and unregisters
415 * everything that has been registered in the gtkTraceSet API.
416 */
417static void destroy() {
418
2b99ec10 419 lttvwindow_unregister_constructor(h_guifilter);
91ad3f0a 420
421}
422
c2774e9d 423/**
424 * The Process Button callback function
425 * @param widget The Button widget passed to the callback function
426 * @param data Data sent along with the callback function
427 */
428void callback_process_button(GtkWidget *widget, gpointer data) {
429
430 FilterViewerData *fvd = (FilterViewerData*)data;
431
432 if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field))) !=0)
433 lttv_filter_new(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field)),NULL);
434}
435
436/**
437 * The Add Button callback function
438 * @param widget The Button widget passed to the callback function
439 * @param data Data sent along with the callback function
440 */
441void callback_expression_field(GtkWidget *widget, gpointer data) {
442
443 FilterViewerData *fvd = (FilterViewerData*)data;
444
445 if(strlen(gtk_entry_get_text(GTK_ENTRY(fvd->f_expression_field))) !=0) {
446 gtk_widget_show(fvd->f_logical_op_junction_box);
447 } else {
448 gtk_widget_hide(fvd->f_logical_op_junction_box);
449 }
450}
451
452
453/**
454 * The Add Button callback function
455 * @param widget The Button widget passed to the callback function
456 * @param data Data sent along with the callback function
457 */
458void callback_add_button(GtkWidget *widget, gpointer data) {
459
460 g_print("filter::callback_add_button()\n");
461
462 FilterViewerData *fvd = (FilterViewerData*)data;
463 FilterViewerDataLine *fvdl = NULL;
464 GString* a_filter_string = g_string_new("");
465
466// g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvd->f_logical_op_junction_box)));
467 gtk_combo_box_set_active(fvd->f_logical_op_junction_box,0);
468
469 g_string_append_c(a_filter_string,"(");
470
471 int i;
472 for(i=0;i<fvd->f_lines->len;i++) {
473 fvdl = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i);
474// g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_struct_box)));
475 g_string_append_c(a_filter_string,".");
476// g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_subfield_box)));
477// g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_math_op_box)));
478// g_string_append(a_filter_string,gtk_entry_get_text(GTK_ENTRY(fvdl->f_value_field)));
479// g_string_append(a_filter_string,gtk_combo_box_get_active_text(GTK_COMBO_BOX(fvdl->f_logical_op_box)));
480 gui_filter_line_reset(fvdl);
481 if(i) gui_filter_line_set_visible(fvdl,FALSE);
482 }
483
484 g_string_append(a_filter_string,")");
485
486 gtk_entry_set_text(GTK_ENTRY(fvdl->f_value_field),a_filter_string->str);
487
488}
489
490/**
491 * The logical op box callback function
492 * @param widget The Button widget passed to the callback function
493 * @param data Data sent along with the callback function
494 */
495void callback_logical_op_box(GtkWidget *widget, gpointer data) {
496
497 g_print("filter::callback_logical_op_box()\n");
498
499 FilterViewerData *fvd = (FilterViewerData*)data;
500 FilterViewerDataLine *fvdl = NULL;
501
502 int i;
503 for(i=0;i<fvd->f_lines->len;i++) {
504 fvdl = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i);
505 if(fvdl->f_logical_op_box == widget) {
506 if(gtk_combo_box_get_active(fvdl->f_logical_op_box) == 0) return;
507 if(i==fvd->f_lines->len-1) { /* create a new line */
508 fvd->rows++;
509 FilterViewerDataLine* fvdl2 = gui_filter_add_line(fvd);
510 g_ptr_array_add(fvd->f_lines,(gpointer) fvdl2);
511 } else {
512 FilterViewerDataLine *fvdl2 = (FilterViewerDataLine*)g_ptr_array_index(fvd->f_lines,i+1);
513 if(!fvdl2->visible) gui_filter_line_set_visible(fvdl2,TRUE);
514 }
515 }
516 }
517
518}
91ad3f0a 519
520LTTV_MODULE("guifilter", "Filter window", \
521 "Graphical module that let user specify their filtering options", \
522 init, destroy, "lttvwindow")
523
This page took 0.043854 seconds and 4 git commands to generate.