toolbar menus now add/remove symmetrical
[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);
001d8606 1236 g_slist_foreach(g_main_window_list, (gpointer)update_menu_toolbar_constructors,
f2d17b4d 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){
001d8606 1281 lttv_library_unload(library);
1282 g_slist_foreach(g_main_window_list,
1283 (gpointer)update_menu_toolbar_constructors,
1284 NULL);
36b3c068 1285 break;
1286 }
1287 }
1288 }
1289
08b1c66e 1290 g_ptr_array_free(name, TRUE);
561eba2a 1291}
1292
1293
abe346a3 1294/* Display a directory dialogue to let user select a path for module searching
1295 */
1296
561eba2a 1297void
1298on_add_module_search_path_activate (GtkMenuItem *menuitem,
1299 gpointer user_data)
1300{
68b48a45 1301 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
67b98724 1302 const char * dir;
fc188b78 1303 gint id;
1304
bca3b81f 1305 MainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
3658a338 1306 if(remember_plugins_dir[0] != '\0')
1307 gtk_dir_selection_set_filename(file_selector, remember_plugins_dir);
fc188b78 1308
68b48a45 1309 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 1310 switch(id){
1311 case GTK_RESPONSE_ACCEPT:
1312 case GTK_RESPONSE_OK:
68b48a45 1313 dir = gtk_dir_selection_get_dir (file_selector);
3658a338 1314 strncpy(remember_plugins_dir,dir,PATH_LENGTH);
1315 strncat(remember_plugins_dir,"/",PATH_LENGTH);
08b1c66e 1316 lttv_library_path_add(dir);
fc188b78 1317 case GTK_RESPONSE_REJECT:
1318 case GTK_RESPONSE_CANCEL:
1319 default:
68b48a45 1320 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 1321 break;
6b1d3120 1322 }
561eba2a 1323}
1324
1325
1326void
1327on_color_activate (GtkMenuItem *menuitem,
1328 gpointer user_data)
1329{
1330 g_printf("Color\n");
1331}
1332
1333
1334void
1335on_filter_activate (GtkMenuItem *menuitem,
1336 gpointer user_data)
1337{
1338 g_printf("Filter\n");
1339}
1340
1341
1342void
1343on_save_configuration_activate (GtkMenuItem *menuitem,
1344 gpointer user_data)
1345{
1346 g_printf("Save configuration\n");
1347}
1348
1349
1350void
1351on_content_activate (GtkMenuItem *menuitem,
1352 gpointer user_data)
1353{
1354 g_printf("Content\n");
1355}
1356
1357
1358void
1359on_about_activate (GtkMenuItem *menuitem,
1360 gpointer user_data)
1361{
1362 g_printf("About...\n");
1363}
1364
1365
1366void
1367on_button_new_clicked (GtkButton *button,
1368 gpointer user_data)
1369{
6f7ad7ae 1370 create_new_window((GtkWidget*)button, user_data, TRUE);
561eba2a 1371}
1372
2901f314 1373void
1374on_button_new_tab_clicked (GtkButton *button,
1375 gpointer user_data)
1376{
1377 create_new_tab((GtkWidget*)button, user_data);
1378}
561eba2a 1379
1380void
1381on_button_open_clicked (GtkButton *button,
1382 gpointer user_data)
1383{
1384 open_traceset((GtkWidget*)button, user_data);
1385}
1386
1387
1388void
1389on_button_add_trace_clicked (GtkButton *button,
1390 gpointer user_data)
1391{
1392 add_trace((GtkWidget*)button, user_data);
1393}
1394
1395
1396void
1397on_button_remove_trace_clicked (GtkButton *button,
1398 gpointer user_data)
1399{
1400 remove_trace((GtkWidget*)button, user_data);
1401}
1402
1403
1404void
1405on_button_save_clicked (GtkButton *button,
1406 gpointer user_data)
1407{
1408 save((GtkWidget*)button, user_data);
1409}
1410
1411
1412void
1413on_button_save_as_clicked (GtkButton *button,
1414 gpointer user_data)
1415{
1416 save_as((GtkWidget*)button, user_data);
1417}
1418
1419
1420void
1421on_button_zoom_in_clicked (GtkButton *button,
1422 gpointer user_data)
1423{
1424 zoom_in((GtkWidget*)button, user_data);
1425}
1426
1427
1428void
1429on_button_zoom_out_clicked (GtkButton *button,
1430 gpointer user_data)
1431{
1432 zoom_out((GtkWidget*)button, user_data);
1433}
1434
1435
1436void
1437on_button_zoom_extended_clicked (GtkButton *button,
1438 gpointer user_data)
1439{
1440 zoom_extended((GtkWidget*)button, user_data);
1441}
1442
1443
1444void
1445on_button_go_to_time_clicked (GtkButton *button,
1446 gpointer user_data)
1447{
1448 go_to_time((GtkWidget*)button, user_data);
1449}
1450
1451
1452void
1453on_button_show_time_frame_clicked (GtkButton *button,
1454 gpointer user_data)
1455{
1456 show_time_frame((GtkWidget*)button, user_data);
1457}
1458
1459
1460void
1461on_button_move_up_clicked (GtkButton *button,
1462 gpointer user_data)
1463{
1464 move_up_viewer((GtkWidget*)button, user_data);
1465}
1466
1467
1468void
1469on_button_move_down_clicked (GtkButton *button,
1470 gpointer user_data)
1471{
1472 move_down_viewer((GtkWidget*)button, user_data);
1473}
1474
1475
1476void
1477on_button_delete_viewer_clicked (GtkButton *button,
1478 gpointer user_data)
1479{
1480 delete_viewer((GtkWidget*)button, user_data);
1481}
1482
1483void
1484on_MWindow_destroy (GtkObject *object,
1485 gpointer user_data)
1486{
e4d09234 1487 MainWindow *Main_Window = get_window_data_struct((GtkWidget*)object);
1488 GtkWidget *widget;
1489 Tab *tab = Main_Window->tab;
1490
68b48a45 1491 g_printf("There are : %d windows\n",g_slist_length(g_main_window_list));
561eba2a 1492
68b48a45 1493 g_win_count--;
1494 if(g_win_count == 0)
7a859036 1495 gtk_main_quit ();
561eba2a 1496}
1497
58eecf4a 1498gboolean
1499on_MWindow_configure (GtkWidget *widget,
1500 GdkEventConfigure *event,
1501 gpointer user_data)
1502{
1503 MainWindow * mw_data = get_window_data_struct((GtkWidget*)widget);
1504 float width = event->width;
1505 Tab * tab = mw_data->tab;
1506 TimeWindow time_win;
1507 double ratio;
1508 TimeInterval *time_span;
1509 LttTime time;
bd24a9af 1510
1511 // MD : removed time width modification upon resizing of the main window.
1512 // The viewers will redraw themselves completely, without time interval
1513 // modification.
1514/* while(tab){
58eecf4a 1515 if(mw_data->window_width){
1516 time_span = LTTV_TRACESET_CONTEXT(tab->traceset_info->traceset_context)->Time_Span ;
1517 time_win = tab->time_window;
1518 ratio = width / mw_data->window_width;
1519 tab->time_window.time_width = ltt_time_mul(time_win.time_width,ratio);
1520 time = ltt_time_sub(time_span->endTime, time_win.start_time);
1521 if(ltt_time_compare(time, tab->time_window.time_width) < 0){
1522 tab->time_window.time_width = time;
1523 }
1524 }
1525 tab = tab->next;
1526 }
1527
1528 mw_data->window_width = (int)width;
bd24a9af 1529 */
58eecf4a 1530 return FALSE;
1531}
561eba2a 1532
abe346a3 1533/* Set current tab
1534 */
1535
561eba2a 1536void
1537on_MNotebook_switch_page (GtkNotebook *notebook,
1538 GtkNotebookPage *page,
1539 guint page_num,
1540 gpointer user_data)
1541{
bca3b81f 1542 MainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
1543 Tab * tab = mw->tab;
561eba2a 1544
1545 while(page_num){
bca3b81f 1546 tab = tab->next;
561eba2a 1547 page_num--;
1548 }
bca3b81f 1549 mw->current_tab = tab;
561eba2a 1550}
1551
abe346a3 1552
1553/* callback function to check or uncheck the check box (filter)
1554 */
1555
49bf71b5 1556void checkbox_changed(GtkTreeView *treeview,
1557 GtkTreePath *arg1,
1558 GtkTreeViewColumn *arg2,
1559 gpointer user_data)
1560{
1561 GtkTreeStore * store = (GtkTreeStore *)gtk_tree_view_get_model (treeview);
1562 GtkTreeIter iter;
1563 gboolean value;
1564
1565 if (gtk_tree_model_get_iter ((GtkTreeModel *)store, &iter, arg1)){
1566 gtk_tree_model_get ((GtkTreeModel *)store, &iter, CHECKBOX_COLUMN, &value, -1);
1567 value = value? FALSE : TRUE;
1568 gtk_tree_store_set (GTK_TREE_STORE (store), &iter, CHECKBOX_COLUMN, value, -1);
1569 }
1570
1571}
1572
abe346a3 1573
1574/* According to user's selection, update selector(filter)
1575 */
1576
49bf71b5 1577void update_filter(LttvTracesetSelector *s, GtkTreeStore *store )
1578{
ed3b99b6 1579 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1580 int i, j, k, nb_eventtype;
49bf71b5 1581 LttvTraceSelector * trace;
1582 LttvTracefileSelector * tracefile;
ed3b99b6 1583 LttvEventtypeSelector * eventtype;
1584 gboolean value, value1, value2;
49bf71b5 1585
1586 if(gtk_tree_model_get_iter_first((GtkTreeModel*)store, &iter)){
1587 i = 0;
1588 do{
ed3b99b6 1589 trace = lttv_traceset_selector_trace_get(s, i);
1590 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
49bf71b5 1591 gtk_tree_model_get ((GtkTreeModel*)store, &iter, CHECKBOX_COLUMN, &value,-1);
1592 if(value){
1593 j = 0;
1594 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter, &iter)){
1595 do{
ed3b99b6 1596 if(j<1){//eventtype selector for trace
1597 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value2,-1);
1598 if(value2){
1599 k=0;
1600 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter1, &child_iter)){
1601 do{
1602 eventtype = lttv_trace_selector_eventtype_get(trace,k);
1603 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1604 lttv_eventtype_selector_set_selected(eventtype,value2);
1605 k++;
1606 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter1));
1607 }
1608 }
1609 }else{ //tracefile selector
1610 tracefile = lttv_trace_selector_tracefile_get(trace, j - 1);
1611 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter, CHECKBOX_COLUMN, &value1,-1);
1612 lttv_tracefile_selector_set_selected(tracefile,value1);
1613 if(value1){
1614 gtk_tree_model_iter_children((GtkTreeModel*)store, &child_iter1, &child_iter); //eventtype selector
1615 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter1, CHECKBOX_COLUMN, &value2,-1);
1616 if(value2){
1617 k = 0;
1618 if(gtk_tree_model_iter_children ((GtkTreeModel*)store, &child_iter2, &child_iter1)){
1619 do{//eventtype selector for tracefile
1620 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1621 gtk_tree_model_get ((GtkTreeModel*)store, &child_iter2, CHECKBOX_COLUMN, &value2,-1);
1622 lttv_eventtype_selector_set_selected(eventtype,value2);
1623 k++;
1624 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter2));
1625 }
1626 }
1627 }
1628 }
49bf71b5 1629 j++;
1630 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &child_iter));
1631 }
1632 }
1633 lttv_trace_selector_set_selected(trace,value);
1634 i++;
1635 }while(gtk_tree_model_iter_next((GtkTreeModel*)store, &iter));
1636 }
1637}
1638
abe346a3 1639
1640/* Display a dialogue showing all eventtypes and traces, let user to select the interested
1641 * eventtypes, tracefiles and traces (filter)
1642 */
1643
a8c0f09d 1644gboolean get_filter_selection(LttvTracesetSelector *s,char *title, char * column_title)
49bf71b5 1645{
1646 GtkWidget * dialogue;
1647 GtkTreeStore * store;
1648 GtkWidget * tree;
1649 GtkWidget * scroll_win;
1650 GtkCellRenderer * renderer;
1651 GtkTreeViewColumn * column;
ed3b99b6 1652 GtkTreeIter iter, child_iter, child_iter1, child_iter2;
1653 int i, j, k, id, nb_trace, nb_tracefile, nb_eventtype;
49bf71b5 1654 LttvTraceSelector * trace;
1655 LttvTracefileSelector * tracefile;
ed3b99b6 1656 LttvEventtypeSelector * eventtype;
49bf71b5 1657 char * name;
1658 gboolean checked;
1659
1660 dialogue = gtk_dialog_new_with_buttons(title,
1661 NULL,
1662 GTK_DIALOG_MODAL,
1663 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1664 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1665 NULL);
ed3b99b6 1666 gtk_window_set_default_size((GtkWindow*)dialogue, 300, 500);
49bf71b5 1667
1668 store = gtk_tree_store_new (TOTAL_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
1669 tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
1670 g_object_unref (G_OBJECT (store));
1671 g_signal_connect (G_OBJECT (tree), "row-activated",
1672 G_CALLBACK (checkbox_changed),
1673 NULL);
1674
1675
1676 renderer = gtk_cell_renderer_toggle_new ();
1677 gtk_cell_renderer_toggle_set_radio((GtkCellRendererToggle *)renderer, FALSE);
1678
1679 g_object_set (G_OBJECT (renderer),"activatable", TRUE, NULL);
1680
1681 column = gtk_tree_view_column_new_with_attributes ("Checkbox",
1682 renderer,
1683 "active", CHECKBOX_COLUMN,
1684 NULL);
1685 gtk_tree_view_column_set_alignment (column, 0.5);
1686 gtk_tree_view_column_set_fixed_width (column, 20);
1687 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1688
1689 renderer = gtk_cell_renderer_text_new ();
1690 column = gtk_tree_view_column_new_with_attributes (column_title,
1691 renderer,
1692 "text", NAME_COLUMN,
1693 NULL);
1694 gtk_tree_view_column_set_alignment (column, 0.0);
1695 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1696 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (tree), FALSE);
1697
1698 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1699 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1700 GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
1701 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1702
1703 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1704
1705 gtk_widget_show(scroll_win);
1706 gtk_widget_show(tree);
1707
ed3b99b6 1708 nb_trace = lttv_traceset_selector_trace_number(s);
49bf71b5 1709 for(i=0;i<nb_trace;i++){
ed3b99b6 1710 trace = lttv_traceset_selector_trace_get(s, i);
49bf71b5 1711 name = lttv_trace_selector_get_name(trace);
1712 gtk_tree_store_append (store, &iter, NULL);
1713 checked = lttv_trace_selector_get_selected(trace);
1714 gtk_tree_store_set (store, &iter,
1715 CHECKBOX_COLUMN,checked,
1716 NAME_COLUMN,name,
1717 -1);
ed3b99b6 1718
1719 gtk_tree_store_append (store, &child_iter, &iter);
1720 gtk_tree_store_set (store, &child_iter,
1721 CHECKBOX_COLUMN, checked,
1722 NAME_COLUMN,"eventtype",
1723 -1);
1724
1725 nb_eventtype = lttv_trace_selector_eventtype_number(trace);
1726 for(j=0;j<nb_eventtype;j++){
1727 eventtype = lttv_trace_selector_eventtype_get(trace,j);
1728 name = lttv_eventtype_selector_get_name(eventtype);
1729 checked = lttv_eventtype_selector_get_selected(eventtype);
1730 gtk_tree_store_append (store, &child_iter1, &child_iter);
1731 gtk_tree_store_set (store, &child_iter1,
1732 CHECKBOX_COLUMN, checked,
1733 NAME_COLUMN,name,
1734 -1);
1735 }
1736
1737 nb_tracefile = lttv_trace_selector_tracefile_number(trace);
49bf71b5 1738 for(j=0;j<nb_tracefile;j++){
ed3b99b6 1739 tracefile = lttv_trace_selector_tracefile_get(trace, j);
49bf71b5 1740 name = lttv_tracefile_selector_get_name(tracefile);
1741 gtk_tree_store_append (store, &child_iter, &iter);
1742 checked = lttv_tracefile_selector_get_selected(tracefile);
1743 gtk_tree_store_set (store, &child_iter,
1744 CHECKBOX_COLUMN, checked,
1745 NAME_COLUMN,name,
1746 -1);
ed3b99b6 1747
1748 gtk_tree_store_append (store, &child_iter1, &child_iter);
1749 gtk_tree_store_set (store, &child_iter1,
1750 CHECKBOX_COLUMN, checked,
1751 NAME_COLUMN,"eventtype",
1752 -1);
1753
1754 for(k=0;k<nb_eventtype;k++){
1755 eventtype = lttv_tracefile_selector_eventtype_get(tracefile,k);
1756 name = lttv_eventtype_selector_get_name(eventtype);
1757 checked = lttv_eventtype_selector_get_selected(eventtype);
1758 gtk_tree_store_append (store, &child_iter2, &child_iter1);
1759 gtk_tree_store_set (store, &child_iter2,
1760 CHECKBOX_COLUMN, checked,
1761 NAME_COLUMN,name,
1762 -1);
1763 }
49bf71b5 1764 }
1765 }
1766
1767 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1768 switch(id){
1769 case GTK_RESPONSE_ACCEPT:
1770 case GTK_RESPONSE_OK:
1771 update_filter(s, store);
a8c0f09d 1772 gtk_widget_destroy(dialogue);
1773 return TRUE;
49bf71b5 1774 case GTK_RESPONSE_REJECT:
1775 case GTK_RESPONSE_CANCEL:
1776 default:
1777 gtk_widget_destroy(dialogue);
1778 break;
1779 }
a8c0f09d 1780 return FALSE;
49bf71b5 1781}
1782
abe346a3 1783
1784/* Select a trace which will be removed from traceset
1785 */
1786
2176f952 1787char * get_remove_trace(char ** all_trace_name, int nb_trace)
1788{
1789 return get_selection(all_trace_name, nb_trace,
1790 "Select a trace", "Trace pathname");
1791}
abe346a3 1792
1793
1794/* Select a module which will be unloaded
1795 */
1796
36b3c068 1797char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 1798{
1799 return get_selection(loaded_module_name, nb_module,
1800 "Select an unload module", "Module pathname");
1801}
1802
abe346a3 1803
1804/* Display a dialogue which shows all selectable items, let user to
1805 * select one of them
1806 */
1807
2176f952 1808char * get_selection(char ** loaded_module_name, int nb_module,
1809 char *title, char * column_title)
36b3c068 1810{
1811 GtkWidget * dialogue;
1812 GtkWidget * scroll_win;
1813 GtkWidget * tree;
1814 GtkListStore * store;
1815 GtkTreeViewColumn * column;
1816 GtkCellRenderer * renderer;
1817 GtkTreeSelection * select;
1818 GtkTreeIter iter;
1819 gint id, i;
1820 char * unload_module_name = NULL;
1821
2176f952 1822 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 1823 NULL,
1824 GTK_DIALOG_MODAL,
1825 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
1826 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
1827 NULL);
1828 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
1829
1830 scroll_win = gtk_scrolled_window_new (NULL, NULL);
1831 gtk_widget_show ( scroll_win);
1832 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
1833 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1834
1835 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
1836 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
1837 gtk_widget_show ( tree);
1838 g_object_unref (G_OBJECT (store));
1839
1840 renderer = gtk_cell_renderer_text_new ();
2176f952 1841 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 1842 renderer,
1843 "text", MODULE_COLUMN,
1844 NULL);
1845 gtk_tree_view_column_set_alignment (column, 0.5);
1846 gtk_tree_view_column_set_fixed_width (column, 150);
1847 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
1848
1849 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
1850 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
1851
1852 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
1853
1854 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
1855
1856 for(i=0;i<nb_module;i++){
1857 gtk_list_store_append (store, &iter);
1858 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
1859 }
1860
1861 id = gtk_dialog_run(GTK_DIALOG(dialogue));
1862 switch(id){
1863 case GTK_RESPONSE_ACCEPT:
1864 case GTK_RESPONSE_OK:
1865 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
1866 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
1867 }
1868 case GTK_RESPONSE_REJECT:
1869 case GTK_RESPONSE_CANCEL:
1870 default:
1871 gtk_widget_destroy(dialogue);
1872 break;
1873 }
1874
1875 return unload_module_name;
1876}
5723fa24 1877
abe346a3 1878
001d8606 1879/* Insert or remove all menu entry and tool buttons into all main windows
1880 * for modules.
1881 *
1882 * It adds them in a hash table as well, so it can keep track of which
1883 * menu entries and buttons are currently in each main window, for later
1884 * removal.
abe346a3 1885 */
1886
001d8606 1887void update_menu_toolbar_constructors(MainWindow * mw, gpointer user_data)
5723fa24 1888{
1889 int i;
1890 GdkPixbuf *pixbuf;
42fcbb71 1891 lttvwindow_viewer_constructor constructor;
001d8606 1892 LttvMenus * global_menu, * instance_menu;
1893 LttvToolbars * global_toolbar, * instance_toolbar;
1894 LttvMenuClosure *menu_item_i, *menu_item_j;
1895 LttvToolbarClosure *toolbar_item_i, *toolbar_item_j;
5723fa24 1896 LttvAttributeValue value;
001d8606 1897 LttvIAttribute *global_attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
1898 LttvIAttribute *attributes = LTTV_IATTRIBUTES(mw->attributes);
1899 GtkWidget * tool_menu_title_menu, *new_widget, *pixmap;
1900
1901 g_assert(lttv_iattribute_find_by_path(global_attributes,
1902 "viewers/menu", LTTV_POINTER, &value));
1903 if(*(value.v_pointer) == NULL)
1904 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
1905 global_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 1906
1907 g_assert(lttv_iattribute_find_by_path(attributes,
1908 "viewers/menu", LTTV_POINTER, &value));
001d8606 1909 if(*(value.v_pointer) == NULL)
1910 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
1911 instance_menu = (LttvMenus*)*(value.v_pointer);
5723fa24 1912
001d8606 1913
1914
1915 g_assert(lttv_iattribute_find_by_path(global_attributes,
1916 "viewers/toolbar", LTTV_POINTER, &value));
1917 if(*(value.v_pointer) == NULL)
1918 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
1919 global_toolbar = (LttvToolbars*)*(value.v_pointer);
1920
1921 g_assert(lttv_iattribute_find_by_path(attributes,
1922 "viewers/toolbar", LTTV_POINTER, &value));
1923 if(*(value.v_pointer) == NULL)
1924 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
1925 instance_toolbar = (LttvToolbars*)*(value.v_pointer);
1926
1927 /* Add missing menu entries to window instance */
1928 for(i=0;i<global_menu->len;i++) {
1929 menu_item_i = &g_array_index(global_menu, LttvMenuClosure, i);
1930
1931 for(j=0;j<instance_menu->len;j++) {
1932 menu_item_j = &g_array_index(instance_menu, LttvMenuClosure, j);
1933
1934 if(menu_item_i->con == menu_item_j->con)
1935 break;
1936 }
1937 if(j == instance_menu->len) /* not found */
1938 {
1939 //add menu_item_i to window instance;
68b48a45 1940 constructor = menu_item->con;
bca3b81f 1941 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
001d8606 1942 new_widget =
1943 gtk_menu_item_new_with_mnemonic (menu_item_i->menuText);
1944 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu),
1945 new_widget);
1946 g_signal_connect ((gpointer) new_widget, "activate",
1947 G_CALLBACK (insert_viewer_wrap),
1948 constructor);
1949 gtk_widget_show (new_widget);
1950 lttv_menus_add(instance_menu, menu_item_i->con,
1951 menu_item_i->menu_path,
1952 menu_item_i->menu_text,
1953 new_widget);
5723fa24 1954 }
001d8606 1955
5723fa24 1956 }
1957
001d8606 1958 /* Remove missing menu entries from window instance */
1959 for(i=0;i<instance_menu->len;i++) {
1960 menu_item_i = &g_array_index(instance_menu, LttvMenuClosure, i);
1961
1962 for(j=0;j<global_menu->len;j++) {
1963 menu_item_j = &g_array_index(global_menu, LttvMenuClosure, j);
1964
1965 if(menu_item_i->con == menu_item_j->con)
1966 break;
1967 }
1968 if(j == global_menu->len) /* not found */
1969 {
1970 //remove menu_item_i from window instance;
1971 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
1972 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu),
1973 menu_item_i->widget);
1974 lttv_menus_remove(instance_menu, menu_item_i->con);
1975 }
1976 }
1977
1978 /* Add missing toolbar entries to window instance */
1979 for(i=0;i<global_toolbar->len;i++) {
1980 toolbar_item_i = &g_array_index(global_toolbar, LttvToolbarClosure, i);
5723fa24 1981
001d8606 1982 for(j=0;j<instance_toolbar->len;j++) {
1983 toolbar_item_j = &g_array_index(instance_toolbar, LttvToolbarClosure, j);
1984
1985 if(toolbar_item_i->con == toolbar_item_j->con)
1986 break;
1987 }
1988 if(j == instance_toolbar->len) /* not found */
1989 {
1990 //add toolbar_item_i to window instance;
68b48a45 1991 constructor = toolbar_item->con;
efde9138 1992 tool_menu_title_menu = lookup_widget(mw->mwindow,"MToolbar1");
001d8606 1993 pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)toolbar_item->pixmap);
5723fa24 1994 pixmap = gtk_image_new_from_pixbuf(pixbuf);
001d8606 1995 new_widget =
1996 gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
1997 GTK_TOOLBAR_CHILD_BUTTON,
1998 NULL,
1999 "",
2000 toolbar_item->tooltip, NULL,
2001 pixmap, NULL, NULL);
2002 gtk_label_set_use_underline(
2003 GTK_LABEL (((GtkToolbarChild*) (
2004 g_list_last (GTK_TOOLBAR
2005 (tool_menu_title_menu)->children)->data))->label),
2006 TRUE);
2007 gtk_container_set_border_width (GTK_CONTAINER (new_widget), 1);
2008 g_signal_connect ((gpointer) new_widget,
2009 "clicked",
2010 G_CALLBACK (insert_viewer_wrap),
2011 constructor);
2012 gtk_widget_show (new_widget);
2013
2014 lttv_toolbars_add(instance_toolbar, toolbar_item_i->con,
2015 toolbar_item_i->tooltip,
2016 toolbar_item_i->pixmap,
2017 new_widget);
2018
2019 }
2020 }
2021
2022 /* Remove missing toolbar entries from window instance */
2023 for(i=0;i<instance_toolbar->len;i++) {
2024 toolbar_item_i = &g_array_index(instance_toolbar, LttvToolbarClosure, i);
2025
2026 for(j=0;j<global_toolbar->len;j++) {
2027 toolbar_item_j = &g_array_index(global_toolbar, LttvToolbarClosure, j);
2028
2029 if(toolbar_item_i->con == toolbar_item_j->con)
2030 break;
2031 }
2032 if(j == global_toolbar->len) /* not found */
2033 {
2034 //remove toolbar_item_i from window instance;
2035 tool_menu_title_menu = lookup_widget(mw->mwindow,"ToolMenuTitle_menu");
2036 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu),
2037 toolbar_item_i->widget);
2038 lttv_toolbars_remove(instance_toolbar, toolbar_item_i->con);
5723fa24 2039 }
2040 }
2041}
2042
abe346a3 2043
2044/* Create a main window
2045 */
2046
08b1c66e 2047void construct_main_window(MainWindow * parent)
5723fa24 2048{
2a2fa4f0 2049 g_debug("construct_main_window()");
68b48a45 2050 GtkWidget * new_window; /* New generated main window */
bca3b81f 2051 MainWindow * new_m_window;/* New main window structure */
5723fa24 2052 GtkNotebook * notebook;
f7afe191 2053 LttvIAttribute *attributes =
2054 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
2055 LttvAttributeValue value;
2061e03d 2056
bca3b81f 2057 new_m_window = g_new(MainWindow, 1);
5723fa24 2058
2059 // Add the object's information to the module's array
68b48a45 2060 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 2061
f7afe191 2062
68b48a45 2063 new_window = create_MWindow();
2064 gtk_widget_show (new_window);
5723fa24 2065
bca3b81f 2066 new_m_window->mwindow = new_window;
2067 new_m_window->tab = NULL;
2068 new_m_window->current_tab = NULL;
a43d67ba 2069 new_m_window->attributes = attributes;
5723fa24 2070
001d8606 2071 g_assert(lttv_iattribute_find_by_path(attributes,
2072 "viewers/menu", LTTV_POINTER, &value));
2073 (LttvMenus*)*(value.v_pointer) = lttv_menus_new();
2074
2075 g_assert(lttv_iattribute_find_by_path(attributes_global,
2076 "viewers/toolbar", LTTV_POINTER, &value));
2077 (LttvToolbars*)*(value.v_pointer) = lttv_toolbars_new();
2061e03d 2078
001d8606 2079 update_menu_toolbar_constructors(new_m_window, NULL);
5723fa24 2080
68b48a45 2081 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
5723fa24 2082 //create a default tab
bca3b81f 2083 notebook = (GtkNotebook *)lookup_widget(new_m_window->mwindow, "MNotebook");
5723fa24 2084 if(notebook == NULL){
2085 g_printf("Notebook does not exist\n");
2086 return;
2087 }
2088 //for now there is no name field in LttvTraceset structure
2089 //Use "Traceset" as the label for the default tab
a43d67ba 2090 create_tab(parent, new_m_window, notebook, "Traceset");
5723fa24 2091
7a859036 2092 g_object_set_data_full(
bca3b81f 2093 G_OBJECT(new_m_window->mwindow),
7a859036 2094 "Main_Window_Data",
68b48a45 2095 new_m_window,
2096 (GDestroyNotify)main_window_free);
7a859036 2097
68b48a45 2098 g_win_count++;
5723fa24 2099}
2100
abe346a3 2101
2102/* Free the memory occupied by a tab structure
2103 * destroy the tab
2104 */
2105
bca3b81f 2106void tab_destructor(Tab * tab_instance)
f7afe191 2107{
716e4367 2108 int i, nb, ref_count;
2109 LttvTrace * trace;
2110
bca3b81f 2111 if(tab_instance->attributes)
2112 g_object_unref(tab_instance->attributes);
2061e03d 2113
bca3b81f 2114 if(tab_instance->mw->tab == tab_instance){
2115 tab_instance->mw->tab = tab_instance->next;
2061e03d 2116 }else{
bca3b81f 2117 Tab * tmp1, *tmp = tab_instance->mw->tab;
68b48a45 2118 while(tmp != tab_instance){
2061e03d 2119 tmp1 = tmp;
bca3b81f 2120 tmp = tmp->next;
2061e03d 2121 }
bca3b81f 2122 tmp1->next = tab_instance->next;
2061e03d 2123 }
716e4367 2124
2125 if(tab_instance->traceset_info->traceset_context != NULL){
784705cc 2126 //remove state update hooks
2127 lttv_state_remove_event_hooks(
2128 (LttvTracesetState*)tab_instance->traceset_info->
2129 traceset_context);
716e4367 2130 lttv_context_fini(LTTV_TRACESET_CONTEXT(tab_instance->traceset_info->
2131 traceset_context));
2132 g_object_unref(tab_instance->traceset_info->traceset_context);
2133 }
2134 if(tab_instance->traceset_info->traceset != NULL) {
2135 nb = lttv_traceset_number(tab_instance->traceset_info->traceset);
2136 for(i = 0 ; i < nb ; i++) {
2137 trace = lttv_traceset_get(tab_instance->traceset_info->traceset, i);
2138 ref_count = lttv_trace_get_ref_number(trace);
49bf71b5 2139 if(ref_count <= 1){
716e4367 2140 ltt_trace_close(lttv_trace(trace));
6f7ad7ae 2141 lttv_trace_destroy(trace);
49bf71b5 2142 }
6f7ad7ae 2143 // lttv_trace_destroy(trace);
716e4367 2144 }
2145 }
a43d67ba 2146 lttv_traceset_destroy(tab_instance->traceset_info->traceset);
2147 g_array_free(tab_instance->time_requests, TRUE);
716e4367 2148 g_free(tab_instance->traceset_info);
68b48a45 2149 g_free(tab_instance);
f7afe191 2150}
2151
abe346a3 2152
2153/* Create a tab and insert it into the current main window
2154 */
2155
716e4367 2156void * create_tab(MainWindow * parent, MainWindow* current_window,
2157 GtkNotebook * notebook, char * label)
5723fa24 2158{
2159 GList * list;
bca3b81f 2160 Tab * tmp_tab;
716e4367 2161 MainWindow * mw_data = current_window;
68b48a45 2162 LttTime tmp_time;
a43d67ba 2163
abe346a3 2164 //create a new tab data structure
bca3b81f 2165 tmp_tab = mw_data->tab;
2166 while(tmp_tab && tmp_tab->next) tmp_tab = tmp_tab->next;
68b48a45 2167 if(!tmp_tab){
bca3b81f 2168 mw_data->current_tab = NULL;
2169 tmp_tab = g_new(Tab,1);
2170 mw_data->tab = tmp_tab;
5723fa24 2171 }else{
bca3b81f 2172 tmp_tab->next = g_new(Tab,1);
2173 tmp_tab = tmp_tab->next;
5723fa24 2174 }
716e4367 2175
abe346a3 2176 //construct and initialize the traceset_info
716e4367 2177 tmp_tab->traceset_info = g_new(TracesetInfo,1);
2178 if(parent){
a43d67ba 2179 if(parent->current_tab){
2180 tmp_tab->traceset_info->traceset =
2181 lttv_traceset_new();
2182 //FIXME lttv_traceset_copy(parent->current_tab->traceset_info->traceset);
2183 }else{
2184 tmp_tab->traceset_info->traceset = lttv_traceset_new();
2185 }
2186
2187 }else{ /* Initial window */
716e4367 2188 if(mw_data->current_tab){
2189 tmp_tab->traceset_info->traceset =
a43d67ba 2190 lttv_traceset_new();
2191 //FIXME lttv_traceset_copy(mw_data->current_tab->traceset_info->traceset);
716e4367 2192 }else{
2193 tmp_tab->traceset_info->traceset = lttv_traceset_new();
49bf71b5 2194 /* Add the command line trace */
a43d67ba 2195 if(g_init_trace != NULL){
49bf71b5 2196 lttv_traceset_add(tmp_tab->traceset_info->traceset, g_init_trace);
a43d67ba 2197 }
716e4367 2198 }
716e4367 2199 }
a43d67ba 2200
716e4367 2201 //FIXME copy not implemented in lower level
2202 tmp_tab->traceset_info->traceset_context =
2203 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
a43d67ba 2204 g_assert(tmp_tab->traceset_info->traceset_context != NULL);
716e4367 2205 lttv_context_init(
2206 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context),
2207 tmp_tab->traceset_info->traceset);
784705cc 2208 //add state update hooks
2209 lttv_state_add_event_hooks(
2210 (LttvTracesetState*)tmp_tab->traceset_info->traceset_context);
2211
abe346a3 2212 //determine the current_time and time_window of the tab
bca3b81f 2213 if(mw_data->current_tab){
716e4367 2214 // Will have to read directly at the main window level, as we want
2215 // to be able to modify a traceset on the fly.
bca3b81f 2216 tmp_tab->time_window = mw_data->current_tab->time_window;
2217 tmp_tab->current_time = mw_data->current_tab->current_time;
5723fa24 2218 }else{
716e4367 2219 // Will have to read directly at the main window level, as we want
2220 // to be able to modify a traceset on the fly.
2221 // get_traceset_time_span(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
bca3b81f 2222 tmp_tab->time_window.start_time =
716e4367 2223 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime;
f7afe191 2224 if(DEFAULT_TIME_WIDTH_S <
716e4367 2225 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec)
68b48a45 2226 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 2227 else
68b48a45 2228 tmp_time.tv_sec =
716e4367 2229 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->endTime.tv_sec;
68b48a45 2230 tmp_time.tv_nsec = 0;
bca3b81f 2231 tmp_tab->time_window.time_width = tmp_time ;
a8c0f09d 2232 tmp_tab->current_time.tv_sec =
2233 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_sec;
2234 tmp_tab->current_time.tv_nsec =
2235 LTTV_TRACESET_CONTEXT(tmp_tab->traceset_info->traceset_context)->Time_Span->startTime.tv_nsec;
5723fa24 2236 }
a43d67ba 2237 /* Become the current tab */
2238 mw_data->current_tab = tmp_tab;
2239
bca3b81f 2240 tmp_tab->attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
daecc161 2241 tmp_tab->multi_vpaned = (GtkMultiVPaned*)gtk_multi_vpaned_new();
2242 tmp_tab->multi_vpaned->mw = mw_data;
2243 gtk_widget_show((GtkWidget*)tmp_tab->multi_vpaned);
bca3b81f 2244 tmp_tab->next = NULL;
68b48a45 2245 tmp_tab->mw = mw_data;
5723fa24 2246
68b48a45 2247 tmp_tab->label = gtk_label_new (label);
2248 gtk_widget_show (tmp_tab->label);
5723fa24 2249
a43d67ba 2250 tmp_tab->time_requests = g_array_new(FALSE, FALSE, sizeof(TimeRequest));
2251 tmp_tab->time_request_pending = FALSE;
2252
f7afe191 2253 g_object_set_data_full(
daecc161 2254 G_OBJECT(tmp_tab->multi_vpaned),
f7afe191 2255 "Tab_Info",
68b48a45 2256 tmp_tab,
2257 (GDestroyNotify)tab_destructor);
540edb40 2258
784705cc 2259 //insert tab into notebook
daecc161 2260 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->multi_vpaned, tmp_tab->label);
5723fa24 2261 list = gtk_container_get_children(GTK_CONTAINER(notebook));
2262 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
a43d67ba 2263 // always show : not if(g_list_length(list)>1)
2264 gtk_notebook_set_show_tabs(notebook, TRUE);
2265
5723fa24 2266}
2061e03d 2267
a43d67ba 2268/**
2269 * Function to show each viewer in the current tab.
2270 * It will be called by main window, call show on each registered viewer,
2271 * will call process traceset and then it will
2272 * @param main_win the main window the viewer belongs to.
2273 */
2274//FIXME Only one time request maximum for now!
2275void show_viewer(MainWindow *main_win)
2276{
2277 LttvAttributeValue value;
2278 LttvHooks * tmp;
2279 int i;
2280 LttvTracesetContext * tsc =
2281 (LttvTracesetContext*)main_win->current_tab->
2282 traceset_info->traceset_context;
2283
2284 g_assert(lttv_iattribute_find_by_path(main_win->current_tab->attributes,
2285 "hooks/showviewer", LTTV_POINTER, &value));
2286 tmp = (LttvHooks*)*(value.v_pointer);
2287 if(tmp == NULL)
2288 {
2289 g_warning("The viewer(s) did not add any show hook");
2290 return;
2291 }
2292
2293
2294 // Call the show, where viewers add hooks to context and fill the
2295 // time and number of events requested it the time_requests GArray.
2296 lttv_hooks_call(tmp, NULL);
2297
2298
2299}
2300
2301
2302gboolean execute_time_requests(MainWindow * mw)
2303{
2304 call_pending_read_hooks(mw);
2305
2306 return FALSE; // automatically removed from the list of event sources
2307}
2308
This page took 0.142074 seconds and 4 git commands to generate.