Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
frmobjectui.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <stdbool.h>
12#include <stdio.h>
13
14#include <stdlib.h>
15#include "gui.h"
16#include <glade/glade.h>
17#include <gdk/gdkkeysyms.h>
18#include <gdk/gdk.h>
19#include "viewport.h"
20#include "frmobjectui.h"
21#include <assert.h>
22#include "gvprpipe.h"
23#include <cgraph/agxbuf.h>
24#include <cgraph/alloc.h>
25#include <cgraph/startswith.h>
26#include <cgraph/strcasecmp.h>
27#include <cgraph/strview.h>
28#include <cgraph/unreachable.h>
29#include <stdint.h>
30#include <string.h>
31
32static int sel_node;
33static int sel_edge;
34static int sel_graph;
35
36static char *safestrdup(const char *src) {
37 if (!src)
38 return NULL;
39 else
40 return gv_strdup(src);
41}
42static int get_object_type(void)
43{
44 if (gtk_toggle_button_get_active
45 ((GtkToggleButton *) glade_xml_get_widget(xml, "attrRB0")))
46 return AGRAPH;
47 if (gtk_toggle_button_get_active
48 ((GtkToggleButton *) glade_xml_get_widget(xml, "attrRB1")))
49 return AGNODE;
50 if (gtk_toggle_button_get_active
51 ((GtkToggleButton *) glade_xml_get_widget(xml, "attrRB2")))
52 return AGEDGE;
53 return -1;
54}
55
56static attr_t *new_attr(void) {
57 return gv_alloc(sizeof(attr_t));
58}
59
61{
62 attr_t *a = new_attr();
63 a->name = gv_strdup(sym->name);
64 switch (sym->kind) {
65 case AGRAPH:
66 a->objType[0] = 1;
67 a->defValG = safestrdup(sym->defval);
68 break;
69 case AGNODE:
70 a->objType[1] = 1;
71 a->defValN = safestrdup(sym->defval);
72 break;
73 case AGEDGE:
74 a->objType[2] = 1;
75 a->defValE = safestrdup(sym->defval);
76 break;
77 default:
79 }
80 return a;
81}
82
83static attr_t *new_attr_ref(attr_t * refAttr)
84{
85 attr_t *a = gv_alloc(sizeof(attr_t));
86 *a = *refAttr;
87 a->defValG = safestrdup(refAttr->defValG);
88 a->defValN = safestrdup(refAttr->defValN);
89 a->defValE = safestrdup(refAttr->defValE);
90 a->name = gv_strdup(refAttr->name);
91 a->value = safestrdup(refAttr->value);
92 return a;
93}
94
96{
97 int id;
98 for (id = 0; id < MAX_FILTERED_ATTR_COUNT; id++) {
99 gtk_label_set_text(l->fLabels[id], "");
100 }
101}
102
103// creates a new attr_list
104// attr_list is a basic stack implementation
105// with alphanumeric sorting functions
106// that uses quicksort
107static attr_list *attr_list_new(bool with_widgets) {
108 int id;
109 attr_list *l = gv_alloc(sizeof(attr_list));
110 l->with_widgets = with_widgets;
111 /*create filter widgets */
112
113 if (with_widgets) {
114 for (id = 0; id < MAX_FILTERED_ATTR_COUNT; id++) {
115 l->fLabels[id] = (GtkLabel *) gtk_label_new("");
116
117 gtk_widget_add_events((GtkWidget *) l->fLabels[id],
118 GDK_BUTTON_MOTION_MASK |
119 GDK_POINTER_MOTION_MASK |
120 GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS |
121 GDK_BUTTON_RELEASE_MASK |
122 GDK_SCROLL | GDK_VISIBILITY_NOTIFY_MASK);
123
124 gtk_widget_show((GtkWidget *) l->fLabels[id]);
125 Color_Widget_bg("blue", (GtkWidget *) l->fLabels[id]);
126 gtk_fixed_put((GtkFixed *) glade_xml_get_widget(xml, "fixed6"),
127 (GtkWidget *) l->fLabels[id], 10, 110 + id * 13);
128 }
129 }
130 return l;
131}
132
133static int attr_compare_core(const void *key, const void *candidate) {
134 const char *k = key;
135 const attr_t *const *c = candidate;
136 return strcasecmp(k, (*c)->name);
137}
138
139static int attr_compare(const attr_t **a, const attr_t **b) {
140 return attr_compare_core((*a)->name, b);
141}
142
143static void attr_list_add(attr_list *l, attr_t *a) {
144 if (!l || !a)
145 return;
146 attrs_append(&l->attributes, a);
147 attrs_sort(&l->attributes, attr_compare);
148 /*update indices */
149 for (size_t id = 0; id < attrs_size(&l->attributes); ++id)
150 attrs_get(&l->attributes, id)->index = id;
151}
152
154{
155 switch (c) {
156 case 'A':
157 return attr_alpha;
158 break;
159 case 'F':
160 return attr_float;
161 break;
162 case 'B':
163 return attr_bool;
164 break;
165 case 'I':
166 return attr_int;
167 break;
168 default:
169 break;
170 }
171 return attr_alpha;
172}
173
174static void object_type_helper(strview_t a, int *t) {
175 if (strview_str_eq(a, "GRAPH"))
176 t[0] = 1;
177 if (strview_str_eq(a, "CLUSTER"))
178 t[0] = 1;
179 if (strview_str_eq(a, "NODE"))
180 t[1] = 1;
181 if (strview_str_eq(a, "EDGE"))
182 t[2] = 1;
183 if (strview_str_eq(a, "ANY_ELEMENT")) {
184 t[0] = 1;
185 t[1] = 1;
186 t[2] = 1;
187 }
188}
189
190static void set_attr_object_type(const char *str, int *t) {
191 strview_t a = strview(str, ' ');
192 object_type_helper(a, t);
193 while (true) {
194 const char *start = a.data + a.size;
195 if (!startswith(start, " or ")) {
196 break;
197 }
198 start += strlen(" or ");
199 const char *end = strstr(start, " or ");
200 if (end == NULL) {
201 a = strview(start, '\0');
202 } else {
203 a = (strview_t){.data = start, .size = (size_t)(end - start)};
204 }
205 object_type_helper(a, t);
206 }
207}
208
209static attr_t *binarySearch(attr_list *l, const char *searchKey) {
210 attr_t **attrp = bsearch(searchKey, attrs_at(&l->attributes, 0),
211 attrs_size(&l->attributes), sizeof(attr_t*),
213 if (attrp != NULL) {
214 return *attrp;
215 }
216 return NULL;
217}
218
219static attr_t *pBinarySearch(attr_list *l, const char *searchKey) {
220 size_t low = 0;
221 size_t high = attrs_size(&l->attributes) - 1;
222
223 while (high != SIZE_MAX && low <= high) {
224 size_t middle = (low + high) / 2;
225 int res = strncasecmp(searchKey, attrs_get(&l->attributes, middle)->name, strlen(searchKey));
226 if (res == 0) {
227 return attrs_get(&l->attributes, middle);
228 }
229 else if (res < 0) {
230 high = middle - 1;
231 } else {
232 low = middle + 1;
233 }
234 }
235 return NULL;
236}
237
238static void create_filtered_list(const char *prefix, attr_list *sl,
239 attr_list *tl) {
240 int res;
241 attr_t *at;
242 int objKind = get_object_type();
243
244 if (strlen(prefix) == 0)
245 return;
246 /*locate first occurrence */
247 at = pBinarySearch(sl, prefix);
248 if (!at)
249 return;
250
251 res = 0;
252 /*go backward to get the first */
253 while (at->index > 0 && res == 0) {
254 at = attrs_get(&sl->attributes, at->index - 1);
255 res = strncasecmp(prefix, at->name, strlen(prefix));
256 }
257 res = 0;
258 while (at->index < attrs_size(&sl->attributes) && res == 0) {
259 at = attrs_get(&sl->attributes, at->index + 1);
260 res = strncasecmp(prefix, at->name, strlen(prefix));
261 if (res == 0 && at->objType[objKind] == 1)
263 }
264}
265
266static void filter_attributes(const char *prefix, topview *t) {
267 int tmp;
268
269 attr_list *l = t->attributes;
270 int objKind = get_object_type();
271
272 attr_list *fl = attr_list_new(false);
275 for (size_t ind = 0; ind < attrs_size(&fl->attributes); ++ind) {
276 gtk_label_set_text(l->fLabels[ind], attrs_get(&fl->attributes, ind)->name);
277 }
278
279 Color_Widget_bg("white", glade_xml_get_widget(xml, "txtAttr"));
280 if (attrs_is_empty(&fl->attributes))
281 Color_Widget_bg("red", glade_xml_get_widget(xml, "txtAttr"));
282 /*a new attribute can be entered */
283
284 gtk_widget_show(glade_xml_get_widget(xml, "txtValue"));
285 gtk_widget_show(glade_xml_get_widget(xml, "txtDefValue"));
286
287 gtk_entry_set_text((GtkEntry *)
288 glade_xml_get_widget(xml, "txtDefValue"), "");
289 gtk_entry_set_text((GtkEntry *) glade_xml_get_widget(xml, "txtValue"),
290 "");
291 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "txtDefValue"), 1);
292 gtk_widget_show(glade_xml_get_widget(xml, "attrAddBtn"));
293 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyBtn"));
294 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyAllBtn"));
295 gtk_widget_hide(glade_xml_get_widget(xml, "attrSearchBtn"));
296 gtk_toggle_button_set_active((GtkToggleButton *)
297 glade_xml_get_widget(xml, "attrProg"), 0);
298
299 if (strlen(prefix) == 0) {
300 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
301 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyBtn"));
302 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyAllBtn"));
303 gtk_widget_hide(glade_xml_get_widget(xml, "attrSearchBtn"));
304 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
305 gtk_widget_hide(glade_xml_get_widget(xml, "txtValue"));
306 gtk_widget_hide(glade_xml_get_widget(xml, "txtDefValue"));
307 Color_Widget_bg("white", glade_xml_get_widget(xml, "txtAttr"));
308 }
309
310 for (size_t ind = 0; ind < attrs_size(&fl->attributes); ++ind) {
311 if (strcasecmp(prefix, attrs_get(&fl->attributes, ind)->name) == 0) { // an existing attribute
312
313 Color_Widget_bg("green", glade_xml_get_widget(xml, "txtAttr"));
314
315 if (get_object_type() == AGRAPH)
316 gtk_entry_set_text((GtkEntry *)
317 glade_xml_get_widget(xml,
318 "txtDefValue"),
319 attrs_get(&fl->attributes, 0)->defValG);
320 if (get_object_type() == AGNODE)
321 gtk_entry_set_text((GtkEntry *)
322 glade_xml_get_widget(xml,
323 "txtDefValue"),
324 attrs_get(&fl->attributes, 0)->defValN);
325 if (get_object_type() == AGEDGE)
326 gtk_entry_set_text((GtkEntry *)
327 glade_xml_get_widget(xml,
328 "txtDefValue"),
329 attrs_get(&fl->attributes, 0)->defValE);
330 gtk_widget_set_sensitive(glade_xml_get_widget
331 (xml, "txtDefValue"), 0);
332 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
333 gtk_widget_show(glade_xml_get_widget(xml, "attrApplyBtn"));
334 gtk_widget_show(glade_xml_get_widget(xml, "attrApplyAllBtn"));
335 gtk_widget_show(glade_xml_get_widget(xml, "attrSearchBtn"));
336 gtk_toggle_button_set_active((GtkToggleButton *)
337 glade_xml_get_widget(xml,
338 "attrProg"),
339 attrs_get(&fl->attributes, 0)->propagate);
340 break;
341 }
342 }
343
344 tmp = (objKind == AGNODE && sel_node)
345 || (objKind == AGEDGE && sel_edge)
346 || (objKind == AGRAPH && sel_graph);
347 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "attrApplyBtn"),
348 tmp);
349}
350
351// attribute text changed call back
352
353_BB void on_txtAttr_changed(GtkWidget * widget, gpointer user_data)
354{
355 (void)user_data;
356 filter_attributes(gtk_entry_get_text((GtkEntry*)widget), view->Topview);
357}
358
359static void set_refresh_filters(ViewInfo * v, char *name)
360{
361 if (strcasecmp(name, "pos") == 0)
362 v->refresh.pos = 1;
363 if (strcasecmp(name, "color") == 0)
364 v->refresh.color = 1;
365 if (strcasecmp(name, "selected") == 0)
366 v->refresh.selection = 1;
367}
368
369static void doApply(void)
370{
371 char *attr_name;
372 int prog;
373 Agnode_t *v;
374 Agedge_t *e;
375 Agraph_t *g;
376 int objKind;
377 Agsym_t *sym;
378 attr_t *attr;
379
380 /*values to be applied to selected objects */
381 attr_name =
382 (char *) gtk_entry_get_text((GtkEntry *)
383 glade_xml_get_widget(xml, "txtAttr"));
384 const char *def_val = gtk_entry_get_text((GtkEntry *)
385 glade_xml_get_widget(xml,
386 "txtDefValue"));
387 const char *value = gtk_entry_get_text((GtkEntry *)
388 glade_xml_get_widget(xml, "txtValue"));
389 prog =
390 gtk_toggle_button_get_active((GtkToggleButton *)
391 glade_xml_get_widget(xml,
392 "attrProg"));
393 g = view->g[view->activeGraph];
394 objKind = get_object_type();
395 attr = binarySearch(view->Topview->attributes, attr_name);
396 assert(attr);
397 attr->propagate = prog;
398 sym = agattr(g, objKind, attr_name, NULL);
399 if (!sym) /*it shouldnt be null, just in case it is null */
400 sym = agattr(g, objKind, attr_name, def_val);
401 /*graph */
402 if (objKind == AGRAPH)
403 agset(g, attr_name, value);
404 /*nodes */
405 else if (objKind == AGNODE) {
406 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
407 if (ND_selected(v))
408 agxset(v, sym, value);
409 }
410 }
411 /*edges */
412 else if (objKind == AGEDGE) {
413 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
414 for (e = agfstout(g, v); e; e = agnxtout(g, e)) {
415 if (ED_selected(e))
416 agxset(e, sym, value);
417 }
418 }
419 } else
420 fprintf(stderr,
421 "on_attrApplyBtn_clicked: unknown object kind %d\n",
422 objKind);
423 set_refresh_filters(view, attr_name);
424}
425
426_BB void on_attrApplyBtn_clicked(GtkWidget * widget, gpointer user_data)
427{
428 (void)widget;
429 (void)user_data;
430
431 doApply();
432}
433
434_BB void on_attrRB0_clicked(GtkWidget * widget, gpointer user_data)
435{
436 (void)widget;
437 (void)user_data;
438
439 filter_attributes(gtk_entry_get_text((GtkEntry*)glade_xml_get_widget(xml,
440 "txtAttr")), view->Topview);
441
442}
443
444/* This is the action attached to the publish button on the attributes
445 * window. What should happen?
446 */
447_BB void on_attrProg_toggled(GtkWidget * widget, gpointer user_data)
448{
449 (void)widget;
450 (void)user_data;
451 /* FIX */
452}
453
454_BB void on_attrAddBtn_clicked(GtkWidget * widget, gpointer user_data)
455{
456 (void)widget;
457 (void)user_data;
458
459 char *attr_name;
460 int objKind;
461 topview *t;
462 Agraph_t *g;
463 attr_t *attr;
464 objKind = get_object_type();
465
466 /*values to be applied to selected objects */
467 attr_name =
468 (char *) gtk_entry_get_text((GtkEntry *)
469 glade_xml_get_widget(xml, "txtAttr"));
470 const char *defValue = gtk_entry_get_text((GtkEntry *)
471 glade_xml_get_widget(xml,
472 "txtDefValue"));
473 g = view->g[view->activeGraph];
474 t = view->Topview;
475 /*try to find first */
476 attr = binarySearch(t->attributes, attr_name);
477 if (!attr) {
478 attr = new_attr();
479 attr->index = 0;
480 attr->name = safestrdup(attr_name);
481 attr->type = attr_alpha;
482 attr->value = gv_strdup("");
483 attr->widget = NULL;
484 attr_list_add(t->attributes, attr);
485 }
486 attr->propagate = 0;
487
488 if (objKind == AGRAPH) {
489 agattr(g, AGRAPH, attr_name, defValue);
490 attr->defValG = safestrdup(defValue);
491 attr->objType[0] = 1;
492 }
493
494 /*nodes */
495 else if (objKind == AGNODE) {
496 agattr(g, AGNODE, attr_name, defValue);
497 attr->defValN = safestrdup(defValue);
498 attr->objType[1] = 1;
499 } else if (objKind == AGEDGE) {
500 agattr(g, AGEDGE, attr_name, defValue);
501 attr->defValE = safestrdup(defValue);
502 attr->objType[2] = 1;
503 } else
504 fprintf(stderr, "on_attrAddBtn_clicked: unknown object kind %d\n",
505 objKind);
506 filter_attributes(attr_name, view->Topview);
507}
508
510{
511 attr_t *attr;
512 attr_list *l;
513 FILE *file;
514 char buffer[BUFSIZ];
515 static char *smyrna_attrs;
516 char *a;
517
518 if (!smyrna_attrs)
519 smyrna_attrs = smyrnaPath("attrs.txt");
520 g = view->g[view->activeGraph];
521 l = attr_list_new(true);
522 file = fopen(smyrna_attrs, "r");
523 if (file != NULL) {
524 for (size_t i = 0; fgets(buffer, sizeof(buffer), file) != NULL; ++i) {
525 attr = new_attr();
526 a = strtok(buffer, ",");
527 attr->index = i;
528 attr->type = get_attr_data_type(a[0]);
529 for (int idx = 0; (a = strtok(NULL, ",")); ++idx) {
530 /*C,(0)color, (1)black, (2)EDGE Or NODE Or CLUSTER, (3)ALL_ENGINES */
531
532 switch (idx) {
533 case 0:
534 attr->name = gv_strdup(a);
535 break;
536 case 1:
537 attr->defValG = gv_strdup(a);
538 attr->defValN = gv_strdup(a);
539 attr->defValE = gv_strdup(a);
540 break;
541 case 2:
543 break;
544 default:
545 break;
546 }
547 }
548 attr_list_add(l, attr);
549
550 }
551 fclose(file);
552 }
553 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGRAPH, sym)); ) {
554 attr = binarySearch(l, sym->name);
555 if (attr)
556 attr->objType[0] = 1;
557 else {
558 attr = new_attr_with_ref(sym);
559 attr_list_add(l, attr);
560 }
561 }
562 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGNODE, sym)); ) {
563 attr = binarySearch(l, sym->name);
564 if (attr) {
565 attr->objType[1] = 1;
566
567 } else {
568 attr = new_attr_with_ref(sym);
569 attr_list_add(l, attr);
570 }
571
572 }
573 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGEDGE, sym)); ) {
574 attr = binarySearch(l, sym->name);
575 if (attr)
576 attr->objType[2] = 1;
577 else {
578 attr = new_attr_with_ref(sym);
579 attr_list_add(l, attr);
580 }
581 }
582 return l;
583}
584
585static void set_header_text(void)
586{
587 int nodeCnt = 0;
588 int edgeCnt = 0;
589 char buf[512];
590 Agedge_t* ep;
591 Agnode_t* v;
592 Agraph_t* g;
593
594 g = view->g[view->activeGraph];
595 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
596 if (ND_selected(v))
597 nodeCnt++;
598 for (ep = agfstout(g, v); ep; ep = agnxtout(g, ep)) {
599 if (ND_selected(v))
600 edgeCnt++;
601 }
602 }
603 sel_node = nodeCnt;
604 sel_edge = edgeCnt;
605 sel_graph = 1;
606
607 snprintf(buf, sizeof(buf), "%d Nodes and %d edges selected", nodeCnt,
608 edgeCnt);
609 gtk_label_set_text((GtkLabel *) glade_xml_get_widget(xml, "label124"),
610 buf);
611 gtk_entry_set_text((GtkEntry *) glade_xml_get_widget(xml, "txtAttr"),
612 "");
613 Color_Widget_bg("white", glade_xml_get_widget(xml, "fixed6"));
614}
615
616void showAttrsWidget(void) {
617 gtk_widget_hide(glade_xml_get_widget(xml, "dlgSettings"));
618 gtk_widget_show(glade_xml_get_widget(xml, "dlgSettings"));
619 gtk_notebook_set_current_page((GtkNotebook *)
620 glade_xml_get_widget(xml, "notebook3"),
624}
625
626static void gvpr_select(const char *attrname, const char *regex_str,
627 int objType) {
628
629 char *bf2;
630 int i, argc;
631
632 agxbuf sf = {0};
633
634 if (objType == AGNODE)
635 agxbprint(&sf, "N[%s==\"%s\"]{selected = \"1\"}", attrname, regex_str);
636 else if (objType == AGEDGE)
637 agxbprint(&sf, "E[%s==\"%s\"]{selected = \"1\"}", attrname, regex_str);
638
639 bf2 = agxbdisown(&sf);
640
641 argc = 1;
642 if (*bf2 != '\0')
643 argc++;
644 char *argv[3] = {0};
645 size_t j = 0;
646 argv[j++] = "smyrna";
647 argv[j++] = bf2;
648
649 run_gvpr(view->g[view->activeGraph], j, argv);
650 for (i = 1; i < argc; i++)
651 free(argv[i]);
653}
654
655_BB void on_attrSearchBtn_clicked(GtkWidget * widget, gpointer user_data)
656{
657 (void)widget;
658 (void)user_data;
659
660 const char *attrname = gtk_entry_get_text((GtkEntry *)
661 glade_xml_get_widget(xml, "txtAttr"));
662 const char *regex_str = gtk_entry_get_text((GtkEntry *)
663 glade_xml_get_widget(xml, "txtValue"));
664 gvpr_select(attrname, regex_str, get_object_type());
665
666}
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:213
static char * agxbdisown(agxbuf *xb)
Definition agxbuf.h:299
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
Definition alloc.h:101
static void * gv_alloc(size_t size)
Definition alloc.h:47
#define _BB
Definition callbacks.h:20
disc key
Definition exparse.y:214
_BB void on_attrProg_toggled(GtkWidget *widget, gpointer user_data)
static void set_attr_object_type(const char *str, int *t)
static void object_type_helper(strview_t a, int *t)
_BB void on_attrAddBtn_clicked(GtkWidget *widget, gpointer user_data)
static char * safestrdup(const char *src)
Definition frmobjectui.c:36
static attr_list * attr_list_new(bool with_widgets)
static int attr_compare(const attr_t **a, const attr_t **b)
_BB void on_attrApplyBtn_clicked(GtkWidget *widget, gpointer user_data)
static attr_t * binarySearch(attr_list *l, const char *searchKey)
static void create_filtered_list(const char *prefix, attr_list *sl, attr_list *tl)
static void attr_list_add(attr_list *l, attr_t *a)
static attr_t * new_attr_with_ref(Agsym_t *sym)
Definition frmobjectui.c:60
static attr_t * new_attr(void)
Definition frmobjectui.c:56
_BB void on_attrRB0_clicked(GtkWidget *widget, gpointer user_data)
_BB void on_txtAttr_changed(GtkWidget *widget, gpointer user_data)
static attr_t * new_attr_ref(attr_t *refAttr)
Definition frmobjectui.c:83
static void reset_attr_list_widgets(attr_list *l)
Definition frmobjectui.c:95
void showAttrsWidget(void)
static void doApply(void)
static void set_header_text(void)
static void set_refresh_filters(ViewInfo *v, char *name)
static attr_data_type get_attr_data_type(char c)
static void gvpr_select(const char *attrname, const char *regex_str, int objType)
static int attr_compare_core(const void *key, const void *candidate)
static attr_t * pBinarySearch(attr_list *l, const char *searchKey)
static int sel_node
Definition frmobjectui.c:32
static int get_object_type(void)
Definition frmobjectui.c:42
_BB void on_attrSearchBtn_clicked(GtkWidget *widget, gpointer user_data)
static int sel_edge
Definition frmobjectui.c:33
static void filter_attributes(const char *prefix, topview *t)
static int sel_graph
Definition frmobjectui.c:34
attr_list * load_attr_list(Agraph_t *g)
#define ATTR_NOTEBOOK_IDX
Definition frmobjectui.h:16
void free(void *)
require define api prefix
Definition gmlparse.y:17
#define SIZE_MAX
Definition gmlscan.c:347
node NULL
Definition grammar.y:149
Agsym_t * agattr(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up attributes of a graph
Definition attr.c:341
int agset(void *obj, char *name, const char *value)
Definition attr.c:469
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
permits traversing the list of attributes of a given type
Definition attr.c:356
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:481
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:23
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:38
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
void Color_Widget_bg(char *colorstring, GtkWidget *widget)
Definition gui.c:25
GladeXML * xml
Definition gui.c:22
static uint64_t id
Definition gv2gml.c:42
int run_gvpr(Agraph_t *srcGraph, size_t argc, char *argv[])
Definition gvprpipe.c:41
agxbuf * str
Definition htmlparse.c:97
char * smyrnaPath(char *suffix)
Definition main.c:68
ViewInfo * view
Definition viewport.c:38
attr_data_type
Definition smyrnadefs.h:60
@ attr_alpha
Definition smyrnadefs.h:60
@ attr_int
Definition smyrnadefs.h:60
@ attr_float
Definition smyrnadefs.h:60
@ attr_bool
Definition smyrnadefs.h:60
#define MAX_FILTERED_ATTR_COUNT
Definition smyrnadefs.h:58
#define ED_selected(e)
Definition smyrnadefs.h:192
#define ND_selected(n)
Definition smyrnadefs.h:179
static bool startswith(const char *s, const char *prefix)
does the string s begin with the string prefix?
Definition startswith.h:11
platform abstraction for case-insensitive string functions
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:639
char * name
Definition cgraph.h:641
unsigned char kind
Definition cgraph.h:644
char * defval
Definition cgraph.h:642
topview * Topview
Definition smyrnadefs.h:334
Agraph_t ** g
Definition smyrnadefs.h:313
int activeGraph
Definition smyrnadefs.h:317
refresh_filter refresh
Definition smyrnadefs.h:369
GtkLabel * fLabels[MAX_FILTERED_ATTR_COUNT]
Definition smyrnadefs.h:89
bool with_widgets
Definition smyrnadefs.h:90
attrs_t attributes
Definition smyrnadefs.h:88
char * defValN
Definition smyrnadefs.h:76
char * name
Definition smyrnadefs.h:73
int propagate
Definition smyrnadefs.h:81
size_t index
Definition smyrnadefs.h:72
GtkWidget * widget
Definition smyrnadefs.h:80
char * defValG
Definition smyrnadefs.h:75
char * value
Definition smyrnadefs.h:74
attr_data_type type
Definition smyrnadefs.h:78
int objType[3]
Definition smyrnadefs.h:79
char * defValE
Definition smyrnadefs.h:77
a non-owning string reference
Definition strview.h:20
const char * data
start of the pointed to string
Definition strview.h:21
size_t size
extent of the string in bytes
Definition strview.h:22
attr_list * attributes
Definition smyrnadefs.h:256
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
Definition strview.h:98
static strview_t strview(const char *referent, char terminator)
create a string reference
Definition strview.h:26
#define UNREACHABLE()
Definition unreachable.h:30