]> granicus.if.org Git - graphviz/commitdiff
prepare strings for tooltips and hrefs (URL) for use in gui
authorellson <devnull@localhost>
Tue, 18 Oct 2005 18:22:40 +0000 (18:22 +0000)
committerellson <devnull@localhost>
Tue, 18 Oct 2005 18:22:40 +0000 (18:22 +0000)
lib/gvc/gvcint.h
lib/gvc/gvevent.c
lib/gvc/gvjobs.c

index 3cd0a523d1902ebcce5b7da4da4ef34576bcdc50..b32689b1a8a5936e411d327361d03bfca97f86af 100644 (file)
@@ -212,6 +212,8 @@ extern "C" {
 
        void *selected_obj;      /* graph object that has been selected */
                                        /* (e.g. button 1 clicked on current obj) */
+       char *active_tooltip;           /* tooltip of active object - or NULL */
+       char *selected_href;            /* href of selected object - or NULL */
        gv_argvlist_t selected_obj_type_name; /* (e.g. "edge" "node3" "e" "->" "node5" "") */
        gv_argvlist_t selected_obj_attributes; /* even args are names, odd are values */
                                /* e.g. "color" "red" "style" "filled" */
index 3bdc8a7d48cd12e5b8c8fa82ade5e278b916a356..638e99d70231962d1d977e4556c33bbb4fb94f4d 100644 (file)
 #define ZOOMFACTOR 1.1
 #define EPSILON .0001
 
+static char *s_digraph = "digraph";
+static char *s_graph = "graph";
+static char *s_subgraph = "subgraph";
+static char *s_node = "node";
+static char *s_edge = "edge";
+static char *s_tooltip = "tooltip";
+static char *s_href = "href";
+static char *s_URL = "URL";
+static char *s_tailport = "tailport";
+static char *s_headport = "headport";
+static char *s_key = "key";
+
 /* FIXME - gv_argvlist_set_item and gv_argvlist_free should be in a utilities sourcefile */
 static void gv_argvlist_set_item(gv_argvlist_t *list, int index, char *item)
 {
@@ -43,12 +55,12 @@ static void gv_graph_state(GVJ_t *job, graph_t *g)
     j = 0;
     if (g == g->root) {
        if (g->kind && AGFLAG_DIRECTED) 
-            gv_argvlist_set_item(list, j++, "digraph");
+            gv_argvlist_set_item(list, j++, s_digraph);
        else
-            gv_argvlist_set_item(list, j++, "graph");
+            gv_argvlist_set_item(list, j++, s_graph);
     }
     else {
-        gv_argvlist_set_item(list, j++, "subgraph");
+        gv_argvlist_set_item(list, j++, s_subgraph);
     }
     gv_argvlist_set_item(list, j++, g->name);
     list->argc = j;
@@ -60,6 +72,12 @@ static void gv_graph_state(GVJ_t *job, graph_t *g)
         gv_argvlist_set_item(list, j++, agxget(g, a->index));
     }
     list->argc = j;
+
+    a = agfindattr(g->root, s_href);
+    if (!a)
+       a = agfindattr(g->root, s_URL);
+    if (a)
+       job->selected_href = strdup_and_subst_graph(agxget(g, a->index), g);
 }
 
 static void gv_node_state(GVJ_t *job, node_t *n)
@@ -71,7 +89,7 @@ static void gv_node_state(GVJ_t *job, node_t *n)
 
     list = &(job->selected_obj_type_name);
     j = 0;
-    gv_argvlist_set_item(list, j++, "node");
+    gv_argvlist_set_item(list, j++, s_node);
     gv_argvlist_set_item(list, j++, n->name);
     list->argc = j;
 
@@ -83,6 +101,12 @@ static void gv_node_state(GVJ_t *job, node_t *n)
         gv_argvlist_set_item(list, j++, agxget(n, a->index));
     }
     list->argc = j;
+
+    a = agfindattr(n->graph->proto->n, s_href);
+    if (!a)
+        a = agfindattr(n->graph->proto->n, s_URL);
+    if (a)
+       job->selected_href = strdup_and_subst_node(agxget(n, a->index), n);
 }
 
 static void gv_edge_state(GVJ_t *job, edge_t *e)
@@ -98,7 +122,7 @@ static void gv_edge_state(GVJ_t *job, edge_t *e)
      * but we commonly alse use edge kind (e.g. "->") and tailport,headport
      * in edge names */
     j = 0;
-    gv_argvlist_set_item(nlist, j++, "edge");
+    gv_argvlist_set_item(nlist, j++, s_edge);
     gv_argvlist_set_item(nlist, j++, e->tail->name);
     j++; /* skip tailport slot for now */
     gv_argvlist_set_item(nlist, j++, (e->tail->graph->kind && AGFLAG_DIRECTED)?"->":"--");
@@ -115,15 +139,15 @@ static void gv_edge_state(GVJ_t *job, edge_t *e)
        /* tailport and headport can be shown as part of the name, but they
         * are not identifying properties of the edge so we 
         * also list them as modifyable attributes. */
-        if (strcmp(a->name,"tailport") == 0)
+        if (strcmp(a->name,s_tailport) == 0)
            gv_argvlist_set_item(nlist, 2, agxget(e, a->index));
-       else if (strcmp(a->name,"headport") == 0)
+       else if (strcmp(a->name,s_headport) == 0)
            gv_argvlist_set_item(nlist, 5, agxget(e, a->index));
 
        /* key is strictly an identifying property to distinguish multiple
         * edges between the same node pair.   Its non-writable, so
         * no need to list it as an attribute as well. */
-       else if (strcmp(a->name,"key") == 0) {
+       else if (strcmp(a->name,s_key) == 0) {
            gv_argvlist_set_item(nlist, 6, agxget(e, a->index));
            continue;
        }
@@ -132,6 +156,12 @@ static void gv_edge_state(GVJ_t *job, edge_t *e)
         gv_argvlist_set_item(alist, j++, agxget(e, a->index));
     }
     alist->argc = j;
+
+    a = agfindattr(e->head->graph->proto->e, s_href);
+    if (!a)
+       a = agfindattr(e->head->graph->proto->e, s_URL);
+    if (a)
+       job->selected_href = strdup_and_subst_edge(agxget(e, a->index), e);
 }
 
 static void gvevent_refresh(GVJ_t * job)
@@ -203,22 +233,44 @@ static void gvevent_leave_obj(GVJ_t * job)
            break;
         }
     }
+    job->active_tooltip = NULL;
 }
 
 static void gvevent_enter_obj(GVJ_t * job)
 {
-    void *obj = job->current_obj;
+    void *obj;
+    graph_t *g;
+    edge_t *e;
+    node_t *n;
+    Agsym_t *a;
 
+    if (job->active_tooltip) {
+       free(job->active_tooltip);
+       job->active_tooltip = NULL;
+    }
+    obj = job->current_obj;
     if (obj) {
         switch (agobjkind(obj)) {
         case AGGRAPH:
-           GD_active((graph_t*)obj) = TRUE;
+           g = (graph_t*)obj;
+           GD_active(g) = TRUE;
+           a = agfindattr(g->root, s_tooltip);
+           if (a)
+               job->active_tooltip = strdup_and_subst_graph(agxget(g, a->index), g);
            break;
         case AGNODE:
-           ND_active((node_t*)obj) = TRUE;
+           n = (node_t*)obj;
+           ND_active(n) = TRUE;
+           a = agfindattr(n->graph->proto->n, s_tooltip);
+           if (a)
+               job->active_tooltip = strdup_and_subst_node(agxget(e, a->index), n);
            break;
         case AGEDGE:
-           ED_active((edge_t*)obj) = TRUE;
+           e = (edge_t*)obj;
+           ED_active(e) = TRUE;
+           a = agfindattr(e->head->graph->proto->e, s_tooltip);
+           if (a)
+               job->active_tooltip = strdup_and_subst_edge(agxget(e, a->index), e);
            break;
         }
     }
@@ -262,7 +314,6 @@ static void gvevent_find_current_obj(GVJ_t * job, pointf pointer)
 static void gvevent_select_current_obj(GVJ_t * job)
 {
     void *obj;
-    int i;
 
     obj = job->selected_obj;
     if (obj) {
@@ -279,6 +330,11 @@ static void gvevent_select_current_obj(GVJ_t * job)
         }
     }
 
+    if (job->selected_href) {
+       free(job->selected_href);
+        job->selected_href = NULL;
+    }
+
     obj = job->selected_obj = job->current_obj;
     if (obj) {
         switch (agobjkind(obj)) {
index 02d301993bd26da1f25a70240f8ba252f6cfc3e9..c92d51f07e0613b1e48a0b0402df651901a7fd06 100644 (file)
@@ -134,6 +134,10 @@ void gvrender_delete_jobs(GVC_t * gvc)
        job = job->next;
        gv_argvlist_free(&(j->selected_obj_attributes));
        gv_argvlist_free(&(j->selected_obj_type_name));
+       if (j->active_tooltip)
+           free(j->active_tooltip);
+       if (j->selected_href)
+           free(j->selected_href);
        free(j);
     }
     gvc->jobs = gvc->job = output_filename_job = output_langname_job =