Viewer contstructor change
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / callbacks.c
CommitLineData
e076699e 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 XangXiu Yang
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
561eba2a 19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <gtk/gtk.h>
561eba2a 24
25#include "callbacks.h"
26#include "interface.h"
27#include "support.h"
a43d67ba 28#include <ltt/trace.h>
29#include <ltt/facility.h>
30#include <ltt/time.h>
31#include <ltt/event.h>
2a2fa4f0 32#include <lttv/lttv.h>
a43d67ba 33#include <lttv/module.h>
34#include <lttv/iattribute.h>
35#include <lttv/stats.h>
13f86ce2 36#include <lttvwindow/mainwindow.h>
37#include <lttvwindow/menu.h>
38#include <lttvwindow/toolbar.h>
36b40c74 39#include <lttvwindow/viewer.h>
13f86ce2 40#include <lttvwindow/gtkdirsel.h>
13f86ce2 41#include <lttvwindow/lttvfilter.h>
6b1d3120 42
f7afe191 43#define PATH_LENGTH 256
44#define DEFAULT_TIME_WIDTH_S 1
45
49bf71b5 46extern LttvTrace *g_init_trace ;
561eba2a 47
ec25ff5e 48
49/** Array containing instanced objects. */
68b48a45 50extern GSList * g_main_window_list;
561eba2a 51
68b48a45 52static int g_win_count = 0;
7a859036 53
a43d67ba 54/** MD : keep old directory. */
3658a338 55static char remember_plugins_dir[PATH_LENGTH] = "";
56static char remember_trace_dir[PATH_LENGTH] = "";
6fbb1ddf 57
58
bca3b81f 59MainWindow * get_window_data_struct(GtkWidget * widget);
36b3c068 60char * get_unload_module(char ** loaded_module_name, int nb_module);
2176f952 61char * get_remove_trace(char ** all_trace_name, int nb_trace);
62char * get_selection(char ** all_name, int nb, char *title, char * column_title);
a8c0f09d 63gboolean get_filter_selection(LttvTracesetSelector *s, char *title, char * column_title);
716e4367 64void * create_tab(MainWindow * parent, MainWindow * current_window,
65 GtkNotebook * notebook, char * label);
561eba2a 66
42fcbb71 67void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor);
49bf71b5 68void update_filter(LttvTracesetSelector *s, GtkTreeStore *store );
69
70void checkbox_changed(GtkTreeView *treeview,
71 GtkTreePath *arg1,
72 GtkTreeViewColumn *arg2,
73 gpointer user_data);
74void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i);
75void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * trace);
76
77LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset);
78
a43d67ba 79void call_pending_read_hooks(MainWindow * mw_data);
a8c0f09d 80unsigned get_max_event_number(MainWindow * mw_data);
202f6c8f 81
49bf71b5 82enum {
83 CHECKBOX_COLUMN,
84 NAME_COLUMN,
85 TOTAL_COLUMNS
86};
561eba2a 87
36b3c068 88enum
89{
90 MODULE_COLUMN,
91 N_COLUMNS
92};
93
abe346a3 94/* Construct a selector(filter), which will be associated with a viewer,
95 * and provides an interface for user to select interested events and traces
96 */
561eba2a 97
49bf71b5 98LttvTracesetSelector * construct_traceset_selector(LttvTraceset * traceset)
99{
100 LttvTracesetSelector * s;
101 LttvTraceSelector * trace;
102 LttvTracefileSelector * tracefile;
ed3b99b6 103 LttvEventtypeSelector * eventtype;
104 int i, j, k, m;
105 int nb_trace, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 106 LttvTrace * trace_v;
107 LttTrace * t;
108 LttTracefile *tf;
ed3b99b6 109 LttFacility * fac;
110 LttEventType * et;
49bf71b5 111
112 s = lttv_traceset_selector_new(lttv_traceset_name(traceset));
113 nb_trace = lttv_traceset_number(traceset);
114 for(i=0;i<nb_trace;i++){
115 trace_v = lttv_traceset_get(traceset, i);
116 t = lttv_trace(trace_v);
117 trace = lttv_trace_selector_new(t);
ed3b99b6 118 lttv_traceset_selector_trace_add(s, trace);
119
120 nb_facility = ltt_trace_facility_number(t);
121 for(k=0;k<nb_facility;k++){
122 fac = ltt_trace_facility_get(t,k);
123 nb_event = (int) ltt_facility_eventtype_number(fac);
124 for(m=0;m<nb_event;m++){
125 et = ltt_facility_eventtype_get(fac,m);
126 eventtype = lttv_eventtype_selector_new(et);
127 lttv_trace_selector_eventtype_add(trace, eventtype);
128 }
129 }
130
49bf71b5 131 nb_control = ltt_trace_control_tracefile_number(t);
132 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
133 nb_tracefile = nb_control + nb_per_cpu;
134
135 for(j = 0 ; j < nb_tracefile ; j++) {
136 if(j < nb_control)
137 tf = ltt_trace_control_tracefile_get(t, j);
138 else
139 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
140 tracefile = lttv_tracefile_selector_new(tf);
ed3b99b6 141 lttv_trace_selector_tracefile_add(trace, tracefile);
142 lttv_eventtype_selector_copy(trace, tracefile);
49bf71b5 143 }
144 }
145 return s;
146}
147
abe346a3 148
149/* insert_viewer function constructs an instance of a viewer first,
150 * then inserts the widget of the instance into the container of the
151 * main window
152 */
153
561eba2a 154void
606309a4 155insert_viewer_wrap(GtkWidget *menuitem, gpointer user_data)
561eba2a 156{
157 guint val = 20;
606309a4 158
42fcbb71 159 insert_viewer((GtkWidget*)menuitem, (lttvwindow_viewer_constructor)user_data);
37d0eca6 160 // selected_hook(&val);
561eba2a 161}
162
561eba2a 163
164/* internal functions */
42fcbb71 165void insert_viewer(GtkWidget* widget, lttvwindow_viewer_constructor constructor)
561eba2a 166{
daecc161 167 GtkMultiVPaned * multi_vpaned;
bca3b81f 168 MainWindow * mw_data;
f9334f6f 169 GtkWidget * viewer;
49bf71b5 170 LttvTracesetSelector * s;
202f6c8f 171 TimeInterval * time_interval;
561eba2a 172
68b48a45 173 mw_data = get_window_data_struct(widget);
bca3b81f 174 if(!mw_data->current_tab) return;
daecc161 175 multi_vpaned = mw_data->current_tab->multi_vpaned;
561eba2a 176
49bf71b5 177 s = construct_traceset_selector(mw_data->current_tab->traceset_info->traceset);
178 viewer = (GtkWidget*)constructor(mw_data, s, "Traceset_Selector");
f9334f6f 179 if(viewer)
f0d936c0 180 {
daecc161 181 gtk_multi_vpaned_widget_add(multi_vpaned, viewer);
a43d67ba 182 // We unref here, because it is now referenced by the multi_vpaned!
183 g_object_unref(G_OBJECT(viewer));
184
185 // The viewer will show itself when it receives a show notify
186 // So we call the show notify hooks here. It will
187 // typically add hooks for reading, we call process trace, and the
188 // end of reading hook will call gtk_widget_show and unregister the
189 // hooks.
190 // Note that show notify gets the time_requested through the call_data.
191 //show_viewer(mw_data);
192 // in expose now call_pending_read_hooks(mw_data);
f0d936c0 193 }
561eba2a 194}
195
abe346a3 196
197/* get_label function is used to get user input, it displays an input
198 * box, which allows user to input a string
199 */
200
561eba2a 201void get_label_string (GtkWidget * text, gchar * label)
202{
203 GtkEntry * entry = (GtkEntry*)text;
204 if(strlen(gtk_entry_get_text(entry))!=0)
205 strcpy(label,gtk_entry_get_text(entry));
206}
207
eb38aea5 208gboolean get_label(MainWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
561eba2a 209{
210 GtkWidget * dialogue;
211 GtkWidget * text;
212 GtkWidget * label;
213 gint id;
214
5723fa24 215 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
561eba2a 216 GTK_DIALOG_MODAL,
217 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
218 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
219 NULL);
220
6b1d3120 221 label = gtk_label_new(label_str);
561eba2a 222 gtk_widget_show(label);
223
224 text = gtk_entry_new();
225 gtk_widget_show(text);
226
227 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
228 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
229
230 id = gtk_dialog_run(GTK_DIALOG(dialogue));
231 switch(id){
232 case GTK_RESPONSE_ACCEPT:
233 get_label_string(text,str);
234 gtk_widget_destroy(dialogue);
235 break;
236 case GTK_RESPONSE_REJECT:
237 default:
238 gtk_widget_destroy(dialogue);
eb38aea5 239 return FALSE;
561eba2a 240 }
eb38aea5 241 return TRUE;
561eba2a 242}
243
abe346a3 244
245/* get_window_data_struct function is actually a lookup function,
246 * given a widget which is in the tree of the main window, it will
247 * return the MainWindow data structure associated with main window
248 */
249
bca3b81f 250MainWindow * get_window_data_struct(GtkWidget * widget)
561eba2a 251{
252 GtkWidget * mw;
bca3b81f 253 MainWindow * mw_data;
561eba2a 254
255 mw = lookup_widget(widget, "MWindow");
256 if(mw == NULL){
257 g_printf("Main window does not exist\n");
258 return;
259 }
260
bca3b81f 261 mw_data = (MainWindow *) g_object_get_data(G_OBJECT(mw),"mainWindow");
68b48a45 262 if(mw_data == NULL){
561eba2a 263 g_printf("Main window data does not exist\n");
264 return;
265 }
68b48a45 266 return mw_data;
561eba2a 267}
268
abe346a3 269
270/* create_new_window function, just constructs a new main window
271 */
272
68b48a45 273void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
561eba2a 274{
bca3b81f 275 MainWindow * parent = get_window_data_struct(widget);
561eba2a 276
561eba2a 277 if(clone){
278 g_printf("Clone : use the same traceset\n");
08b1c66e 279 construct_main_window(parent);
561eba2a 280 }else{
281 g_printf("Empty : traceset is set to NULL\n");
08b1c66e 282 construct_main_window(NULL);
561eba2a 283 }
284}
285
abe346a3 286
287/* move_*_viewer functions move the selected view up/down in
288 * the current tab
289 */
290
561eba2a 291void move_up_viewer(GtkWidget * widget, gpointer user_data)
292{
bca3b81f 293 MainWindow * mw = get_window_data_struct(widget);
294 if(!mw->current_tab) return;
daecc161 295 gtk_multi_vpaned_widget_move_up(mw->current_tab->multi_vpaned);
561eba2a 296}
297
298void move_down_viewer(GtkWidget * widget, gpointer user_data)
299{
bca3b81f 300 MainWindow * mw = get_window_data_struct(widget);
301 if(!mw->current_tab) return;
daecc161 302 gtk_multi_vpaned_widget_move_down(mw->current_tab->multi_vpaned);
561eba2a 303}
304
abe346a3 305
306/* delete_viewer deletes the selected viewer in the current tab
307 */
308
561eba2a 309void delete_viewer(GtkWidget * widget, gpointer user_data)
310{
bca3b81f 311 MainWindow * mw = get_window_data_struct(widget);
312 if(!mw->current_tab) return;
daecc161 313 gtk_multi_vpaned_widget_delete(mw->current_tab->multi_vpaned);
561eba2a 314}
315
abe346a3 316
317/* open_traceset will open a traceset saved in a file
318 * Right now, it is not finished yet, (not working)
a43d67ba 319 * FIXME
abe346a3 320 */
321
561eba2a 322void open_traceset(GtkWidget * widget, gpointer user_data)
323{
2176f952 324 char ** dir;
325 gint id;
326 LttvTraceset * traceset;
bca3b81f 327 MainWindow * mw_data = get_window_data_struct(widget);
68b48a45 328 GtkFileSelection * file_selector =
2176f952 329 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
330
68b48a45 331 gtk_file_selection_hide_fileop_buttons(file_selector);
c64c7ea1 332
68b48a45 333 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 334 switch(id){
335 case GTK_RESPONSE_ACCEPT:
336 case GTK_RESPONSE_OK:
68b48a45 337 dir = gtk_file_selection_get_selections (file_selector);
2176f952 338 traceset = lttv_traceset_load(dir[0]);
339 g_printf("Open a trace set %s\n", dir[0]);
340 //Not finished yet
341 g_strfreev(dir);
342 case GTK_RESPONSE_REJECT:
343 case GTK_RESPONSE_CANCEL:
344 default:
68b48a45 345 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 346 break;
347 }
c64c7ea1 348
561eba2a 349}
350
abe346a3 351
352/* get_max_event_number returns the event number limit used by
353 * lttv_process_traceset(LttvTracesetContext, endTime, maxNumEvents)
354 * each viewer can set the limit
355 */
356
a8c0f09d 357unsigned get_max_event_number(MainWindow * mw_data)
202f6c8f 358{
a8c0f09d 359 unsigned nb = 0, *size;
360 GtkWidget * w;
361
362 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
363 while(w){
364 size = (unsigned*)g_object_get_data(G_OBJECT(w), MAX_NUMBER_EVENT);
365 if(size == NULL){
366 nb = G_MAXULONG;
367 break;
368 }else{
369 if(nb < *size)
370 nb = *size;
371 }
372 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
373 }
374 return nb;
375}
376
abe346a3 377
a43d67ba 378/* call_pending_read_hooks parses the traceset first by calling
491f466f 379 * process_traceset, then display all viewers of
abe346a3 380 * the current tab
a43d67ba 381 * It will then remove all entries from the time_requests array.
8f2872f4 382 * CHECK : we give more events than requested to the viewers. They
383 * Have to filter them by themselves.
abe346a3 384 */
385
a43d67ba 386gint compare_time_request(TimeRequest *a, TimeRequest *b)
387{
388 return ltt_time_compare(a->time_window.start_time, b->time_window.start_time);
389}
390
391void call_pending_read_hooks(MainWindow * mw_data)
a8c0f09d 392{
393 unsigned max_nb_events;
394 GdkWindow * win;
395 GdkCursor * new;
396 GtkWidget* widget;
a43d67ba 397 int i;
398 LttvTracesetContext *tsc;
399
400 /* Current tab check : if no current tab is present, no hooks to call. */
401 /* It makes the expose works.. */
402 if(mw_data->current_tab == NULL)
403 return;
404
405 if(mw_data->current_tab->time_requests->len == 0)
406 return;
407
408 LttvHooks *tmp_hooks = lttv_hooks_new();
409
410 tsc =
224446ce 411 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
491f466f 412 traceset_context);
a8c0f09d 413
abe346a3 414 //set the cursor to be X shape, indicating that the computer is busy in doing its job
a8c0f09d 415 new = gdk_cursor_new(GDK_X_CURSOR);
efde9138 416 widget = lookup_widget(mw_data->mwindow, "MToolbar1");
a8c0f09d 417 win = gtk_widget_get_parent_window(widget);
418 gdk_window_set_cursor(win, new);
419 gdk_cursor_unref(new);
420 gdk_window_stick(win);
421 gdk_window_unstick(win);
a43d67ba 422
423
424 g_array_sort(mw_data->current_tab->time_requests,
425 (GCompareFunc)compare_time_request);
426
427
202f6c8f 428 //update time window of each viewer, let viewer insert hooks needed by process_traceset
a43d67ba 429 //lttvwindow_report_time_window(mw_data, time_window);
a8c0f09d 430
a43d67ba 431 //max_nb_events = get_max_event_number(mw_data);
202f6c8f 432
433 //call hooks to show each viewer and let them remove hooks
a43d67ba 434 //show_viewer(mw_data);
a8c0f09d 435
a43d67ba 436 // FIXME
437 // call process trace for each time interval
438 // Will have to be combined!
439 g_critical("SIZE time req len : %d", mw_data->current_tab->time_requests->len);
440
441 //g_assert(mw_data->current_tab->time_requests->len <= 1); //FIXME
442 /* Go through each time request. As they are already sorted by start_time,
443 * we check with the current event time if processing is needed. */
444 for(i=0; i < mw_data->current_tab->time_requests->len; i++)
445 {
446 g_critical("RUN i %d", i);
447 TimeRequest *time_request =
448 &g_array_index(mw_data->current_tab->time_requests, TimeRequest, i);
449 LttTime end_time = ltt_time_add( time_request->time_window.start_time,
450 time_request->time_window.time_width);
451
8f2872f4 452 if(i == 0 || !(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0) )
a43d67ba 453 {
454 /* do it if first request or start_time >= last event's time */
455 lttv_process_traceset_seek_time(tsc, time_request->time_window.start_time);
456 lttv_process_traceset(tsc, end_time, time_request->num_events);
457 }
8f2872f4 458 else
459 {
460 if(ltt_time_compare(time_request->time_window.start_time, ltt_event_time(tsc->e))<0
461 && !(ltt_time_compare(end_time, ltt_event_time(tsc->e))<0))
462 {
463 /* Continue reading from current event */
464 lttv_process_traceset(tsc, end_time, time_request->num_events);
465
466 }
467 else
468 {
469 if(ltt_time_compare(time_request->time_window.start_time, end_time) > 0)
470 {
471 /* This is a request for a minimum number of events, give
472 * more events than necessary */
473 lttv_process_traceset(tsc, end_time, time_request->num_events);
474 }
475 }
476 }
a43d67ba 477
478 /* Call the end of process_traceset hook */
479 lttv_hooks_add(tmp_hooks,
480 time_request->after_hook,
481 time_request->after_hook_data);
482 lttv_hooks_call(tmp_hooks, time_request);
483 lttv_hooks_remove(tmp_hooks, time_request->after_hook);
484 }
485
486 /* Free the time requests */
487 g_array_free(mw_data->current_tab->time_requests, TRUE);
488 mw_data->current_tab->time_requests =
489 g_array_new(FALSE, FALSE, sizeof(TimeRequest));
490
491 mw_data->current_tab->time_request_pending = FALSE;
492
493 lttv_hooks_destroy(tmp_hooks);
494
abe346a3 495 //set the cursor back to normal
a8c0f09d 496 gdk_window_set_cursor(win, NULL);
202f6c8f 497}
498
abe346a3 499
500/* add_trace_into_traceset_selector, each instance of a viewer has an associated
501 * selector (filter), when a trace is added into traceset, the selector should
502 * reflect the change. The function is used to update the selector
503 */
504
49bf71b5 505void add_trace_into_traceset_selector(GtkMultiVPaned * paned, LttTrace * t)
506{
ed3b99b6 507 int j, k, m, nb_tracefile, nb_control, nb_per_cpu, nb_facility, nb_event;
49bf71b5 508 LttvTracesetSelector * s;
509 LttvTraceSelector * trace;
510 LttvTracefileSelector * tracefile;
ed3b99b6 511 LttvEventtypeSelector * eventtype;
49bf71b5 512 LttTracefile * tf;
513 GtkWidget * w;
ed3b99b6 514 LttFacility * fac;
515 LttEventType * et;
49bf71b5 516
517 w = gtk_multi_vpaned_get_first_widget(paned);
518 while(w){
519 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
49bf71b5 520
abe346a3 521 if(s){
522 trace = lttv_trace_selector_new(t);
523 lttv_traceset_selector_trace_add(s, trace);
524
525 nb_facility = ltt_trace_facility_number(t);
526 for(k=0;k<nb_facility;k++){
527 fac = ltt_trace_facility_get(t,k);
528 nb_event = (int) ltt_facility_eventtype_number(fac);
529 for(m=0;m<nb_event;m++){
530 et = ltt_facility_eventtype_get(fac,m);
531 eventtype = lttv_eventtype_selector_new(et);
532 lttv_trace_selector_eventtype_add(trace, eventtype);
533 }
534 }
535
536 nb_control = ltt_trace_control_tracefile_number(t);
537 nb_per_cpu = ltt_trace_per_cpu_tracefile_number(t);
538 nb_tracefile = nb_control + nb_per_cpu;
539
540 for(j = 0 ; j < nb_tracefile ; j++) {
541 if(j < nb_control)
542 tf = ltt_trace_control_tracefile_get(t, j);
543 else
544 tf = ltt_trace_per_cpu_tracefile_get(t, j - nb_control);
545 tracefile = lttv_tracefile_selector_new(tf);
546 lttv_trace_selector_tracefile_add(trace, tracefile);
547 lttv_eventtype_selector_copy(trace, tracefile);
548 }
549 }else g_warning("Module does not support filtering\n");
49bf71b5 550
551 w = gtk_multi_vpaned_get_next_widget(paned);
552 }
553}
554
abe346a3 555
556/* add_trace adds a trace into the current traceset. It first displays a
557 * directory selection dialogue to let user choose a trace, then recreates
558 * tracset_context, and redraws all the viewer of the current tab
559 */
560
561eba2a 561void add_trace(GtkWidget * widget, gpointer user_data)
562{
2176f952 563 LttTrace *trace;
564 LttvTrace * trace_v;
565 LttvTraceset * traceset;
94dcfb9e 566 const char * dir;
2176f952 567 gint id;
a43d67ba 568 gint i;
bca3b81f 569 MainWindow * mw_data = get_window_data_struct(widget);
68b48a45 570 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
571 gtk_dir_selection_hide_fileop_buttons(file_selector);
3658a338 572 if(remember_trace_dir[0] != '\0')
573 gtk_dir_selection_set_filename(file_selector, remember_trace_dir);
2176f952 574
68b48a45 575 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 576 switch(id){
577 case GTK_RESPONSE_ACCEPT:
578 case GTK_RESPONSE_OK:
68b48a45 579 dir = gtk_dir_selection_get_dir (file_selector);
3658a338 580 strncpy(remember_trace_dir, dir, PATH_LENGTH);
a43d67ba 581 if(!dir || strlen(dir) == 0){
582 gtk_widget_destroy((GtkWidget*)file_selector);
583 break;
284675e3 584 }
2176f952 585 trace = ltt_trace_open(dir);
586 if(trace == NULL) g_critical("cannot open trace %s", dir);
587 trace_v = lttv_trace_new(trace);
716e4367 588 traceset = mw_data->current_tab->traceset_info->traceset;
c2619a30 589
a43d67ba 590 //Keep a reference to the traces so they are not freed.
591 for(i=0; i<lttv_traceset_number(traceset); i++)
592 {
593 LttvTrace * trace = lttv_traceset_get(traceset, i);
594 lttv_trace_ref(trace);
595 }
596
597 //remove state update hooks
598 lttv_state_remove_event_hooks(
599 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
600
601 lttv_context_fini(LTTV_TRACESET_CONTEXT(
602 mw_data->current_tab->traceset_info->traceset_context));
603 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
604
c2619a30 605
2176f952 606 lttv_traceset_add(traceset, trace_v);
a43d67ba 607
608 /* Create new context */
716e4367 609 mw_data->current_tab->traceset_info->traceset_context =
c2619a30 610 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
2176f952 611 lttv_context_init(
c2619a30 612 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
613 traceset_context),
614 traceset);
784705cc 615 //add state update hooks
616 lttv_state_add_event_hooks(
617 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
a43d67ba 618 //Remove local reference to the traces.
619 for(i=0; i<lttv_traceset_number(traceset); i++)
c2619a30 620 {
a43d67ba 621 LttvTrace * trace = lttv_traceset_get(traceset, i);
622 lttv_trace_unref(trace);
c2619a30 623 }
624
625
49bf71b5 626 add_trace_into_traceset_selector(mw_data->current_tab->multi_vpaned, trace);
627
628 gtk_widget_destroy((GtkWidget*)file_selector);
629
630 //update current tab
a43d67ba 631 //update_traceset(mw_data);
21e8c385 632
297f7a48 633 //get_traceset_time_span(mw_data,LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context)->Time_Span);
a43d67ba 634 if(
635 lttv_traceset_number(mw_data->current_tab->traceset_info->traceset) == 1
636 || ltt_time_compare(mw_data->current_tab->current_time,
637 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
638 traceset_context)->Time_Span->startTime)<0)
639 {
640 /* Set initial time if this is the first trace in the traceset */
641 mw_data->current_tab->current_time =
642 LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->
643 traceset_context)->Time_Span->startTime;
644 mw_data->current_tab->time_window.start_time =
645 mw_data->current_tab->current_time;
646 mw_data->current_tab->time_window.time_width.tv_sec =
647 DEFAULT_TIME_WIDTH_S;
648 mw_data->current_tab->time_window.time_width.tv_nsec = 0;
21e8c385 649 }
650
a43d67ba 651 /* Call the updatetraceset hooks */
652
653 SetTraceset(mw_data, (gpointer)traceset);
654 // in expose now call_pending_read_hooks(mw_data);
655
656 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
49bf71b5 657 break;
2176f952 658 case GTK_RESPONSE_REJECT:
659 case GTK_RESPONSE_CANCEL:
660 default:
68b48a45 661 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 662 break;
663 }
49bf71b5 664}
665
abe346a3 666
667/* remove_trace_into_traceset_selector, each instance of a viewer has an associated
668 * selector (filter), when a trace is remove from traceset, the selector should
669 * reflect the change. The function is used to update the selector
670 */
671
49bf71b5 672void remove_trace_from_traceset_selector(GtkMultiVPaned * paned, unsigned i)
673{
674 LttvTracesetSelector * s;
675 LttvTraceSelector * t;
676 GtkWidget * w;
677
678 w = gtk_multi_vpaned_get_first_widget(paned);
679 while(w){
680 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 681 if(s){
682 t = lttv_traceset_selector_trace_get(s,i);
683 lttv_traceset_selector_trace_remove(s, i);
684 lttv_trace_selector_destroy(t);
685 }g_warning("Module dose not support filtering\n");
49bf71b5 686 w = gtk_multi_vpaned_get_next_widget(paned);
687 }
561eba2a 688}
689
abe346a3 690
691/* remove_trace removes a trace from the current traceset if all viewers in
692 * the current tab are not interested in the trace. It first displays a
693 * dialogue, which shows all traces in the current traceset, to let user choose
694 * a trace, then it checks if all viewers unselect the trace, if it is true,
695 * it will remove the trace, recreate the traceset_contex,
696 * and redraws all the viewer of the current tab. If there is on trace in the
697 * current traceset, it will delete all viewers of the current tab
698 */
699
561eba2a 700void remove_trace(GtkWidget * widget, gpointer user_data)
701{
2176f952 702 LttTrace *trace;
703 LttvTrace * trace_v;
704 LttvTraceset * traceset;
a43d67ba 705 gint i, j, nb_trace;
2176f952 706 char ** name, *remove_trace_name;
bca3b81f 707 MainWindow * mw_data = get_window_data_struct(widget);
49bf71b5 708 LttvTracesetSelector * s;
709 LttvTraceSelector * t;
710 GtkWidget * w;
711 gboolean selected;
2176f952 712
716e4367 713 nb_trace =lttv_traceset_number(mw_data->current_tab->traceset_info->traceset);
2176f952 714 name = g_new(char*,nb_trace);
715 for(i = 0; i < nb_trace; i++){
716e4367 716 trace_v = lttv_traceset_get(mw_data->current_tab->
717 traceset_info->traceset, i);
2176f952 718 trace = lttv_trace(trace_v);
a5dcde2f 719 name[i] = ltt_trace_name(trace);
2176f952 720 }
721
722 remove_trace_name = get_remove_trace(name, nb_trace);
723
724 if(remove_trace_name){
725 for(i=0; i<nb_trace; i++){
726 if(strcmp(remove_trace_name,name[i]) == 0){
49bf71b5 727 //unselect the trace from the current viewer
728 w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
9f0a7b47 729 if(w){
49bf71b5 730 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 731 if(s){
732 t = lttv_traceset_selector_trace_get(s,i);
733 lttv_trace_selector_set_selected(t, FALSE);
734 }
9f0a7b47 735
736 //check if other viewers select the trace
737 w = gtk_multi_vpaned_get_first_widget(mw_data->current_tab->multi_vpaned);
738 while(w){
739 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
abe346a3 740 if(s){
741 t = lttv_traceset_selector_trace_get(s,i);
742 selected = lttv_trace_selector_get_selected(t);
743 if(selected)break;
744 }
9f0a7b47 745 w = gtk_multi_vpaned_get_next_widget(mw_data->current_tab->multi_vpaned);
746 }
747 }else selected = FALSE;
49bf71b5 748
749 //if no viewer selects the trace, remove it
750 if(!selected){
751 remove_trace_from_traceset_selector(mw_data->current_tab->multi_vpaned, i);
752
753 traceset = mw_data->current_tab->traceset_info->traceset;
754 trace_v = lttv_traceset_get(traceset, i);
755 if(lttv_trace_get_ref_number(trace_v) <= 1)
756 ltt_trace_close(lttv_trace(trace_v));
a43d67ba 757
758 //Keep a reference to the traces so they are not freed.
759 for(j=0; j<lttv_traceset_number(traceset); j++)
760 {
761 LttvTrace * trace = lttv_traceset_get(traceset, j);
762 lttv_trace_ref(trace);
763 }
764
765 //remove state update hooks
766 lttv_state_remove_event_hooks(
767 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
768 lttv_context_fini(LTTV_TRACESET_CONTEXT(mw_data->current_tab->traceset_info->traceset_context));
769 g_object_unref(mw_data->current_tab->traceset_info->traceset_context);
770
c2619a30 771
49bf71b5 772 lttv_traceset_remove(traceset, i);
a43d67ba 773 lttv_trace_unref(trace_v); // Remove local reference
912be9a5 774 if(!lttv_trace_get_ref_number(trace_v))
775 lttv_trace_destroy(trace_v);
a43d67ba 776
49bf71b5 777 mw_data->current_tab->traceset_info->traceset_context =
778 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
a43d67ba 779 lttv_context_init(
49bf71b5 780 LTTV_TRACESET_CONTEXT(mw_data->current_tab->
781 traceset_info->traceset_context),traceset);
784705cc 782 //add state update hooks
a43d67ba 783 lttv_state_add_event_hooks(
784705cc 784 (LttvTracesetState*)mw_data->current_tab->traceset_info->traceset_context);
c2619a30 785
a43d67ba 786 //Remove local reference to the traces.
787 for(j=0; j<lttv_traceset_number(traceset); j++)
788 {
789 LttvTrace * trace = lttv_traceset_get(traceset, j);
790 lttv_trace_unref(trace);
791 }
792
c2619a30 793
49bf71b5 794 //update current tab
a43d67ba 795 //update_traceset(mw_data);
912be9a5 796 if(nb_trace > 1){
a43d67ba 797
798 SetTraceset(mw_data, (gpointer)traceset);
799 // in expose now call_pending_read_hooks(mw_data);
800
801 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
912be9a5 802 }else{
803 if(mw_data->current_tab){
804 while(mw_data->current_tab->multi_vpaned->num_children){
805 gtk_multi_vpaned_widget_delete(mw_data->current_tab->multi_vpaned);
806 }
807 }
808 }
2176f952 809 }
2176f952 810 break;
811 }
812 }
813 }
814
815 g_free(name);
561eba2a 816}
817
abe346a3 818
819/* save will save the traceset to a file
a43d67ba 820 * Not implemented yet FIXME
abe346a3 821 */
822
561eba2a 823void save(GtkWidget * widget, gpointer user_data)
824{
825 g_printf("Save\n");
826}
827
828void save_as(GtkWidget * widget, gpointer user_data)
829{
830 g_printf("Save as\n");
831}
832
abe346a3 833
834/* zoom will change the time_window of all the viewers of the
835 * current tab, and redisplay them. The main functionality is to
836 * determine the new time_window of the current tab
837 */
838
1f1ae829 839void zoom(GtkWidget * widget, double size)
840{
841 TimeInterval *time_span;
a43d67ba 842 TimeWindow new_time_window;
843 LttTime current_time, time_delta, time_s, time_e, time_tmp;
1f1ae829 844 MainWindow * mw_data = get_window_data_struct(widget);
845
fda16332 846 if(size == 1) return;
847
716e4367 848 time_span = LTTV_TRACESET_CONTEXT(mw_data->current_tab->
849 traceset_info->traceset_context)->Time_Span;
a43d67ba 850 new_time_window = mw_data->current_tab->time_window;
1f1ae829 851 current_time = mw_data->current_tab->current_time;
852
853 time_delta = ltt_time_sub(time_span->endTime,time_span->startTime);
854 if(size == 0){
a43d67ba 855 new_time_window.start_time = time_span->startTime;
856 new_time_window.time_width = time_delta;
1f1ae829 857 }else{
a43d67ba 858 new_time_window.time_width = ltt_time_div(new_time_window.time_width, size);
859 if(ltt_time_compare(new_time_window.time_width,time_delta) > 0)
860 { /* Case where zoom out is bigger than trace length */
861 new_time_window.start_time = time_span->startTime;
862 new_time_window.time_width = time_delta;
a8c0f09d 863 }
a43d67ba 864 else
865 {
866 /* Center the image on the current time */
867 g_critical("update is HERE");
868 new_time_window.start_time =
869 ltt_time_sub(current_time, ltt_time_div(new_time_window.time_width, 2.0));
870 /* If on borders, don't fall off */
871 if(ltt_time_compare(new_time_window.start_time, time_span->startTime) <0)
872 {
873 new_time_window.start_time = time_span->startTime;
874 }
875 else
876 {
877 if(ltt_time_compare(
878 ltt_time_add(new_time_window.start_time, new_time_window.time_width),
879 time_span->endTime) > 0)
880 {
881 new_time_window.start_time =
882 ltt_time_sub(time_span->endTime, new_time_window.time_width);
883 }
884 }
885
1f1ae829 886 }
a43d67ba 887
888
889
890 //time_tmp = ltt_time_div(new_time_window.time_width, 2);
891 //if(ltt_time_compare(current_time, time_tmp) < 0){
892 // time_s = time_span->startTime;
893 //} else {
894 // time_s = ltt_time_sub(current_time,time_tmp);
895 //}
896 //time_e = ltt_time_add(current_time,time_tmp);
897 //if(ltt_time_compare(time_span->startTime, time_s) > 0){
898 // time_s = time_span->startTime;
899 //}else if(ltt_time_compare(time_span->endTime, time_e) < 0){
900 // time_e = time_span->endTime;
901 // time_s = ltt_time_sub(time_e,new_time_window.time_width);
902 //}
903 //new_time_window.start_time = time_s;
1f1ae829 904 }
a43d67ba 905
906 //lttvwindow_report_time_window(mw_data, &new_time_window);
907 //call_pending_read_hooks(mw_data);
908
909 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
910 set_time_window(mw_data, &new_time_window);
911 // in expose now call_pending_read_hooks(mw_data);
912 gtk_multi_vpaned_set_adjust(mw_data->current_tab->multi_vpaned, &new_time_window, FALSE);
1f1ae829 913}
914
561eba2a 915void zoom_in(GtkWidget * widget, gpointer user_data)
916{
1f1ae829 917 zoom(widget, 2);
561eba2a 918}
919
920void zoom_out(GtkWidget * widget, gpointer user_data)
921{
1f1ae829 922 zoom(widget, 0.5);
561eba2a 923}
924
925void zoom_extended(GtkWidget * widget, gpointer user_data)
926{
1f1ae829 927 zoom(widget, 0);
561eba2a 928}
929
930void go_to_time(GtkWidget * widget, gpointer user_data)
931{
932 g_printf("Go to time\n");
933}
934
935void show_time_frame(GtkWidget * widget, gpointer user_data)
936{
937 g_printf("Show time frame\n");
938}
939
940
941/* callback function */
942
943void
944on_empty_traceset_activate (GtkMenuItem *menuitem,
945 gpointer user_data)
946{
68b48a45 947 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 948}
949
950
951void
952on_clone_traceset_activate (GtkMenuItem *menuitem,
953 gpointer user_data)
954{
68b48a45 955 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 956}
957
abe346a3 958
959/* create_new_tab calls create_tab to construct a new tab in the main window
960 */
961
2901f314 962void create_new_tab(GtkWidget* widget, gpointer user_data){
6b1d3120 963 gchar label[PATH_LENGTH];
2901f314 964 MainWindow * mw_data = get_window_data_struct(widget);
965 GtkNotebook * notebook = (GtkNotebook *)lookup_widget(widget, "MNotebook");
561eba2a 966 if(notebook == NULL){
967 g_printf("Notebook does not exist\n");
968 return;
969 }
970
6b1d3120 971 strcpy(label,"Page");
eb38aea5 972 if(get_label(mw_data, label,"Get the name of the tab","Please input tab's name"))
a43d67ba 973 create_tab (NULL, mw_data, notebook, label);
561eba2a 974}
975
2901f314 976void
977on_tab_activate (GtkMenuItem *menuitem,
978 gpointer user_data)
979{
980 create_new_tab((GtkWidget*)menuitem, user_data);
981}
982
561eba2a 983
984void
985on_open_activate (GtkMenuItem *menuitem,
986 gpointer user_data)
987{
988 open_traceset((GtkWidget*)menuitem, user_data);
989}
990
991
992void
993on_close_activate (GtkMenuItem *menuitem,
994 gpointer user_data)
995{
bca3b81f 996 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 997 main_window_destructor(mw_data);
561eba2a 998}
999
1000
abe346a3 1001/* remove the current tab from the main window if it is not the default tab
1002 */
1003
561eba2a 1004void
1005on_close_tab_activate (GtkMenuItem *menuitem,
1006 gpointer user_data)
1007{
efde9138 1008 GList * list;
2061e03d 1009 int count = 0;
1010 GtkWidget * notebook;
bca3b81f 1011 Tab * tmp;
1012 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2061e03d 1013 notebook = lookup_widget((GtkWidget*)menuitem, "MNotebook");
1014 if(notebook == NULL){
1015 g_printf("Notebook does not exist\n");
1016 return;
1017 }
1018
bca3b81f 1019 if(mw_data->tab == mw_data->current_tab){
1020 // tmp = mw_data->current_tb;
1021 // mw_data->tab = mw_data->current_tab->next;
2061e03d 1022 g_printf("The default TAB can not be deleted\n");
1023 return;
1024 }else{
bca3b81f 1025 tmp = mw_data->tab;
1026 while(tmp != mw_data->current_tab){
1027 tmp = tmp->next;
abe346a3 1028 count++;
2061e03d 1029 }
1030 }
1031
1032 gtk_notebook_remove_page((GtkNotebook*)notebook, count);
efde9138 1033 list = gtk_container_get_children(GTK_CONTAINER(notebook));
1034 if(g_list_length(list)==1)
1035 gtk_notebook_set_show_tabs((GtkNotebook*)notebook, FALSE);
561eba2a 1036}
1037
1038
1039void
1040on_add_trace_activate (GtkMenuItem *menuitem,
1041 gpointer user_data)
1042{
1043 add_trace((GtkWidget*)menuitem, user_data);
1044}
1045
1046
1047void
1048on_remove_trace_activate (GtkMenuItem *menuitem,
1049 gpointer user_data)
1050{
1051 remove_trace((GtkWidget*)menuitem, user_data);
1052}
1053
1054
1055void
1056on_save_activate (GtkMenuItem *menuitem,
1057 gpointer user_data)
1058{
1059 save((GtkWidget*)menuitem, user_data);
1060}
1061
1062
1063void
1064on_save_as_activate (GtkMenuItem *menuitem,
1065 gpointer user_data)
1066{
1067 save_as((GtkWidget*)menuitem, user_data);
1068}
1069
1070
1071void
1072on_quit_activate (GtkMenuItem *menuitem,
1073 gpointer user_data)
1074{
2061e03d 1075 gtk_main_quit ();
561eba2a 1076}
1077
1078
1079void
1080on_cut_activate (GtkMenuItem *menuitem,
1081 gpointer user_data)
1082{
1083 g_printf("Cut\n");
1084}
1085
1086
1087void
1088on_copy_activate (GtkMenuItem *menuitem,
1089 gpointer user_data)
1090{
1091 g_printf("Copye\n");
1092}
1093
1094
1095void
1096on_paste_activate (GtkMenuItem *menuitem,
1097 gpointer user_data)
1098{
1099 g_printf("Paste\n");
1100}
1101
1102
1103void
1104on_delete_activate (GtkMenuItem *menuitem,
1105 gpointer user_data)
1106{
1107 g_printf("Delete\n");
1108}
1109
1110
1111void
1112on_zoom_in_activate (GtkMenuItem *menuitem,
1113 gpointer user_data)
1114{
1115 zoom_in((GtkWidget*)menuitem, user_data);
1116}
1117
1118
1119void
1120on_zoom_out_activate (GtkMenuItem *menuitem,
1121 gpointer user_data)
1122{
1123 zoom_out((GtkWidget*)menuitem, user_data);
1124}
1125
1126
1127void
1128on_zoom_extended_activate (GtkMenuItem *menuitem,
1129 gpointer user_data)
1130{
1131 zoom_extended((GtkWidget*)menuitem, user_data);
1132}
1133
1134
1135void
1136on_go_to_time_activate (GtkMenuItem *menuitem,
1137 gpointer user_data)
1138{
1139 go_to_time((GtkWidget*)menuitem, user_data);
1140}
1141
1142
1143void
1144on_show_time_frame_activate (GtkMenuItem *menuitem,
1145 gpointer user_data)
1146{
1147 show_time_frame((GtkWidget*)menuitem, user_data);
1148}
1149
1150
1151void
1152on_move_viewer_up_activate (GtkMenuItem *menuitem,
1153 gpointer user_data)
1154{
1155 move_up_viewer((GtkWidget*)menuitem, user_data);
1156}
1157
1158
1159void
1160on_move_viewer_down_activate (GtkMenuItem *menuitem,
1161 gpointer user_data)
1162{
1163 move_down_viewer((GtkWidget*)menuitem, user_data);
1164}
1165
1166
1167void
1168on_remove_viewer_activate (GtkMenuItem *menuitem,
1169 gpointer user_data)
1170{
1171 delete_viewer((GtkWidget*)menuitem, user_data);
1172}
1173
49bf71b5 1174void
1175on_trace_filter_activate (GtkMenuItem *menuitem,
1176 gpointer user_data)
1177{
1178 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
1179 LttvTracesetSelector * s;
1180 GtkWidget * w = gtk_multi_vpaned_get_widget(mw_data->current_tab->multi_vpaned);
1181
1182 s = g_object_get_data(G_OBJECT(w), "Traceset_Selector");
1183 if(!s){
1184 g_printf("There is no viewer yet\n");
1185 return;
1186 }
a8c0f09d 1187 if(get_filter_selection(s, "Configure trace and tracefile filter", "Select traces and tracefiles")){
a43d67ba 1188 //FIXME report filter change
1189 //update_traceset(mw_data);
1190 //call_pending_read_hooks(mw_data);
1191 //lttvwindow_report_current_time(mw_data,&(mw_data->current_tab->current_time));
a8c0f09d 1192 }
49bf71b5 1193}
1194
1195void
1196on_trace_facility_activate (GtkMenuItem *menuitem,
1197 gpointer user_data)
1198{
1199 g_printf("Trace facility selector: %s\n");
1200}
561eba2a 1201
abe346a3 1202
1203/* Dispaly a file selection dialogue to let user select a module, then call
1204 * lttv_module_load(), finally insert tool button and menu entry in the main window
1205 * for the loaded module
1206 */
1207
561eba2a 1208void
1209on_load_module_activate (GtkMenuItem *menuitem,
1210 gpointer user_data)
1211{
36b3c068 1212 char ** dir;
1213 gint id;
3872a20e 1214 char str[PATH_LENGTH], *str1;
bca3b81f 1215 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
68b48a45 1216 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a module");
3658a338 1217 if(remember_plugins_dir[0] != '\0')
1218 gtk_file_selection_set_filename(file_selector, remember_plugins_dir);
68b48a45 1219 gtk_file_selection_hide_fileop_buttons(file_selector);
36b3c068 1220
1221 str[0] = '\0';
68b48a45 1222 id = gtk_dialog_run(GTK_DIALOG(file_selector));
36b3c068 1223 switch(id){
1224 case GTK_RESPONSE_ACCEPT:
1225 case GTK_RESPONSE_OK:
68b48a45 1226 dir = gtk_file_selection_get_selections (file_selector);
6fbb1ddf 1227 strncpy(str,dir[0],PATH_LENGTH);
3658a338 1228 strncpy(remember_plugins_dir,dir[0],PATH_LENGTH);
3872a20e 1229 str1 = strrchr(str,'/');
1230 if(str1)str1++;
1231 else{
1232 str1 = strrchr(str,'\\');
1233 str1++;
1234 }
08b1c66e 1235 lttv_module_require(str1, NULL);
f2d17b4d 1236 g_slist_foreach(g_main_window_list, (gpointer)insert_menu_toolbar_item,
1237 NULL);
36b3c068 1238 g_strfreev(dir);
1239 case GTK_RESPONSE_REJECT:
1240 case GTK_RESPONSE_CANCEL:
1241 default:
68b48a45 1242 gtk_widget_destroy((GtkWidget*)file_selector);
36b3c068 1243 break;
1244 }
1245 g_printf("Load module: %s\n", str);
561eba2a 1246}
1247
1248
abe346a3 1249/* Display all loaded modules, let user to select a module to unload
1250 * by calling lttv_module_unload
1251 */
1252
561eba2a 1253void
1254on_unload_module_activate (GtkMenuItem *menuitem,
1255 gpointer user_data)
1256{
36b3c068 1257 int i;
08b1c66e 1258 GPtrArray *name;
1259 char *unload_module_name;
36b3c068 1260 guint nb;
08b1c66e 1261 LttvLibrary *library;
1262 LttvLibraryInfo library_info;
bca3b81f 1263 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
36b3c068 1264
08b1c66e 1265 name = g_ptr_array_new();
1266 nb = lttv_library_number();
1267
36b3c068 1268 for(i=0;i<nb;i++){
08b1c66e 1269 library = lttv_library_get(i);
1270 lttv_library_info(library, &library_info);
1271 if(library_info.load_count > 0) g_ptr_array_add(name, library_info.name);
36b3c068 1272 }
1273
08b1c66e 1274 unload_module_name =get_unload_module((char **)(name->pdata), name->len);
36b3c068 1275
1276 if(unload_module_name){
1277 for(i=0;i<nb;i++){
08b1c66e 1278 library = lttv_library_get(i);
1279 lttv_library_info(library, &library_info);
1280 if(strcmp(unload_module_name, library_info.name) == 0){
1281 lttv_library_unload(library);
36b3c068 1282 break;
1283 }
1284 }
1285 }
1286
08b1c66e 1287 g_ptr_array_free(name, TRUE);
561eba2a 1288}
1289
1290
abe346a3 1291/* Display a directory dialogue to let user select a path for module searching
1292 */
1293
561eba2a 1294void
1295on_add_module_search_path_activate (GtkMenuItem *menuitem,
1296 gpointer user_data)
1297{
68b48a45 1298 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
67b98724 1299 const char * dir;
fc188b78 1300 gint id;
1301
bca3b81f 1302 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 1303 if(remember_plugins_dir[0] != '\0')
1304 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 1305
68b48a45 1306 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 1307 switch(id){
1308 case GTK_RESPONSE_ACCEPT:
1309 case GTK_RESPONSE_OK:
68b48a45 1310 dir = gtk_dir_selection_get_dir (file_selector);
3658a338 1311 strncpy(remember_plugins_dir,dir,PATH_LENGTH);
1312 strncat(remember_plugins_dir,"/",PATH_LENGTH);
08b1c66e 1313 lttv_library_path_add(dir);
fc188b78 1314 case GTK_RESPONSE_REJECT:
1315 case GTK_RESPONSE_CANCEL:
1316 default:
68b48a45 1317 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 1318 break;
6b1d3120 1319 }
561eba2a 1320}
1321
1322
1323void
1324on_color_activate (GtkMenuItem *menuitem,
1325 gpointer user_data)
1326{
1327 g_printf("Color\n");
1328}
1329
1330
1331void
1332on_filter_activate (GtkMenuItem *menuitem,
1333 gpointer user_data)
1334{
1335 g_printf("Filter\n");
1336}
1337
1338
1339void
1340on_save_configuration_activate (GtkMenuItem *menuitem,
1341 gpointer user_data)
1342{
1343 g_printf("Save configuration\n");
1344}
1345
1346
1347void
1348on_content_activate (GtkMenuItem *menuitem,
1349 gpointer user_data)
1350{
1351 g_printf("Content\n");
1352}
1353
1354
1355void
1356on_about_activate (GtkMenuItem *menuitem,
1357 gpointer user_data)
1358{
1359 g_printf("About...\n");
1360}
1361
1362
1363void
1364on_button_new_clicked (GtkButton *button,
1365 gpointer user_data)
1366{
6f7ad7ae 1367 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 1368}
1369
2901f314 1370void
1371on_button_new_tab_clicked (GtkButton *button,
1372 gpointer user_data)
1373{
1374 create_new_tab((GtkWidget*)button, user_data);
1375}
561eba2a 1376
1377void
1378on_button_open_clicked (GtkButton *button,
1379 gpointer user_data)
1380{
1381 open_traceset((GtkWidget*)button, user_data);
1382}
1383
1384
1385void
1386on_button_add_trace_clicked (GtkButton *button,
1387 gpointer user_data)
1388{
1389 add_trace((GtkWidget*)button, user_data);
1390}
1391
1392
1393void
1394on_button_remove_trace_clicked (GtkButton *button,
1395 gpointer user_data)
1396{
1397 remove_trace((GtkWidget*)button, user_data);
1398}
1399
1400
1401void
1402on_button_save_clicked (GtkButton *button,
1403 gpointer user_data)
1404{
1405 save((GtkWidget*)button, user_data);
1406}
1407
1408
1409void
1410on_button_save_as_clicked (GtkButton *button,
1411 gpointer user_data)
1412{
1413 save_as((GtkWidget*)button, user_data);
1414}
1415
1416
1417void
1418on_button_zoom_in_clicked (GtkButton *button,
1419 gpointer user_data)
1420{
1421 zoom_in((GtkWidget*)button, user_data);
1422}
1423
1424
1425void
1426on_button_zoom_out_clicked (GtkButton *button,
1427 gpointer user_data)
1428{
1429 zoom_out((GtkWidget*)button, user_data);
1430}
1431
1432
1433void
1434on_button_zoom_extended_clicked (GtkButton *button,
1435 gpointer user_data)
1436{
1437 zoom_extended((GtkWidget*)button, user_data);
1438}
1439
1440
1441void
1442on_button_go_to_time_clicked (GtkButton *button,
1443 gpointer user_data)
1444{
1445 go_to_time((GtkWidget*)button, user_data);
1446}
1447
1448
1449void
1450on_button_show_time_frame_clicked (GtkButton *button,
1451 gpointer user_data)
1452{
1453 show_time_frame((GtkWidget*)button, user_data);
1454}
1455
1456
1457void
1458on_button_move_up_clicked (GtkButton *button,
1459 gpointer user_data)
1460{
1461 move_up_viewer((GtkWidget*)button, user_data);
1462}
1463
1464
1465void
1466on_button_move_down_clicked (GtkButton *button,
1467 gpointer user_data)
1468{
1469 move_down_viewer((GtkWidget*)button, user_data);
1470}
1471
1472
1473void
1474on_button_delete_viewer_clicked (GtkButton *button,
1475 gpointer user_data)
1476{
1477 delete_viewer((GtkWidget*)button, user_data);
1478}
1479
1480void
1481on_MWindow_destroy (GtkObject *object,
1482 gpointer user_data)
1483{
e4d09234 1484 MainWindow *Main_Window = get_window_data_struct((GtkWidget*)object);
1485 GtkWidget *widget;
1486 Tab *tab = Main_Window->tab;
1487
68b48a45 1488 g_printf("There are : %d windows\n",g_slist_length(g_main_window_list));
561eba2a 1489
68b48a45 1490 g_win_count--;
1491 if(g_win_count == 0)
7a859036 1492 gtk_main_quit ();
561eba2a 1493}
1494
58eecf4a 1495gboolean
1496on_MWindow_configure (GtkWidget *widget,
1497 GdkEventConfigure *event,
1498 gpointer user_data)
1499{
1500 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
1501 float width = event->width;
1502 Tab * tab = mw_data->tab;
1503 TimeWindow time_win;
1504 double ratio;
1505 TimeInterval *time_span;
1506 LttTime time;
bd24a9af 1507
1508 // MD : removed time width modification upon resizing of the main window.
1509 // The viewers will redraw themselves completely, without time interval
1510 // modification.
1511/* while(tab){
58eecf4a 1512 if(mw_data->window_width){
1513 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1514 time_win = tab->time_window;
1515 ratio = width / mw_data->window_width;
1516 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1517 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1518 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1519 tab->time_window.time_width = time;
1520 }
1521 }
1522 tab = tab->next;
1523 }
1524
1525 mw_data->window_width = (int)width;
bd24a9af 1526 */
58eecf4a 1527 return FALSE;
1528}
561eba2a 1529
abe346a3 1530/* Set current tab
1531 */
1532
561eba2a 1533void
1534on_MNotebook_switch_page (GtkNotebook *notebook,
1535 GtkNotebookPage *page,
1536 guint page_num,
1537 gpointer user_data)
1538{
bca3b81f 1539 MainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
1540 Tab * tab = mw->tab;
561eba2a 1541
1542 while(page_num){
bca3b81f 1543 tab = tab->next;
561eba2a 1544 page_num--;
1545 }
bca3b81f 1546 mw->current_tab = tab;
561eba2a 1547}
1548
abe346a3 1549
1550/* callback function to check or uncheck the check box (filter)
1551 */
1552
49bf71b5 1553void checkbox_changed(GtkTreeView *treeview,
1554 GtkTreePath *arg1,
1555 GtkTreeViewColumn *arg2,
1556 gpointer user_data)
1557{
1558 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
1559 GtkTreeIter iter;
1560 gboolean value;
1561
1562 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
1563 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
1564 value = value? FALSE : TRUE;
1565 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
1566 }
1567
1568}
1569
abe346a3 1570
1571/* According to user's selection, update selector(filter)
1572 */
1573
49bf71b5 1574void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
1575{
ed3b99b6 1576 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1577 int i, j, k, nb_eventtype;
49bf71b5 1578 LttvTraceSelector * trace;
1579 LttvTracefileSelector * tracefile;
ed3b99b6 1580 LttvEventtypeSelector * eventtype;
1581 gboolean value, value1, value2;
49bf71b5 1582
1583 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
1584 i = 0;
1585 do{
ed3b99b6 1586 trace = lttv_traceset_selector_trace_get(s, i);
1587 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
49bf71b5 1588 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
1589 if(value){
1590 j = 0;
1591 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
1592 do{
ed3b99b6 1593 if(j<1){//eventtype selector for trace
1594 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
1595 if(value2){
1596 k=0;
1597 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
1598 do{
1599 eventtype = lttv_trace_selector_eventtype_get(trace,k);
1600 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1601 lttv_eventtype_selector_set_selected(eventtype,value2);
1602 k++;
1603 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
1604 }
1605 }
1606 }else{ //tracefile selector
1607 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
1608 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
1609 lttv_tracefile_selector_set_selected(tracefile,value1);
1610 if(value1){
1611 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
1612 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1613 if(value2){
1614 k = 0;
1615 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
1616 do{//eventtype selector for tracefile
1617 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1618 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
1619 lttv_eventtype_selector_set_selected(eventtype,value2);
1620 k++;
1621 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
1622 }
1623 }
1624 }
1625 }
49bf71b5 1626 j++;
1627 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
1628 }
1629 }
1630 lttv_trace_selector_set_selected(trace,value);
1631 i++;
1632 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
1633 }
1634}
1635
abe346a3 1636
1637/* Display a dialogue showing all eventtypes and traces, let user to select the interested
1638 * eventtypes, tracefiles and traces (filter)
1639 */
1640
a8c0f09d 1641gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
49bf71b5 1642{
1643 GtkWidget * dialogue;
1644 GtkTreeStore * store;
1645 GtkWidget * tree;
1646 GtkWidget * scroll_win;
1647 GtkCellRenderer * renderer;
1648 GtkTreeViewColumn * column;
ed3b99b6 1649 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1650 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
49bf71b5 1651 LttvTraceSelector * trace;
1652 LttvTracefileSelector * tracefile;
ed3b99b6 1653 LttvEventtypeSelector * eventtype;
49bf71b5 1654 char * name;
1655 gboolean checked;
1656
1657 dialogue = gtk_dialog_new_with_buttons(title,
1658 NULL,
1659 GTK_DIALOG_MODAL,
1660 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1661 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1662 NULL);
ed3b99b6 1663 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
49bf71b5 1664
1665 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
1666 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1667 g_object_unref (G_OBJECT (store));
1668 g_signal_connect (G_OBJECT (tree), "row-activated",
1669 G_CALLBACK (checkbox_changed),
1670 NULL);
1671
1672
1673 renderer = gtk_cell_renderer_toggle_new ();
1674 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
1675
1676 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
1677
1678 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
1679 renderer,
1680 "active", CHECKBOX_COLUMN,
1681 NULL);
1682 gtk_tree_view_column_set_alignment (column, 0.5);
1683 gtk_tree_view_column_set_fixed_width (column, 20);
1684 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1685
1686 renderer = gtk_cell_renderer_text_new ();
1687 column = gtk_tree_view_column_new_with_attributes (column_title,
1688 renderer,
1689 "text", NAME_COLUMN,
1690 NULL);
1691 gtk_tree_view_column_set_alignment (column, 0.0);
1692 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1693 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
1694
1695 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1696 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1697 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
1698 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1699
1700 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1701
1702 gtk_widget_show(scroll_win);
1703 gtk_widget_show(tree);
1704
ed3b99b6 1705 nb_trace = lttv_traceset_selector_trace_number(s);
49bf71b5 1706 for(i=0;i<nb_trace;i++){
ed3b99b6 1707 trace = lttv_traceset_selector_trace_get(s, i);
49bf71b5 1708 name = lttv_trace_selector_get_name(trace);
1709 gtk_tree_store_append (store, &iter, NULL);
1710 checked = lttv_trace_selector_get_selected(trace);
1711 gtk_tree_store_set (store, &iter,
1712 CHECKBOX_COLUMN,checked,
1713 NAME_COLUMN,name,
1714 -1);
ed3b99b6 1715
1716 gtk_tree_store_append (store, &child_iter, &iter);
1717 gtk_tree_store_set (store, &child_iter,
1718 CHECKBOX_COLUMN, checked,
1719 NAME_COLUMN,"eventtype",
1720 -1);
1721
1722 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1723 for(j=0;j<nb_eventtype;j++){
1724 eventtype = lttv_trace_selector_eventtype_get(trace,j);
1725 name = lttv_eventtype_selector_get_name(eventtype);
1726 checked = lttv_eventtype_selector_get_selected(eventtype);
1727 gtk_tree_store_append (store, &child_iter1, &child_iter);
1728 gtk_tree_store_set (store, &child_iter1,
1729 CHECKBOX_COLUMN, checked,
1730 NAME_COLUMN,name,
1731 -1);
1732 }
1733
1734 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
49bf71b5 1735 for(j=0;j<nb_tracefile;j++){
ed3b99b6 1736 tracefile = lttv_trace_selector_tracefile_get(trace, j);
49bf71b5 1737 name = lttv_tracefile_selector_get_name(tracefile);
1738 gtk_tree_store_append (store, &child_iter, &iter);
1739 checked = lttv_tracefile_selector_get_selected(tracefile);
1740 gtk_tree_store_set (store, &child_iter,
1741 CHECKBOX_COLUMN, checked,
1742 NAME_COLUMN,name,
1743 -1);
ed3b99b6 1744
1745 gtk_tree_store_append (store, &child_iter1, &child_iter);
1746 gtk_tree_store_set (store, &child_iter1,
1747 CHECKBOX_COLUMN, checked,
1748 NAME_COLUMN,"eventtype",
1749 -1);
1750
1751 for(k=0;k<nb_eventtype;k++){
1752 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1753 name = lttv_eventtype_selector_get_name(eventtype);
1754 checked = lttv_eventtype_selector_get_selected(eventtype);
1755 gtk_tree_store_append (store, &child_iter2, &child_iter1);
1756 gtk_tree_store_set (store, &child_iter2,
1757 CHECKBOX_COLUMN, checked,
1758 NAME_COLUMN,name,
1759 -1);
1760 }
49bf71b5 1761 }
1762 }
1763
1764 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1765 switch(id){
1766 case GTK_RESPONSE_ACCEPT:
1767 case GTK_RESPONSE_OK:
1768 update_filter(s, store);
a8c0f09d 1769 gtk_widget_destroy(dialogue);
1770 return TRUE;
49bf71b5 1771 case GTK_RESPONSE_REJECT:
1772 case GTK_RESPONSE_CANCEL:
1773 default:
1774 gtk_widget_destroy(dialogue);
1775 break;
1776 }
a8c0f09d 1777 return FALSE;
49bf71b5 1778}
1779
abe346a3 1780
1781/* Select a trace which will be removed from traceset
1782 */
1783
2176f952 1784char * get_remove_trace(char ** all_trace_name, int nb_trace)
1785{
1786 return get_selection(all_trace_name, nb_trace,
1787 "Select a trace", "Trace pathname");
1788}
abe346a3 1789
1790
1791/* Select a module which will be unloaded
1792 */
1793
36b3c068 1794char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 1795{
1796 return get_selection(loaded_module_name, nb_module,
1797 "Select an unload module", "Module pathname");
1798}
1799
abe346a3 1800
1801/* Display a dialogue which shows all selectable items, let user to
1802 * select one of them
1803 */
1804
2176f952 1805char * get_selection(char ** loaded_module_name, int nb_module,
1806 char *title, char * column_title)
36b3c068 1807{
1808 GtkWidget * dialogue;
1809 GtkWidget * scroll_win;
1810 GtkWidget * tree;
1811 GtkListStore * store;
1812 GtkTreeViewColumn * column;
1813 GtkCellRenderer * renderer;
1814 GtkTreeSelection * select;
1815 GtkTreeIter iter;
1816 gint id, i;
1817 char * unload_module_name = NULL;
1818
2176f952 1819 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 1820 NULL,
1821 GTK_DIALOG_MODAL,
1822 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1823 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1824 NULL);
1825 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
1826
1827 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1828 gtk_widget_show ( scroll_win);
1829 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1830 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1831
1832 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
1833 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
1834 gtk_widget_show ( tree);
1835 g_object_unref (G_OBJECT (store));
1836
1837 renderer = gtk_cell_renderer_text_new ();
2176f952 1838 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 1839 renderer,
1840 "text", MODULE_COLUMN,
1841 NULL);
1842 gtk_tree_view_column_set_alignment (column, 0.5);
1843 gtk_tree_view_column_set_fixed_width (column, 150);
1844 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1845
1846 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
1847 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
1848
1849 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1850
1851 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1852
1853 for(i=0;i<nb_module;i++){
1854 gtk_list_store_append (store, &iter);
1855 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
1856 }
1857
1858 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1859 switch(id){
1860 case GTK_RESPONSE_ACCEPT:
1861 case GTK_RESPONSE_OK:
1862 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
1863 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
1864 }
1865 case GTK_RESPONSE_REJECT:
1866 case GTK_RESPONSE_CANCEL:
1867 default:
1868 gtk_widget_destroy(dialogue);
1869 break;
1870 }
1871
1872 return unload_module_name;
1873}
5723fa24 1874
abe346a3 1875
1876/* hash funtions
1877 */
1878
2176f952 1879void main_window_destroy_hash_key(gpointer key)
2061e03d 1880{
1881 g_free(key);
1882}
1883
2176f952 1884void main_window_destroy_hash_data(gpointer data)
2061e03d 1885{
1886}
1887
1888
abe346a3 1889/* Insert menu entry and tool button into all main windows for modules
1890 * It checks whether the menu entry or tool button exists or not,
1891 * if they do not exist, then construct the widget and insert them
1892 * into all main windows
1893 */
1894
bca3b81f 1895void insert_menu_toolbar_item(MainWindow * mw, gpointer user_data)
5723fa24 1896{
1897 int i;
1898 GdkPixbuf *pixbuf;
42fcbb71 1899 lttvwindow_viewer_constructor constructor;
5723fa24 1900 LttvMenus * menu;
1901 LttvToolbars * toolbar;
68b48a45 1902 lttv_menu_closure *menu_item;
1903 lttv_toolbar_closure *toolbar_item;
5723fa24 1904 LttvAttributeValue value;
1905 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
68b48a45 1906 GtkWidget * tool_menu_title_menu, *insert_view, *pixmap, *tmp;
5723fa24 1907
1908 g_assert(lttv_iattribute_find_by_path(attributes,
1909 "viewers/menu", LTTV_POINTER, &value));
1910 menu = (LttvMenus*)*(value.v_pointer);
1911
1912 if(menu){
1913 for(i=0;i<menu->len;i++){
68b48a45 1914 menu_item = &g_array_index(menu, lttv_menu_closure, i);
1915 tmp = g_hash_table_lookup(mw->hash_menu_item, g_strdup(menu_item->menuText));
3872a20e 1916 if(tmp)continue;
68b48a45 1917 constructor = menu_item->con;
bca3b81f 1918 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
68b48a45 1919 insert_view = gtk_menu_item_new_with_mnemonic (menu_item->menuText);
5723fa24 1920 gtk_widget_show (insert_view);
68b48a45 1921 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), insert_view);
5723fa24 1922 g_signal_connect ((gpointer) insert_view, "activate",
68b48a45 1923 G_CALLBACK (insert_viewer_wrap),
5723fa24 1924 constructor);
68b48a45 1925 g_hash_table_insert(mw->hash_menu_item, g_strdup(menu_item->menuText),
2061e03d 1926 insert_view);
5723fa24 1927 }
1928 }
1929
1930 g_assert(lttv_iattribute_find_by_path(attributes,
1931 "viewers/toolbar", LTTV_POINTER, &value));
1932 toolbar = (LttvToolbars*)*(value.v_pointer);
1933
1934 if(toolbar){
1935 for(i=0;i<toolbar->len;i++){
68b48a45 1936 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
1937 tmp = g_hash_table_lookup(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip));
3872a20e 1938 if(tmp)continue;
68b48a45 1939 constructor = toolbar_item->con;
efde9138 1940 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
68b48a45 1941 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**)toolbar_item->pixmap);
5723fa24 1942 pixmap = gtk_image_new_from_pixbuf(pixbuf);
68b48a45 1943 insert_view = gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
5723fa24 1944 GTK_TOOLBAR_CHILD_BUTTON,
1945 NULL,
1946 "",
68b48a45 1947 toolbar_item->tooltip, NULL,
5723fa24 1948 pixmap, NULL, NULL);
68b48a45 1949 gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (tool_menu_title_menu)->children)->data))->label), TRUE);
5723fa24 1950 gtk_widget_show (insert_view);
1951 gtk_container_set_border_width (GTK_CONTAINER (insert_view), 1);
68b48a45 1952 g_signal_connect ((gpointer) insert_view, "clicked",G_CALLBACK (insert_viewer_wrap),constructor);
1953 g_hash_table_insert(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip),
2061e03d 1954 insert_view);
5723fa24 1955 }
1956 }
1957}
1958
abe346a3 1959
1960/* Create a main window
1961 */
1962
08b1c66e 1963void construct_main_window(MainWindow * parent)
5723fa24 1964{
2a2fa4f0 1965 g_debug("construct_main_window()");
68b48a45 1966 GtkWidget * new_window; /* New generated main window */
bca3b81f 1967 MainWindow * new_m_window;/* New main window structure */
5723fa24 1968 GtkNotebook * notebook;
f7afe191 1969 LttvIAttribute *attributes =
1970 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
1971 LttvAttributeValue value;
2061e03d 1972
bca3b81f 1973 new_m_window = g_new(MainWindow, 1);
5723fa24 1974
1975 // Add the object's information to the module's array
68b48a45 1976 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 1977
f7afe191 1978
68b48a45 1979 new_window = create_MWindow();
1980 gtk_widget_show (new_window);
5723fa24 1981
bca3b81f 1982 new_m_window->mwindow = new_window;
1983 new_m_window->tab = NULL;
1984 new_m_window->current_tab = NULL;
a43d67ba 1985 new_m_window->attributes = attributes;
5723fa24 1986
68b48a45 1987 new_m_window->hash_menu_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1988 main_window_destroy_hash_key,
1989 main_window_destroy_hash_data);
68b48a45 1990 new_m_window->hash_toolbar_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1991 main_window_destroy_hash_key,
1992 main_window_destroy_hash_data);
2061e03d 1993
68b48a45 1994 insert_menu_toolbar_item(new_m_window, NULL);
5723fa24 1995
68b48a45 1996 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
5723fa24 1997 //create a default tab
bca3b81f 1998 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
5723fa24 1999 if(notebook == NULL){
2000 g_printf("Notebook does not exist\n");
2001 return;
2002 }
2003 //for now there is no name field in LttvTraceset structure
2004 //Use "Traceset" as the label for the default tab
a43d67ba 2005 create_tab(parent, new_m_window, notebook, "Traceset");
5723fa24 2006
7a859036 2007 g_object_set_data_full(
bca3b81f 2008 G_OBJECT(new_m_window->mwindow),
7a859036 2009 "Main_Window_Data",
68b48a45 2010 new_m_window,
2011 (GDestroyNotify)main_window_free);
7a859036 2012
68b48a45 2013 g_win_count++;
5723fa24 2014}
2015
abe346a3 2016
2017/* Free the memory occupied by a tab structure
2018 * destroy the tab
2019 */
2020
bca3b81f 2021void tab_destructor(Tab * tab_instance)
f7afe191 2022{
716e4367 2023 int i, nb, ref_count;
2024 LttvTrace * trace;
2025
bca3b81f 2026 if(tab_instance->attributes)
2027 g_object_unref(tab_instance->attributes);
2061e03d 2028
bca3b81f 2029 if(tab_instance->mw->tab == tab_instance){
2030 tab_instance->mw->tab = tab_instance->next;
2061e03d 2031 }else{
bca3b81f 2032 Tab * tmp1, *tmp = tab_instance->mw->tab;
68b48a45 2033 while(tmp != tab_instance){
2061e03d 2034 tmp1 = tmp;
bca3b81f 2035 tmp = tmp->next;
2061e03d 2036 }
bca3b81f 2037 tmp1->next = tab_instance->next;
2061e03d 2038 }
716e4367 2039
2040 if(tab_instance->traceset_info->traceset_context != NULL){
784705cc 2041 //remove state update hooks
2042 lttv_state_remove_event_hooks(
2043 (LttvTracesetState*)tab_instance->traceset_info->
2044 traceset_context);
716e4367 2045 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2046 traceset_context));
2047 g_object_unref(tab_instance->traceset_info->traceset_context);
2048 }
2049 if(tab_instance->traceset_info->traceset != NULL) {
2050 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2051 for(i = 0 ; i < nb ; i++) {
2052 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2053 ref_count = lttv_trace_get_ref_number(trace);
49bf71b5 2054 if(ref_count <= 1){
716e4367 2055 ltt_trace_close(lttv_trace(trace));
6f7ad7ae 2056 lttv_trace_destroy(trace);
49bf71b5 2057 }
6f7ad7ae 2058 // lttv_trace_destroy(trace);
716e4367 2059 }
2060 }
a43d67ba 2061 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2062 g_array_free(tab_instance->time_requests, TRUE);
716e4367 2063 g_free(tab_instance->traceset_info);
68b48a45 2064 g_free(tab_instance);
f7afe191 2065}
2066
abe346a3 2067
2068/* Create a tab and insert it into the current main window
2069 */
2070
716e4367 2071void * create_tab(MainWindow * parent, MainWindow* current_window,
2072 GtkNotebook * notebook, char * label)
5723fa24 2073{
2074 GList * list;
bca3b81f 2075 Tab * tmp_tab;
716e4367 2076 MainWindow * mw_data = current_window;
68b48a45 2077 LttTime tmp_time;
a43d67ba 2078
abe346a3 2079 //create a new tab data structure
bca3b81f 2080 tmp_tab = mw_data->tab;
2081 while(tmp_tab && tmp_tab->next) tmp_tab = tmp_tab->next;
68b48a45 2082 if(!tmp_tab){
bca3b81f 2083 mw_data->current_tab = NULL;
2084 tmp_tab = g_new(Tab,1);
2085 mw_data->tab = tmp_tab;
5723fa24 2086 }else{
bca3b81f 2087 tmp_tab->next = g_new(Tab,1);
2088 tmp_tab = tmp_tab->next;
5723fa24 2089 }
716e4367 2090
abe346a3 2091 //construct and initialize the traceset_info
716e4367 2092 tmp_tab->traceset_info = g_new(TracesetInfo,1);
2093 if(parent){
a43d67ba 2094 if(parent->current_tab){
2095 tmp_tab->traceset_info->traceset =
2096 lttv_traceset_new();
2097 //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset);
2098 }else{
2099 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2100 }
2101
2102 }else{ /* Initial window */
716e4367 2103 if(mw_data->current_tab){
2104 tmp_tab->traceset_info->traceset =
a43d67ba 2105 lttv_traceset_new();
2106 //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset);
716e4367 2107 }else{
2108 tmp_tab->traceset_info->traceset = lttv_traceset_new();
49bf71b5 2109 /* Add the command line trace */
a43d67ba 2110 if(g_init_trace != NULL){
49bf71b5 2111 lttv_traceset_add(tmp_tab->traceset_info->traceset, g_init_trace);
a43d67ba 2112 }
716e4367 2113 }
716e4367 2114 }
a43d67ba 2115
716e4367 2116 //FIXME copy not implemented in lower level
2117 tmp_tab->traceset_info->traceset_context =
2118 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
a43d67ba 2119 g_assert(tmp_tab->traceset_info->traceset_context != NULL);
716e4367 2120 lttv_context_init(
2121 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context),
2122 tmp_tab->traceset_info->traceset);
784705cc 2123 //add state update hooks
2124 lttv_state_add_event_hooks(
2125 (LttvTracesetState*)tmp_tab->traceset_info->traceset_context);
2126
abe346a3 2127 //determine the current_time and time_window of the tab
bca3b81f 2128 if(mw_data->current_tab){
716e4367 2129 // Will have to read directly at the main window level, as we want
2130 // to be able to modify a traceset on the fly.
bca3b81f 2131 tmp_tab->time_window = mw_data->current_tab->time_window;
2132 tmp_tab->current_time = mw_data->current_tab->current_time;
5723fa24 2133 }else{
716e4367 2134 // Will have to read directly at the main window level, as we want
2135 // to be able to modify a traceset on the fly.
2136 // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
bca3b81f 2137 tmp_tab->time_window.start_time =
716e4367 2138 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime;
f7afe191 2139 if(DEFAULT_TIME_WIDTH_S <
716e4367 2140 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec)
68b48a45 2141 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 2142 else
68b48a45 2143 tmp_time.tv_sec =
716e4367 2144 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec;
68b48a45 2145 tmp_time.tv_nsec = 0;
bca3b81f 2146 tmp_tab->time_window.time_width = tmp_time ;
a8c0f09d 2147 tmp_tab->current_time.tv_sec =
2148 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec;
2149 tmp_tab->current_time.tv_nsec =
2150 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec;
5723fa24 2151 }
a43d67ba 2152 /* Become the current tab */
2153 mw_data->current_tab = tmp_tab;
2154
bca3b81f 2155 tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
daecc161 2156 tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2157 tmp_tab->multi_vpaned->mw = mw_data;
2158 gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned);
bca3b81f 2159 tmp_tab->next = NULL;
68b48a45 2160 tmp_tab->mw = mw_data;
5723fa24 2161
68b48a45 2162 tmp_tab->label = gtk_label_new (label);
2163 gtk_widget_show (tmp_tab->label);
5723fa24 2164
a43d67ba 2165 tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest));
2166 tmp_tab->time_request_pending = FALSE;
2167
f7afe191 2168 g_object_set_data_full(
daecc161 2169 G_OBJECT(tmp_tab->multi_vpaned),
f7afe191 2170 "Tab_Info",
68b48a45 2171 tmp_tab,
2172 (GDestroyNotify)tab_destructor);
540edb40 2173
784705cc 2174 //insert tab into notebook
daecc161 2175 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->multi_vpaned, tmp_tab->label);
5723fa24 2176 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2177 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
a43d67ba 2178 // always show : not if(g_list_length(list)>1)
2179 gtk_notebook_set_show_tabs(notebook, TRUE);
2180
5723fa24 2181}
2061e03d 2182
abe346a3 2183
2184/* Remove menu entry and tool button from main window for the
2185 * unloaded module
2186 */
2187
2061e03d 2188void remove_menu_item(gpointer main_win, gpointer user_data)
2189{
bca3b81f 2190 MainWindow * mw = (MainWindow *) main_win;
68b48a45 2191 lttv_menu_closure *menu_item = (lttv_menu_closure *)user_data;
2192 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 2193
bca3b81f 2194 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
2061e03d 2195 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_menu_item,
68b48a45 2196 menu_item->menuText);
2061e03d 2197 if(insert_view){
68b48a45 2198 g_hash_table_remove(mw->hash_menu_item, menu_item->menuText);
2199 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 2200 }
2201}
2202
2203void remove_toolbar_item(gpointer main_win, gpointer user_data)
2204{
bca3b81f 2205 MainWindow * mw = (MainWindow *) main_win;
68b48a45 2206 lttv_toolbar_closure *toolbar_item = (lttv_toolbar_closure *)user_data;
2207 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 2208
2209
efde9138 2210 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
2061e03d 2211 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_toolbar_item,
68b48a45 2212 toolbar_item->tooltip);
2061e03d 2213 if(insert_view){
68b48a45 2214 g_hash_table_remove(mw->hash_toolbar_item, toolbar_item->tooltip);
2215 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 2216 }
2217}
2218
2219/**
abe346a3 2220 * Remove menu and toolbar item when a module unloaded from all
2221 * main windows
2061e03d 2222 */
2176f952 2223
224446ce 2224void main_window_remove_menu_item(lttvwindow_viewer_constructor constructor)
2061e03d 2225{
2226 int i;
2227 LttvMenus * menu;
68b48a45 2228 lttv_menu_closure *menu_item;
2061e03d 2229 LttvAttributeValue value;
2230 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2231
2232 g_assert(lttv_iattribute_find_by_path(attributes,
2233 "viewers/menu", LTTV_POINTER, &value));
2234 menu = (LttvMenus*)*(value.v_pointer);
2235
2236 if(menu){
2237 for(i=0;i<menu->len;i++){
68b48a45 2238 menu_item = &g_array_index(menu, lttv_menu_closure, i);
2239 if(menu_item->con != constructor) continue;
2240 if(g_main_window_list){
2241 g_slist_foreach(g_main_window_list, remove_menu_item, menu_item);
2176f952 2242 }
2061e03d 2243 break;
2244 }
2245 }
2246
2247}
2248
224446ce 2249void main_window_remove_toolbar_item(lttvwindow_viewer_constructor constructor)
2061e03d 2250{
2251 int i;
2252 LttvToolbars * toolbar;
68b48a45 2253 lttv_toolbar_closure *toolbar_item;
2061e03d 2254 LttvAttributeValue value;
2255 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
2256
2257 g_assert(lttv_iattribute_find_by_path(attributes,
2258 "viewers/toolbar", LTTV_POINTER, &value));
2259 toolbar = (LttvToolbars*)*(value.v_pointer);
2260
2261 if(toolbar){
2262 for(i=0;i<toolbar->len;i++){
68b48a45 2263 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
2264 if(toolbar_item->con != constructor) continue;
2265 if(g_main_window_list){
2266 g_slist_foreach(g_main_window_list, remove_toolbar_item, toolbar_item);
2176f952 2267 }
2061e03d 2268 break;
2269 }
2270 }
2271}
a43d67ba 2272
2273/**
2274 * Function to show each viewer in the current tab.
2275 * It will be called by main window, call show on each registered viewer,
2276 * will call process traceset and then it will
2277 * @param main_win the main window the viewer belongs to.
2278 */
2279//FIXME Only one time request maximum for now!
2280void show_viewer(MainWindow *main_win)
2281{
2282 LttvAttributeValue value;
2283 LttvHooks * tmp;
2284 int i;
2285 LttvTracesetContext * tsc =
2286 (LttvTracesetContext*)main_win->current_tab->
2287 traceset_info->traceset_context;
2288
2289 g_assert(lttv_iattribute_find_by_path(main_win->current_tab->attributes,
2290 "hooks/showviewer", LTTV_POINTER, &value));
2291 tmp = (LttvHooks*)*(value.v_pointer);
2292 if(tmp == NULL)
2293 {
2294 g_warning("The viewer(s) did not add any show hook");
2295 return;
2296 }
2297
2298
2299 // Call the show, where viewers add hooks to context and fill the
2300 // time and number of events requested it the time_requests GArray.
2301 lttv_hooks_call(tmp, NULL);
2302
2303
2304}
2305
2306
2307gboolean execute_time_requests(MainWindow * mw)
2308{
2309 call_pending_read_hooks(mw);
2310
2311 return FALSE; // automatically removed from the list of event sources
2312}
2313
This page took 0.146597 seconds and 4 git commands to generate.