Graphviz 14.1.2~dev.20260118.1035
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 "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 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) {
211 attr_t **attrp = bsearch(searchKey, LIST_FRONT(&l->attributes),
212 LIST_SIZE(&l->attributes), sizeof(attr_t*),
214 if (attrp != NULL) {
215 return *attrp;
216 }
217 return NULL;
218}
219
220static int cmp(const void *key, const void *candidate) {
221 const attr_t *const a = candidate;
222 return strncasecmp(key, a->name, strlen(key));
223}
224
225static void create_filtered_list(const char *prefix, attr_list *sl,
226 attr_list *tl) {
227 int objKind = get_object_type();
228
229 if (strlen(prefix) == 0)
230 return;
231 /*locate first occurrence */
232 LIST_SYNC(&sl->attributes);
233 attr_t **attrp = bsearch(prefix, LIST_FRONT(&sl->attributes),
234 LIST_SIZE(&sl->attributes), sizeof(attr_t *), cmp);
235 if (!attrp)
236 return;
237
238 /*go backward to get the first */
239 for (int res = 0; attrp > LIST_FRONT(&sl->attributes) && res == 0; ) {
240 --attrp;
241 res = strncasecmp(prefix, (*attrp)->name, strlen(prefix));
242 }
243 // step forward past the non-matching one we landed on
244 if (strncasecmp(prefix, (*attrp)->name, strlen(prefix)) != 0) {
245 ++attrp;
246 }
247 // copy matching entries
248 for (int res = 0; res == 0; ) {
249 res = strncasecmp(prefix, (*attrp)->name, strlen(prefix));
250 if (res == 0 && (*attrp)->objType[objKind] == 1)
251 attr_list_add(tl, new_attr_ref(*attrp));
252 if (attrp == LIST_BACK(&sl->attributes)) {
253 break;
254 }
255 ++attrp;
256 }
257}
258
259static void filter_attributes(const char *prefix, topview *t) {
260 int tmp;
261
262 attr_list *l = t->attributes;
263 int objKind = get_object_type();
264
265 attr_list *fl = attr_list_new(false);
268 for (size_t ind = 0; ind < LIST_SIZE(&fl->attributes); ++ind) {
269 gtk_label_set_text(l->fLabels[ind], LIST_GET(&fl->attributes, ind)->name);
270 }
271
272 Color_Widget_bg("white", glade_xml_get_widget(xml, "txtAttr"));
273 if (LIST_IS_EMPTY(&fl->attributes))
274 Color_Widget_bg("red", glade_xml_get_widget(xml, "txtAttr"));
275 /*a new attribute can be entered */
276
277 gtk_widget_show(glade_xml_get_widget(xml, "txtValue"));
278 gtk_widget_show(glade_xml_get_widget(xml, "txtDefValue"));
279
280 gtk_entry_set_text((GtkEntry *)
281 glade_xml_get_widget(xml, "txtDefValue"), "");
282 gtk_entry_set_text((GtkEntry *) glade_xml_get_widget(xml, "txtValue"),
283 "");
284 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "txtDefValue"), 1);
285 gtk_widget_show(glade_xml_get_widget(xml, "attrAddBtn"));
286 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyBtn"));
287 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyAllBtn"));
288 gtk_widget_hide(glade_xml_get_widget(xml, "attrSearchBtn"));
289 gtk_toggle_button_set_active((GtkToggleButton *)
290 glade_xml_get_widget(xml, "attrProg"), 0);
291
292 if (strlen(prefix) == 0) {
293 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
294 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyBtn"));
295 gtk_widget_hide(glade_xml_get_widget(xml, "attrApplyAllBtn"));
296 gtk_widget_hide(glade_xml_get_widget(xml, "attrSearchBtn"));
297 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
298 gtk_widget_hide(glade_xml_get_widget(xml, "txtValue"));
299 gtk_widget_hide(glade_xml_get_widget(xml, "txtDefValue"));
300 Color_Widget_bg("white", glade_xml_get_widget(xml, "txtAttr"));
301 }
302
303 for (size_t ind = 0; ind < LIST_SIZE(&fl->attributes); ++ind) {
304 if (strcasecmp(prefix, LIST_GET(&fl->attributes, ind)->name) == 0) { // an existing attribute
305
306 Color_Widget_bg("green", glade_xml_get_widget(xml, "txtAttr"));
307
308 if (get_object_type() == AGRAPH)
309 gtk_entry_set_text((GtkEntry *)
310 glade_xml_get_widget(xml,
311 "txtDefValue"),
312 LIST_GET(&fl->attributes, 0)->defValG);
313 if (get_object_type() == AGNODE)
314 gtk_entry_set_text((GtkEntry *)
315 glade_xml_get_widget(xml,
316 "txtDefValue"),
317 LIST_GET(&fl->attributes, 0)->defValN);
318 if (get_object_type() == AGEDGE)
319 gtk_entry_set_text((GtkEntry *)
320 glade_xml_get_widget(xml,
321 "txtDefValue"),
322 LIST_GET(&fl->attributes, 0)->defValE);
323 gtk_widget_set_sensitive(glade_xml_get_widget
324 (xml, "txtDefValue"), 0);
325 gtk_widget_hide(glade_xml_get_widget(xml, "attrAddBtn"));
326 gtk_widget_show(glade_xml_get_widget(xml, "attrApplyBtn"));
327 gtk_widget_show(glade_xml_get_widget(xml, "attrApplyAllBtn"));
328 gtk_widget_show(glade_xml_get_widget(xml, "attrSearchBtn"));
329 gtk_toggle_button_set_active((GtkToggleButton *)
330 glade_xml_get_widget(xml,
331 "attrProg"),
332 LIST_GET(&fl->attributes, 0)->propagate);
333 break;
334 }
335 }
336
337 LIST_FREE(&fl->attributes);
338 free(fl);
339
340 tmp = (objKind == AGNODE && sel_node)
341 || (objKind == AGEDGE && sel_edge)
342 || (objKind == AGRAPH && sel_graph);
343 gtk_widget_set_sensitive(glade_xml_get_widget(xml, "attrApplyBtn"),
344 tmp);
345}
346
347// attribute text changed call back
348
349_BB void on_txtAttr_changed(GtkWidget *widget, void *user_data) {
350 (void)user_data;
351 filter_attributes(gtk_entry_get_text((GtkEntry*)widget), view->Topview);
352}
353
354static void doApply(void)
355{
356 char *attr_name;
357 int prog;
358 Agnode_t *v;
359 Agedge_t *e;
360 Agraph_t *g;
361 int objKind;
362 Agsym_t *sym;
363 attr_t *attr;
364
365 /*values to be applied to selected objects */
366 attr_name =
367 (char *) gtk_entry_get_text((GtkEntry *)
368 glade_xml_get_widget(xml, "txtAttr"));
369 const char *def_val = gtk_entry_get_text((GtkEntry *)
370 glade_xml_get_widget(xml,
371 "txtDefValue"));
372 const char *value = gtk_entry_get_text((GtkEntry *)
373 glade_xml_get_widget(xml, "txtValue"));
374 prog =
375 gtk_toggle_button_get_active((GtkToggleButton *)
376 glade_xml_get_widget(xml,
377 "attrProg"));
378 g = view->g[view->activeGraph];
379 objKind = get_object_type();
380 attr = binarySearch(view->Topview->attributes, attr_name);
381 assert(attr);
382 attr->propagate = prog;
383 sym = agattr_text(g, objKind, attr_name, NULL);
384 if (!sym) /*it shouldnt be null, just in case it is null */
385 sym = agattr_text(g, objKind, attr_name, def_val);
386 /*graph */
387 if (objKind == AGRAPH)
388 agset(g, attr_name, value);
389 /*nodes */
390 else if (objKind == AGNODE) {
391 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
392 if (ND_selected(v))
393 agxset(v, sym, value);
394 }
395 }
396 /*edges */
397 else if (objKind == AGEDGE) {
398 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
399 for (e = agfstout(g, v); e; e = agnxtout(g, e)) {
400 if (ED_selected(e))
401 agxset(e, sym, value);
402 }
403 }
404 } else
405 fprintf(stderr,
406 "on_attrApplyBtn_clicked: unknown object kind %d\n",
407 objKind);
408}
409
410_BB void on_attrApplyBtn_clicked(GtkWidget *widget, void *user_data) {
411 (void)widget;
412 (void)user_data;
413
414 doApply();
415}
416
417_BB void on_attrRB0_clicked(GtkWidget *widget, void *user_data) {
418 (void)widget;
419 (void)user_data;
420
421 filter_attributes(gtk_entry_get_text((GtkEntry*)glade_xml_get_widget(xml,
422 "txtAttr")), view->Topview);
423
424}
425
426/* This is the action attached to the publish button on the attributes
427 * window. What should happen?
428 */
429_BB void on_attrProg_toggled(GtkWidget *widget, void *user_data) {
430 (void)widget;
431 (void)user_data;
432 /* FIX */
433}
434
435_BB void on_attrAddBtn_clicked(GtkWidget *widget, void *user_data) {
436 (void)widget;
437 (void)user_data;
438
439 char *attr_name;
440 int objKind;
441 topview *t;
442 Agraph_t *g;
443 attr_t *attr;
444 objKind = get_object_type();
445
446 /*values to be applied to selected objects */
447 attr_name =
448 (char *) gtk_entry_get_text((GtkEntry *)
449 glade_xml_get_widget(xml, "txtAttr"));
450 const char *defValue = gtk_entry_get_text((GtkEntry *)
451 glade_xml_get_widget(xml,
452 "txtDefValue"));
453 g = view->g[view->activeGraph];
454 t = view->Topview;
455 /*try to find first */
456 attr = binarySearch(t->attributes, attr_name);
457 if (!attr) {
458 attr = new_attr();
459 attr->name = safestrdup(attr_name);
460 attr->type = attr_alpha;
461 attr->value = gv_strdup("");
462 attr_list_add(t->attributes, attr);
463 }
464 attr->propagate = 0;
465
466 if (objKind == AGRAPH) {
467 agattr_text(g, AGRAPH, attr_name, defValue);
468 attr->defValG = safestrdup(defValue);
469 attr->objType[0] = 1;
470 }
471
472 /*nodes */
473 else if (objKind == AGNODE) {
474 agattr_text(g, AGNODE, attr_name, defValue);
475 attr->defValN = safestrdup(defValue);
476 attr->objType[1] = 1;
477 } else if (objKind == AGEDGE) {
478 agattr_text(g, AGEDGE, attr_name, defValue);
479 attr->defValE = safestrdup(defValue);
480 attr->objType[2] = 1;
481 } else
482 fprintf(stderr, "on_attrAddBtn_clicked: unknown object kind %d\n",
483 objKind);
484 filter_attributes(attr_name, view->Topview);
485}
486
488{
489 attr_t *attr;
490 attr_list *l;
491 FILE *file;
492 char buffer[BUFSIZ];
493 static char *smyrna_attrs;
494 char *a;
495
496 if (!smyrna_attrs)
497 smyrna_attrs = smyrnaPath("attrs.txt");
498 g = view->g[view->activeGraph];
499 l = attr_list_new(true);
500 file = fopen(smyrna_attrs, "r");
501 if (file != NULL) {
502 for (size_t i = 0; fgets(buffer, sizeof(buffer), file) != NULL; ++i) {
503 attr = new_attr();
504 a = strtok(buffer, ",");
505 attr->type = get_attr_data_type(a[0]);
506 for (int idx = 0; (a = strtok(NULL, ",")); ++idx) {
507 /*C,(0)color, (1)black, (2)EDGE Or NODE Or CLUSTER, (3)ALL_ENGINES */
508
509 switch (idx) {
510 case 0:
511 attr->name = gv_strdup(a);
512 break;
513 case 1:
514 attr->defValG = gv_strdup(a);
515 attr->defValN = gv_strdup(a);
516 attr->defValE = gv_strdup(a);
517 break;
518 case 2:
520 break;
521 default:
522 break;
523 }
524 }
525 attr_list_add(l, attr);
526
527 }
528 fclose(file);
529 }
530 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGRAPH, sym)); ) {
531 attr = binarySearch(l, sym->name);
532 if (attr)
533 attr->objType[0] = 1;
534 else {
535 attr = new_attr_with_ref(sym);
536 attr_list_add(l, attr);
537 }
538 }
539 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGNODE, sym)); ) {
540 attr = binarySearch(l, sym->name);
541 if (attr) {
542 attr->objType[1] = 1;
543
544 } else {
545 attr = new_attr_with_ref(sym);
546 attr_list_add(l, attr);
547 }
548
549 }
550 for (Agsym_t *sym = NULL; (sym = agnxtattr(g, AGEDGE, sym)); ) {
551 attr = binarySearch(l, sym->name);
552 if (attr)
553 attr->objType[2] = 1;
554 else {
555 attr = new_attr_with_ref(sym);
556 attr_list_add(l, attr);
557 }
558 }
559 return l;
560}
561
562static void set_header_text(void)
563{
564 int nodeCnt = 0;
565 int edgeCnt = 0;
566 char buf[512];
567
569 for (Agnode_t *v = agfstnode(g); v; v = agnxtnode(g, v)) {
570 if (ND_selected(v))
571 nodeCnt++;
572 for (Agedge_t *ep = agfstout(g, v); ep; ep = agnxtout(g, ep)) {
573 if (ND_selected(v))
574 edgeCnt++;
575 }
576 }
577 sel_node = nodeCnt;
578 sel_edge = edgeCnt;
579 sel_graph = 1;
580
581 snprintf(buf, sizeof(buf), "%d Nodes and %d edges selected", nodeCnt,
582 edgeCnt);
583 gtk_label_set_text((GtkLabel *) glade_xml_get_widget(xml, "label124"),
584 buf);
585 gtk_entry_set_text((GtkEntry *) glade_xml_get_widget(xml, "txtAttr"),
586 "");
587 Color_Widget_bg("white", glade_xml_get_widget(xml, "fixed6"));
588}
589
590void showAttrsWidget(void) {
591 if (view->activeGraph < 0) {
592 void *const dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
593 GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK,
594 "No active graph");
595 (void)gtk_dialog_run(dlg);
596 gtk_widget_destroy(dlg);
597 return;
598 }
599
600 gtk_widget_hide(glade_xml_get_widget(xml, "dlgSettings"));
601 gtk_widget_show(glade_xml_get_widget(xml, "dlgSettings"));
602 gtk_notebook_set_current_page((GtkNotebook *)
603 glade_xml_get_widget(xml, "notebook3"),
607}
608
609static void gvpr_select(const char *attrname, const char *regex_str,
610 int objType) {
611 agxbuf sf = {0};
612
613 if (objType == AGNODE)
614 agxbprint(&sf, "N[%s==\"%s\"]{selected = \"1\"}", attrname, regex_str);
615 else if (objType == AGEDGE)
616 agxbprint(&sf, "E[%s==\"%s\"]{selected = \"1\"}", attrname, regex_str);
617
618 char *const bf2 = agxbdisown(&sf);
619
620 enum { argc = 2 };
621 char *argv[argc + 1] = {"smyrna", bf2};
622
623 run_gvpr(view->g[view->activeGraph], argc, argv);
624 free(bf2);
626}
627
628_BB void on_attrSearchBtn_clicked(GtkWidget *widget, void *user_data) {
629 (void)widget;
630 (void)user_data;
631
632 const char *attrname = gtk_entry_get_text((GtkEntry *)
633 glade_xml_get_widget(xml, "txtAttr"));
634 const char *regex_str = gtk_entry_get_text((GtkEntry *)
635 glade_xml_get_widget(xml, "txtValue"));
636 gvpr_select(attrname, regex_str, get_object_type());
637
638}
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:336
int agset(void *obj, char *name, const char *value)
Definition attr.c:477
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
permits traversing the list of attributes of a given type
Definition attr.c:365
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:524
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_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: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: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