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