#include "topviewfuncs.h"
#include "memory.h"
-typedef struct{
+typedef struct {
GType type;
- char* name;
+ 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",
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);
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(char* str)
+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;
#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;
- GtkTreeViewColumn* column;
+ 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()
{
- grid* gr = 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 grid* gr;
- 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);
}
-