following GTK convention
[lttv.git] / ltt / branches / poly / lttv / modules / gui / mainWin / src / callbacks.c
CommitLineData
561eba2a 1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <gtk/gtk.h>
6#include <gmodule.h>
7
8#include "callbacks.h"
9#include "interface.h"
10#include "support.h"
95cd67ef 11#include <lttv/mainWindow.h>
37d0eca6 12#include <lttv/menu.h>
13#include <lttv/toolbar.h>
58960b51 14#include <lttv/gtkTraceSet.h>
6b1d3120 15#include <lttv/module.h>
fc188b78 16#include <lttv/gtkdirsel.h>
f7afe191 17#include <lttv/iattribute.h>
6b1d3120 18
f7afe191 19#define PATH_LENGTH 256
20#define DEFAULT_TIME_WIDTH_S 1
21
22//extern LttvTracesetContext * gTracesetContext;
68b48a45 23extern LttTrace *g_init_trace ;
561eba2a 24
ec25ff5e 25
26/** Array containing instanced objects. */
68b48a45 27extern GSList * g_main_window_list;
561eba2a 28
68b48a45 29static int g_win_count = 0;
7a859036 30
561eba2a 31mainWindow * get_window_data_struct(GtkWidget * widget);
36b3c068 32char * get_unload_module(char ** loaded_module_name, int nb_module);
2176f952 33char * get_remove_trace(char ** all_trace_name, int nb_trace);
34char * get_selection(char ** all_name, int nb, char *title, char * column_title);
5723fa24 35void * create_tab(GtkWidget* parent, GtkNotebook * notebook, char * label);
561eba2a 36
68b48a45 37void insert_viewer(GtkWidget* widget, view_constructor constructor);
561eba2a 38
36b3c068 39enum
40{
41 MODULE_COLUMN,
42 N_COLUMNS
43};
44
561eba2a 45
46void
68b48a45 47insert_viewer_wrap(GtkMenuItem *menuitem, gpointer user_data)
561eba2a 48{
49 guint val = 20;
68b48a45 50 insert_viewer((GtkWidget*)menuitem, (view_constructor)user_data);
37d0eca6 51 // selected_hook(&val);
561eba2a 52}
53
561eba2a 54
55/* internal functions */
68b48a45 56void insert_viewer(GtkWidget* widget, view_constructor constructor)
561eba2a 57{
58 GtkCustom * custom;
68b48a45 59 mainWindow * mw_data;
f9334f6f 60 GtkWidget * viewer;
561eba2a 61
68b48a45 62 mw_data = get_window_data_struct(widget);
63 if(!mw_data->CurrentTab) return;
64 custom = mw_data->CurrentTab->custom;
561eba2a 65
68b48a45 66 viewer = (GtkWidget*)constructor(mw_data);
f9334f6f 67 if(viewer)
f0d936c0 68 {
69 gtk_custom_widget_add(custom, viewer);
70 // Added by MD
8af8e4c5 71 // g_object_unref(G_OBJECT(viewer));
f0d936c0 72 }
561eba2a 73}
74
75void get_label_string (GtkWidget * text, gchar * label)
76{
77 GtkEntry * entry = (GtkEntry*)text;
78 if(strlen(gtk_entry_get_text(entry))!=0)
79 strcpy(label,gtk_entry_get_text(entry));
80}
81
6b1d3120 82void get_label(GtkWindow * mw, gchar * str, gchar* dialogue_title, gchar * label_str)
561eba2a 83{
84 GtkWidget * dialogue;
85 GtkWidget * text;
86 GtkWidget * label;
87 gint id;
88
5723fa24 89 dialogue = gtk_dialog_new_with_buttons(dialogue_title,NULL,
561eba2a 90 GTK_DIALOG_MODAL,
91 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
92 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
93 NULL);
94
6b1d3120 95 label = gtk_label_new(label_str);
561eba2a 96 gtk_widget_show(label);
97
98 text = gtk_entry_new();
99 gtk_widget_show(text);
100
101 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), label,TRUE, TRUE,0);
102 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), text,FALSE, FALSE,0);
103
104 id = gtk_dialog_run(GTK_DIALOG(dialogue));
105 switch(id){
106 case GTK_RESPONSE_ACCEPT:
107 get_label_string(text,str);
108 gtk_widget_destroy(dialogue);
109 break;
110 case GTK_RESPONSE_REJECT:
111 default:
112 gtk_widget_destroy(dialogue);
113 break;
114 }
115}
116
117mainWindow * get_window_data_struct(GtkWidget * widget)
118{
119 GtkWidget * mw;
68b48a45 120 mainWindow * mw_data;
561eba2a 121
122 mw = lookup_widget(widget, "MWindow");
123 if(mw == NULL){
124 g_printf("Main window does not exist\n");
125 return;
126 }
127
68b48a45 128 mw_data = (mainWindow *) g_object_get_data(G_OBJECT(mw),"mainWindow");
129 if(mw_data == NULL){
561eba2a 130 g_printf("Main window data does not exist\n");
131 return;
132 }
68b48a45 133 return mw_data;
561eba2a 134}
135
68b48a45 136void create_new_window(GtkWidget* widget, gpointer user_data, gboolean clone)
561eba2a 137{
5723fa24 138 mainWindow * parent = get_window_data_struct(widget);
561eba2a 139
561eba2a 140 if(clone){
141 g_printf("Clone : use the same traceset\n");
68b48a45 142 construct_main_window(parent, NULL, FALSE);
561eba2a 143 }else{
144 g_printf("Empty : traceset is set to NULL\n");
68b48a45 145 construct_main_window(NULL, parent->winCreationData, FALSE);
561eba2a 146 }
147}
148
149void move_up_viewer(GtkWidget * widget, gpointer user_data)
150{
151 mainWindow * mw = get_window_data_struct(widget);
152 if(!mw->CurrentTab) return;
153 gtk_custom_widget_move_up(mw->CurrentTab->custom);
154}
155
156void move_down_viewer(GtkWidget * widget, gpointer user_data)
157{
158 mainWindow * mw = get_window_data_struct(widget);
159 if(!mw->CurrentTab) return;
160 gtk_custom_widget_move_down(mw->CurrentTab->custom);
161}
162
163void delete_viewer(GtkWidget * widget, gpointer user_data)
164{
165 mainWindow * mw = get_window_data_struct(widget);
166 if(!mw->CurrentTab) return;
167 gtk_custom_widget_delete(mw->CurrentTab->custom);
168}
169
170void open_traceset(GtkWidget * widget, gpointer user_data)
171{
2176f952 172 char ** dir;
173 gint id;
174 LttvTraceset * traceset;
68b48a45 175 mainWindow * mw_data = get_window_data_struct(widget);
176 GtkFileSelection * file_selector =
2176f952 177 (GtkFileSelection *)gtk_file_selection_new("Select a traceset");
178
68b48a45 179 gtk_file_selection_hide_fileop_buttons(file_selector);
c64c7ea1 180
68b48a45 181 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 182 switch(id){
183 case GTK_RESPONSE_ACCEPT:
184 case GTK_RESPONSE_OK:
68b48a45 185 dir = gtk_file_selection_get_selections (file_selector);
2176f952 186 traceset = lttv_traceset_load(dir[0]);
187 g_printf("Open a trace set %s\n", dir[0]);
188 //Not finished yet
189 g_strfreev(dir);
190 case GTK_RESPONSE_REJECT:
191 case GTK_RESPONSE_CANCEL:
192 default:
68b48a45 193 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 194 break;
195 }
c64c7ea1 196
561eba2a 197}
198
199void add_trace(GtkWidget * widget, gpointer user_data)
200{
2176f952 201 LttTrace *trace;
202 LttvTrace * trace_v;
203 LttvTraceset * traceset;
204 char * dir;
205 gint id;
68b48a45 206 mainWindow * mw_data = get_window_data_struct(widget);
207 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select a trace");
208 gtk_dir_selection_hide_fileop_buttons(file_selector);
2176f952 209
68b48a45 210 id = gtk_dialog_run(GTK_DIALOG(file_selector));
2176f952 211 switch(id){
212 case GTK_RESPONSE_ACCEPT:
213 case GTK_RESPONSE_OK:
68b48a45 214 dir = gtk_dir_selection_get_dir (file_selector);
2176f952 215 trace = ltt_trace_open(dir);
216 if(trace == NULL) g_critical("cannot open trace %s", dir);
217 trace_v = lttv_trace_new(trace);
68b48a45 218 traceset = mw_data->Traceset_Info->traceset;
219 if(mw_data->Traceset_Info->TracesetContext != NULL){
220 lttv_context_fini(LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext));
221 g_object_unref(mw_data->Traceset_Info->TracesetContext);
2176f952 222 }
223 lttv_traceset_add(traceset, trace_v);
68b48a45 224 mw_data->Traceset_Info->TracesetContext =
2176f952 225 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
226 lttv_context_init(
68b48a45 227 LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext),traceset);
2176f952 228 case GTK_RESPONSE_REJECT:
229 case GTK_RESPONSE_CANCEL:
230 default:
68b48a45 231 gtk_widget_destroy((GtkWidget*)file_selector);
2176f952 232 break;
233 }
234
561eba2a 235 g_printf("add a trace to a trace set\n");
236}
237
238void remove_trace(GtkWidget * widget, gpointer user_data)
239{
2176f952 240 LttTrace *trace;
241 LttvTrace * trace_v;
242 LttvTraceset * traceset;
243 gint i, nb_trace;
244 char ** name, *remove_trace_name;
68b48a45 245 mainWindow * mw_data = get_window_data_struct(widget);
2176f952 246
68b48a45 247 nb_trace =lttv_traceset_number(mw_data->Traceset_Info->traceset);
2176f952 248 name = g_new(char*,nb_trace);
249 for(i = 0; i < nb_trace; i++){
68b48a45 250 trace_v = lttv_traceset_get(mw_data->Traceset_Info->traceset, i);
2176f952 251 trace = lttv_trace(trace_v);
252 name[i] = trace->pathname;
253 }
254
255 remove_trace_name = get_remove_trace(name, nb_trace);
256
257 if(remove_trace_name){
258 for(i=0; i<nb_trace; i++){
259 if(strcmp(remove_trace_name,name[i]) == 0){
68b48a45 260 traceset = mw_data->Traceset_Info->traceset;
261 if(mw_data->Traceset_Info->TracesetContext != NULL){
262 lttv_context_fini(LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext));
263 g_object_unref(mw_data->Traceset_Info->TracesetContext);
2176f952 264 }
265 lttv_traceset_remove(traceset, i);
68b48a45 266 mw_data->Traceset_Info->TracesetContext =
2176f952 267 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
268 lttv_context_init(
68b48a45 269 LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext),traceset);
2176f952 270 break;
271 }
272 }
273 }
274
275 g_free(name);
561eba2a 276 g_printf("remove a trace from a trace set\n");
277}
278
279void save(GtkWidget * widget, gpointer user_data)
280{
281 g_printf("Save\n");
282}
283
284void save_as(GtkWidget * widget, gpointer user_data)
285{
286 g_printf("Save as\n");
287}
288
289void zoom_in(GtkWidget * widget, gpointer user_data)
290{
291 g_printf("Zoom in\n");
292}
293
294void zoom_out(GtkWidget * widget, gpointer user_data)
295{
296 g_printf("Zoom out\n");
297}
298
299void zoom_extended(GtkWidget * widget, gpointer user_data)
300{
301 g_printf("Zoom extended\n");
302}
303
304void go_to_time(GtkWidget * widget, gpointer user_data)
305{
306 g_printf("Go to time\n");
307}
308
309void show_time_frame(GtkWidget * widget, gpointer user_data)
310{
311 g_printf("Show time frame\n");
312}
313
314
315/* callback function */
316
317void
318on_empty_traceset_activate (GtkMenuItem *menuitem,
319 gpointer user_data)
320{
68b48a45 321 create_new_window((GtkWidget*)menuitem, user_data, FALSE);
561eba2a 322}
323
324
325void
326on_clone_traceset_activate (GtkMenuItem *menuitem,
327 gpointer user_data)
328{
68b48a45 329 create_new_window((GtkWidget*)menuitem, user_data, TRUE);
561eba2a 330}
331
332
333void
334on_tab_activate (GtkMenuItem *menuitem,
335 gpointer user_data)
336{
6b1d3120 337 gchar label[PATH_LENGTH];
561eba2a 338 GtkNotebook * notebook = (GtkNotebook *)lookup_widget((GtkWidget*)menuitem, "MNotebook");
339 if(notebook == NULL){
340 g_printf("Notebook does not exist\n");
341 return;
342 }
343
6b1d3120 344 strcpy(label,"Page");
5723fa24 345 get_label(NULL, label,"Get the name of the tab","Please input tab's name");
561eba2a 346
5723fa24 347 create_tab ((GtkWidget*)menuitem, notebook, label);
561eba2a 348}
349
350
351void
352on_open_activate (GtkMenuItem *menuitem,
353 gpointer user_data)
354{
355 open_traceset((GtkWidget*)menuitem, user_data);
356}
357
358
359void
360on_close_activate (GtkMenuItem *menuitem,
361 gpointer user_data)
362{
68b48a45 363 mainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
364 main_window_destructor(mw_data);
561eba2a 365}
366
367
368void
369on_close_tab_activate (GtkMenuItem *menuitem,
370 gpointer user_data)
371{
2061e03d 372 int count = 0;
373 GtkWidget * notebook;
374 tab * tmp;
68b48a45 375 mainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
2061e03d 376 notebook = lookup_widget((GtkWidget*)menuitem, "MNotebook");
377 if(notebook == NULL){
378 g_printf("Notebook does not exist\n");
379 return;
380 }
381
68b48a45 382 if(mw_data->Tab == mw_data->CurrentTab){
383 // tmp = mw_data->CurrentTab;
384 // mw_data->Tab = mw_data->CurrentTab->Next;
2061e03d 385 g_printf("The default TAB can not be deleted\n");
386 return;
387 }else{
68b48a45 388 tmp = mw_data->Tab;
389 while(tmp != mw_data->CurrentTab){
2061e03d 390 tmp = tmp->Next;
391 count++;
392 }
393 }
394
395 gtk_notebook_remove_page((GtkNotebook*)notebook, count);
561eba2a 396}
397
398
399void
400on_add_trace_activate (GtkMenuItem *menuitem,
401 gpointer user_data)
402{
403 add_trace((GtkWidget*)menuitem, user_data);
404}
405
406
407void
408on_remove_trace_activate (GtkMenuItem *menuitem,
409 gpointer user_data)
410{
411 remove_trace((GtkWidget*)menuitem, user_data);
412}
413
414
415void
416on_save_activate (GtkMenuItem *menuitem,
417 gpointer user_data)
418{
419 save((GtkWidget*)menuitem, user_data);
420}
421
422
423void
424on_save_as_activate (GtkMenuItem *menuitem,
425 gpointer user_data)
426{
427 save_as((GtkWidget*)menuitem, user_data);
428}
429
430
431void
432on_quit_activate (GtkMenuItem *menuitem,
433 gpointer user_data)
434{
2061e03d 435 gtk_main_quit ();
561eba2a 436}
437
438
439void
440on_cut_activate (GtkMenuItem *menuitem,
441 gpointer user_data)
442{
443 g_printf("Cut\n");
444}
445
446
447void
448on_copy_activate (GtkMenuItem *menuitem,
449 gpointer user_data)
450{
451 g_printf("Copye\n");
452}
453
454
455void
456on_paste_activate (GtkMenuItem *menuitem,
457 gpointer user_data)
458{
459 g_printf("Paste\n");
460}
461
462
463void
464on_delete_activate (GtkMenuItem *menuitem,
465 gpointer user_data)
466{
467 g_printf("Delete\n");
468}
469
470
471void
472on_zoom_in_activate (GtkMenuItem *menuitem,
473 gpointer user_data)
474{
475 zoom_in((GtkWidget*)menuitem, user_data);
476}
477
478
479void
480on_zoom_out_activate (GtkMenuItem *menuitem,
481 gpointer user_data)
482{
483 zoom_out((GtkWidget*)menuitem, user_data);
484}
485
486
487void
488on_zoom_extended_activate (GtkMenuItem *menuitem,
489 gpointer user_data)
490{
491 zoom_extended((GtkWidget*)menuitem, user_data);
492}
493
494
495void
496on_go_to_time_activate (GtkMenuItem *menuitem,
497 gpointer user_data)
498{
499 go_to_time((GtkWidget*)menuitem, user_data);
500}
501
502
503void
504on_show_time_frame_activate (GtkMenuItem *menuitem,
505 gpointer user_data)
506{
507 show_time_frame((GtkWidget*)menuitem, user_data);
508}
509
510
511void
512on_move_viewer_up_activate (GtkMenuItem *menuitem,
513 gpointer user_data)
514{
515 move_up_viewer((GtkWidget*)menuitem, user_data);
516}
517
518
519void
520on_move_viewer_down_activate (GtkMenuItem *menuitem,
521 gpointer user_data)
522{
523 move_down_viewer((GtkWidget*)menuitem, user_data);
524}
525
526
527void
528on_remove_viewer_activate (GtkMenuItem *menuitem,
529 gpointer user_data)
530{
531 delete_viewer((GtkWidget*)menuitem, user_data);
532}
533
534
535void
536on_load_module_activate (GtkMenuItem *menuitem,
537 gpointer user_data)
538{
36b3c068 539 char ** dir;
540 gint id;
3872a20e 541 char str[PATH_LENGTH], *str1;
68b48a45 542 mainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
543 GtkFileSelection * file_selector = (GtkFileSelection *)gtk_file_selection_new("Select a module");
544 gtk_file_selection_hide_fileop_buttons(file_selector);
36b3c068 545
546 str[0] = '\0';
68b48a45 547 id = gtk_dialog_run(GTK_DIALOG(file_selector));
36b3c068 548 switch(id){
549 case GTK_RESPONSE_ACCEPT:
550 case GTK_RESPONSE_OK:
68b48a45 551 dir = gtk_file_selection_get_selections (file_selector);
36b3c068 552 sprintf(str,dir[0]);
3872a20e 553 str1 = strrchr(str,'/');
554 if(str1)str1++;
555 else{
556 str1 = strrchr(str,'\\');
557 str1++;
558 }
68b48a45 559 if(mw_data->winCreationData)
560 lttv_module_load(str1, mw_data->winCreationData->argc,mw_data->winCreationData->argv);
36b3c068 561 else
3872a20e 562 lttv_module_load(str1, 0,NULL);
68b48a45 563 g_slist_foreach(g_main_window_list, insert_menu_toolbar_item, NULL);
36b3c068 564 g_strfreev(dir);
565 case GTK_RESPONSE_REJECT:
566 case GTK_RESPONSE_CANCEL:
567 default:
68b48a45 568 gtk_widget_destroy((GtkWidget*)file_selector);
36b3c068 569 break;
570 }
571 g_printf("Load module: %s\n", str);
561eba2a 572}
573
574
575void
576on_unload_module_activate (GtkMenuItem *menuitem,
577 gpointer user_data)
578{
36b3c068 579 int i;
580 char **name, *unload_module_name;
581 guint nb;
582 LttvModule ** modules, *module;
68b48a45 583 mainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
36b3c068 584
585 modules = lttv_module_list(&nb);
586 name = g_new(char*, nb);
587 for(i=0;i<nb;i++){
588 module = modules[i];
589 name[i] = lttv_module_name(module);
590 }
591
592 unload_module_name =get_unload_module(name,nb);
593
594 if(unload_module_name){
595 for(i=0;i<nb;i++){
596 if(strcmp(unload_module_name, name[i]) == 0){
597 lttv_module_unload(modules[i]);
598 break;
599 }
600 }
601 }
602
603 g_free(name);
561eba2a 604}
605
606
607void
608on_add_module_search_path_activate (GtkMenuItem *menuitem,
609 gpointer user_data)
610{
68b48a45 611 GtkDirSelection * file_selector = (GtkDirSelection *)gtk_dir_selection_new("Select module path");
fc188b78 612 char * dir;
613 gint id;
614
68b48a45 615 mainWindow * mw_data = get_window_data_struct((GtkWidget*)menuitem);
fc188b78 616
68b48a45 617 id = gtk_dialog_run(GTK_DIALOG(file_selector));
fc188b78 618 switch(id){
619 case GTK_RESPONSE_ACCEPT:
620 case GTK_RESPONSE_OK:
68b48a45 621 dir = gtk_dir_selection_get_dir (file_selector);
fc188b78 622 lttv_module_path_add(dir);
623 case GTK_RESPONSE_REJECT:
624 case GTK_RESPONSE_CANCEL:
625 default:
68b48a45 626 gtk_widget_destroy((GtkWidget*)file_selector);
fc188b78 627 break;
6b1d3120 628 }
561eba2a 629}
630
631
632void
633on_color_activate (GtkMenuItem *menuitem,
634 gpointer user_data)
635{
636 g_printf("Color\n");
637}
638
639
640void
641on_filter_activate (GtkMenuItem *menuitem,
642 gpointer user_data)
643{
644 g_printf("Filter\n");
645}
646
647
648void
649on_save_configuration_activate (GtkMenuItem *menuitem,
650 gpointer user_data)
651{
652 g_printf("Save configuration\n");
653}
654
655
656void
657on_content_activate (GtkMenuItem *menuitem,
658 gpointer user_data)
659{
660 g_printf("Content\n");
661}
662
663
664void
665on_about_activate (GtkMenuItem *menuitem,
666 gpointer user_data)
667{
668 g_printf("About...\n");
669}
670
671
672void
673on_button_new_clicked (GtkButton *button,
674 gpointer user_data)
675{
68b48a45 676 create_new_window((GtkWidget*)button, user_data, FALSE);
561eba2a 677}
678
679
680void
681on_button_open_clicked (GtkButton *button,
682 gpointer user_data)
683{
684 open_traceset((GtkWidget*)button, user_data);
685}
686
687
688void
689on_button_add_trace_clicked (GtkButton *button,
690 gpointer user_data)
691{
692 add_trace((GtkWidget*)button, user_data);
693}
694
695
696void
697on_button_remove_trace_clicked (GtkButton *button,
698 gpointer user_data)
699{
700 remove_trace((GtkWidget*)button, user_data);
701}
702
703
704void
705on_button_save_clicked (GtkButton *button,
706 gpointer user_data)
707{
708 save((GtkWidget*)button, user_data);
709}
710
711
712void
713on_button_save_as_clicked (GtkButton *button,
714 gpointer user_data)
715{
716 save_as((GtkWidget*)button, user_data);
717}
718
719
720void
721on_button_zoom_in_clicked (GtkButton *button,
722 gpointer user_data)
723{
724 zoom_in((GtkWidget*)button, user_data);
725}
726
727
728void
729on_button_zoom_out_clicked (GtkButton *button,
730 gpointer user_data)
731{
732 zoom_out((GtkWidget*)button, user_data);
733}
734
735
736void
737on_button_zoom_extended_clicked (GtkButton *button,
738 gpointer user_data)
739{
740 zoom_extended((GtkWidget*)button, user_data);
741}
742
743
744void
745on_button_go_to_time_clicked (GtkButton *button,
746 gpointer user_data)
747{
748 go_to_time((GtkWidget*)button, user_data);
749}
750
751
752void
753on_button_show_time_frame_clicked (GtkButton *button,
754 gpointer user_data)
755{
756 show_time_frame((GtkWidget*)button, user_data);
757}
758
759
760void
761on_button_move_up_clicked (GtkButton *button,
762 gpointer user_data)
763{
764 move_up_viewer((GtkWidget*)button, user_data);
765}
766
767
768void
769on_button_move_down_clicked (GtkButton *button,
770 gpointer user_data)
771{
772 move_down_viewer((GtkWidget*)button, user_data);
773}
774
775
776void
777on_button_delete_viewer_clicked (GtkButton *button,
778 gpointer user_data)
779{
780 delete_viewer((GtkWidget*)button, user_data);
781}
782
783void
784on_MWindow_destroy (GtkObject *object,
785 gpointer user_data)
786{
f7afe191 787 mainWindow *Main_Window = (mainWindow*)user_data;
788
68b48a45 789 g_printf("There are : %d windows\n",g_slist_length(g_main_window_list));
561eba2a 790
68b48a45 791 g_win_count--;
792 if(g_win_count == 0)
7a859036 793 gtk_main_quit ();
561eba2a 794}
795
796
797void
798on_MNotebook_switch_page (GtkNotebook *notebook,
799 GtkNotebookPage *page,
800 guint page_num,
801 gpointer user_data)
802{
803 mainWindow * mw = get_window_data_struct((GtkWidget*)notebook);
804 tab * Tab = mw->Tab;
805
806 while(page_num){
807 Tab = Tab->Next;
808 page_num--;
809 }
810 mw->CurrentTab = Tab;
811}
812
2176f952 813char * get_remove_trace(char ** all_trace_name, int nb_trace)
814{
815 return get_selection(all_trace_name, nb_trace,
816 "Select a trace", "Trace pathname");
817}
36b3c068 818char * get_unload_module(char ** loaded_module_name, int nb_module)
2176f952 819{
820 return get_selection(loaded_module_name, nb_module,
821 "Select an unload module", "Module pathname");
822}
823
824char * get_selection(char ** loaded_module_name, int nb_module,
825 char *title, char * column_title)
36b3c068 826{
827 GtkWidget * dialogue;
828 GtkWidget * scroll_win;
829 GtkWidget * tree;
830 GtkListStore * store;
831 GtkTreeViewColumn * column;
832 GtkCellRenderer * renderer;
833 GtkTreeSelection * select;
834 GtkTreeIter iter;
835 gint id, i;
836 char * unload_module_name = NULL;
837
2176f952 838 dialogue = gtk_dialog_new_with_buttons(title,
36b3c068 839 NULL,
840 GTK_DIALOG_MODAL,
841 GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,
842 GTK_STOCK_CANCEL,GTK_RESPONSE_REJECT,
843 NULL);
844 gtk_window_set_default_size((GtkWindow*)dialogue, 500, 200);
845
846 scroll_win = gtk_scrolled_window_new (NULL, NULL);
847 gtk_widget_show ( scroll_win);
848 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
849 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
850
851 store = gtk_list_store_new (N_COLUMNS,G_TYPE_STRING);
852 tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL (store));
853 gtk_widget_show ( tree);
854 g_object_unref (G_OBJECT (store));
855
856 renderer = gtk_cell_renderer_text_new ();
2176f952 857 column = gtk_tree_view_column_new_with_attributes (column_title,
36b3c068 858 renderer,
859 "text", MODULE_COLUMN,
860 NULL);
861 gtk_tree_view_column_set_alignment (column, 0.5);
862 gtk_tree_view_column_set_fixed_width (column, 150);
863 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
864
865 select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
866 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
867
868 gtk_container_add (GTK_CONTAINER (scroll_win), tree);
869
870 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialogue)->vbox), scroll_win,TRUE, TRUE,0);
871
872 for(i=0;i<nb_module;i++){
873 gtk_list_store_append (store, &iter);
874 gtk_list_store_set (store, &iter, MODULE_COLUMN,loaded_module_name[i],-1);
875 }
876
877 id = gtk_dialog_run(GTK_DIALOG(dialogue));
878 switch(id){
879 case GTK_RESPONSE_ACCEPT:
880 case GTK_RESPONSE_OK:
881 if (gtk_tree_selection_get_selected (select, (GtkTreeModel**)&store, &iter)){
882 gtk_tree_model_get ((GtkTreeModel*)store, &iter, MODULE_COLUMN, &unload_module_name, -1);
883 }
884 case GTK_RESPONSE_REJECT:
885 case GTK_RESPONSE_CANCEL:
886 default:
887 gtk_widget_destroy(dialogue);
888 break;
889 }
890
891 return unload_module_name;
892}
5723fa24 893
2176f952 894void main_window_destroy_hash_key(gpointer key)
2061e03d 895{
896 g_free(key);
897}
898
2176f952 899void main_window_destroy_hash_data(gpointer data)
2061e03d 900{
901}
902
903
68b48a45 904void insert_menu_toolbar_item(mainWindow * mw, gpointer user_data)
5723fa24 905{
906 int i;
907 GdkPixbuf *pixbuf;
908 view_constructor constructor;
909 LttvMenus * menu;
910 LttvToolbars * toolbar;
68b48a45 911 lttv_menu_closure *menu_item;
912 lttv_toolbar_closure *toolbar_item;
5723fa24 913 LttvAttributeValue value;
914 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
68b48a45 915 GtkWidget * tool_menu_title_menu, *insert_view, *pixmap, *tmp;
5723fa24 916
917 g_assert(lttv_iattribute_find_by_path(attributes,
918 "viewers/menu", LTTV_POINTER, &value));
919 menu = (LttvMenus*)*(value.v_pointer);
920
921 if(menu){
922 for(i=0;i<menu->len;i++){
68b48a45 923 menu_item = &g_array_index(menu, lttv_menu_closure, i);
924 tmp = g_hash_table_lookup(mw->hash_menu_item, g_strdup(menu_item->menuText));
3872a20e 925 if(tmp)continue;
68b48a45 926 constructor = menu_item->con;
927 tool_menu_title_menu = lookup_widget(mw->MWindow,"ToolMenuTitle_menu");
928 insert_view = gtk_menu_item_new_with_mnemonic (menu_item->menuText);
5723fa24 929 gtk_widget_show (insert_view);
68b48a45 930 gtk_container_add (GTK_CONTAINER (tool_menu_title_menu), insert_view);
5723fa24 931 g_signal_connect ((gpointer) insert_view, "activate",
68b48a45 932 G_CALLBACK (insert_viewer_wrap),
5723fa24 933 constructor);
68b48a45 934 g_hash_table_insert(mw->hash_menu_item, g_strdup(menu_item->menuText),
2061e03d 935 insert_view);
5723fa24 936 }
937 }
938
939 g_assert(lttv_iattribute_find_by_path(attributes,
940 "viewers/toolbar", LTTV_POINTER, &value));
941 toolbar = (LttvToolbars*)*(value.v_pointer);
942
943 if(toolbar){
944 for(i=0;i<toolbar->len;i++){
68b48a45 945 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
946 tmp = g_hash_table_lookup(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip));
3872a20e 947 if(tmp)continue;
68b48a45 948 constructor = toolbar_item->con;
949 tool_menu_title_menu = lookup_widget(mw->MWindow,"MToolbar2");
950 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**)toolbar_item->pixmap);
5723fa24 951 pixmap = gtk_image_new_from_pixbuf(pixbuf);
68b48a45 952 insert_view = gtk_toolbar_append_element (GTK_TOOLBAR (tool_menu_title_menu),
5723fa24 953 GTK_TOOLBAR_CHILD_BUTTON,
954 NULL,
955 "",
68b48a45 956 toolbar_item->tooltip, NULL,
5723fa24 957 pixmap, NULL, NULL);
68b48a45 958 gtk_label_set_use_underline (GTK_LABEL (((GtkToolbarChild*) (g_list_last (GTK_TOOLBAR (tool_menu_title_menu)->children)->data))->label), TRUE);
5723fa24 959 gtk_widget_show (insert_view);
960 gtk_container_set_border_width (GTK_CONTAINER (insert_view), 1);
68b48a45 961 g_signal_connect ((gpointer) insert_view, "clicked",G_CALLBACK (insert_viewer_wrap),constructor);
962 g_hash_table_insert(mw->hash_toolbar_item, g_strdup(toolbar_item->tooltip),
2061e03d 963 insert_view);
5723fa24 964 }
965 }
966}
967
68b48a45 968void construct_main_window(mainWindow * parent, WindowCreationData * win_creation_data,
2061e03d 969 gboolean first_window)
5723fa24 970{
68b48a45 971 g_critical("construct_main_window()");
972 GtkWidget * new_window; /* New generated main window */
973 mainWindow * new_m_window;/* New main window structure */
5723fa24 974 GtkNotebook * notebook;
f7afe191 975 LttvIAttribute *attributes =
976 LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
977 LttvAttributeValue value;
2061e03d 978
68b48a45 979 new_m_window = g_new(mainWindow, 1);
5723fa24 980
981 // Add the object's information to the module's array
68b48a45 982 g_main_window_list = g_slist_append(g_main_window_list, new_m_window);
5723fa24 983
f7afe191 984
68b48a45 985 new_window = create_MWindow();
986 gtk_widget_show (new_window);
5723fa24 987
68b48a45 988 new_m_window->Attributes = attributes;
f7afe191 989
68b48a45 990 new_m_window->Traceset_Info = g_new(TracesetInfo,1);
991 new_m_window->Traceset_Info->path = NULL ;
f7afe191 992
993
68b48a45 994 new_m_window->Traceset_Info->before_traceset = lttv_hooks_new();
995 new_m_window->Traceset_Info->after_traceset = lttv_hooks_new();
996 new_m_window->Traceset_Info->before_trace = lttv_hooks_new();
997 new_m_window->Traceset_Info->after_trace = lttv_hooks_new();
998 new_m_window->Traceset_Info->before_tracefile = lttv_hooks_new();
999 new_m_window->Traceset_Info->after_tracefile = lttv_hooks_new();
1000 new_m_window->Traceset_Info->before_event = lttv_hooks_new();
1001 new_m_window->Traceset_Info->after_event = lttv_hooks_new();
f7afe191 1002
1003 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/before",
1004 LTTV_POINTER, &value));
68b48a45 1005 *(value.v_pointer) = new_m_window->Traceset_Info->before_traceset;
f7afe191 1006 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/traceset/after",
1007 LTTV_POINTER, &value));
68b48a45 1008 *(value.v_pointer) = new_m_window->Traceset_Info->after_traceset;
f7afe191 1009 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/before",
1010 LTTV_POINTER, &value));
68b48a45 1011 *(value.v_pointer) = new_m_window->Traceset_Info->before_trace;
f7afe191 1012 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/trace/after",
1013 LTTV_POINTER, &value));
68b48a45 1014 *(value.v_pointer) = new_m_window->Traceset_Info->after_trace;
f7afe191 1015 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/before",
1016 LTTV_POINTER, &value));
68b48a45 1017 *(value.v_pointer) = new_m_window->Traceset_Info->before_tracefile;
f7afe191 1018 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/tracefile/after",
1019 LTTV_POINTER, &value));
68b48a45 1020 *(value.v_pointer) = new_m_window->Traceset_Info->after_tracefile;
f7afe191 1021 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/before",
1022 LTTV_POINTER, &value));
68b48a45 1023 *(value.v_pointer) = new_m_window->Traceset_Info->before_event;
f7afe191 1024 g_assert(lttv_iattribute_find_by_path(attributes, "hooks/event/after",
1025 LTTV_POINTER, &value));
68b48a45 1026 *(value.v_pointer) = new_m_window->Traceset_Info->after_event;
f7afe191 1027
1028
68b48a45 1029 new_m_window->MWindow = new_window;
1030 new_m_window->Tab = NULL;
1031 new_m_window->CurrentTab = NULL;
1032 new_m_window->Attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
5723fa24 1033 if(parent){
68b48a45 1034 new_m_window->Traceset_Info->traceset =
f7afe191 1035 lttv_traceset_copy(parent->Traceset_Info->traceset);
1036
1037//FIXME copy not implemented in lower level
68b48a45 1038 new_m_window->Traceset_Info->TracesetContext =
f7afe191 1039 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1040 lttv_context_init(
68b48a45 1041 LTTV_TRACESET_CONTEXT(new_m_window->Traceset_Info->TracesetContext),
1042 new_m_window->Traceset_Info->traceset);
1043 //new_m_window->traceset_context = parent->traceset_context;
1044 new_m_window->winCreationData = parent->winCreationData;
5723fa24 1045 }else{
68b48a45 1046 new_m_window->Traceset_Info->traceset = lttv_traceset_new();
f7afe191 1047
1048 /* Add the command line trace */
68b48a45 1049 if(g_init_trace != NULL && first_window)
1050 lttv_traceset_add(new_m_window->Traceset_Info->traceset, g_init_trace);
f7afe191 1051 /* NOTE : the context must be recreated if we change the traceset,
1052 * ie : adding/removing traces */
68b48a45 1053 new_m_window->Traceset_Info->TracesetContext =
f7afe191 1054 g_object_new(LTTV_TRACESET_STATS_TYPE, NULL);
1055 lttv_context_init(
68b48a45 1056 LTTV_TRACESET_CONTEXT(new_m_window->Traceset_Info->TracesetContext),
1057 new_m_window->Traceset_Info->traceset);
f7afe191 1058
68b48a45 1059 new_m_window->winCreationData = win_creation_data;
5723fa24 1060 }
1061
68b48a45 1062 new_m_window->hash_menu_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1063 main_window_destroy_hash_key,
1064 main_window_destroy_hash_data);
68b48a45 1065 new_m_window->hash_toolbar_item = g_hash_table_new_full (g_str_hash, g_str_equal,
2176f952 1066 main_window_destroy_hash_key,
1067 main_window_destroy_hash_data);
2061e03d 1068
68b48a45 1069 insert_menu_toolbar_item(new_m_window, NULL);
5723fa24 1070
68b48a45 1071 g_object_set_data(G_OBJECT(new_window), "mainWindow", (gpointer)new_m_window);
5723fa24 1072
1073 //create a default tab
68b48a45 1074 notebook = (GtkNotebook *)lookup_widget(new_m_window->MWindow, "MNotebook");
5723fa24 1075 if(notebook == NULL){
1076 g_printf("Notebook does not exist\n");
1077 return;
1078 }
1079 //for now there is no name field in LttvTraceset structure
1080 //Use "Traceset" as the label for the default tab
68b48a45 1081 create_tab(new_m_window->MWindow, notebook,"Traceset");
5723fa24 1082
7a859036 1083 g_object_set_data_full(
68b48a45 1084 G_OBJECT(new_m_window->MWindow),
7a859036 1085 "Main_Window_Data",
68b48a45 1086 new_m_window,
1087 (GDestroyNotify)main_window_free);
7a859036 1088
68b48a45 1089 g_win_count++;
5723fa24 1090}
1091
68b48a45 1092void tab_destructor(tab * tab_instance)
f7afe191 1093{
68b48a45 1094 if(tab_instance->Attributes)
1095 g_object_unref(tab_instance->Attributes);
2061e03d 1096
68b48a45 1097 if(tab_instance->mw->Tab == tab_instance){
1098 tab_instance->mw->Tab = tab_instance->Next;
2061e03d 1099 }else{
68b48a45 1100 tab * tmp1, *tmp = tab_instance->mw->Tab;
1101 while(tmp != tab_instance){
2061e03d 1102 tmp1 = tmp;
1103 tmp = tmp->Next;
1104 }
68b48a45 1105 tmp1->Next = tab_instance->Next;
2061e03d 1106 }
68b48a45 1107 g_free(tab_instance);
f7afe191 1108}
1109
5723fa24 1110void * create_tab(GtkWidget* parent, GtkNotebook * notebook, char * label)
1111{
1112 GList * list;
68b48a45 1113 tab * tmp_tab;
1114 mainWindow * mw_data;
1115 LttTime tmp_time;
1116
1117 mw_data = get_window_data_struct(parent);
1118 tmp_tab = mw_data->Tab;
1119 while(tmp_tab && tmp_tab->Next) tmp_tab = tmp_tab->Next;
1120 if(!tmp_tab){
1121 mw_data->CurrentTab = NULL;
1122 tmp_tab = g_new(tab,1);
1123 mw_data->Tab = tmp_tab;
5723fa24 1124 }else{
68b48a45 1125 tmp_tab->Next = g_new(tab,1);
1126 tmp_tab = tmp_tab->Next;
5723fa24 1127 }
68b48a45 1128 if(mw_data->CurrentTab){
f7afe191 1129 // Will have to read directly at the main window level, as we want
1130 // to be able to modify a traceset on the fly.
68b48a45 1131 // tmp_tab->traceStartTime = mw_data->CurrentTab->traceStartTime;
1132 // tmp_tab->traceEndTime = mw_data->CurrentTab->traceEndTime;
1133 tmp_tab->Time_Window = mw_data->CurrentTab->Time_Window;
1134 tmp_tab->currentTime = mw_data->CurrentTab->currentTime;
5723fa24 1135 }else{
f7afe191 1136 // Will have to read directly at the main window level, as we want
1137 // to be able to modify a traceset on the fly.
68b48a45 1138 // getTracesetTimeSpan(mw_data,&tmp_tab->traceStartTime, &tmp_tab->traceEndTime);
1139 tmp_tab->Time_Window.startTime =
1140 LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext)->Time_Span->startTime;
f7afe191 1141 if(DEFAULT_TIME_WIDTH_S <
68b48a45 1142 LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext)->Time_Span->endTime.tv_sec)
1143 tmp_time.tv_sec = DEFAULT_TIME_WIDTH_S;
f7afe191 1144 else
68b48a45 1145 tmp_time.tv_sec =
1146 LTTV_TRACESET_CONTEXT(mw_data->Traceset_Info->TracesetContext)->Time_Span->endTime.tv_sec;
1147 tmp_time.tv_nsec = 0;
1148 tmp_tab->Time_Window.Time_Width = tmp_time ;
1149 tmp_tab->currentTime.tv_sec = tmp_time.tv_sec / 2;
1150 tmp_tab->currentTime.tv_nsec = 0 ;
5723fa24 1151 }
68b48a45 1152 tmp_tab->Attributes = LTTV_IATTRIBUTE(g_object_new(LTTV_ATTRIBUTE_TYPE, NULL));
1153 // mw_data->CurrentTab = tmp_tab;
1154 tmp_tab->custom = (GtkCustom*)gtk_custom_new();
1155 tmp_tab->custom->mw = mw_data;
1156 gtk_widget_show((GtkWidget*)tmp_tab->custom);
1157 tmp_tab->Next = NULL;
1158 tmp_tab->mw = mw_data;
5723fa24 1159
68b48a45 1160 tmp_tab->label = gtk_label_new (label);
1161 gtk_widget_show (tmp_tab->label);
5723fa24 1162
f7afe191 1163 g_object_set_data_full(
68b48a45 1164 G_OBJECT(tmp_tab->custom),
f7afe191 1165 "Tab_Info",
68b48a45 1166 tmp_tab,
1167 (GDestroyNotify)tab_destructor);
5723fa24 1168
68b48a45 1169 gtk_notebook_append_page(notebook, (GtkWidget*)tmp_tab->custom, tmp_tab->label);
5723fa24 1170 list = gtk_container_get_children(GTK_CONTAINER(notebook));
1171 gtk_notebook_set_current_page(notebook,g_list_length(list)-1);
1172}
2061e03d 1173
1174void remove_menu_item(gpointer main_win, gpointer user_data)
1175{
1176 mainWindow * mw = (mainWindow *) main_win;
68b48a45 1177 lttv_menu_closure *menu_item = (lttv_menu_closure *)user_data;
1178 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 1179
68b48a45 1180 tool_menu_title_menu = lookup_widget(mw->MWindow,"ToolMenuTitle_menu");
2061e03d 1181 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_menu_item,
68b48a45 1182 menu_item->menuText);
2061e03d 1183 if(insert_view){
68b48a45 1184 g_hash_table_remove(mw->hash_menu_item, menu_item->menuText);
1185 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 1186 }
1187}
1188
1189void remove_toolbar_item(gpointer main_win, gpointer user_data)
1190{
1191 mainWindow * mw = (mainWindow *) main_win;
68b48a45 1192 lttv_toolbar_closure *toolbar_item = (lttv_toolbar_closure *)user_data;
1193 GtkWidget * tool_menu_title_menu, *insert_view;
2061e03d 1194
1195
68b48a45 1196 tool_menu_title_menu = lookup_widget(mw->MWindow,"MToolbar2");
2061e03d 1197 insert_view = (GtkWidget*)g_hash_table_lookup(mw->hash_toolbar_item,
68b48a45 1198 toolbar_item->tooltip);
2061e03d 1199 if(insert_view){
68b48a45 1200 g_hash_table_remove(mw->hash_toolbar_item, toolbar_item->tooltip);
1201 gtk_container_remove (GTK_CONTAINER (tool_menu_title_menu), insert_view);
2061e03d 1202 }
1203}
1204
1205/**
1206 * Remove menu and toolbar item when a module unloaded
1207 */
2176f952 1208
2061e03d 1209void main_window_remove_menu_item(lttv_constructor constructor)
1210{
1211 int i;
1212 LttvMenus * menu;
68b48a45 1213 lttv_menu_closure *menu_item;
2061e03d 1214 LttvAttributeValue value;
1215 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
1216
1217 g_assert(lttv_iattribute_find_by_path(attributes,
1218 "viewers/menu", LTTV_POINTER, &value));
1219 menu = (LttvMenus*)*(value.v_pointer);
1220
1221 if(menu){
1222 for(i=0;i<menu->len;i++){
68b48a45 1223 menu_item = &g_array_index(menu, lttv_menu_closure, i);
1224 if(menu_item->con != constructor) continue;
1225 if(g_main_window_list){
1226 g_slist_foreach(g_main_window_list, remove_menu_item, menu_item);
2176f952 1227 }
2061e03d 1228 break;
1229 }
1230 }
1231
1232}
1233
1234void main_window_remove_toolbar_item(lttv_constructor constructor)
1235{
1236 int i;
1237 LttvToolbars * toolbar;
68b48a45 1238 lttv_toolbar_closure *toolbar_item;
2061e03d 1239 LttvAttributeValue value;
1240 LttvIAttribute *attributes = LTTV_IATTRIBUTE(lttv_global_attributes());
1241
1242 g_assert(lttv_iattribute_find_by_path(attributes,
1243 "viewers/toolbar", LTTV_POINTER, &value));
1244 toolbar = (LttvToolbars*)*(value.v_pointer);
1245
1246 if(toolbar){
1247 for(i=0;i<toolbar->len;i++){
68b48a45 1248 toolbar_item = &g_array_index(toolbar, lttv_toolbar_closure, i);
1249 if(toolbar_item->con != constructor) continue;
1250 if(g_main_window_list){
1251 g_slist_foreach(g_main_window_list, remove_toolbar_item, toolbar_item);
2176f952 1252 }
2061e03d 1253 break;
1254 }
1255 }
1256}
This page took 0.080119 seconds and 4 git commands to generate.