]> granicus.if.org Git - graphviz/commitdiff
Fix node list window to work when the datacolumns attribute is changed;
authorerg <devnull@localhost>
Thu, 15 Jul 2010 14:34:20 +0000 (14:34 +0000)
committererg <devnull@localhost>
Thu, 15 Jul 2010 14:34:20 +0000 (14:34 +0000)
add a button to export a selected subgraph with induced edges

cmd/smyrna/draw.c
cmd/smyrna/gui/datalistcallbacks.c
cmd/smyrna/tvnodes.c
cmd/smyrna/tvnodes.h

index 07003d2d4c71223ac64536db4f1981e4e1f067e1..41549b4c84a77747ff3295fa19849b0dc66b99e6 100755 (executable)
@@ -426,8 +426,6 @@ void SetFont(sdot_op * o, int param)
 /*for now we only support png files in 2d space, no image rotation*/
 void InsertImage(sdot_op * o, int param)
 {
-
-
     float w,h,x,y,X,Y,Z;
     glCompImage *i;
 
@@ -442,11 +440,9 @@ void InsertImage(sdot_op * o, int param)
        i = glCompImageNew(NULL, x, y);
        glCompImageLoadPng(i, o->op.u.image.name,0);
        i->common.functions.draw(i);
-
     }
-
-
 }
+
 void EmbedText(sdot_op* o, int param)
 {
        GLfloat x,y;
index ea638565d49df31b24d07158ee2ca860d53cd047..2516f39e26dd095c6077e4242955e29c1e003450 100755 (executable)
@@ -75,5 +75,10 @@ void btnTVHideAll_clicked_cb(GtkWidget * widget, gpointer user_data)
 
 void btnTVSaveAs_clicked_cb(GtkWidget * widget, gpointer user_data)
 {
-    tv_save_as();
+    tv_save_as(0);
+}
+
+void btnTVSaveWith_clicked_cb(GtkWidget * widget, gpointer user_data)
+{
+    tv_save_as(1);
 }
index f6730580b639d0ad5d1f0a989358c59c2195f259..5721068fbcc0304322384d4247ff8848de3c6eb5 100755 (executable)
 #include "topviewfuncs.h"
 #include "memory.h"
 
-typedef struct{
+typedef struct {
     GType type;
-    charname;
+    char *name;
     int editable;
-}gridCol;
-typedef struct
-{
+} gridCol;
+typedef struct {
     int count;
-    gridCol** columns;
+    gridCol **columns;
     GtkTreeStore *store;
-    char* flds;
-}grid;
+    char *flds;
+    char *buf;
+} grid;
+
+static char* ID = "ID";
+static char* Name = "Name";
+static char* Visible = "Visible";
+
+/* induceEdges:
+ * Add all edges of g which have both ends in sg to sg
+ */
+static void induceEdges (Agraph_t * g, Agraph_t * sg)
+{
+    Agnode_t *n;
+    Agedge_t *e;
+
+    for (n = agfstnode(sg); n; n = agnxtnode(sg, n)) {
+       for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+           if (agsubnode(sg, aghead(e), 0)) {
+               agsubedge(sg, e, 1);
+           }
+       }
+    }
+}
 
 /*
        call this function to create a subgraph from filtered nodes and maybe edges
 */
-
-static int create_save_subgraph_from_filter(char *filename)
+static int create_save_subgraph_from_filter(char *filename, int withEdges)
 {
     Agraph_t *subg = agsubg(view->g[view->activeGraph], "temp", 1);
     FILE *outputfile;
-    Agnode_t* v;
-    Agraph_t* g;
+    Agnode_t *v;
+    Agraph_t *g;
+    int ret;
 
     g = view->g[view->activeGraph];
     for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
        if (ND_selected(v))
            agsubnode(subg, v, 1);
     }
+    if (withEdges)
+       induceEdges (view->g[view->activeGraph], subg);
 
     if ((outputfile = fopen(filename, "w"))) {
-       int ret = agwrite(subg, outputfile);
-       fclose (outputfile);
-       if (ret) {
-           agdelsubg(view->g[view->activeGraph], subg);
-           return 1;
-       } else {
-           agdelsubg(view->g[view->activeGraph], subg);
-           return 0;
-       }
+       ret = agwrite(subg, outputfile);
+       fclose(outputfile);
     } else {
-       agdelsubg(view->g[view->activeGraph], subg);
-       return 0;
+       fprintf (stderr, "Could not open %s for writing\n", filename);
+       ret = 1;
     }
-
-
+    agdelsubg(view->g[view->activeGraph], subg);
+    return ret;
 }
 
 
-static void set_visibility(Agraph_t* g,int visibility)
+static void set_visibility(Agraph_t * g, int visibility)
 {
     Agnode_t *v;
-    char bf1[2];
-    char* bf2;
-    Agsym_t* visible_attr = GN_visible(g);
-    Agsym_t* selected_attr = GN_selected(g);
+    char *bf;
+    Agsym_t *visible_attr = GN_visible(g);
+    Agsym_t *selected_attr = GN_selected(g);
 
-    if (!visible_attr)
-       visible_attr = GN_visible(g) = agattr(g, AGNODE,"visible","1");
     if (!selected_attr)
        return;
-    sprintf(bf1,"%d",visibility);
-    for (v = agfstnode(g); v; v = agnxtnode(g, v)) 
-    {
-       bf2=agxget(v,selected_attr);
-       if((*bf2 == '\0') || (strcmp(bf2,"0")==0))
-               continue;
-       agxset(v,visible_attr,bf1);
+    if (!visible_attr)
+       visible_attr = GN_visible(g) = agattr(g, AGNODE, "visible", "1");
+    if (visibility)
+       bf = "1";
+    else
+       bf = "0";
+    for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
+       if (!ND_selected(v)) continue;
+       agxset(v, visible_attr, bf);
     }
 }
 
 int tv_show_all(void)
 {
-    set_visibility(view->g[view->activeGraph],1);
-    updateSmGraph(view->g[view->activeGraph],view->Topview);
+    set_visibility(view->g[view->activeGraph], 1);
+    updateSmGraph(view->g[view->activeGraph], view->Topview);
     return 1;
 }
 
 int tv_hide_all(void)
 {
-    set_visibility(view->g[view->activeGraph],0);
-    updateSmGraph(view->g[view->activeGraph],view->Topview);
+    set_visibility(view->g[view->activeGraph], 0);
+    updateSmGraph(view->g[view->activeGraph], view->Topview);
 
     return 1;
 }
-int tv_save_as(void)
+
+int tv_save_as(int withEdges)
 {
     GtkWidget *dialog;
     dialog = gtk_file_chooser_dialog_new("Save File",
@@ -120,7 +136,7 @@ int tv_save_as(void)
        char *filename;
        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
-       create_save_subgraph_from_filter(filename);
+       create_save_subgraph_from_filter(filename, withEdges);
        g_free(filename);
        gtk_widget_destroy(dialog);
 
@@ -132,47 +148,57 @@ int tv_save_as(void)
     return 0;
 }
 
-
-
-static void create_text_column(char* Title,GtkTreeView* tree,int asso,int editable)
+static void create_text_column(char *Title, GtkTreeView * tree, int asso,
+                              int editable)
 {
-   PangoColor c;
+    PangoColor c;
     GtkTreeViewColumn *column;
     GtkCellRendererText *renderer;
 
 
-   renderer = (GtkCellRendererText*)gtk_cell_renderer_text_new ();
-    ((GtkCellRenderer*)renderer)->mode=GTK_CELL_RENDERER_MODE_EDITABLE;
-   renderer->editable=editable;
-   c.blue=0;
-   c.green=1;
-   c.red=0;
-   renderer->foreground=c;
-
+    renderer = (GtkCellRendererText *) gtk_cell_renderer_text_new();
+    ((GtkCellRenderer *) renderer)->mode = GTK_CELL_RENDERER_MODE_EDITABLE;
+    renderer->editable = editable;
+    c.blue = 0;
+    c.green = 1;
+    c.red = 0;
+    renderer->foreground = c;
 
-   column = gtk_tree_view_column_new_with_attributes (Title,(GtkCellRenderer*)renderer,"text",asso,NULL);
+    column =
+       gtk_tree_view_column_new_with_attributes(Title,
+                                                (GtkCellRenderer *)
+                                                renderer, "text", asso,
+                                                NULL);
 
-   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
-   gtk_tree_view_column_set_resizable  (column,1);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
+    gtk_tree_view_column_set_resizable(column, 1);
 
 }
-static void create_toggle_column(char* Title,GtkTreeView* tree,int asso,int editable)
-{
-   GtkTreeViewColumn *column;
-    GtkCellRendererToggle* renderer;
-   renderer =(GtkCellRendererToggle*)gtk_cell_renderer_toggle_new ();
-   renderer->activatable=editable;
-   g_object_set (G_OBJECT (renderer),"foreground", "red",NULL);
 
-   column =  gtk_tree_view_column_new_with_attributes (Title,(GtkCellRenderer*)renderer,"active",asso,NULL);
-   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
-    gtk_tree_view_column_set_resizable  (column,1);
+static void create_toggle_column(char *Title, GtkTreeView * tree, int asso,
+                                int editable)
+{
+    GtkTreeViewColumn *column;
+    GtkCellRendererToggle *renderer;
+    renderer = (GtkCellRendererToggle *) gtk_cell_renderer_toggle_new();
+    renderer->activatable = editable;
+    /* g_object_set(G_OBJECT(renderer), "foreground", "red", NULL); */
+
+    column =
+       gtk_tree_view_column_new_with_attributes(Title,
+                                                (GtkCellRenderer *)
+                                                renderer, "active", asso,
+                                                NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
+    gtk_tree_view_column_set_resizable(column, 1);
 
 }
+
 #ifdef UNUSED
-static int boolStrMap(charstr)
+static int boolStrMap(char *str)
 {
-    if (strcmp(str,"1") ||strcmp(str,"true")|| strcmp(str,"TRUE") || strcmp(str,"True"))
+    if (strcmp(str, "1") || strcmp(str, "true") || strcmp(str, "TRUE")
+       || strcmp(str, "True"))
        return 1;
     return 0;
 
@@ -180,202 +206,199 @@ static int boolStrMap(char* str)
 
 #endif
 
-static void populate_data(Agraph_t* g,grid* grid)
+static void populate_data(Agraph_t * g, grid * grid)
 {
     Agnode_t *v;
-    int id=0;
+    int id = 0;
     GtkTreeIter iter;
-    static GValue valueData;
-    static GValue* value;
-
+    GValue value = {0};
     char* bf;
-    value=&valueData;
-
-    //GValue* g_value_init (GValue *value,GType g_type);
-/*    if(!value)
-       value=(GValue*)malloc(sizeof(GValue));*/
-    value=g_value_init (value,G_TYPE_STRING);
+    gridCol* cp;
 
     for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
-       if (!ND_selected(v)) continue;
-       gtk_tree_store_append (grid->store, &iter, NULL);
-
-       for (id=1;id < grid->count;id ++)
-       {
-           g_value_unset (value);
-           value=g_value_init (value,grid->columns[id]->type);
-           if(id==1)
-               bf=agnameof(v);
+       if (!ND_selected(v))
+           continue;
+       gtk_tree_store_append(grid->store, &iter, NULL);
+
+       for (id = 0; id < grid->count; id++) {
+           cp = grid->columns[id];
+           if (cp->name == ID) continue;
+
+           if (cp->name == Name)
+               bf = agnameof(v);
            else
-           bf=agget(v,grid->columns[id]->name);
-           if((!bf) && (id !=2))
+               bf = agget(v, cp->name);
+           if ((!bf) && (cp->name != Visible))
                continue;
 
-           switch(grid->columns[id]->type)
-           {
+           g_value_init(&value, cp->type);
+           switch (grid->columns[id]->type) {
            case G_TYPE_BOOLEAN:
-                   if(bf)
-                   {
-                       if((strcmp(bf,"1")==0) || (strcmp(bf,"true")==0) || (strcmp(bf,"True")==0))
-                           g_value_set_boolean (value, 1);
-                       else
-                           g_value_set_boolean (value, 0);
-                   }
+               if (bf) {
+                   if ((strcmp(bf, "1") == 0) || (strcmp(bf, "true") == 0)
+                       || (strcmp(bf, "True") == 0))
+                       g_value_set_boolean(&value, 1);
                    else
-                   {
-                       if(id==2)
-                           g_value_set_boolean (value, 1);
-                   }
-
+                       g_value_set_boolean(&value, 0);
+               } else {
+                   if (cp->name == Visible)
+                       g_value_set_boolean(&value, 1);
+               }
                break;
            default:
-                   g_value_set_string (value, bf);
+               g_value_set_static_string(&value, bf);
 
            }
-           gtk_tree_store_set_value(grid->store,&iter,id,value);
-        }
-
+           gtk_tree_store_set_value(grid->store, &iter, id, &value);
+           g_value_unset(&value);
+       }
     }
 }
 
-static GtkTreeStore* update_tree_store(GtkTreeStore* store,int ncolumns,GType *types)
+static GtkTreeStore *update_tree_store(GtkTreeStore * store, int ncolumns,
+                                      GType * types)
 {
-    if ((ncolumns ==0) || (types==NULL))
+    if ((ncolumns == 0) || (types == NULL))
        return NULL;
-    if(store)
-    {
+    if (store) {
        gtk_tree_store_clear(store);
        g_object_unref(store);
     }
-       
-    store=gtk_tree_store_newv (ncolumns,types);
+
+    store = gtk_tree_store_newv(ncolumns, types);
     return store;
 }
 
 
-static void create_column(gridCol* c,GtkTreeView *tree,int id)
+static void create_column(gridCol * c, GtkTreeView * tree, int id)
 {
     if (!c)
        return;
-    switch (c->type)
-    {
+    switch (c->type) {
     case G_TYPE_STRING:
     case G_TYPE_INT:
-       create_text_column(c->name,tree,id,c->editable);
+       create_text_column(c->name, tree, id, c->editable);
        break;
     case G_TYPE_BOOLEAN:
-       create_toggle_column(c->name,tree,id,c->editable);
+       create_toggle_column(c->name, tree, id, c->editable);
        break;
     default:
-       create_text_column(c->name,tree,id,c->editable);
+       create_text_column(c->name, tree, id, c->editable);
     }
 }
 
-GtkTreeView* update_tree (GtkTreeView *tree,grid* g)
+static GtkTreeView *update_tree(GtkTreeView * tree, grid * g)
 {
 
-    GtkTreeStore* store=NULL;
-    GtkTreeViewColumncolumn;
+    GtkTreeStore *store = NULL;
+    GtkTreeViewColumn *column;
     GType *types;
-    int id=0;
+    int id = 0;
 
-    if(tree) {
-        while ((column=gtk_tree_view_get_column(tree,0)))  /*clear all columns*/
-           gtk_tree_view_remove_column(tree,column);
-       store=(GtkTreeStore*)gtk_tree_view_get_model(tree);
-    }
-    else {
-       tree=(GtkTreeView*)gtk_tree_view_new();
-        gtk_widget_show((GtkWidget*)tree);
+    if (tree) {
+       while ((column = gtk_tree_view_get_column(tree, 0)))    /*clear all columns */
+           gtk_tree_view_remove_column(tree, column);
+       store = (GtkTreeStore *) gtk_tree_view_get_model(tree);
+    } else {
+       tree = (GtkTreeView *) gtk_tree_view_new();
+       gtk_widget_show((GtkWidget *) tree);
 
-       gtk_container_add((GtkContainer*)glade_xml_get_widget(xml, "scrolledwindow9"),(GtkWidget*)tree);
+       gtk_container_add((GtkContainer *)
+                         glade_xml_get_widget(xml, "scrolledwindow9"),
+                         (GtkWidget *) tree);
 
     }
-    if(g->count > 0) {
-       types=N_NEW(g->count, GType);
-       for (id=0;id < g->count;id++)
-           types[id]=g->columns[id]->type;
-        store=update_tree_store(g->store,g->count,types);
-        gtk_tree_view_set_model(tree,(GtkTreeModel*)store);
-       /*insert columns*/
-       for (id=0;id < g->count;id ++)
-           create_column(g->columns[id],tree,id);
+    if (g->count > 0) {
+       types = N_NEW(g->count, GType);
+       for (id = 0; id < g->count; id++)
+           types[id] = g->columns[id]->type;
+       store = update_tree_store(g->store, g->count, types);
+       free (types);
+       gtk_tree_view_set_model(tree, (GtkTreeModel *) store);
+       /*insert columns */
+       for (id = 0; id < g->count; id++)
+           create_column(g->columns[id], tree, id);
     }
-    g->store=store;
+    g->store = store;
     return tree;
 }
 
-static void add_column(grid* g,char* name,int editable,GType g_type)
+static void add_column(grid * g, char *name, int editable, GType g_type)
 {
-    if (*name == '\0') return;
-    g->columns=(gridCol**)realloc(g->columns,sizeof(gridCol*)*(g->count+1));
+    if (*name == '\0')
+       return;
+    g->columns =
+       (gridCol **) realloc(g->columns,
+                            sizeof(gridCol *) * (g->count + 1));
     g->columns[g->count] = NEW(gridCol);
-    g->columns[g->count]->editable=editable;
-    g->columns[g->count]->name=strdup(name);
-    g->columns[g->count]->type=g_type;
+    g->columns[g->count]->editable = editable;
+    g->columns[g->count]->name = name;
+    g->columns[g->count]->type = g_type;
     g->count++;
 }
 
-static void clear_grid(grid* g, char* flds)
+static void clearGrid(grid * g)
 {
     int id;
-    if (g->count) {
-        for (id=0;id < g->count ; id++) {
-           free(g->columns[id]->name);
-           free (g->columns[id]);
-       }
+    for (id = 0; id < g->count; id++) {
+       free(g->columns[id]);
     }
-    free (g->columns);
+    free(g->columns);
+    free(g->buf);
     g->count = 0;
     g->columns = 0;
-    g->flds=flds;
+    g->flds = 0;
 }
 
-static grid* initGrid(char* flds)
+static grid *initGrid()
 {
-    gridgr = NEW(grid);
-    gr->columns=NULL;
-    gr->count=0;
-    gr->flds=flds;
+    grid *gr = NEW(grid);
+    gr->columns = NULL;
+    gr->count = 0;
+    gr->buf = 0;
     return gr;
 }
 
-static grid* update_columns(grid* g,char* str)
+static grid *update_columns(grid * g, char *str)
 {
     /*free existing memory if necessary */
-    char* a;
-    if(g) {
-       if (g->flds != str) clear_grid(g, str);
-       else return g;
-    }
-    else
-       g=initGrid(str);
-    add_column(g,"ID",0,G_TYPE_STRING);
-    add_column(g,"Name",0,G_TYPE_STRING);
-    add_column(g,"visible",0,G_TYPE_BOOLEAN);
-    if(!str)
+    char *a;
+    char *buf;
+
+    if (g) {
+       if (g->flds != str)
+           clearGrid(g);
+       else
+           return g;
+    } else
+       g = initGrid(str);
+    /* add_column(g, ID, 0, G_TYPE_STRING); */
+    add_column(g, Name, 0, G_TYPE_STRING);
+    /* add_column(g, visible, 0, G_TYPE_BOOLEAN); */
+    if (!str)
        return g;
-    
-    a=strtok(str,",");
-    add_column(g,a,1,G_TYPE_STRING);
-    while ((a=strtok(NULL,",")))
-        add_column(g,a,1,G_TYPE_STRING);
+
+    g->flds = str;
+    buf = strdup (str);  /* need to dup because str is actual graph attribute value */
+    a = strtok(buf, ",");
+    add_column(g, a, 1, G_TYPE_STRING);
+    while ((a = strtok(NULL, ",")))
+       add_column(g, a, 1, G_TYPE_STRING);
     return g;
 }
 
-void setup_tree (Agraph_t* g)
+void setup_tree(Agraph_t * g)
 {
     /*
-    G_TYPE_STRING:
-    G_TYPE_INT:
-    G_TYPE_BOOLEAN:
-    */
+       G_TYPE_STRING:
+       G_TYPE_INT:
+       G_TYPE_BOOLEAN:
+     */
     static GtkTreeView *tree;
-    static gridgr;
-    char* buf = agget(g,"datacolumns");
+    static grid *gr;
+    char *buf = agget(g, "datacolumns");
 
-    gr = update_columns(gr,buf);
-    tree=update_tree (tree,gr);
-    populate_data(g,gr);
+    gr = update_columns(gr, buf);
+    tree = update_tree(tree, gr);
+    populate_data(g, gr);
 }
-
index d70e94c2014e27ff7a42779d8831070b5a2036c1..0852e8ec76f5e66d3d831e55073b4516bc7db284 100755 (executable)
@@ -131,7 +131,7 @@ extern "C" {
 */
     int tv_show_all(void);
     int tv_hide_all(void);
-    int tv_save_as(void);
+    int tv_save_as(int);
     void setup_tree (Agraph_t* g);
 
 #ifdef __cplusplus