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