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