1 /*
2 * Copyright (c) Tristan Gingold and Tony Bybell 2006-2017.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 */
9 #include <config.h>
10 #include "globals.h"
11 #include <gtk/gtk.h>
12 #include <gdk/gdkkeysyms.h>
13 #include <string.h>
14 #include <ctype.h>
15 #include "gtk12compat.h"
16 #include "analyzer.h"
17 #include "tree.h"
18 #include "symbol.h"
19 #include "vcd.h"
20 #include "lx2.h"
21 #include "busy.h"
22 #include "debug.h"
23 #include "hierpack.h"
24 #include "tcl_helper.h"
25
26 WAVE_NODEVARTYPE_STR
27 WAVE_NODEVARDIR_STR
28 WAVE_NODEVARDATATYPE_STR
29
30 enum { VIEW_DRAG_INACTIVE, TREE_TO_VIEW_DRAG_ACTIVE, SEARCH_TO_VIEW_DRAG_ACTIVE };
31
32 /* Treesearch is a pop-up window used to select signals.
33 It is composed of two main areas:
34 * A tree area to select the hierarchy [tree area]
35 * The (filtered) list of signals contained in the hierarchy [signal area].
36 */
37
38 /* SIG_ROOT is the branch currently selected.
39 Signals of SIG_ROOT are displayed in the signals window. */
40
41 /* Only signals which match the filter are displayed in the signal area. */
42
43 /* The signal area is based on a tree view which requires a store model.
44 This store model contains the list of signals to be displayed.
45 */
46 enum { NAME_COLUMN, TREE_COLUMN, TYPE_COLUMN, DIR_COLUMN, DTYPE_COLUMN, N_COLUMNS };
47
48 /* list of autocoalesced (synthesized) filter names that need to be freed at some point) */
49
free_afl(void)50 void free_afl(void)
51 {
52 struct autocoalesce_free_list *at;
53
54 while(GLOBALS->afl_treesearch_gtk2_c_1)
55 {
56 if(GLOBALS->afl_treesearch_gtk2_c_1->name) free_2(GLOBALS->afl_treesearch_gtk2_c_1->name);
57 at = GLOBALS->afl_treesearch_gtk2_c_1->next;
58 free_2(GLOBALS->afl_treesearch_gtk2_c_1);
59 GLOBALS->afl_treesearch_gtk2_c_1 = at;
60 }
61 }
62
63
64 /* point to pure signame (remove hierarchy) for fill_sig_store() */
prune_hierarchy(char * nam)65 static char *prune_hierarchy(char *nam)
66 {
67 char cmpchar = GLOBALS->alt_hier_delimeter ? GLOBALS->alt_hier_delimeter : '.';
68 char *t = nam;
69 char *lastmatch = NULL;
70
71 while(t && *t)
72 {
73 if(*t == cmpchar) { lastmatch = t+1; }
74 t++;
75 }
76
77 return(lastmatch ? lastmatch : nam);
78 }
79
80 /* fix escaped signal names */
fix_escaped_names(char * s,int do_free)81 static void *fix_escaped_names(char *s, int do_free)
82 {
83 char *s2 = s;
84 int found = 0;
85
86 while(*s2)
87 {
88 if((*s2) == VCDNAM_ESCAPE)
89 {
90 found = 1;
91 break;
92 }
93 s2++;
94 }
95
96 if(found)
97 {
98 s2 = strdup_2(s);
99 if(do_free) free_2(s);
100 s = s2;
101
102 while(*s2)
103 {
104 if(*s2 == VCDNAM_ESCAPE) { *s2 = GLOBALS->hier_delimeter; } /* restore back to normal */
105 s2++;
106 }
107 }
108
109 return(s);
110 }
111
112
113 /* truncate VHDL types to string directly after final '.' */
varxt_fix(char * s)114 char *varxt_fix(char *s)
115 {
116 char *pnt = strrchr(s, '.');
117 return(pnt ? (pnt+1) : s);
118 }
119
120
121 /* Fill the store model using current SIG_ROOT and FILTER_STR. */
122 void
fill_sig_store(void)123 fill_sig_store (void)
124 {
125 struct tree *t;
126 struct tree *t_prev = NULL;
127 GtkTreeIter iter;
128
129 if(GLOBALS->selected_sig_name)
130 {
131 free_2(GLOBALS->selected_sig_name);
132 GLOBALS->selected_sig_name = NULL;
133 }
134
135 free_afl();
136 gtk_list_store_clear (GLOBALS->sig_store_treesearch_gtk2_c_1);
137
138 for (t = GLOBALS->sig_root_treesearch_gtk2_c_1; t != NULL; t = t->next)
139 {
140 int i = t->t_which;
141 char *s, *tmp2;
142 int vartype;
143 int vardir;
144 int is_tname = 0;
145 int wrexm;
146 int vardt;
147 unsigned int varxt;
148 char *varxt_pnt;
149
150 if(i < 0)
151 {
152 t_prev = NULL;
153 continue;
154 }
155
156 if(t_prev) /* duplicates removal for faulty dumpers */
157 {
158 if(!strcmp(t_prev->name, t->name))
159 {
160 continue;
161 }
162 }
163 t_prev = t;
164
165 varxt = GLOBALS->facs[i]->n->varxt;
166 varxt_pnt = varxt ? varxt_fix(GLOBALS->subvar_pnt[varxt]) : NULL;
167
168 vartype = GLOBALS->facs[i]->n->vartype;
169 if((vartype < 0) || (vartype > ND_VARTYPE_MAX))
170 {
171 vartype = 0;
172 }
173
174 vardir = GLOBALS->facs[i]->n->vardir; /* two bit already chops down to 0..3, but this doesn't hurt */
175 if((vardir < 0) || (vardir > ND_DIR_MAX))
176 {
177 vardir = 0;
178 }
179
180 vardt = GLOBALS->facs[i]->n->vardt;
181 if((vardt < 0) || (vardt > ND_VDT_MAX))
182 {
183 vardt = 0;
184 }
185
186 if(!GLOBALS->facs[i]->vec_root)
187 {
188 is_tname = 1;
189 s = t->name;
190 s = fix_escaped_names(s, 0);
191 }
192 else
193 {
194 if(GLOBALS->autocoalesce)
195 {
196 char *p;
197 if(GLOBALS->facs[i]->vec_root!=GLOBALS->facs[i]) continue;
198
199 tmp2=makename_chain(GLOBALS->facs[i]);
200 p = prune_hierarchy(tmp2);
201 s=(char *)malloc_2(strlen(p)+4);
202 strcpy(s,"[] ");
203 strcpy(s+3, p);
204 s = fix_escaped_names(s, 1);
205 free_2(tmp2);
206 }
207 else
208 {
209 char *p = prune_hierarchy(GLOBALS->facs[i]->name);
210 s=(char *)malloc_2(strlen(p)+4);
211 strcpy(s,"[] ");
212 strcpy(s+3, p);
213 s = fix_escaped_names(s, 1);
214 }
215 }
216
217 wrexm = 0;
218 if (
219 (GLOBALS->filter_str_treesearch_gtk2_c_1 == NULL) ||
220 ((!GLOBALS->filter_noregex_treesearch_gtk2_c_1) && (wrexm = wave_regex_match(t->name, WAVE_REGEX_TREE)) && (!GLOBALS->filter_matlen_treesearch_gtk2_c_1)) ||
221 (GLOBALS->filter_matlen_treesearch_gtk2_c_1 && ((GLOBALS->filter_typ_treesearch_gtk2_c_1 == vardir) ^ GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1) &&
222 (wrexm || (wrexm = wave_regex_match(t->name, WAVE_REGEX_TREE))) )
223 )
224 {
225 gtk_list_store_prepend (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter);
226 if(is_tname)
227 {
228 gtk_list_store_set (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter,
229 NAME_COLUMN, s,
230 TREE_COLUMN, t,
231 TYPE_COLUMN,
232 (((GLOBALS->supplemental_datatypes_encountered) && (!GLOBALS->supplemental_vartypes_encountered)) ?
233 (varxt ? varxt_pnt : vardatatype_strings[vardt]) : vartype_strings[vartype]),
234 DIR_COLUMN, vardir_strings[vardir],
235 DTYPE_COLUMN, varxt ? varxt_pnt : vardatatype_strings[vardt],
236 -1);
237
238 if(s != t->name)
239 {
240 free_2(s);
241 }
242 }
243 else
244 {
245 struct autocoalesce_free_list *a = calloc_2(1, sizeof(struct autocoalesce_free_list));
246 a->name = s;
247 a->next = GLOBALS->afl_treesearch_gtk2_c_1;
248 GLOBALS->afl_treesearch_gtk2_c_1 = a;
249
250 gtk_list_store_set (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter,
251 NAME_COLUMN, s,
252 TREE_COLUMN, t,
253 TYPE_COLUMN,
254 (((GLOBALS->supplemental_datatypes_encountered) && (!GLOBALS->supplemental_vartypes_encountered)) ?
255 (varxt ? varxt_pnt : vardatatype_strings[vardt]) : vartype_strings[vartype]),
256 DIR_COLUMN, vardir_strings[vardir],
257 DTYPE_COLUMN, varxt ? varxt_pnt : vardatatype_strings[vardt],
258 -1);
259 }
260 }
261 else
262 {
263 if(s != t->name)
264 {
265 free_2(s);
266 }
267 }
268 }
269 }
270
271 /*
272 * tree open/close handling
273 */
create_sst_nodes_if_necessary(GtkCTreeNode * node)274 static void create_sst_nodes_if_necessary(GtkCTreeNode *node)
275 {
276 #ifndef WAVE_DISABLE_FAST_TREE
277 if(node)
278 {
279 GtkCTreeRow *gctr = GTK_CTREE_ROW(node);
280 struct tree *t = (struct tree *)(gctr->row.data);
281
282 if(t->child)
283 {
284 GtkCTree *ctree = GLOBALS->ctree_main;
285 GtkCTreeNode *n = gctr->children;
286
287 gtk_clist_freeze(GTK_CLIST(ctree));
288
289 while(n)
290 {
291 GtkCTreeRow *g = GTK_CTREE_ROW(n);
292
293 t = (struct tree *)(g->row.data);
294 if(t->t_which < 0)
295 {
296 if(!t->children_in_gui)
297 {
298 t->children_in_gui = 1;
299 maketree2(n, t, 0, n);
300 }
301 }
302
303 n = GTK_CTREE_NODE_NEXT(n);
304 }
305
306 gtk_clist_thaw(GTK_CLIST(ctree));
307 }
308 }
309 #endif
310 }
311
312
force_open_tree_node(char * name,int keep_path_nodes_open,struct tree ** t_pnt)313 int force_open_tree_node(char *name, int keep_path_nodes_open, struct tree **t_pnt) {
314 GtkCTree *ctree = GLOBALS->ctree_main;
315 int rv = 1 ; /* can possible open */
316 if(ctree && GLOBALS->any_tree_node) {
317 int namlen = strlen(name);
318 char *namecache = wave_alloca(namlen+1);
319 char *name_end = name + namlen - 1;
320 char *zap = name;
321 GtkCTreeNode *node = GLOBALS->any_tree_node;
322 GtkCTreeRow *gctr = GTK_CTREE_ROW(node);
323 int depth = 1;
324
325 strcpy(namecache, name);
326 while(gctr->parent) {
327 node = gctr->parent;
328 gctr = GTK_CTREE_ROW(node);
329 }
330 for(;;) {
331 struct tree *t = gctr->row.data;
332 if(t_pnt) { *t_pnt = t; }
333 while(*zap) {
334 if(*zap != GLOBALS->hier_delimeter) {
335 zap++;
336 }
337 else {
338 *zap = 0;
339 break;
340 }
341 }
342 if(!strcmp(t->name, name)) {
343 if(zap == name_end) {
344 GtkCTreeNode **nodehist = wave_alloca(depth * sizeof(GtkCTreeNode *));
345 int *exp1 = wave_alloca(depth * sizeof(int));
346 int i = depth-1;
347 nodehist[i] = node;
348 exp1[i--] = 1;
349 /* now work backwards up to parent getting the node open/close history*/
350 gctr = GTK_CTREE_ROW(node);
351 while(gctr->parent) {
352 node = gctr->parent;
353 gctr = GTK_CTREE_ROW(node);
354 nodehist[i] = node;
355 exp1[i--] = gctr->expanded || (keep_path_nodes_open != 0);
356 }
357 gtk_clist_freeze(GTK_CLIST(ctree));
358 /* fully expand down */
359 for(i=0;i<depth;i++) {
360 gtk_ctree_expand(ctree, nodehist[i]);
361 }
362 /* work backwards and close up nodes that were originally closed */
363 for(i=depth-1;i>=0;i--) {
364 if(exp1[i]) {
365 gtk_ctree_expand(ctree, nodehist[i]);
366 }
367 else {
368 gtk_ctree_collapse(ctree, nodehist[i]);
369 }
370 }
371 gtk_clist_thaw(GTK_CLIST(ctree));
372
373 gtk_ctree_node_moveto(ctree, nodehist[depth-1],
374 depth /*column*/,
375 0.5 /*row_align*/,
376 0.5 /*col_align*/);
377 /* printf("[treeopennode] '%s' ok\n", name); */
378 rv = 0 ; /* opened */
379 GLOBALS->open_tree_nodes = xl_insert(namecache, GLOBALS->open_tree_nodes, NULL);
380 return rv;
381 }
382 else {
383 depth++;
384 create_sst_nodes_if_necessary(node);
385 node = gctr->children;
386 if(!node) break;
387 gctr = GTK_CTREE_ROW(node);
388 if(!gctr) break;
389 name = ++zap;
390 continue;
391 }
392 }
393 node = gctr->sibling;
394 if(!node) break;
395 gctr = GTK_CTREE_ROW(node);
396 }
397 /* printf("[treeopennode] '%s' failed\n", name); */
398 } else {
399 rv = -1 ; /* tree does not exist */
400 }
401 return rv ;
402 }
403
dump_open_tree_nodes(FILE * wave,xl_Tree * t)404 void dump_open_tree_nodes(FILE *wave, xl_Tree *t)
405 {
406 if(t->left)
407 {
408 dump_open_tree_nodes(wave, t->left);
409 }
410
411 fprintf(wave, "[treeopen] %s\n", t->item);
412
413 if(t->right)
414 {
415 dump_open_tree_nodes(wave, t->right);
416 }
417 }
418
generic_tree_expand_collapse_callback(int is_expand,GtkCTreeNode * node)419 static void generic_tree_expand_collapse_callback(int is_expand, GtkCTreeNode *node)
420 {
421 GtkCTreeRow **gctr;
422 int depth, i;
423 int len = 1;
424 char *tstring;
425 char hier_suffix[2];
426 int found;
427
428 hier_suffix[0] = GLOBALS->hier_delimeter;
429 hier_suffix[1] = 0;
430
431 if(!node) return;
432
433 depth = GTK_CTREE_ROW(node)->level;
434 gctr = wave_alloca(depth * sizeof(GtkCTreeRow *));
435
436 for(i=depth-1;i>=0;i--)
437 {
438 struct tree *t;
439 gctr[i] = GTK_CTREE_ROW(node);
440 t = gctr[i]->row.data;
441 len += (strlen(t->name) + 1);
442 node = gctr[i]->parent;
443 }
444
445 tstring = wave_alloca(len);
446 memset(tstring, 0, len);
447
448 for(i=0;i<depth;i++)
449 {
450 struct tree *t = gctr[i]->row.data;
451 strcat(tstring, t->name);
452 strcat(tstring, hier_suffix);
453 }
454
455
456 if(GLOBALS->open_tree_nodes) /* cut down on chatter to Tcl clients */
457 {
458 GLOBALS->open_tree_nodes = xl_splay(tstring, GLOBALS->open_tree_nodes);
459 if(!strcmp(GLOBALS->open_tree_nodes->item, tstring))
460 {
461 found = 1;
462 }
463 else
464 {
465 found = 0;
466 }
467 }
468 else
469 {
470 found = 0;
471 }
472
473 if(is_expand)
474 {
475 GLOBALS->open_tree_nodes = xl_insert(tstring, GLOBALS->open_tree_nodes, NULL);
476 if(!found)
477 {
478 gtkwavetcl_setvar(WAVE_TCLCB_TREE_EXPAND, tstring, WAVE_TCLCB_TREE_EXPAND_FLAGS);
479 }
480 }
481 else
482 {
483 GLOBALS->open_tree_nodes = xl_delete(tstring, GLOBALS->open_tree_nodes);
484 if(found)
485 {
486 gtkwavetcl_setvar(WAVE_TCLCB_TREE_COLLAPSE, tstring, WAVE_TCLCB_TREE_COLLAPSE_FLAGS);
487 }
488 }
489 }
490
tree_expand_callback(GtkCTree * ctree,GtkCTreeNode * node,gpointer user_data)491 static void tree_expand_callback(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data)
492 {
493 (void)ctree;
494 (void)user_data;
495
496 create_sst_nodes_if_necessary(node);
497 generic_tree_expand_collapse_callback(1, node);
498 #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND
499 #ifdef MAC_INTEGRATION
500 /* workaround for ctree not rendering properly in OSX */
501 gtk_widget_hide(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1));
502 gtk_widget_show(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1));
503 #endif
504 #endif
505 }
506
tree_collapse_callback(GtkCTree * ctree,GtkCTreeNode * node,gpointer user_data)507 static void tree_collapse_callback(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data)
508 {
509 (void)ctree;
510 (void)user_data;
511
512 generic_tree_expand_collapse_callback(0, node);
513 #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND
514 #ifdef MAC_INTEGRATION
515 /* workaround for ctree not rendering properly in OSX */
516 gtk_widget_hide(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1));
517 gtk_widget_show(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1));
518 #endif
519 #endif
520 }
521
522
select_tree_node(char * name)523 void select_tree_node(char *name)
524 {
525 GtkCTree *ctree = GLOBALS->ctree_main;
526
527 if(ctree && GLOBALS->any_tree_node)
528 {
529 int namlen = strlen(name);
530 char *namecache = wave_alloca(namlen+1);
531 char *name_end = name + namlen - 1;
532 char *zap = name;
533 GtkCTreeNode *node = GLOBALS->any_tree_node;
534 GtkCTreeRow *gctr = GTK_CTREE_ROW(node);
535
536 strcpy(namecache, name);
537
538 while(gctr->parent)
539 {
540 node = gctr->parent;
541 gctr = GTK_CTREE_ROW(node);
542 }
543
544 for(;;)
545 {
546 struct tree *t = gctr->row.data;
547
548 while(*zap)
549 {
550 if(*zap != GLOBALS->hier_delimeter)
551 {
552 zap++;
553 }
554 else
555 {
556 *zap = 0;
557 break;
558 }
559 }
560
561 if(!strcmp(t->name, name))
562 {
563 if(zap == name_end)
564 {
565 /* printf("[treeselectnode] '%s' ok\n", name); */
566 gtk_ctree_select(ctree, node);
567
568 GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = t;
569 GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child;
570 fill_sig_store ();
571
572 return;
573 }
574 else
575 {
576 node = gctr->children;
577 gctr = GTK_CTREE_ROW(node);
578 if(!gctr) break;
579
580 name = ++zap;
581 continue;
582 }
583 }
584
585 node = gctr->sibling;
586 if(!node) break;
587 gctr = GTK_CTREE_ROW(node);
588 }
589
590 /* printf("[treeselectnode] '%s' failed\n", name); */
591 }
592 }
593
594
595
596 /* Callbacks for tree area when a row is selected/deselected. */
select_row_callback(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)597 static void select_row_callback(GtkWidget *widget, gint row, gint column,
598 GdkEventButton *event, gpointer data)
599 {
600 (void)widget;
601 (void)column;
602 (void)event;
603 (void)data;
604
605 struct tree *t;
606 GtkCTreeNode* node = gtk_ctree_node_nth(GLOBALS->ctree_main, row);
607
608 if(node)
609 {
610 GtkCTreeRow **gctr;
611 int depth, i;
612 int len = 1;
613 char *tstring;
614 char hier_suffix[2];
615
616 hier_suffix[0] = GLOBALS->hier_delimeter;
617 hier_suffix[1] = 0;
618
619 depth = GTK_CTREE_ROW(node)->level;
620 gctr = wave_alloca(depth * sizeof(GtkCTreeRow *));
621
622 for(i=depth-1;i>=0;i--)
623 {
624 gctr[i] = GTK_CTREE_ROW(node);
625 t = gctr[i]->row.data;
626 len += (strlen(t->name) + 1);
627 node = gctr[i]->parent;
628 }
629
630 tstring = wave_alloca(len);
631 memset(tstring, 0, len);
632
633 for(i=0;i<depth;i++)
634 {
635 t = gctr[i]->row.data;
636 strcat(tstring, t->name);
637 strcat(tstring, hier_suffix);
638 }
639
640 if(GLOBALS->selected_hierarchy_name)
641 {
642 free_2(GLOBALS->selected_hierarchy_name);
643 }
644 GLOBALS->selected_hierarchy_name = strdup_2(tstring);
645 }
646
647 t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row);
648 DEBUG(printf("TS: %08x %s\n",t,t->name));
649 GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = t;
650 GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child;
651 fill_sig_store ();
652 gtkwavetcl_setvar(WAVE_TCLCB_TREE_SELECT, GLOBALS->selected_hierarchy_name, WAVE_TCLCB_TREE_SELECT_FLAGS);
653 }
654
unselect_row_callback(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)655 static void unselect_row_callback(GtkWidget *widget, gint row, gint column,
656 GdkEventButton *event, gpointer data)
657 {
658 (void)widget;
659 (void)column;
660 (void)event;
661 (void)data;
662
663 struct tree *t;
664
665 if(GLOBALS->selected_hierarchy_name)
666 {
667 gtkwavetcl_setvar(WAVE_TCLCB_TREE_UNSELECT, GLOBALS->selected_hierarchy_name, WAVE_TCLCB_TREE_UNSELECT_FLAGS);
668 free_2(GLOBALS->selected_hierarchy_name);
669 GLOBALS->selected_hierarchy_name = NULL;
670 }
671
672 t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row);
673 if(t)
674 {
675 /* unused */
676 }
677 DEBUG(printf("TU: %08x %s\n",t,t->name));
678 GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL;
679 GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot;
680 fill_sig_store ();
681 }
682
683 /* Signal callback for the filter widget.
684 This catch the return key to update the signal area. */
685 static
filter_edit_cb(GtkWidget * widget,GdkEventKey * ev,gpointer * data)686 gboolean filter_edit_cb (GtkWidget *widget, GdkEventKey *ev, gpointer *data)
687 {
688 (void)data;
689
690 /* Maybe this test is too strong ? */
691 if (ev->keyval == GDK_Return)
692 {
693 const char *t;
694
695 /* Get the filter string, save it and change the store. */
696 if(GLOBALS->filter_str_treesearch_gtk2_c_1)
697 {
698 free_2((char *)GLOBALS->filter_str_treesearch_gtk2_c_1);
699 GLOBALS->filter_str_treesearch_gtk2_c_1 = NULL;
700 }
701 t = gtk_entry_get_text (GTK_ENTRY (widget));
702 if (t == NULL || *t == 0)
703 GLOBALS->filter_str_treesearch_gtk2_c_1 = NULL;
704 else
705 {
706 int i;
707
708 GLOBALS->filter_str_treesearch_gtk2_c_1 = malloc_2(strlen(t) + 1);
709 strcpy(GLOBALS->filter_str_treesearch_gtk2_c_1, t);
710
711 GLOBALS->filter_typ_treesearch_gtk2_c_1 = ND_DIR_UNSPECIFIED;
712 GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1 = 0;
713 GLOBALS->filter_matlen_treesearch_gtk2_c_1 = 0;
714 GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 0;
715
716 if(GLOBALS->filter_str_treesearch_gtk2_c_1[0] == '+')
717 {
718 for(i=0;i<=ND_DIR_MAX;i++)
719 {
720 int tlen = strlen(vardir_strings[i]);
721 if(!strncasecmp(vardir_strings[i], GLOBALS->filter_str_treesearch_gtk2_c_1 + 1, tlen))
722 {
723 if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 1] == '+')
724 {
725 GLOBALS->filter_matlen_treesearch_gtk2_c_1 = tlen + 2;
726 GLOBALS->filter_typ_treesearch_gtk2_c_1 = i;
727 if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 2] == 0)
728 {
729 GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 1;
730 }
731 }
732 }
733 }
734 }
735 else
736 if(GLOBALS->filter_str_treesearch_gtk2_c_1[0] == '-')
737 {
738 for(i=0;i<=ND_DIR_MAX;i++)
739 {
740 int tlen = strlen(vardir_strings[i]);
741 if(!strncasecmp(vardir_strings[i], GLOBALS->filter_str_treesearch_gtk2_c_1 + 1, tlen))
742 {
743 if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 1] == '-')
744 {
745 GLOBALS->filter_matlen_treesearch_gtk2_c_1 = tlen + 2;
746 GLOBALS->filter_typ_treesearch_gtk2_c_1 = i;
747 GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1 = 1; /* invert via XOR with 1 */
748 if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 2] == 0)
749 {
750 GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 1;
751 }
752 }
753 }
754 }
755 }
756
757 wave_regex_compile(GLOBALS->filter_str_treesearch_gtk2_c_1 + GLOBALS->filter_matlen_treesearch_gtk2_c_1, WAVE_REGEX_TREE);
758 }
759 fill_sig_store ();
760 }
761 return FALSE;
762 }
763
764
765 /*
766 * for dynamic updates, simply fake the return key to the function above
767 */
768 static
press_callback(GtkWidget * widget,gpointer * data)769 void press_callback (GtkWidget *widget, gpointer *data)
770 {
771 GdkEventKey ev;
772
773 ev.keyval = GDK_Return;
774
775 filter_edit_cb (widget, &ev, data);
776 }
777
778
779 /*
780 * select/unselect all in treeview
781 */
treeview_select_all_callback(void)782 void treeview_select_all_callback(void)
783 {
784 GtkTreeSelection* ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->dnd_sigview));
785 gtk_tree_selection_select_all(ts);
786 }
787
treeview_unselect_all_callback(void)788 void treeview_unselect_all_callback(void)
789 {
790 GtkTreeSelection* ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->dnd_sigview));
791 gtk_tree_selection_unselect_all(ts);
792 }
793
794
treebox_is_active(void)795 int treebox_is_active(void)
796 {
797 return(GLOBALS->is_active_treesearch_gtk2_c_6);
798 }
799
800 #if 0
801 static void enter_callback_e(GtkWidget *widget, GtkWidget *nothing)
802 {
803 (void)widget;
804 (void)nothing;
805
806 G_CONST_RETURN gchar *entry_text;
807 int len;
808 entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk2_c_2));
809 entry_text = entry_text ? entry_text : "";
810 DEBUG(printf("Entry contents: %s\n", entry_text));
811 if(!(len=strlen(entry_text))) GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=NULL;
812 else strcpy((GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=(char *)malloc_2(len+1)),entry_text);
813
814 wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk2_c_3);
815 gtk_widget_destroy(GLOBALS->window1_treesearch_gtk2_c_3);
816 GLOBALS->window1_treesearch_gtk2_c_3 = NULL;
817
818 GLOBALS->cleanup_e_treesearch_gtk2_c_3();
819 }
820
821 static void destroy_callback_e(GtkWidget *widget, GtkWidget *nothing)
822 {
823 (void)widget;
824 (void)nothing;
825
826 DEBUG(printf("Entry Cancel\n"));
827 GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=NULL;
828 wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk2_c_3);
829 gtk_widget_destroy(GLOBALS->window1_treesearch_gtk2_c_3);
830 GLOBALS->window1_treesearch_gtk2_c_3 = NULL;
831 }
832
833 static void entrybox_local(char *title, int width, char *default_text, int maxch, GtkSignalFunc func)
834 {
835 GtkWidget *vbox, *hbox;
836 GtkWidget *button1, *button2;
837
838 GLOBALS->cleanup_e_treesearch_gtk2_c_3=func;
839
840 /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
841 if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
842
843 /* create a new modal window */
844 GLOBALS->window1_treesearch_gtk2_c_3 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
845 install_focus_cb(GLOBALS->window1_treesearch_gtk2_c_3, ((char *)&GLOBALS->window1_treesearch_gtk2_c_3) - ((char *)GLOBALS));
846
847 gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window1_treesearch_gtk2_c_3), width, 60);
848 gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_treesearch_gtk2_c_3), title);
849 gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window1_treesearch_gtk2_c_3), "delete_event",(GtkSignalFunc) destroy_callback_e, NULL);
850
851 vbox = gtk_vbox_new (FALSE, 0);
852 gtk_container_add (GTK_CONTAINER (GLOBALS->window1_treesearch_gtk2_c_3), vbox);
853 gtk_widget_show (vbox);
854
855 GLOBALS->entry_a_treesearch_gtk2_c_2 = gtk_entry_new_with_max_length (maxch);
856 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_a_treesearch_gtk2_c_2), "activate",GTK_SIGNAL_FUNC(enter_callback_e),GLOBALS->entry_a_treesearch_gtk2_c_2);
857 gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk2_c_2), default_text);
858 gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk2_c_2),0, GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk2_c_2)->text_length);
859 gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_a_treesearch_gtk2_c_2, TRUE, TRUE, 0);
860 gtk_widget_show (GLOBALS->entry_a_treesearch_gtk2_c_2);
861
862 hbox = gtk_hbox_new (FALSE, 1);
863 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
864 gtk_widget_show (hbox);
865
866 button1 = gtk_button_new_with_label ("OK");
867 gtk_widget_set_usize(button1, 100, -1);
868 gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback_e), NULL);
869 gtk_widget_show (button1);
870 gtk_container_add (GTK_CONTAINER (hbox), button1);
871 GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
872 gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1));
873
874 button2 = gtk_button_new_with_label ("Cancel");
875 gtk_widget_set_usize(button2, 100, -1);
876 gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback_e), NULL);
877 GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
878 gtk_widget_show (button2);
879 gtk_container_add (GTK_CONTAINER (hbox), button2);
880
881 gtk_widget_show(GLOBALS->window1_treesearch_gtk2_c_3);
882 wave_gtk_grab_add(GLOBALS->window1_treesearch_gtk2_c_3);
883 }
884 #endif
885
886 /***************************************************************************/
887
888 /* Callback for insert/replace/append buttions.
889 This call-back is called for every signal selected. */
890
891 static void
sig_selection_foreach(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)892 sig_selection_foreach (GtkTreeModel *model,
893 GtkTreePath *path,
894 GtkTreeIter *iter,
895 gpointer data)
896 {
897 (void)path;
898 (void)data;
899
900 struct tree *sel;
901 /* const enum sst_cb_action action = (enum sst_cb_action)data; */
902 int i;
903 int low, high;
904
905 /* Get the tree. */
906 gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1);
907
908 if(!sel) return;
909
910 low = fetchlow(sel)->t_which;
911 high = fetchhigh(sel)->t_which;
912
913 /* Add signals and vectors. */
914 for(i=low;i<=high;i++)
915 {
916 int len;
917 struct symbol *s, *t;
918 s=GLOBALS->facs[i];
919 t=s->vec_root;
920 if((t)&&(GLOBALS->autocoalesce))
921 {
922 if(get_s_selected(t))
923 {
924 set_s_selected(t,0);
925 len=0;
926 while(t)
927 {
928 len++;
929 t=t->vec_chain;
930 }
931 if(len) add_vector_chain(s->vec_root, len);
932 }
933 }
934 else
935 {
936 AddNodeUnroll(s->n, NULL);
937 }
938 }
939 }
940
941 static void
sig_selection_foreach_finalize(gpointer data)942 sig_selection_foreach_finalize (gpointer data)
943 {
944 const enum sst_cb_action action = (enum sst_cb_action)data;
945
946 if (action == SST_ACTION_REPLACE || action == SST_ACTION_INSERT || action == SST_ACTION_PREPEND)
947 {
948 Trptr tfirst=NULL, tlast=NULL;
949 Trptr t;
950 Trptr *tp = NULL;
951 int numhigh = 0;
952 int it;
953
954 if (action == SST_ACTION_REPLACE)
955 {
956 tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */
957 }
958
959 GLOBALS->traces.buffercount=GLOBALS->traces.total;
960 GLOBALS->traces.buffer=GLOBALS->traces.first;
961 GLOBALS->traces.bufferlast=GLOBALS->traces.last;
962 GLOBALS->traces.first=GLOBALS->tcache_treesearch_gtk2_c_2.first;
963 GLOBALS->traces.last=GLOBALS->tcache_treesearch_gtk2_c_2.last;
964 GLOBALS->traces.total=GLOBALS->tcache_treesearch_gtk2_c_2.total;
965
966 if (action == SST_ACTION_REPLACE)
967 {
968 t = GLOBALS->traces.first;
969 while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; }
970 if(numhigh)
971 {
972 tp = calloc_2(numhigh, sizeof(Trptr));
973 t = GLOBALS->traces.first;
974 it = 0;
975 while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; }
976 }
977 }
978
979 if(action == SST_ACTION_PREPEND)
980 {
981 PrependBuffer();
982 }
983 else
984 {
985 PasteBuffer();
986 }
987
988 GLOBALS->traces.buffercount=GLOBALS->tcache_treesearch_gtk2_c_2.buffercount;
989 GLOBALS->traces.buffer=GLOBALS->tcache_treesearch_gtk2_c_2.buffer;
990 GLOBALS->traces.bufferlast=GLOBALS->tcache_treesearch_gtk2_c_2.bufferlast;
991
992 if (action == SST_ACTION_REPLACE)
993 {
994 for(it=0;it<numhigh;it++)
995 {
996 tp[it]->flags |= TR_HIGHLIGHT;
997 }
998
999 t = tfirst;
1000 while(t)
1001 {
1002 t->flags &= ~TR_HIGHLIGHT;
1003 if(t==tlast) break;
1004 t=t->t_next;
1005 }
1006
1007 CutBuffer();
1008
1009 while(tfirst)
1010 {
1011 tfirst->flags |= TR_HIGHLIGHT;
1012 if(tfirst==tlast) break;
1013 tfirst=tfirst->t_next;
1014 }
1015
1016 if(tp)
1017 {
1018 free_2(tp);
1019 }
1020 }
1021 }
1022 }
1023
1024 static void
sig_selection_foreach_preload_lx2(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)1025 sig_selection_foreach_preload_lx2
1026 (GtkTreeModel *model,
1027 GtkTreePath *path,
1028 GtkTreeIter *iter,
1029 gpointer data)
1030 {
1031 (void)path;
1032 (void)data;
1033
1034 struct tree *sel;
1035 /* const enum sst_cb_action action = (enum sst_cb_action)data; */
1036 int i;
1037 int low, high;
1038
1039 /* Get the tree. */
1040 gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1);
1041
1042 if(!sel) return;
1043
1044 low = fetchlow(sel)->t_which;
1045 high = fetchhigh(sel)->t_which;
1046
1047 /* If signals are vectors, coalesces vectors if so. */
1048 for(i=low;i<=high;i++)
1049 {
1050 struct symbol *s;
1051 s=GLOBALS->facs[i];
1052 if(s->vec_root)
1053 {
1054 set_s_selected(s->vec_root, GLOBALS->autocoalesce);
1055 }
1056 }
1057
1058 /* LX2 */
1059 if(GLOBALS->is_lx2)
1060 {
1061 for(i=low;i<=high;i++)
1062 {
1063 struct symbol *s, *t;
1064 s=GLOBALS->facs[i];
1065 t=s->vec_root;
1066 if((t)&&(GLOBALS->autocoalesce))
1067 {
1068 if(get_s_selected(t))
1069 {
1070 while(t)
1071 {
1072 if(t->n->mv.mvlfac)
1073 {
1074 lx2_set_fac_process_mask(t->n);
1075 GLOBALS->pre_import_treesearch_gtk2_c_1++;
1076 }
1077 t=t->vec_chain;
1078 }
1079 }
1080 }
1081 else
1082 {
1083 if(s->n->mv.mvlfac)
1084 {
1085 lx2_set_fac_process_mask(s->n);
1086 GLOBALS->pre_import_treesearch_gtk2_c_1++;
1087 }
1088 }
1089 }
1090 }
1091 /* LX2 */
1092 }
1093
1094
1095 static void
action_callback(enum sst_cb_action action)1096 action_callback(enum sst_cb_action action)
1097 {
1098 if(action == SST_ACTION_NONE) return; /* only used for double-click in signals pane of SST */
1099
1100 GLOBALS->pre_import_treesearch_gtk2_c_1 = 0;
1101
1102 /* once through to mass gather lx2 traces... */
1103 gtk_tree_selection_selected_foreach
1104 (GLOBALS->sig_selection_treesearch_gtk2_c_1, &sig_selection_foreach_preload_lx2, (void *)action);
1105 if(GLOBALS->pre_import_treesearch_gtk2_c_1)
1106 {
1107 lx2_import_masked();
1108 }
1109
1110 /* then do */
1111 if (action == SST_ACTION_INSERT || action == SST_ACTION_REPLACE || action == SST_ACTION_PREPEND)
1112 {
1113 /* Save and clear current traces. */
1114 memcpy(&GLOBALS->tcache_treesearch_gtk2_c_2,&GLOBALS->traces,sizeof(Traces));
1115 GLOBALS->traces.total=0;
1116 GLOBALS->traces.first=GLOBALS->traces.last=NULL;
1117 }
1118
1119 gtk_tree_selection_selected_foreach
1120 (GLOBALS->sig_selection_treesearch_gtk2_c_1, &sig_selection_foreach, (void *)action);
1121
1122 sig_selection_foreach_finalize((void *)action);
1123
1124 if(action == SST_ACTION_APPEND)
1125 {
1126 GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last;
1127 }
1128 MaxSignalLength();
1129 signalarea_configure_event(GLOBALS->signalarea, NULL);
1130 wavearea_configure_event(GLOBALS->wavearea, NULL);
1131 }
1132
insert_callback(GtkWidget * widget,GtkWidget * nothing)1133 static void insert_callback(GtkWidget *widget, GtkWidget *nothing)
1134 {
1135 (void)nothing;
1136
1137 set_window_busy(widget);
1138 action_callback (SST_ACTION_INSERT);
1139 set_window_idle(widget);
1140 }
1141
replace_callback(GtkWidget * widget,GtkWidget * nothing)1142 static void replace_callback(GtkWidget *widget, GtkWidget *nothing)
1143 {
1144 (void)nothing;
1145
1146 set_window_busy(widget);
1147 action_callback (SST_ACTION_REPLACE);
1148 set_window_idle(widget);
1149 }
1150
ok_callback(GtkWidget * widget,GtkWidget * nothing)1151 static void ok_callback(GtkWidget *widget, GtkWidget *nothing)
1152 {
1153 (void)nothing;
1154
1155 set_window_busy(widget);
1156 action_callback (SST_ACTION_APPEND);
1157 set_window_idle(widget);
1158 }
1159
1160
destroy_callback(GtkWidget * widget,GtkWidget * nothing)1161 static void destroy_callback(GtkWidget *widget, GtkWidget *nothing)
1162 {
1163 (void)widget;
1164 (void)nothing;
1165
1166 GLOBALS->is_active_treesearch_gtk2_c_6=0;
1167 gtk_widget_destroy(GLOBALS->window_treesearch_gtk2_c_12);
1168 GLOBALS->window_treesearch_gtk2_c_12 = NULL;
1169 GLOBALS->dnd_sigview = NULL;
1170 GLOBALS->gtk2_tree_frame = NULL;
1171 GLOBALS->ctree_main = NULL;
1172 GLOBALS->filter_entry = NULL; /* when treebox() SST goes away after closed and rc hide_sst is true */
1173 free_afl();
1174
1175 if(GLOBALS->selected_hierarchy_name)
1176 {
1177 free_2(GLOBALS->selected_hierarchy_name);
1178 GLOBALS->selected_hierarchy_name = NULL;
1179 }
1180 }
1181
1182 /**********************************************************************/
1183
1184 static gboolean
view_selection_func(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,gpointer userdata)1185 view_selection_func (GtkTreeSelection *selection,
1186 GtkTreeModel *model,
1187 GtkTreePath *path,
1188 gboolean path_currently_selected,
1189 gpointer userdata)
1190 {
1191 (void)selection;
1192 (void)userdata;
1193
1194 GtkTreeIter iter;
1195
1196 if (gtk_tree_model_get_iter(model, &iter, path))
1197 {
1198 gchar *name;
1199
1200 gtk_tree_model_get(model, &iter, 0, &name, -1);
1201
1202 if(GLOBALS->selected_sig_name)
1203 {
1204 free_2(GLOBALS->selected_sig_name);
1205 GLOBALS->selected_sig_name = NULL;
1206 }
1207
1208 if (!path_currently_selected)
1209 {
1210 GLOBALS->selected_sig_name = strdup_2(name);
1211 gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_SELECT, name, WAVE_TCLCB_TREE_SIG_SELECT_FLAGS);
1212 }
1213 else
1214 {
1215 gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_UNSELECT, name, WAVE_TCLCB_TREE_SIG_UNSELECT_FLAGS);
1216 }
1217
1218 g_free(name);
1219 }
1220 return TRUE; /* allow selection state to change */
1221 }
1222
1223 /**********************************************************************/
1224
button_press_event_std(GtkWidget * widget,GdkEventButton * event)1225 static gint button_press_event_std(GtkWidget *widget, GdkEventButton *event)
1226 {
1227 (void)widget;
1228
1229 if(event->type == GDK_2BUTTON_PRESS)
1230 {
1231 if(GLOBALS->selected_hierarchy_name && GLOBALS->selected_sig_name)
1232 {
1233 char *sstr = wave_alloca(strlen(GLOBALS->selected_hierarchy_name) + strlen(GLOBALS->selected_sig_name) + 1);
1234 strcpy(sstr, GLOBALS->selected_hierarchy_name);
1235 strcat(sstr, GLOBALS->selected_sig_name);
1236
1237 gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK, sstr, WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_FLAGS);
1238 action_callback(GLOBALS->sst_dbl_action_type);
1239 }
1240 }
1241
1242 return(FALSE);
1243 }
1244
hier_top_button_press_event_std(GtkWidget * widget,GdkEventButton * event)1245 static gint hier_top_button_press_event_std(GtkWidget *widget, GdkEventButton *event)
1246 {
1247 if((event->button == 3) && (event->type == GDK_BUTTON_PRESS))
1248 {
1249 if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1)
1250 {
1251 do_sst_popup_menu (widget, event);
1252 return(TRUE);
1253 }
1254 }
1255
1256 return(FALSE);
1257 }
1258
1259 /**********************************************************************/
1260
1261 /*
1262 * mainline..
1263 */
treebox(char * title,GtkSignalFunc func,GtkWidget * old_window)1264 void treebox(char *title, GtkSignalFunc func, GtkWidget *old_window)
1265 {
1266 GtkWidget *scrolled_win, *sig_scroll_win;
1267 GtkWidget *hbox;
1268 GtkWidget *button1, *button2, *button4, *button5;
1269 GtkWidget *frameh, *sig_frame;
1270 GtkWidget *vbox, *vpan, *filter_hbox;
1271 GtkWidget *filter_label;
1272 GtkWidget *sig_view;
1273 GtkTooltips *tooltips;
1274 GtkCList *clist;
1275
1276 /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
1277 if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
1278
1279 if(old_window)
1280 {
1281 GLOBALS->is_active_treesearch_gtk2_c_6=1;
1282 GLOBALS->cleanup_treesearch_gtk2_c_8=func;
1283 goto do_tooltips;
1284 }
1285
1286 if(GLOBALS->is_active_treesearch_gtk2_c_6)
1287 {
1288 if(GLOBALS->window_treesearch_gtk2_c_12)
1289 {
1290 gdk_window_raise(GLOBALS->window_treesearch_gtk2_c_12->window);
1291 }
1292 else
1293 {
1294 #if GTK_CHECK_VERSION(2,4,0)
1295 if(GLOBALS->expanderwindow)
1296 {
1297 gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), TRUE);
1298 }
1299 #endif
1300 }
1301 return;
1302 }
1303
1304 GLOBALS->is_active_treesearch_gtk2_c_6=1;
1305 GLOBALS->cleanup_treesearch_gtk2_c_8=func;
1306
1307 /* create a new modal window */
1308 GLOBALS->window_treesearch_gtk2_c_12 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
1309 install_focus_cb(GLOBALS->window_treesearch_gtk2_c_12, ((char *)&GLOBALS->window_treesearch_gtk2_c_12) - ((char *)GLOBALS));
1310
1311 gtk_window_set_title(GTK_WINDOW (GLOBALS->window_treesearch_gtk2_c_12), title);
1312 gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12), "delete_event",(GtkSignalFunc) destroy_callback, NULL);
1313
1314 do_tooltips:
1315 tooltips=gtk_tooltips_new_2();
1316
1317 GLOBALS->treesearch_gtk2_window_vbox = vbox = gtk_vbox_new (FALSE, 1);
1318 gtk_widget_show (vbox);
1319
1320 gtkwave_signal_connect(GTK_OBJECT(vbox), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL);
1321
1322 vpan = gtk_vpaned_new ();
1323 gtk_widget_show (vpan);
1324 gtk_box_pack_start (GTK_BOX (vbox), vpan, TRUE, TRUE, 1);
1325
1326 /* Hierarchy. */
1327 GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL);
1328 gtk_container_border_width (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), 3);
1329 gtk_widget_show(GLOBALS->gtk2_tree_frame);
1330
1331 gtk_paned_pack1 (GTK_PANED (vpan), GLOBALS->gtk2_tree_frame, TRUE, FALSE);
1332
1333 GLOBALS->tree_treesearch_gtk2_c_1=gtk_ctree_new(1,0);
1334 GLOBALS->ctree_main=GTK_CTREE(GLOBALS->tree_treesearch_gtk2_c_1);
1335 gtk_clist_set_column_auto_resize (GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), 0, TRUE);
1336 gtk_widget_show(GLOBALS->tree_treesearch_gtk2_c_1);
1337
1338 gtk_clist_set_use_drag_icons(GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), FALSE);
1339
1340 clist=GTK_CLIST(GLOBALS->tree_treesearch_gtk2_c_1);
1341
1342 gtkwave_signal_connect_object (GTK_OBJECT (clist), "select_row", GTK_SIGNAL_FUNC(select_row_callback), NULL);
1343 gtkwave_signal_connect_object (GTK_OBJECT (clist), "unselect_row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL);
1344 gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_expand", GTK_SIGNAL_FUNC(tree_expand_callback), NULL);
1345 gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_collapse", GTK_SIGNAL_FUNC(tree_collapse_callback), NULL);
1346
1347 gtk_clist_freeze(clist);
1348 gtk_clist_clear(clist);
1349
1350 decorated_module_cleanup();
1351 maketree(NULL, GLOBALS->treeroot);
1352 gtk_clist_thaw(clist);
1353
1354 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1355 gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 50);
1356 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1357 GTK_POLICY_AUTOMATIC,
1358 GTK_POLICY_AUTOMATIC);
1359 gtk_widget_show(scrolled_win);
1360 gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (GLOBALS->tree_treesearch_gtk2_c_1));
1361 gtk_container_add (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), scrolled_win);
1362
1363
1364 /* Signal names. */
1365 GLOBALS->sig_store_treesearch_gtk2_c_1 = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
1366 GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL;
1367 GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot;
1368 fill_sig_store ();
1369
1370 sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_treesearch_gtk2_c_1));
1371 gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL);
1372
1373 /* The view now holds a reference. We can get rid of our own reference */
1374 g_object_unref (G_OBJECT (GLOBALS->sig_store_treesearch_gtk2_c_1));
1375
1376
1377 {
1378 GtkCellRenderer *renderer;
1379 GtkTreeViewColumn *column;
1380
1381 renderer = gtk_cell_renderer_text_new ();
1382
1383 switch(GLOBALS->loaded_file_type)
1384 {
1385 #ifdef EXTLOAD_SUFFIX
1386 case EXTLOAD_FILE:
1387 #endif
1388 case FST_FILE:
1389 /* fallthrough for Dir is deliberate for extload and FST */
1390 if(GLOBALS->nonimplicit_direction_encountered)
1391 {
1392 column = gtk_tree_view_column_new_with_attributes ("Dir",
1393 renderer,
1394 "text", DIR_COLUMN,
1395 NULL);
1396 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1397 }
1398 /* fallthrough */
1399 case AE2_FILE:
1400 case VCD_FILE:
1401 case VCD_RECODER_FILE:
1402 case DUMPLESS_FILE:
1403 column = gtk_tree_view_column_new_with_attributes (((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) ? "VType" : "Type",
1404 renderer,
1405 "text", TYPE_COLUMN,
1406 NULL);
1407 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1408 if((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered))
1409 {
1410 column = gtk_tree_view_column_new_with_attributes ("DType",
1411 renderer,
1412 "text", DTYPE_COLUMN,
1413 NULL);
1414 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1415 }
1416 break;
1417 default:
1418 break;
1419 }
1420
1421 column = gtk_tree_view_column_new_with_attributes ("Signals",
1422 renderer,
1423 "text", NAME_COLUMN,
1424 NULL);
1425 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1426
1427
1428 /* Setup the selection handler */
1429 GLOBALS->sig_selection_treesearch_gtk2_c_1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view));
1430 gtk_tree_selection_set_mode (GLOBALS->sig_selection_treesearch_gtk2_c_1, GTK_SELECTION_MULTIPLE);
1431 gtk_tree_selection_set_select_function (GLOBALS->sig_selection_treesearch_gtk2_c_1,
1432 view_selection_func, NULL, NULL);
1433
1434 gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL);
1435 }
1436
1437 GLOBALS->dnd_sigview = sig_view;
1438 dnd_setup(GLOBALS->dnd_sigview, GLOBALS->signalarea, 0);
1439
1440 sig_frame = gtk_frame_new (NULL);
1441 gtk_container_border_width (GTK_CONTAINER (sig_frame), 3);
1442 gtk_widget_show(sig_frame);
1443
1444 gtk_paned_pack2 (GTK_PANED (vpan), sig_frame, TRUE, FALSE);
1445
1446 sig_scroll_win = gtk_scrolled_window_new (NULL, NULL);
1447 gtk_widget_set_usize (GTK_WIDGET (sig_scroll_win), 80, 100);
1448 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sig_scroll_win),
1449 GTK_POLICY_AUTOMATIC,
1450 GTK_POLICY_AUTOMATIC);
1451 gtk_widget_show(sig_scroll_win);
1452 gtk_container_add (GTK_CONTAINER (sig_frame), sig_scroll_win);
1453 gtk_container_add (GTK_CONTAINER (sig_scroll_win), sig_view);
1454 gtk_widget_show (sig_view);
1455
1456
1457 /* Filter. */
1458 filter_hbox = gtk_hbox_new (FALSE, 1);
1459 gtk_widget_show (filter_hbox);
1460
1461 filter_label = gtk_label_new ("Filter:");
1462 gtk_widget_show (filter_label);
1463 gtk_box_pack_start (GTK_BOX (filter_hbox), filter_label, FALSE, FALSE, 1);
1464
1465 GLOBALS->filter_entry = gtk_entry_new ();
1466 if(GLOBALS->filter_str_treesearch_gtk2_c_1)
1467 {
1468 gtk_entry_set_text(GTK_ENTRY(GLOBALS->filter_entry), GLOBALS->filter_str_treesearch_gtk2_c_1);
1469 }
1470
1471 gtk_widget_show (GLOBALS->filter_entry);
1472
1473 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "activate", GTK_SIGNAL_FUNC(press_callback), NULL);
1474 if(!GLOBALS->do_dynamic_treefilter)
1475 {
1476 gtkwave_signal_connect(GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GtkSignalFunc) filter_edit_cb, NULL);
1477 }
1478 else
1479 {
1480 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "changed", GTK_SIGNAL_FUNC(press_callback), NULL);
1481 }
1482
1483 gtk_tooltips_set_tip_2(tooltips, GLOBALS->filter_entry,
1484 "Add a POSIX filter. "
1485 "'.*' matches any number of characters,"
1486 " '.' matches any character. Hit Return to apply."
1487 " The filter may be preceded with the port direction if it exists such as ++ (show only non-port), +I+, +O+, +IO+, etc."
1488 " Use -- to exclude all non-ports (i.e., show only all ports), -I- to exclude all input ports, etc.",
1489 NULL);
1490
1491 gtk_box_pack_start (GTK_BOX (filter_hbox), GLOBALS->filter_entry, FALSE, FALSE, 1);
1492
1493 gtk_box_pack_start (GTK_BOX (vbox), filter_hbox, FALSE, FALSE, 1);
1494
1495 /* Buttons. */
1496 frameh = gtk_frame_new (NULL);
1497 gtk_container_border_width (GTK_CONTAINER (frameh), 3);
1498 gtk_widget_show(frameh);
1499 gtk_box_pack_start (GTK_BOX (vbox), frameh, FALSE, FALSE, 1);
1500
1501
1502 hbox = gtk_hbox_new (FALSE, 1);
1503 gtk_widget_show (hbox);
1504
1505 button1 = gtk_button_new_with_label ("Append");
1506 gtk_container_border_width (GTK_CONTAINER (button1), 3);
1507 gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12));
1508 gtk_widget_show (button1);
1509 gtk_tooltips_set_tip_2(tooltips, button1,
1510 "Add selected signal hierarchy to end of the display on the main window.",NULL);
1511
1512 gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0);
1513
1514 button2 = gtk_button_new_with_label (" Insert ");
1515 gtk_container_border_width (GTK_CONTAINER (button2), 3);
1516 gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked",GTK_SIGNAL_FUNC(insert_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12));
1517 gtk_widget_show (button2);
1518 gtk_tooltips_set_tip_2(tooltips, button2,
1519 "Add selected signal hierarchy after last highlighted signal on the main window.",NULL);
1520 gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0);
1521
1522 button4 = gtk_button_new_with_label (" Replace ");
1523 gtk_container_border_width (GTK_CONTAINER (button4), 3);
1524 gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked",GTK_SIGNAL_FUNC(replace_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12));
1525 gtk_widget_show (button4);
1526 gtk_tooltips_set_tip_2(tooltips, button4,
1527 "Replace highlighted signals on the main window with signals selected above.",NULL);
1528 gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0);
1529
1530 button5 = gtk_button_new_with_label (" Exit ");
1531 gtk_container_border_width (GTK_CONTAINER (button5), 3);
1532 gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12));
1533 gtk_tooltips_set_tip_2(tooltips, button5,
1534 "Do nothing and return to the main window.",NULL);
1535 gtk_widget_show (button5);
1536 gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0);
1537
1538 gtk_container_add (GTK_CONTAINER (frameh), hbox);
1539 gtk_container_add (GTK_CONTAINER (GLOBALS->window_treesearch_gtk2_c_12), vbox);
1540
1541 gtk_window_set_default_size (GTK_WINDOW (GLOBALS->window_treesearch_gtk2_c_12), 200, 400);
1542 gtk_widget_show(GLOBALS->window_treesearch_gtk2_c_12);
1543 }
1544
1545
1546 /*
1547 * for use with expander in gtk2.4 and higher...
1548 */
treeboxframe(char * title,GtkSignalFunc func)1549 GtkWidget* treeboxframe(char *title, GtkSignalFunc func)
1550 {
1551 (void)title;
1552
1553 GtkWidget *scrolled_win, *sig_scroll_win;
1554 GtkWidget *hbox;
1555 GtkWidget *button1, *button2, *button4;
1556 GtkWidget *frameh, *sig_frame;
1557 GtkWidget *vbox, *vpan, *filter_hbox;
1558 GtkWidget *filter_label;
1559 GtkWidget *sig_view;
1560 GtkTooltips *tooltips;
1561 GtkCList *clist;
1562
1563 GLOBALS->is_active_treesearch_gtk2_c_6=1;
1564 GLOBALS->cleanup_treesearch_gtk2_c_8=func;
1565
1566 /* create a new modal window */
1567 tooltips=gtk_tooltips_new_2();
1568
1569 vbox = gtk_vbox_new (FALSE, 1);
1570 gtk_widget_show (vbox);
1571
1572 gtkwave_signal_connect(GTK_OBJECT(vbox), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL);
1573
1574 vpan = gtk_vpaned_new (); /* GLOBALS->sst_vpaned is to be used to clone position over during reload */
1575 GLOBALS->sst_vpaned = (GtkPaned *)vpan;
1576 if(GLOBALS->vpanedwindow_size_cache)
1577 {
1578 gtk_paned_set_position(GTK_PANED(GLOBALS->sst_vpaned), GLOBALS->vpanedwindow_size_cache);
1579 GLOBALS->vpanedwindow_size_cache = 0;
1580 }
1581 gtk_widget_show (vpan);
1582 gtk_box_pack_start (GTK_BOX (vbox), vpan, TRUE, TRUE, 1);
1583
1584 /* Hierarchy. */
1585 GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL);
1586 gtk_container_border_width (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), 3);
1587 gtk_widget_show(GLOBALS->gtk2_tree_frame);
1588
1589 gtk_paned_pack1 (GTK_PANED (vpan), GLOBALS->gtk2_tree_frame, TRUE, FALSE);
1590
1591 GLOBALS->tree_treesearch_gtk2_c_1=gtk_ctree_new(1,0);
1592 GLOBALS->ctree_main=GTK_CTREE(GLOBALS->tree_treesearch_gtk2_c_1);
1593 gtk_clist_set_column_auto_resize (GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), 0, TRUE);
1594 gtk_widget_show(GLOBALS->tree_treesearch_gtk2_c_1);
1595
1596 clist=GTK_CLIST(GLOBALS->tree_treesearch_gtk2_c_1);
1597 gtkwave_signal_connect_object (GTK_OBJECT (clist), "select_row", GTK_SIGNAL_FUNC(select_row_callback), NULL);
1598 gtkwave_signal_connect_object (GTK_OBJECT (clist), "unselect_row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL);
1599 gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_expand", GTK_SIGNAL_FUNC(tree_expand_callback), NULL);
1600 gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_collapse", GTK_SIGNAL_FUNC(tree_collapse_callback), NULL);
1601
1602 gtk_clist_freeze(clist);
1603 gtk_clist_clear(clist);
1604
1605 decorated_module_cleanup();
1606 maketree(NULL, GLOBALS->treeroot);
1607 gtk_clist_thaw(clist);
1608
1609 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1610 gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 50);
1611 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1612 GTK_POLICY_AUTOMATIC,
1613 GTK_POLICY_AUTOMATIC);
1614 gtk_widget_show(scrolled_win);
1615 gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (GLOBALS->tree_treesearch_gtk2_c_1));
1616 gtk_container_add (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), scrolled_win);
1617
1618
1619 /* Signal names. */
1620 GLOBALS->sig_store_treesearch_gtk2_c_1 = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
1621 GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL;
1622 GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot;
1623 fill_sig_store ();
1624
1625 sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_treesearch_gtk2_c_1));
1626 gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL);
1627
1628 /* The view now holds a reference. We can get rid of our own reference */
1629 g_object_unref (G_OBJECT (GLOBALS->sig_store_treesearch_gtk2_c_1));
1630
1631
1632 {
1633 GtkCellRenderer *renderer;
1634 GtkTreeViewColumn *column;
1635
1636 renderer = gtk_cell_renderer_text_new ();
1637
1638 switch(GLOBALS->loaded_file_type)
1639 {
1640 #ifdef EXTLOAD_SUFFIX
1641 case EXTLOAD_FILE:
1642 #endif
1643 case FST_FILE:
1644 /* fallthrough for Dir is deliberate for extload and FST */
1645 if(GLOBALS->nonimplicit_direction_encountered)
1646 {
1647 column = gtk_tree_view_column_new_with_attributes ("Dir",
1648 renderer,
1649 "text", DIR_COLUMN,
1650 NULL);
1651 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1652 }
1653 /* fallthrough */
1654
1655 case AE2_FILE:
1656 case VCD_FILE:
1657 case VCD_RECODER_FILE:
1658 case DUMPLESS_FILE:
1659 column = gtk_tree_view_column_new_with_attributes (((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) ? "VType" : "Type",
1660 renderer,
1661 "text", TYPE_COLUMN,
1662 NULL);
1663 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1664 if((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered))
1665 {
1666 column = gtk_tree_view_column_new_with_attributes ("DType",
1667 renderer,
1668 "text", DTYPE_COLUMN,
1669 NULL);
1670 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1671 }
1672 break;
1673 default:
1674 break;
1675 }
1676
1677 column = gtk_tree_view_column_new_with_attributes ("Signals",
1678 renderer,
1679 "text", NAME_COLUMN,
1680 NULL);
1681 gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column);
1682
1683 /* Setup the selection handler */
1684 GLOBALS->sig_selection_treesearch_gtk2_c_1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view));
1685 gtk_tree_selection_set_mode (GLOBALS->sig_selection_treesearch_gtk2_c_1, GTK_SELECTION_MULTIPLE);
1686 gtk_tree_selection_set_select_function (GLOBALS->sig_selection_treesearch_gtk2_c_1,
1687 view_selection_func, NULL, NULL);
1688
1689 gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL);
1690 }
1691
1692 GLOBALS->dnd_sigview = sig_view;
1693
1694 sig_frame = gtk_frame_new (NULL);
1695 gtk_container_border_width (GTK_CONTAINER (sig_frame), 3);
1696 gtk_widget_show(sig_frame);
1697
1698 gtk_paned_pack2 (GTK_PANED (vpan), sig_frame, TRUE, FALSE);
1699
1700 sig_scroll_win = gtk_scrolled_window_new (NULL, NULL);
1701 gtk_widget_set_usize (GTK_WIDGET (sig_scroll_win), 80, 100);
1702 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sig_scroll_win),
1703 GTK_POLICY_AUTOMATIC,
1704 GTK_POLICY_AUTOMATIC);
1705 gtk_widget_show(sig_scroll_win);
1706 gtk_container_add (GTK_CONTAINER (sig_frame), sig_scroll_win);
1707 gtk_container_add (GTK_CONTAINER (sig_scroll_win), sig_view);
1708 gtk_widget_show (sig_view);
1709
1710
1711 /* Filter. */
1712 filter_hbox = gtk_hbox_new (FALSE, 1);
1713 gtk_widget_show (filter_hbox);
1714
1715 filter_label = gtk_label_new ("Filter:");
1716 gtk_widget_show (filter_label);
1717 gtk_box_pack_start (GTK_BOX (filter_hbox), filter_label, FALSE, FALSE, 1);
1718
1719 GLOBALS->filter_entry = gtk_entry_new ();
1720 if(GLOBALS->filter_str_treesearch_gtk2_c_1) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->filter_entry), GLOBALS->filter_str_treesearch_gtk2_c_1); }
1721 gtk_widget_show (GLOBALS->filter_entry);
1722
1723 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "activate", GTK_SIGNAL_FUNC(press_callback), NULL);
1724 if(!GLOBALS->do_dynamic_treefilter)
1725 {
1726 gtkwave_signal_connect(GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GtkSignalFunc) filter_edit_cb, NULL);
1727 }
1728 else
1729 {
1730 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "changed", GTK_SIGNAL_FUNC(press_callback), NULL);
1731 }
1732
1733 gtk_tooltips_set_tip_2(tooltips, GLOBALS->filter_entry,
1734 "Add a POSIX filter. "
1735 "'.*' matches any number of characters,"
1736 " '.' matches any character. Hit Return to apply."
1737 " The filter may be preceded with the port direction if it exists such as ++ (show only non-port), +I+, +O+, +IO+, etc."
1738 " Use -- to exclude all non-ports (i.e., show only all ports), -I- to exclude all input ports, etc.",
1739 NULL);
1740
1741 gtk_box_pack_start (GTK_BOX (filter_hbox), GLOBALS->filter_entry, FALSE, FALSE, 1);
1742
1743 gtk_box_pack_start (GTK_BOX (vbox), filter_hbox, FALSE, FALSE, 1);
1744
1745 /* Buttons. */
1746 frameh = gtk_frame_new (NULL);
1747 gtk_container_border_width (GTK_CONTAINER (frameh), 3);
1748 gtk_widget_show(frameh);
1749 gtk_box_pack_start (GTK_BOX (vbox), frameh, FALSE, FALSE, 1);
1750
1751
1752 hbox = gtk_hbox_new (FALSE, 1);
1753 gtk_widget_show (hbox);
1754
1755 button1 = gtk_button_new_with_label ("Append");
1756 gtk_container_border_width (GTK_CONTAINER (button1), 3);
1757 gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame));
1758 gtk_widget_show (button1);
1759 gtk_tooltips_set_tip_2(tooltips, button1,
1760 "Add selected signal hierarchy to end of the display on the main window.",NULL);
1761
1762 gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0);
1763
1764 button2 = gtk_button_new_with_label (" Insert ");
1765 gtk_container_border_width (GTK_CONTAINER (button2), 3);
1766 gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(insert_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame));
1767 gtk_widget_show (button2);
1768 gtk_tooltips_set_tip_2(tooltips, button2,
1769 "Add selected signal hierarchy after last highlighted signal on the main window.",NULL);
1770 gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0);
1771
1772 button4 = gtk_button_new_with_label (" Replace ");
1773 gtk_container_border_width (GTK_CONTAINER (button4), 3);
1774 gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked", GTK_SIGNAL_FUNC(replace_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame));
1775 gtk_widget_show (button4);
1776 gtk_tooltips_set_tip_2(tooltips, button4,
1777 "Replace highlighted signals on the main window with signals selected above.",NULL);
1778 gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0);
1779
1780 gtk_container_add (GTK_CONTAINER (frameh), hbox);
1781 return vbox;
1782 }
1783
1784
1785 /****************************************************************
1786 **
1787 ** dnd
1788 **
1789 ****************************************************************/
1790
1791 /*
1792 * DND "drag_begin" handler, this is called whenever a drag starts.
1793 */
DNDBeginCB(GtkWidget * widget,GdkDragContext * dc,gpointer data)1794 static void DNDBeginCB(
1795 GtkWidget *widget, GdkDragContext *dc, gpointer data
1796 )
1797 {
1798 (void)data;
1799
1800 if((widget == NULL) || (dc == NULL))
1801 return;
1802
1803 /* Put any needed drag begin setup code here. */
1804 if(!GLOBALS->dnd_state)
1805 {
1806 if(widget == GLOBALS->clist_search_c_3)
1807 {
1808 GLOBALS->tree_dnd_begin = SEARCH_TO_VIEW_DRAG_ACTIVE;
1809 }
1810 else
1811 {
1812 GLOBALS->tree_dnd_begin = TREE_TO_VIEW_DRAG_ACTIVE;
1813 }
1814 }
1815 }
1816
1817 /*
1818 * DND "drag_failed" handler, this is called when a drag and drop has
1819 * failed (e.g., by pressing ESC).
1820 */
DNDFailedCB(GtkWidget * widget,GdkDragContext * context,GtkDragResult result)1821 static gboolean DNDFailedCB(
1822 GtkWidget *widget, GdkDragContext *context, GtkDragResult result)
1823 {
1824 (void)widget;
1825 (void)context;
1826 (void)result;
1827
1828 GLOBALS->dnd_state = 0;
1829 GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE;
1830 GLOBALS->tree_dnd_requested = 0;
1831
1832 MaxSignalLength();
1833 signalarea_configure_event(GLOBALS->signalarea, NULL);
1834 wavearea_configure_event(GLOBALS->wavearea, NULL);
1835
1836 return(FALSE);
1837 }
1838
1839
1840 /*
1841 * DND "drag_end" handler, this is called when a drag and drop has
1842 * completed. So this function is the last one to be called in
1843 * any given DND operation.
1844 */
DNDEndCB_2(GtkWidget * widget,GdkDragContext * dc,gpointer data)1845 static void DNDEndCB_2(
1846 GtkWidget *widget, GdkDragContext *dc, gpointer data
1847 )
1848 {
1849 (void)widget;
1850 (void)dc;
1851 (void)data;
1852
1853 Trptr t;
1854 int trwhich, trtarget;
1855 GdkModifierType state;
1856 gdouble x, y;
1857 #ifdef WAVE_USE_GTK2
1858 gint xi, yi;
1859 #endif
1860
1861 /* Put any needed drag end cleanup code here. */
1862
1863 if(GLOBALS->dnd_tgt_on_signalarea_treesearch_gtk2_c_1)
1864 {
1865 WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state);
1866 WAVE_GDK_GET_POINTER_COPY;
1867
1868 if((x<0)||(y<0)||(x>=GLOBALS->signalarea->allocation.width)||(y>=GLOBALS->signalarea->allocation.height)) return;
1869 }
1870 else
1871 if(GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1)
1872 {
1873 WAVE_GDK_GET_POINTER(GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state);
1874 WAVE_GDK_GET_POINTER_COPY;
1875
1876 if((x<0)||(y<0)||(x>=GLOBALS->wavearea->allocation.width)||(y>=GLOBALS->wavearea->allocation.height)) return;
1877 }
1878 else
1879 {
1880 return;
1881 }
1882
1883
1884 if((t=GLOBALS->traces.first))
1885 {
1886 while(t)
1887 {
1888 t->flags&=~TR_HIGHLIGHT;
1889 t=t->t_next;
1890 }
1891 signalarea_configure_event(GLOBALS->signalarea, NULL);
1892 wavearea_configure_event(GLOBALS->wavearea, NULL);
1893 }
1894
1895 trtarget = ((int)y / (int)GLOBALS->fontheight) - 2;
1896 if(trtarget < 0)
1897 {
1898 Trptr tp = GLOBALS->topmost_trace ? GivePrevTrace(GLOBALS->topmost_trace): NULL;
1899 trtarget = 0;
1900
1901 if(tp)
1902 {
1903 t = tp;
1904 }
1905 else
1906 {
1907 if(GLOBALS->tree_dnd_begin == SEARCH_TO_VIEW_DRAG_ACTIVE)
1908 {
1909 if(GLOBALS->window_search_c_7)
1910 {
1911 search_insert_callback(GLOBALS->window_search_c_7, 1 /* is prepend */);
1912 }
1913 }
1914 else
1915 {
1916 action_callback(SST_ACTION_PREPEND); /* prepend in this widget only ever used by this function call */
1917 }
1918 goto dnd_import_fini;
1919 }
1920 }
1921 else
1922 {
1923 t=GLOBALS->topmost_trace;
1924 }
1925
1926 trwhich=0;
1927 while(t)
1928 {
1929 if((trwhich<trtarget)&&(GiveNextTrace(t)))
1930 {
1931 trwhich++;
1932 t=GiveNextTrace(t);
1933 }
1934 else
1935 {
1936 break;
1937 }
1938 }
1939
1940 if(t)
1941 {
1942 t->flags |= TR_HIGHLIGHT;
1943 }
1944
1945 if(GLOBALS->tree_dnd_begin == SEARCH_TO_VIEW_DRAG_ACTIVE)
1946 {
1947 if(GLOBALS->window_search_c_7)
1948 {
1949 search_insert_callback(GLOBALS->window_search_c_7, 0 /* is insert */);
1950 }
1951 }
1952 else
1953 {
1954 action_callback (SST_ACTION_INSERT);
1955 }
1956
1957 if(t)
1958 {
1959 t->flags &= ~TR_HIGHLIGHT;
1960 }
1961
1962 dnd_import_fini:
1963
1964 MaxSignalLength();
1965 signalarea_configure_event(GLOBALS->signalarea, NULL);
1966 wavearea_configure_event(GLOBALS->wavearea, NULL);
1967 }
1968
1969
DNDEndCB(GtkWidget * widget,GdkDragContext * dc,gpointer data)1970 static void DNDEndCB(
1971 GtkWidget *widget, GdkDragContext *dc, gpointer data
1972 )
1973 {
1974 if((widget == NULL) || (dc == NULL))
1975 {
1976 GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE;
1977 return;
1978 }
1979
1980 if(GLOBALS->tree_dnd_begin == VIEW_DRAG_INACTIVE)
1981 {
1982 return; /* to keep cut and paste in signalwindow from conflicting */
1983 }
1984
1985 if(GLOBALS->tree_dnd_requested)
1986 {
1987 GLOBALS->tree_dnd_requested = 0;
1988
1989 if(GLOBALS->is_lx2 == LXT2_IS_VLIST)
1990 {
1991 set_window_busy(NULL);
1992 }
1993 DNDEndCB_2(widget, dc, data);
1994 if(GLOBALS->is_lx2 == LXT2_IS_VLIST)
1995 {
1996 set_window_idle(NULL);
1997 }
1998 }
1999
2000 GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE;
2001 }
2002
2003
2004
2005 /*
2006 * DND "drag_motion" handler, this is called whenever the
2007 * pointer is dragging over the target widget.
2008 */
DNDDragMotionCB(GtkWidget * widget,GdkDragContext * dc,gint x,gint y,guint t,gpointer data)2009 static gboolean DNDDragMotionCB(
2010 GtkWidget *widget, GdkDragContext *dc,
2011 gint x, gint y, guint t,
2012 gpointer data
2013 )
2014 {
2015 (void)x;
2016 (void)y;
2017 (void)data;
2018
2019 gboolean same_widget;
2020 GdkDragAction suggested_action;
2021 GtkWidget *src_widget, *tar_widget;
2022 if((widget == NULL) || (dc == NULL))
2023 {
2024 gdk_drag_status(dc, 0, t);
2025 return(FALSE);
2026 }
2027
2028 /* Get source widget and target widget. */
2029 src_widget = gtk_drag_get_source_widget(dc);
2030 tar_widget = widget;
2031
2032 /* Note if source widget is the same as the target. */
2033 same_widget = (src_widget == tar_widget) ? TRUE : FALSE;
2034
2035 GLOBALS->dnd_tgt_on_signalarea_treesearch_gtk2_c_1 = (tar_widget == GLOBALS->signalarea);
2036 GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1 = (tar_widget == GLOBALS->wavearea);
2037
2038 /* If this is the same widget, our suggested action should be
2039 * move. For all other case we assume copy.
2040 */
2041 if(same_widget)
2042 suggested_action = GDK_ACTION_MOVE;
2043 else
2044 suggested_action = GDK_ACTION_COPY;
2045
2046 /* Respond with default drag action (status). First we check
2047 * the dc's list of actions. If the list only contains
2048 * move, copy, or link then we select just that, otherwise we
2049 * return with our default suggested action.
2050 * If no valid actions are listed then we respond with 0.
2051 */
2052
2053 /* Only move? */
2054 if(dc->actions == GDK_ACTION_MOVE)
2055 gdk_drag_status(dc, GDK_ACTION_MOVE, t);
2056 /* Only copy? */
2057 else if(dc->actions == GDK_ACTION_COPY)
2058 gdk_drag_status(dc, GDK_ACTION_COPY, t);
2059 /* Only link? */
2060 else if(dc->actions == GDK_ACTION_LINK)
2061 gdk_drag_status(dc, GDK_ACTION_LINK, t);
2062 /* Other action, check if listed in our actions list? */
2063 else if(dc->actions & suggested_action)
2064 gdk_drag_status(dc, suggested_action, t);
2065 /* All else respond with 0. */
2066 else
2067 gdk_drag_status(dc, 0, t);
2068
2069 return(FALSE);
2070 }
2071
2072 /*
2073 * DND "drag_data_get" handler, for handling requests for DND
2074 * data on the specified widget. This function is called when
2075 * there is need for DND data on the source, so this function is
2076 * responsable for setting up the dynamic data exchange buffer
2077 * (DDE as sometimes it is called) and sending it out.
2078 */
DNDDataRequestCB(GtkWidget * widget,GdkDragContext * dc,GtkSelectionData * selection_data,guint info,guint t,gpointer data)2079 static void DNDDataRequestCB(
2080 GtkWidget *widget, GdkDragContext *dc,
2081 GtkSelectionData *selection_data, guint info, guint t,
2082 gpointer data
2083 )
2084 {
2085 (void)dc;
2086 (void)info;
2087 (void)t;
2088 (void)data;
2089
2090 int upd = 0;
2091 GLOBALS->tree_dnd_requested = 1; /* indicate that a request for data occurred... */
2092
2093 if(widget == GLOBALS->clist_search_c_3) /* from search */
2094 {
2095 char *text = add_dnd_from_searchbox();
2096 if(text)
2097 {
2098 gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text));
2099 free_2(text);
2100 }
2101 upd = 1;
2102 }
2103 else if(widget == GLOBALS->signalarea)
2104 {
2105 char *text = add_dnd_from_signal_window();
2106 if(text)
2107 {
2108 char *text2 = emit_gtkwave_savefile_formatted_entries_in_tcl_list(GLOBALS->traces.first, TRUE);
2109 if(text2)
2110 {
2111 int textlen = strlen(text);
2112 int text2len = strlen(text2);
2113 char *pnt = calloc_2(1, textlen + text2len + 1);
2114
2115 memcpy(pnt, text, textlen);
2116 memcpy(pnt + textlen, text2, text2len);
2117
2118 free_2(text2);
2119 free_2(text);
2120 text = pnt;
2121 }
2122
2123 gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text));
2124 free_2(text);
2125 }
2126 upd = 1;
2127 }
2128 else if(widget == GLOBALS->dnd_sigview)
2129 {
2130 char *text = add_dnd_from_tree_window();
2131 if(text)
2132 {
2133 gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text));
2134 free_2(text);
2135 }
2136 upd = 1;
2137 }
2138
2139 if(upd)
2140 {
2141 MaxSignalLength();
2142 signalarea_configure_event(GLOBALS->signalarea, NULL);
2143 wavearea_configure_event(GLOBALS->wavearea, NULL);
2144 }
2145 }
2146
2147 /*
2148 * DND "drag_data_received" handler. When DNDDataRequestCB()
2149 * calls gtk_selection_data_set() to send out the data, this function
2150 * receives it and is responsible for handling it.
2151 *
2152 * This is also the only DND callback function where the given
2153 * inputs may reflect those of the drop target so we need to check
2154 * if this is the same structure or not.
2155 */
DNDDataReceivedCB(GtkWidget * widget,GdkDragContext * dc,gint x,gint y,GtkSelectionData * selection_data,guint info,guint t,gpointer data)2156 static void DNDDataReceivedCB(
2157 GtkWidget *widget, GdkDragContext *dc,
2158 gint x, gint y, GtkSelectionData *selection_data,
2159 guint info, guint t, gpointer data) {
2160 (void)x;
2161 (void)y;
2162 (void)t;
2163
2164 gboolean same;
2165 GtkWidget *source_widget;
2166
2167 if((widget == NULL) || (data == NULL) || (dc == NULL)) return;
2168
2169 /* Important, check if we actually got data. Sometimes errors
2170 * occure and selection_data will be NULL.
2171 */
2172 if(selection_data == NULL) return;
2173 if(selection_data->length < 0) return;
2174
2175 /* Source and target widgets are the same? */
2176 source_widget = gtk_drag_get_source_widget(dc);
2177 same = (source_widget == widget) ? TRUE : FALSE;
2178 if(same)
2179 {
2180 /* unused */
2181 }
2182
2183 if(source_widget)
2184 if((source_widget == GLOBALS->clist_search_c_3) || /* from search */
2185 (source_widget == GLOBALS->signalarea) ||
2186 (source_widget == GLOBALS->dnd_sigview))
2187 {
2188 /* use internal mechanism instead of passing names around... */
2189 return;
2190 }
2191
2192 GLOBALS->dnd_state = 0;
2193 GLOBALS->tree_dnd_requested = 0;
2194
2195 /* Now check if the data format type is one that we support
2196 * (remember, data format type, not data type).
2197 *
2198 * We check this by testing if info matches one of the info
2199 * values that we have defined.
2200 *
2201 * Note that we can also iterate through the atoms in:
2202 * GList *glist = dc->targets;
2203 *
2204 * while(glist != NULL)
2205 * {
2206 * gchar *name = gdk_atom_name((GdkAtom)glist->data);
2207 * * strcmp the name to see if it matches
2208 * * one that we support
2209 * *
2210 * glist = glist->next;
2211 * }
2212 */
2213 if((info == WAVE_DRAG_TAR_INFO_0) ||
2214 (info == WAVE_DRAG_TAR_INFO_1) ||
2215 (info == WAVE_DRAG_TAR_INFO_2))
2216 {
2217 /* printf("XXX %08x '%s'\n", selection_data->data, selection_data->data); */
2218 #ifndef MAC_INTEGRATION
2219 DND_helper_quartz((char *)selection_data->data);
2220 #else
2221 if(!GLOBALS->dnd_helper_quartz)
2222 {
2223 GLOBALS->dnd_helper_quartz = strdup_2((const char *)selection_data->data);
2224 }
2225 #endif
2226 }
2227 }
2228
2229
DND_helper_quartz(char * data)2230 void DND_helper_quartz(char *data)
2231 {
2232 int num_found;
2233
2234 if(!GLOBALS->splash_is_loading)
2235 {
2236 #if GTK_CHECK_VERSION(2,4,0)
2237 if(!GLOBALS->pFileChoose)
2238 #endif
2239 {
2240 if(!(num_found = process_url_list(data)))
2241 {
2242 num_found = process_tcl_list(data, TRUE);
2243 }
2244
2245 if(num_found)
2246 {
2247 MaxSignalLength();
2248 signalarea_configure_event(GLOBALS->signalarea, NULL);
2249 wavearea_configure_event(GLOBALS->wavearea, NULL);
2250 }
2251 }
2252 #if GTK_CHECK_VERSION(2,4,0)
2253 else
2254 {
2255 MaxSignalLength();
2256 signalarea_configure_event(GLOBALS->signalarea, NULL);
2257 wavearea_configure_event(GLOBALS->wavearea, NULL);
2258 }
2259 #endif
2260 }
2261 }
2262
2263
2264 /*
2265 * DND "drag_data_delete" handler, this function is called when
2266 * the data on the source `should' be deleted (ie if the DND was
2267 * a move).
2268 */
DNDDataDeleteCB(GtkWidget * widget,GdkDragContext * dc,gpointer data)2269 static void DNDDataDeleteCB(
2270 GtkWidget *widget, GdkDragContext *dc, gpointer data
2271 )
2272 {
2273 (void)widget;
2274 (void)dc;
2275 (void)data;
2276
2277 /* nothing */
2278 }
2279
2280
2281 /***********************/
2282
2283
dnd_setup(GtkWidget * src,GtkWidget * w,int enable_receive)2284 void dnd_setup(GtkWidget *src, GtkWidget *w, int enable_receive)
2285 {
2286 GtkWidget *win = w;
2287 GtkTargetEntry target_entry[3];
2288
2289 /* Realize the clist widget and make sure it has a window,
2290 * this will be for DND setup.
2291 */
2292 if(!GTK_WIDGET_NO_WINDOW(w))
2293 {
2294 /* DND: Set up the clist as a potential DND destination.
2295 * First we set up target_entry which is a sequence of of
2296 * structure which specify the kinds (which we define) of
2297 * drops accepted on this widget.
2298 */
2299
2300 /* Set up the list of data format types that our DND
2301 * callbacks will accept.
2302 */
2303 target_entry[0].target = WAVE_DRAG_TAR_NAME_0;
2304 target_entry[0].flags = 0;
2305 target_entry[0].info = WAVE_DRAG_TAR_INFO_0;
2306 target_entry[1].target = WAVE_DRAG_TAR_NAME_1;
2307 target_entry[1].flags = 0;
2308 target_entry[1].info = WAVE_DRAG_TAR_INFO_1;
2309 target_entry[2].target = WAVE_DRAG_TAR_NAME_2;
2310 target_entry[2].flags = 0;
2311 target_entry[2].info = WAVE_DRAG_TAR_INFO_2;
2312
2313 /* Set the drag destination for this widget, using the
2314 * above target entry types, accept move's and coppies'.
2315 */
2316 gtk_drag_dest_set(
2317 w,
2318 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
2319 GTK_DEST_DEFAULT_DROP,
2320 target_entry,
2321 sizeof(target_entry) / sizeof(GtkTargetEntry),
2322 GDK_ACTION_MOVE | GDK_ACTION_COPY
2323 );
2324 gtkwave_signal_connect(GTK_OBJECT(w), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), win);
2325
2326 /* Set the drag source for this widget, allowing the user
2327 * to drag items off of this clist.
2328 */
2329 if(src)
2330 {
2331 gtk_drag_source_set(
2332 src,
2333 GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
2334 target_entry,
2335 sizeof(target_entry) / sizeof(GtkTargetEntry),
2336 GDK_ACTION_MOVE | GDK_ACTION_COPY
2337 );
2338 /* Set DND signals on clist. */
2339 gtkwave_signal_connect(GTK_OBJECT(src), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), win);
2340 gtkwave_signal_connect(GTK_OBJECT(src), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), win);
2341 gtkwave_signal_connect(GTK_OBJECT(src), "drag_data_get", GTK_SIGNAL_FUNC(DNDDataRequestCB), win);
2342 gtkwave_signal_connect(GTK_OBJECT(src), "drag_data_delete", GTK_SIGNAL_FUNC(DNDDataDeleteCB), win);
2343 gtkwave_signal_connect(GTK_OBJECT(src), "drag_failed", GTK_SIGNAL_FUNC(DNDFailedCB), win);
2344 }
2345
2346 if(enable_receive) gtkwave_signal_connect(GTK_OBJECT(w), "drag_data_received", GTK_SIGNAL_FUNC(DNDDataReceivedCB), win);
2347 }
2348 }
2349
2350 /***************************************************************************/
2351
recurse_append_callback(GtkWidget * widget,gpointer data)2352 static void recurse_append_callback(GtkWidget *widget, gpointer data)
2353 {
2354 int i;
2355
2356 if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return;
2357
2358 set_window_busy(widget);
2359
2360 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2361 {
2362 struct symbol *s;
2363 if(i<0) break; /* GHW */
2364 s=GLOBALS->facs[i];
2365 if(s->vec_root)
2366 {
2367 set_s_selected(s->vec_root, GLOBALS->autocoalesce);
2368 }
2369 }
2370
2371 /* LX2 */
2372 if(GLOBALS->is_lx2)
2373 {
2374 int pre_import = 0;
2375
2376 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2377 {
2378 struct symbol *s, *t;
2379 if(i<0) break; /* GHW */
2380 s=GLOBALS->facs[i];
2381 t=s->vec_root;
2382 if((t)&&(GLOBALS->autocoalesce))
2383 {
2384 if(get_s_selected(t))
2385 {
2386 while(t)
2387 {
2388 if(t->n->mv.mvlfac)
2389 {
2390 lx2_set_fac_process_mask(t->n);
2391 pre_import++;
2392 }
2393 t=t->vec_chain;
2394 }
2395 }
2396 }
2397 else
2398 {
2399 if(s->n->mv.mvlfac)
2400 {
2401 lx2_set_fac_process_mask(s->n);
2402 pre_import++;
2403 }
2404 }
2405 }
2406
2407 if(pre_import)
2408 {
2409 lx2_import_masked();
2410 }
2411 }
2412 /* LX2 */
2413
2414 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2415 {
2416 int len;
2417 struct symbol *s, *t;
2418 if(i<0) break; /* GHW */
2419 s=GLOBALS->facs[i];
2420 t=s->vec_root;
2421 if((t)&&(GLOBALS->autocoalesce))
2422 {
2423 if(get_s_selected(t))
2424 {
2425 set_s_selected(t, 0);
2426 len=0;
2427 while(t)
2428 {
2429 len++;
2430 t=t->vec_chain;
2431 }
2432 if(len) add_vector_chain(s->vec_root, len);
2433 }
2434 }
2435 else
2436 {
2437 AddNodeUnroll(s->n, NULL);
2438 }
2439 }
2440
2441 set_window_idle(widget);
2442
2443 GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last;
2444 MaxSignalLength();
2445 signalarea_configure_event(GLOBALS->signalarea, NULL);
2446 wavearea_configure_event(GLOBALS->wavearea, NULL);
2447 }
2448
2449
recurse_insert_callback(GtkWidget * widget,gpointer data)2450 static void recurse_insert_callback(GtkWidget *widget, gpointer data)
2451 {
2452 Traces tcache;
2453 int i;
2454
2455 if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return;
2456
2457 memcpy(&tcache,&GLOBALS->traces,sizeof(Traces));
2458 GLOBALS->traces.total=0;
2459 GLOBALS->traces.first=GLOBALS->traces.last=NULL;
2460
2461 set_window_busy(widget);
2462
2463 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2464 {
2465 struct symbol *s;
2466 if(i<0) break; /* GHW */
2467 s=GLOBALS->facs[i];
2468 if(s->vec_root)
2469 {
2470 set_s_selected(s->vec_root, GLOBALS->autocoalesce);
2471 }
2472 }
2473
2474 /* LX2 */
2475 if(GLOBALS->is_lx2)
2476 {
2477 int pre_import = 0;
2478
2479 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2480 {
2481 struct symbol *s, *t;
2482 if(i<0) break; /* GHW */
2483 s=GLOBALS->facs[i];
2484 t=s->vec_root;
2485 if((t)&&(GLOBALS->autocoalesce))
2486 {
2487 if(get_s_selected(t))
2488 {
2489 while(t)
2490 {
2491 if(t->n->mv.mvlfac)
2492 {
2493 lx2_set_fac_process_mask(t->n);
2494 pre_import++;
2495 }
2496 t=t->vec_chain;
2497 }
2498 }
2499 }
2500 else
2501 {
2502 if(s->n->mv.mvlfac)
2503 {
2504 lx2_set_fac_process_mask(s->n);
2505 pre_import++;
2506 }
2507 }
2508 }
2509
2510 if(pre_import)
2511 {
2512 lx2_import_masked();
2513 }
2514 }
2515 /* LX2 */
2516
2517 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2518 {
2519 int len;
2520 struct symbol *s, *t;
2521 if(i<0) break; /* GHW */
2522 s=GLOBALS->facs[i];
2523 t=s->vec_root;
2524 if((t)&&(GLOBALS->autocoalesce))
2525 {
2526 if(get_s_selected(t))
2527 {
2528 set_s_selected(t, 0);
2529 len=0;
2530 while(t)
2531 {
2532 len++;
2533 t=t->vec_chain;
2534 }
2535 if(len) add_vector_chain(s->vec_root, len);
2536 }
2537 }
2538 else
2539 {
2540 AddNodeUnroll(s->n, NULL);
2541 }
2542 }
2543
2544 set_window_idle(widget);
2545
2546 GLOBALS->traces.buffercount=GLOBALS->traces.total;
2547 GLOBALS->traces.buffer=GLOBALS->traces.first;
2548 GLOBALS->traces.bufferlast=GLOBALS->traces.last;
2549 GLOBALS->traces.first=tcache.first;
2550 GLOBALS->traces.last=tcache.last;
2551 GLOBALS->traces.total=tcache.total;
2552
2553 PasteBuffer();
2554
2555 GLOBALS->traces.buffercount=tcache.buffercount;
2556 GLOBALS->traces.buffer=tcache.buffer;
2557 GLOBALS->traces.bufferlast=tcache.bufferlast;
2558
2559 MaxSignalLength();
2560 signalarea_configure_event(GLOBALS->signalarea, NULL);
2561 wavearea_configure_event(GLOBALS->wavearea, NULL);
2562 }
2563
2564
recurse_replace_callback(GtkWidget * widget,gpointer data)2565 static void recurse_replace_callback(GtkWidget *widget, gpointer data)
2566 {
2567 Traces tcache;
2568 int i;
2569 Trptr tfirst=NULL, tlast=NULL;
2570
2571 if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return;
2572
2573 memcpy(&tcache,&GLOBALS->traces,sizeof(Traces));
2574 GLOBALS->traces.total=0;
2575 GLOBALS->traces.first=GLOBALS->traces.last=NULL;
2576
2577 set_window_busy(widget);
2578
2579 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2580 {
2581 struct symbol *s;
2582 if(i<0) break; /* GHW */
2583 s=GLOBALS->facs[i];
2584 if(s->vec_root)
2585 {
2586 set_s_selected(s->vec_root, GLOBALS->autocoalesce);
2587 }
2588 }
2589
2590 /* LX2 */
2591 if(GLOBALS->is_lx2)
2592 {
2593 int pre_import = 0;
2594
2595 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2596 {
2597 struct symbol *s, *t;
2598 if(i<0) break; /* GHW */
2599 s=GLOBALS->facs[i];
2600 t=s->vec_root;
2601 if((t)&&(GLOBALS->autocoalesce))
2602 {
2603 if(get_s_selected(t))
2604 {
2605 while(t)
2606 {
2607 if(t->n->mv.mvlfac)
2608 {
2609 lx2_set_fac_process_mask(t->n);
2610 pre_import++;
2611 }
2612 t=t->vec_chain;
2613 }
2614 }
2615 }
2616 else
2617 {
2618 if(s->n->mv.mvlfac)
2619 {
2620 lx2_set_fac_process_mask(s->n);
2621 pre_import++;
2622 }
2623 }
2624 }
2625
2626 if(pre_import)
2627 {
2628 lx2_import_masked();
2629 }
2630 }
2631 /* LX2 */
2632
2633 for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;i++)
2634 {
2635 int len;
2636 struct symbol *s, *t;
2637 if(i<0) break; /* GHW */
2638 s=GLOBALS->facs[i];
2639 t=s->vec_root;
2640 if((t)&&(GLOBALS->autocoalesce))
2641 {
2642 if(get_s_selected(t))
2643 {
2644 set_s_selected(t, 0);
2645 len=0;
2646 while(t)
2647 {
2648 len++;
2649 t=t->vec_chain;
2650 }
2651 if(len) add_vector_chain(s->vec_root, len);
2652 }
2653 }
2654 else
2655 {
2656 AddNodeUnroll(s->n, NULL);
2657 }
2658 }
2659
2660 set_window_idle(widget);
2661
2662 tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */
2663
2664 GLOBALS->traces.buffercount=GLOBALS->traces.total;
2665 GLOBALS->traces.buffer=GLOBALS->traces.first;
2666 GLOBALS->traces.bufferlast=GLOBALS->traces.last;
2667 GLOBALS->traces.first=tcache.first;
2668 GLOBALS->traces.last=tcache.last;
2669 GLOBALS->traces.total=tcache.total;
2670
2671 {
2672 Trptr t = GLOBALS->traces.first;
2673 Trptr *tp = NULL;
2674 int numhigh = 0;
2675 int it;
2676
2677 while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; }
2678 if(numhigh)
2679 {
2680 tp = calloc_2(numhigh, sizeof(Trptr));
2681 t = GLOBALS->traces.first;
2682 it = 0;
2683 while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; }
2684 }
2685
2686 PasteBuffer();
2687
2688 GLOBALS->traces.buffercount=tcache.buffercount;
2689 GLOBALS->traces.buffer=tcache.buffer;
2690 GLOBALS->traces.bufferlast=tcache.bufferlast;
2691
2692 for(i=0;i<numhigh;i++)
2693 {
2694 tp[i]->flags |= TR_HIGHLIGHT;
2695 }
2696
2697 t = tfirst;
2698 while(t)
2699 {
2700 t->flags &= ~TR_HIGHLIGHT;
2701 if(t==tlast) break;
2702 t=t->t_next;
2703 }
2704
2705 CutBuffer();
2706
2707 while(tfirst)
2708 {
2709 tfirst->flags |= TR_HIGHLIGHT;
2710 if(tfirst==tlast) break;
2711 tfirst=tfirst->t_next;
2712 }
2713
2714 if(tp)
2715 {
2716 free_2(tp);
2717 }
2718 }
2719
2720 MaxSignalLength();
2721 signalarea_configure_event(GLOBALS->signalarea, NULL);
2722 wavearea_configure_event(GLOBALS->wavearea, NULL);
2723 }
2724
2725
recurse_import(GtkWidget * widget,guint callback_action)2726 void recurse_import(GtkWidget *widget, guint callback_action)
2727 {
2728 if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1)
2729 {
2730 int fz;
2731
2732 GLOBALS->fetchlow = GLOBALS->fetchhigh = -1;
2733 if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1->child) recurse_fetch_high_low(GLOBALS->sst_sig_root_treesearch_gtk2_c_1->child);
2734 fz = GLOBALS->fetchhigh - GLOBALS->fetchlow + 1;
2735 void (*func)(GtkWidget *, gpointer);
2736
2737 switch(callback_action)
2738 {
2739 case WV_RECURSE_INSERT: func = recurse_insert_callback; break;
2740 case WV_RECURSE_REPLACE: func = recurse_replace_callback; break;
2741
2742 case WV_RECURSE_APPEND:
2743 default: func = recurse_append_callback; break;
2744 }
2745
2746 if((GLOBALS->fetchlow >= 0) && (GLOBALS->fetchhigh >= 0))
2747 {
2748 widget = GLOBALS->mainwindow; /* otherwise using widget passed from the menu item crashes on OSX */
2749
2750 if(fz > WV_RECURSE_IMPORT_WARN)
2751 {
2752 char recwarn[128];
2753 sprintf(recwarn, "Really import %d facilit%s?", fz, (fz==1)?"y":"ies");
2754
2755 simplereqbox("Recurse Warning",300,recwarn,"Yes", "No", GTK_SIGNAL_FUNC(func), 0);
2756 }
2757 else
2758 {
2759 func(widget, (gpointer)1);
2760 }
2761 }
2762 }
2763 }
2764
2765 /***************************************************************************/
2766