From: ellson Date: Wed, 23 Jan 2008 20:52:43 +0000 (+0000) Subject: Add smyrna to main graphviz tree X-Git-Tag: LAST_LIBGRAPH~32^2~4850 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c0cd0f5e82f81dec058b4f3eb53e098ea0a8f1a;p=graphviz Add smyrna to main graphviz tree --- diff --git a/cmd/smyrna/tvnodes.c b/cmd/smyrna/tvnodes.c new file mode 100755 index 000000000..66a88c208 --- /dev/null +++ b/cmd/smyrna/tvnodes.c @@ -0,0 +1,679 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#include "topview.h" +#include "tvnodes.h" +#include "btree.h" +tv_nodes TV_Nodes; +static char buf [255]; +int MP_Flag=0; +tv_filter* create_tv_filter() +{ + tv_filter* f; + f=(tv_filter*)malloc(sizeof(tv_filter)); + clear_tv_filter(f); + return f; +} +void init_tv_nodes(tv_nodes* TV_Nodes) +{ + int i; + TV_Nodes->filtered=0; + TV_Nodes->activepage=-1; + TV_Nodes->firstnodeid=0; + TV_Nodes->pagecount=0; + TV_Nodes->recordperpage=22; + TV_Nodes->page_data_index=0; + TV_Nodes->Y_Gap=25; + TV_Nodes->Y=12; + TV_Nodes->initial_Y=12; + TV_Nodes->chkSelected_X=5; + TV_Nodes->IDLabel_X=10; + TV_Nodes->chkVisible_X=55; + TV_Nodes->chkHighlighted_X=85; + TV_Nodes->Data1_X=105; + TV_Nodes->Data2_X=305; + TV_Nodes->page_data_node_index=0; + reset_page_History(); + + //null gui elemetns + for (i=0;i < MAX_NODE_PER_PAGE ;i ++) + { + TV_Nodes->TV_Node[i].chkHighlighted=NULL; + TV_Nodes->TV_Node[i].chkSelected=NULL; + TV_Nodes->TV_Node[i].chkVisible=NULL; + TV_Nodes->TV_Node[i].Data1=NULL; + TV_Nodes->TV_Node[i].Data2=NULL; + TV_Nodes->TV_Node[i].IDLabel=NULL; + } + TV_Nodes->initialized=1; +} + +void clear_tv_filter(tv_filter* TV_Filter) +{ + TV_Filter->highlighted=-1; + TV_Filter->visible=-1; + TV_Filter->min_data1=NULL; + TV_Filter->max_data1=NULL; + TV_Filter->min_data2=NULL; + TV_Filter->max_data2=NULL; + + TV_Nodes.filtered=0; + +} + +extern int set_filter(tv_filter* TV_Filter,char* MinData1,char* MaxData1,char* MinData2,char* MaxData2,char* Filter_String,int selected,int visible,int highlighted) +{ + TV_Filter->selected=selected; + TV_Filter->highlighted=highlighted; + TV_Filter->visible=visible; + TV_Filter->min_data1=MinData1; + TV_Filter->max_data1=MaxData1; + TV_Filter->min_data2=MinData2; + TV_Filter->max_data2=MaxData2; + TV_Filter->filter_string=Filter_String; + TV_Nodes.filtered=1; +} +int reverse_selection() +{ + int i=0; + for (i; i < Topview.Nodecount ; i ++) + { + if (((custom_object_data*)AGDATA(Topview.Nodes[i].Node))->Selected ) + deselect_node(view.g[view.activeGraph],Topview.Nodes[i].Node); + else + select_node(view.g[view.activeGraph],Topview.Nodes[i].Node); + } + for (i=0; i < Topview.Edgecount ; i ++) + { + if (((custom_object_data*)AGDATA(Topview.Edges[i].Edge))->Selected ) + deselect_edge(view.g[view.activeGraph],Topview.Edges[i].Edge); + else + select_edge(view.g[view.activeGraph],Topview.Edges[i].Edge); + } +} +int validate_node(tv_node* TV_Node) +{ + static btree_node* n=0; + char* data_attr1; + char* data_attr2; + char* data1; + char* data2; +// n=tree_from_filter_string("([IP=\"^10.*\",min=\"0\",max=\"0\"])"); + // get attributes from graph + data_attr1=agget(view.g[view.activeGraph],"DataAttribute1"); + data_attr2=agget(view.g[view.activeGraph],"DataAttribute2"); + + + if (TV_Nodes.filtered) + { + int valid=1; + if((MP_Flag==1) || (!n)) + { + n=tree_from_filter_string(TV_Nodes.filter.filter_string); + MP_Flag=0; + if (strcmp(TV_Nodes.filter.min_data1, agget(Topview.Nodes[TV_Node->index].Node,data_attr1) )) + valid=0; + } + if (data_attr1 && TV_Nodes.filter.max_data1 && agget(Topview.Nodes[TV_Node->index].Node,data_attr1)) + { + if (strcmp(agget(Topview.Nodes[TV_Node->index].Node,data_attr1),TV_Nodes.filter.min_data1)) + valid=0; + } + //string data checks attr2 + if (data_attr2 && TV_Nodes.filter.min_data2 && agget(Topview.Nodes[TV_Node->index].Node,data_attr2)) + { + if (strcmp(TV_Nodes.filter.min_data2, agget(Topview.Nodes[TV_Node->index].Node,data_attr2) )) + valid=0; + } + if (data_attr2 && TV_Nodes.filter.max_data2 && agget(Topview.Nodes[TV_Node->index].Node,data_attr2)) + { + if (agget(Topview.Nodes[TV_Node->index].Node,data_attr2),TV_Nodes.filter.min_data2) + valid=0; + } + if (strlen(TV_Nodes.filter.filter_string)>0) + valid=evaluate_expresions (TV_Node,n); + //if show only highlighted + if (TV_Nodes.filter.highlighted >= 0) + { + if(((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Highlighted!= TV_Nodes.filter.highlighted) + valid=0; + } + //if show only visibles + if (TV_Nodes.filter.visible >= 0) + { + if(((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Visible!= TV_Nodes.filter.visible) + valid=0; + } + //if show only selected + if (TV_Nodes.filter.selected >= 0) + { + if(((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Selected!= TV_Nodes.filter.selected) + valid=0; + } + return valid; + } + else + return 1; +} + +int update_node_gui_objects(tv_node* TV_Node) +{ + char* data_attr1; + char* data_attr2; + char buf[255]; + GtkLayout* layout; + + // get attributes from graph + data_attr1=agget(view.g[view.activeGraph],"DataAttribute1"); + data_attr2=agget(view.g[view.activeGraph],"DataAttribute2"); + + //create if objects are null + layout=glade_xml_get_widget(xml, "layoutTVData"); + //select box + if (!TV_Node->chkSelected) + { + TV_Node->chkSelected=gtk_check_button_new(); + gtk_layout_put (layout,TV_Node->chkSelected,LOCATION_X_CHKSELECTED,TV_Nodes.Y); + } + gtk_widget_show(TV_Node->chkSelected); + gtk_toggle_button_set_active(TV_Node->chkSelected,((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Selected); + + //Id Label + if (!TV_Node->IDLabel) + { + TV_Node->IDLabel=gtk_label_new(""); + gtk_layout_put (layout,TV_Node->IDLabel,LOCATION_X_IDLABEL,TV_Nodes.Y); + } + sprintf(buf, "%d", TV_Node->index); + gtk_label_set_text (TV_Node->IDLabel,buf); + gtk_widget_show(TV_Node->IDLabel); + + //visible + if (!TV_Node->chkVisible) + { + TV_Node->chkVisible=gtk_check_button_new(); + gtk_layout_put (layout,TV_Node->chkVisible,LOCATION_X_CHKVISIBLE,TV_Nodes.Y); + } + + gtk_widget_show(TV_Node->chkVisible); + gtk_toggle_button_set_active(TV_Node->chkVisible,((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Visible); + //highlighted + if (!TV_Node->chkHighlighted) + { + TV_Node->chkHighlighted=gtk_check_button_new(); + gtk_layout_put (layout,TV_Node->chkHighlighted,LOCATION_X_CHKHIGHLIGHTED,TV_Nodes.Y); + } + gtk_widget_show(TV_Node->chkHighlighted); + gtk_toggle_button_set_active(TV_Node->chkHighlighted,((custom_object_data*)AGDATA(Topview.Nodes[TV_Node->index].Node))->Highlighted); + + + //DATA 1 + if (!TV_Node->Data1) + { + TV_Node->Data1=gtk_entry_new(); + gtk_layout_put (layout,TV_Node->Data1,LOCATION_X_DATA1,TV_Nodes.Y); + gtk_widget_set_size_request(TV_Node->Data1,300,23); + + } + if(data_attr1) + { + gtk_entry_set_text (TV_Node->Data1,agget(Topview.Nodes[TV_Node->index].Node,data_attr1)); + } + else + gtk_entry_set_text (TV_Node->Data1,""); + gtk_widget_show(TV_Node->Data1); + + //DATA 2 + if (!TV_Node->Data2) + { + TV_Node->Data2=gtk_entry_new(); + gtk_layout_put (layout,TV_Node->Data2,LOCATION_X_DATA2,TV_Nodes.Y); + gtk_widget_set_size_request(TV_Node->Data2,300,23); + } + if(data_attr2) + { + gtk_entry_set_text (TV_Node->Data2,agget(Topview.Nodes[TV_Node->index].Node,data_attr2)); + } + else + gtk_entry_set_text (TV_Node->Data2,""); + gtk_widget_show(TV_Node->Data2); +} + + +extern int tv_nodes_last_page() +{ + if (TV_Nodes.activepage0) + return tv_nodes_goto_page(0); + else + return 0; +} + +extern int tv_nodes_goto_page(int page) +{ + GtkSpinButton* spn; + tv_node* tvn; + GtkLabel* lblTVPage; + + if ((page >=0) && page <= TV_Nodes.pagecount) + { + if(TV_Nodes.general_purpose_flag==1) + { + update_TV_data_from_gui(); + TV_Nodes.general_purpose_flag=0; + } + TV_Nodes.activepage=page; + TV_Nodes.page_data_node_index=TV_Nodes.page_history[TV_Nodes.activepage]; + TV_Nodes.page_data_index=0; + TV_Nodes.firstnodeid=TV_Nodes.page_data_node_index; + TV_Nodes.Y=TV_Nodes.initial_Y; + hide_data_widgets(); + } + else + return 0; + while ((TV_Nodes.page_data_index < TV_Nodes.recordperpage)&&(TV_Nodes.page_data_node_index < Topview.Nodecount)) + { + tvn=&TV_Nodes.TV_Node[TV_Nodes.page_data_index]; + tvn->index=TV_Nodes.page_data_node_index; + if(Topview.Nodes[TV_Nodes.page_data_node_index].valid==1) + { + TV_Nodes.page_data_index++; + update_node_gui_objects(tvn); + TV_Nodes.Y=TV_Nodes.Y+TV_Nodes.Y_Gap; + } + TV_Nodes.page_data_node_index++; + } + lblTVPage=glade_xml_get_widget(xml, "lblTVPage"); + sprintf(buf,"(%i / %i)", TV_Nodes.activepage+1,TV_Nodes.pagecount+1); + gtk_label_set_text(lblTVPage,buf); + spn=glade_xml_get_widget(xml, "spnTVGotopage"); + gtk_spin_button_set_value(spn,page+1); + + + + + return 1; +} + +extern int tv_nodes_prior_page() +{ + tv_node* tvn; + GtkLabel* lblTVPage; + if (TV_Nodes.activepage >0) + { + return tv_nodes_goto_page(TV_Nodes.activepage -1); + } + else + return 0; +} + + +extern int tv_nodes_next_page() +{ + tv_node* tvn; + GtkLabel* lblTVPage; + if (TV_Nodes.activepage < TV_Nodes.pagecount) + { + return tv_nodes_goto_page(TV_Nodes.activepage +1); + } + else + return 0; +} +extern void execute_tv_nodes() +{ + + gtk_widget_hide(glade_xml_get_widget(xml, "frmTVNodes")); + gtk_widget_show(glade_xml_get_widget(xml, "frmTVNodes")); +// gtk_window_set_keep_above (glade_xml_get_widget(xml, "frmTVNodes"),1); + if(TV_Nodes.initialized < 1) + { + init_tv_nodes(&TV_Nodes); + } + //test filter + prepare_page_history(); + TV_Nodes.general_purpose_flag=1; + tv_nodes_next_page(); +} + + +static int hide_data_widgets() +{ + int i; + for (i=0;i < MAX_NODE_PER_PAGE ;i ++) + { + if (TV_Nodes.TV_Node[i].chkHighlighted) + { + gtk_widget_hide(TV_Nodes.TV_Node[i].chkHighlighted); + gtk_widget_hide(TV_Nodes.TV_Node[i].chkSelected); + gtk_widget_hide(TV_Nodes.TV_Node[i].chkVisible); + gtk_widget_hide(TV_Nodes.TV_Node[i].Data1); + gtk_widget_hide(TV_Nodes.TV_Node[i].Data2); + gtk_widget_hide(TV_Nodes.TV_Node[i].IDLabel); + } + } + + +} +extern int reset_page_History() +{ +/* if(TV_Nodes.page_history_count > 0) + { + free(TV_Nodes.page_history); + TV_Nodes.page_history_count=0; + }*/ + TV_Nodes.page_history_count=0; + TV_Nodes.page_history=realloc(TV_Nodes.page_history,sizeof(int) * TV_Nodes.page_history_count); + +} +static int push_to_page_history(int index) +{ + TV_Nodes.page_history_count++; + TV_Nodes.page_history=realloc(TV_Nodes.page_history,sizeof(int) * TV_Nodes.page_history_count); + TV_Nodes.page_history[TV_Nodes.page_history_count-1]=index; + return 1; +} +static int pop_from_page_history() +{ + if(TV_Nodes.page_history_count > 0) + { + int return_value; + return_value=TV_Nodes.page_history[TV_Nodes.page_history_count-1]; + TV_Nodes.page_history_count--; + TV_Nodes.page_history=realloc(TV_Nodes.page_history,sizeof(int) * TV_Nodes.page_history_count); + return return_value; + } + return 0; +} + +extern int prepare_page_history() +{ + GtkLabel* lblTVPage; + GtkSpinButton* spn; + int i=0; + int count=0; + tv_node tvn; + TV_Nodes.pagecount=0; + TV_Nodes.activepage=-1; + reset_page_History(); + push_to_page_history(0); + + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + count ++; + Topview.Nodes[i].valid=1; + } + else + Topview.Nodes[i].valid=0; + if (count== TV_Nodes.recordperpage) + { + push_to_page_history(i+1); + TV_Nodes.pagecount++; + count=0; + } + } + spn=glade_xml_get_widget(xml, "spnTVGotopage"); + gtk_spin_button_set_value(spn,0); + gtk_spin_button_set_range(spn,0,TV_Nodes.pagecount+1); + + + lblTVPage=glade_xml_get_widget(xml, "lblTVPage"); + sprintf(buf,"(%i / %i)", 1,TV_Nodes.pagecount+1); + gtk_label_set_text(lblTVPage,buf); + set_data_attributes(); +} +static int set_data_attributes() +{ + GtkLabel* lblData1; + GtkLabel* lblData2; + char* data_attr1; + char* data_attr2; + char buf[255]; + // get attributes from graph + data_attr1=agget(view.g[view.activeGraph],"DataAttribute1"); + data_attr2=agget(view.g[view.activeGraph],"DataAttribute2"); + if (!data_attr1) + { + agattr(view.g[view.activeGraph],AGRAPH,"DataAttribute1","DATA1"); + agattr(view.g[view.activeGraph],AGNODE,"DATA1",""); + } + if (!data_attr2) + { + agattr(view.g[view.activeGraph],AGRAPH,"DataAttribute2","DATA2"); + agattr(view.g[view.activeGraph],AGNODE,"DATA2",""); + } + + data_attr1=agget(view.g[view.activeGraph],"DataAttribute1"); + data_attr2=agget(view.g[view.activeGraph],"DataAttribute2"); + + lblData1=glade_xml_get_widget(xml, "lblTVData1"); + lblData2=glade_xml_get_widget(xml, "lblTVData2"); + gtk_label_set_text (lblData1,data_attr1); + gtk_label_set_text (lblData2,data_attr2); + return 1; + +} + +extern int update_TV_data_from_gui() +{ + int i=0; + int index=0; + char* data_attr1; + char* data_attr2; + // get attributes from graph + data_attr1=agget(view.g[view.activeGraph],"DataAttribute1"); + data_attr2=agget(view.g[view.activeGraph],"DataAttribute2"); + + for (i;i < TV_Nodes.recordperpage ; i++) + { + index=TV_Nodes.TV_Node[i].index; + if (index < Topview.Nodecount) + { + // apply if selected + if(gtk_toggle_button_get_active(TV_Nodes.TV_Node[i].chkSelected)) + { + if (!((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Selected) + select_node(view.g[view.activeGraph],Topview.Nodes[index].Node); + } + else + { + if (((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Selected) + deselect_node(view.g[view.activeGraph],Topview.Nodes[index].Node); + } + // apply if Visible + if(gtk_toggle_button_get_active(TV_Nodes.TV_Node[i].chkVisible)) + { + if (!((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Visible) + ((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Visible=1; + } + else + { + if (((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Visible) + ((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Visible=0; + } + // apply if Highlighted + if(gtk_toggle_button_get_active(TV_Nodes.TV_Node[i].chkHighlighted)) + { + if (!((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Highlighted) + ((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Highlighted=1; + } + else + { + if (((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Highlighted) + ((custom_object_data*)AGDATA(Topview.Nodes[index].Node))->Highlighted=0; + } + //Data1 + agset(Topview.Nodes[index].Node,data_attr1,gtk_entry_get_text (TV_Nodes.TV_Node[i].Data1)); + //Data2 + agset(Topview.Nodes[index].Node,data_attr2,gtk_entry_get_text (TV_Nodes.TV_Node[i].Data2)); + + } + } + +} + +extern int apply_filter_from_gui() +{ + int selected; + int visible; + int highlighted; + + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterSel1"))) + selected=-1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterSel2"))) + selected=1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterSel3"))) + selected=0; + + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterVisible1"))) + visible=-1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterVisible2"))) + visible=1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterVisible3"))) + visible=0; + + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterHigh1"))) + highlighted=-1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterHigh2"))) + highlighted=1; + if(gtk_toggle_button_get_active(glade_xml_get_widget(xml,"rbTVFilterHigh3"))) + highlighted=0; + set_filter(&TV_Nodes.filter, + gtk_entry_get_text ( glade_xml_get_widget(xml,"edtTVFilterMinData1") ), + gtk_entry_get_text ( glade_xml_get_widget(xml,"edtTVFilterMaxData1") ), + gtk_entry_get_text ( glade_xml_get_widget(xml,"edtTVFilterMinData2") ), + gtk_entry_get_text ( glade_xml_get_widget(xml,"edtTVFilterMaxData2") ), + gtk_entry_get_text ( glade_xml_get_widget(xml,"edtTVFilterString") ), + selected,visible,highlighted); + MP_Flag=1; + prepare_page_history(); + tv_nodes_next_page(); + return 1; +} + + +extern int tv_select_all() +{ + + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + select_node(view.g[view.activeGraph],Topview.Nodes[i].Node); + } + } + apply_filter_from_gui(); +} +extern int tv_unselect_all() +{ + + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + deselect_node(view.g[view.activeGraph],Topview.Nodes[i].Node); + } + } + apply_filter_from_gui(); +} +extern int tv_highligh_all() +{ + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + ((custom_object_data*)AGDATA(Topview.Nodes[i].Node))->Highlighted=1; + } + } + apply_filter_from_gui(); + return 1; + + +} +extern int tv_unhighligh_all() +{ + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + ((custom_object_data*)AGDATA(Topview.Nodes[i].Node))->Highlighted=0; + } + } + apply_filter_from_gui(); + return 1; + +} +extern int tv_show_all() +{ + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + ((custom_object_data*)AGDATA(Topview.Nodes[i].Node))->Visible=1; + } + } + apply_filter_from_gui(); + return 1; + + + +} +extern int tv_hide_all() +{ + tv_node tvn; + int i=0; + for (i;i < Topview.Nodecount ; i++) + { + tvn.index=i; + if(validate_node(&tvn)) + { + ((custom_object_data*)AGDATA(Topview.Nodes[i].Node))->Visible=0; + } + } + apply_filter_from_gui(); + return 1; + + +} + + + + + + diff --git a/cmd/smyrna/tvnodes.h b/cmd/smyrna/tvnodes.h new file mode 100755 index 000000000..7120594fd --- /dev/null +++ b/cmd/smyrna/tvnodes.h @@ -0,0 +1,142 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifndef TVNODES_H +#define TVNODES_H + +#include "gui.h" + +#define MAX_NODE_PER_PAGE 100 +#define LOCATION_X_CHKSELECTED 16 +#define LOCATION_X_IDLABEL 45 +#define LOCATION_X_CHKVISIBLE 139 +#define LOCATION_X_CHKHIGHLIGHTED 202 +#define LOCATION_X_DATA1 276 +#define LOCATION_X_DATA2 600 + +typedef struct token_info +{ + int op_index; // has to + int op1_length; + int op2_length; + +}token_info; + +typedef struct btree_node +{ + int child_count; + struct btree_node** childs; + struct btree_node* parent; + int rank; //0 root + char op;// & | + - whatever + int node_type; //0 and 1 or 2 atom + char* attr_name; + char* regex; + float min; + float max; + int value; //filter result true false, 0 , 1 + int active; +}btree_node; + +typedef struct _tv_filter +{ + btree_node* root; + char * min_data1; + char * min_data2; + char * max_data1; + char * max_data2; + char* filter_string; + int active; + int visible; //-1 all 0 not not visible 1 only visibles + int highlighted; //same above + int selected; //same above +}tv_filter; + +typedef struct _tv_node +{ + int index; + GtkCheckButton* chkSelected; + GtkCheckButton* chkVisible; + GtkCheckButton* chkHighlighted; + GtkLabel* IDLabel; + GtkEntry* Data1; + GtkEntry* Data2; + int valid; +}tv_node; + + +typedef struct _tv_nodes +{ + int pagecount; + int activepage; + int firstnodeid; + int* page_history; + int page_history_count; + int recordperpage; //dynamic so that can be changed by plugins etc + int filtered ; + int page_data_index; + int page_data_node_index; + tv_node TV_Node[MAX_NODE_PER_PAGE]; + tv_filter filter; + int Y; + int Y_Gap; + int initial_Y; + int chkSelected_X; + int IDLabel_X; + int chkVisible_X; + int chkHighlighted_X; + int Data1_X; + int Data2_X; + int initialized; + int general_purpose_flag; //dont forget to to set it back +}tv_nodes; +extern tv_nodes TV_Nodes; + + + +extern void execute_tv_nodes(); +static void init_tv_nodes(tv_nodes* TV_Nodes); +static tv_filter* create_tv_filter(); +static void clear_tv_filter(tv_filter* TV_Filter); +extern int set_filter(tv_filter* TV_Filter,char* MinData1,char* MaxData1,char* MinData2,char* MaxData2,char* Filter_String,int selected,int visible,int highlighted); +static int reverse_selection(); +static int validate_node(tv_node* TV_Node); +static int update_node_gui_objects(tv_node* TV_Node); +extern int tv_nodes_goto_page(int page); +extern int tv_nodes_next_page(); +extern int tv_nodes_prior_page(); +extern int tv_nodes_last_page(); +extern int tv_nodes_first_page(); + +static int hide_data_widgets(); +extern int reset_page_History(); +static int push_to_page_history(int index); +static int pop_from_page_history(); +extern int prepare_page_history(); +extern int update_TV_data_from_gui(); +static int set_data_attributes(); +extern int apply_filter_from_gui(); +extern int tv_select_all(); +extern int tv_unselect_all(); +extern int tv_highligh_all(); +extern int tv_unhighligh_all(); +extern int tv_show_all(); +extern int tv_hide_all(); + + +#endif + + diff --git a/cmd/smyrna/viewport.c b/cmd/smyrna/viewport.c new file mode 100755 index 000000000..9dac28b03 --- /dev/null +++ b/cmd/smyrna/viewport.c @@ -0,0 +1,867 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifdef _WIN32 +#include +#endif +#include "compat.h" +#include "viewport.h" +#include "color.h" +#include +#include "gui.h" +#include "string.h" + +#define countof( array ) ( sizeof( array )/sizeof( array[0] ) ) + +char* globalString; +ViewInfo view; +Agraph_t* tempG; //helper graph for default attr values, +int SignalBlock; + +float TopViewPointsX [50000]; +float TopViewPointsY [50000]; + +float TopViewEdgesHeadX[50000]; +float TopViewEdgesHeadY[50000]; +float TopViewEdgesTailX[50000]; +float TopViewEdgesTailY[50000]; + +int TopViewNodeCount; +int TopViewEdgeCount; +GtkMessageDialog* Dlg; +int respond; + +void init_viewport(ViewInfo* view) +{ + + //init graphs + view->g=NULL; //no graph, gl screen should check it + view->graphCount=0; //and disable interactivity if count is zero + + + view->bdxLeft=0; + view->bdxRight=500; + view->bdyBottom=0; + view->bdyTop=500; + view->bdzBottom=0; + view->bdzTop=0; + + view->bdA=1; + view->bdR=1; + view->bdG=0; + view->bdB=0; + view->bdVisible=0; //show borders red + + view->gridSize=10; + view->grR=0.5; + view->grG=0.5; + view->grB=0.5; + view->grA=1; + view->gridVisible=0; //show grids in light gray + + //mouse mode=pan + view->mouse.mouse_mode=0; + //pen color + view->penColor.R=0; + view->penColor.G=0; + view->penColor.B=0; + view->penColor.A=1; + + view->fillColor.R=1; + view->fillColor.G=0; + view->fillColor.B=0; + view->fillColor.A=1; + //background color , default white + view->bgColor.R=1; + view->bgColor.G=1; + view->bgColor.B=1; + view->bgColor.A=1; + + //selected objets are drawn with this color + view->selectColor.R=1; + view->selectColor.G=0; + view->selectColor.B=0; + view->selectColor.A=1; + + //default line width; + view->LineWidth=1; + + //default view settings , camera is not active + view->GLDepth=1; //should be set before GetFixedOGLPos(int x, int y,float kts) funtion is used!!!! + view->panx=0; + view->pany=0; + view->panz=0; + + view->prevpanx=0; + view->prevpany=0; + + + view->zoom=-20; + view->texture=1; + view->font_textures=NULL; + view->font_texture_count=0; //number of openGL textures, used internally + view->FontSize=52; + + view->mg.active=0; + view->mg.x=0; + view->mg.y=0; + view->mg.width=DEFAULT_MAGNIFIER_WIDTH; + view->mg.height=DEFAULT_MAGNIFIER_HEIGHT; + view->mg.kts=DEFAULT_MAGNIFIER_KTS; + view->fmg.R=DEFAULT_FISHEYE_MAGNIFIER_RADIUS; + view->fmg.active=0; + view->mouse.mouse_down=0; + view->activeGraph=-1; + SignalBlock=0; + view->Selection.Active=0; + view->Selection.SelectionColor.R=0.5; + view->Selection.SelectionColor.G=0.2; + view->Selection.SelectionColor.B=1; + view->Selection.SelectionColor.A=1; + view->Selection.Anti=0; +} + +int add_graph_to_viewport_from_file (char* fileName) +{ + //returns 1 if successfull else 0 + Agraph_t* graph; + graph=loadGraph(fileName); + if(graph) + { + view.graphCount = view.graphCount + 1; + view.g= (Agraph_t**)realloc(view.g,sizeof(Agraph_t*)*view.graphCount); + view.g[view.graphCount-1]=graph; + view.activeGraph=view.graphCount-1; + //GUI update , graph combo box on top-right should be updated + refreshControls(&view); + return 1; + } + else + return 0; + +} + +int add_new_graph_to_viewport() +{ + //returns graph index , otherwise -1 + Agraph_t* graph; + graph=(Agraph_t*) malloc(sizeof(Agraph_t)); + if(graph) + { + view.graphCount = view.graphCount + 1; + view.g[view.graphCount-1]=graph; + return (view.graphCount-1); + } + else + return -1; +} + + +void refreshControls(ViewInfo* v) +{ + + int i=0; + GtkComboBox* widget; + widget=get_SelectGraph(); + //load graph names to combobox + for (i=0; i < v->graphCount; i ++) + { + gtk_combo_box_append_text(widget,((custom_graph_data*)(AGDATA(v->g[i])))->GraphFileName); + } + SignalBlock=1; //HACK + gtk_combo_box_set_active (widget,view.activeGraph); + SignalBlock=0; + + + //change button colors + Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnDot")); + Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnNeato")); + Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnTwopi")); + Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnCirco")); + Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnFdp")); + + + switch( ((custom_graph_data*)(AGDATA(view.g[view.activeGraph])))->Engine ) + { + case 0: + Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnDot")); + break; + + case 1: + Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnNeato")); + break; + + case 2: + Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnTwopi")); + break; + + case 3: + Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnCirco")); + break; + + case 4: + Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnFdp")); + break; + + + } + expose_event (drawing_area,NULL,NULL); + + + + + +} + + +void update_graph_params(Agraph_t* graph) //adds gledit params +{ + + + char tempString[100]; + agattr(graph,AGRAPH,"GraphFileName",((custom_graph_data*)(AGDATA(graph)))->GraphFileName); + agattr(graph,AGRAPH,"GraphName",((custom_graph_data*)(AGDATA(graph)))->GraphName); + sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->AlwaysShow ); + agattr(graph,AGRAPH,"AlwaysShow",tempString); + sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->TopView); + agattr(graph,AGRAPH,"TopView",tempString); + sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->Locked); + agattr(graph,AGRAPH,"Locked",tempString); + sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->Engine); + agattr(graph,AGRAPH,"Engine",tempString); + +} + +void load_graph_params(Agraph_t* graph) //run once right after loading graph +{ + //file may or may have not gl edit attributes + //first defaults are set in loading function + //here file is checked for previously saved gledit attributes + if(agget(graph, "GraphName")) //Graph Name + { + ((custom_graph_data*)AGDATA(graph))->GraphName=(char*)malloc((strlen(agget(graph, "GraphName"))+1)*sizeof(char)); + strcpy(((custom_graph_data*)AGDATA(graph))->GraphName,agget(graph, "GraphName")); + } + if(agget(graph, "AlwaysShow")) //Graph Name + ((custom_graph_data*)AGDATA(graph))->AlwaysShow=atoi(agget(graph, "AlwaysShow")); + else + ((custom_graph_data*)AGDATA(graph))->AlwaysShow=0; + + if(agget(graph, "TopView")) //Graph Name + ((custom_graph_data*)AGDATA(graph))->TopView=atoi(agget(graph, "TopView")); + else + ((custom_graph_data*)AGDATA(graph))->TopView=0; + if(agget(graph, "Locked")) //Graph Name + ((custom_graph_data*)AGDATA(graph))->Locked=atoi(agget(graph, "Locked")); + else + ((custom_graph_data*)AGDATA(graph))->Locked=0; + if(agget(graph, "Engine")) //Graph Name + ((custom_graph_data*)AGDATA(graph))->Engine=atoi(agget(graph, "Engine")); + else + ((custom_graph_data*)AGDATA(graph))->Engine=0; //DOT + + ((custom_graph_data*)AGDATA(graph))->Modified=0; //not modified yet + ((custom_graph_data*)AGDATA(graph))->selectedEdges='\0'; + ((custom_graph_data*)AGDATA(graph))->selectedNodes='\0'; + ((custom_graph_data*)AGDATA(graph))->selectedGraphs='\0'; + + ((custom_graph_data*)AGDATA(graph))->selectedNodesCount=0; + ((custom_graph_data*)AGDATA(graph))->selectedEdgesCount=0; + ((custom_graph_data*)AGDATA(graph))->selectedGraphsCount=0; + + + +/* if(agget((void*)g, "xdotversion")) //xdot exists + ((custom_graph_data*)AGDATA(g))->TopView=0; //need to check xdot version attribute + else //we dont know if it is topview or simply a graph with no xdot, for testing i ll use topview + ((custom_graph_data*)AGDATA(g))->TopView=1; */ + + + + + +} + +int save_graph() //save without prompt +{ + //check if there is an active graph + if(view.activeGraph > -1) + { + //check if active graph has a file name + if (((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->GraphFileName) + { + return save_graph_with_file_name(view.g[view.activeGraph],((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->GraphFileName); + } + else + return save_as_graph(); + } + +} +int save_as_graph() //save with prompt +{ + //check if there is an active graph + if(view.activeGraph > -1) + { + GtkWidget *dialog; + dialog = gtk_file_chooser_dialog_new ("Save File", + NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) + { + char *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + save_graph_with_file_name(view.g[view.activeGraph],filename); + g_free (filename); + gtk_widget_destroy (dialog); + + return 1; + } + else + { + gtk_widget_destroy (dialog); + return 0; + } + } +} +int save_graph_with_file_name(Agraph_t* graph,char* fileName) //saves graph with file name,if file name is NULL save as is ++ +{ + //if file name is NULL save to graph's filename + //else use file name, this implements save as.. + FILE* output_file; + update_graph_params(graph); + if(fileName) + output_file = fopen(fileName, "w"); + else + { + if ( ((custom_graph_data*)(AGDATA(graph)))->GraphFileName ) + output_file = fopen(((custom_graph_data*)(AGDATA(graph)))->GraphFileName, "w"); + else + { + g_print("there is no file name to save! Programmer error\n"); + return 0; + } + } + if (output_file == NULL) + { + g_print("Cannot create file \n"); + return 0; + } + else if (agwrite(graph,(void*) output_file)) + { + g_print("%s sucessfully saved \n", fileName); + return 1; + } +} + +int create_xdot_for_graph(Agraph_t* graph,int keeppos) +{ + //0 failed , 1 successfull + //save graph to __temp.dot + //run dot/neato whatever to create the xdot version __temp.xdot + //delete temp files + //use this function to do layouts too + int r=0; + FILE* output_file; + update_graph_params(graph); +#ifdef _WIN3 + if(output_file = fopen("c:/__tempfile.dot", "w")) +#else + if(output_file = fopen("/tmp/__tempfile.dot", "w")) +#endif + { + clear_graph_xdot(graph); + agwrite(graph,(void*) output_file); //save graph + fclose(output_file);//close file desc + + if(keeppos==0) + { +#ifdef _WIN32 + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 0) + system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kdot c:/__tempfile.dot -oc:/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 1) + system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kneato c:/__tempfile.dot -oc:/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 2) + system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Ktwopi c:/__tempfile.dot -oc:/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 3) + system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kcirco c:/__tempfile.dot -oc:/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 4) + system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kfdp c:/__tempfile.dot -oc:/__tempfile.xdot"); +#else + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 0) + system("\"dot\" -Txdot -Kdot /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 1) + system("\"dot\" -Txdot -Kneato /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 2) + system("\"dot\" -Txdot -Ktwopi /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 3) + system("\"dot\" -Txdot -Kcirco /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); + if ( ((custom_graph_data*)AGDATA(graph))->Engine == 4) + system("\"dot\" -Txdot -Kfdp /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); +#endif + } + + //no position change + else +#ifdef _WIN32 + system("\"C:/Program Files/Graphviz2.15/bin/neato.exe\" -n2 -Txdot c:/__tempfile.dot -oc:/__tempfile.xdot"); +#else + system("\"neato\" -n2 -Txdot /tmp/__tempfile.dot -o/tmp/__tempfile.xdot"); +#endif + + if(r) //load the new graph and change file name + { + clear_graph(graph); //i am not sure about this, need to talk to North + return TRUE; + + } + } + else + return FALSE; + +} +int do_graph_layout(Agraph_t* graph,int Engine,int keeppos) //changes the layout, all user relocations are reset unless keeppos is set to 1 +{ +/* Agnode_t *v; + Agedge_t *e; + Agsym_t *attr; + Dict_t *d; + int cnt;*/ +// mydata *p; + FILE* input_file; + char* _filename=(char*)malloc((strlen(((custom_graph_data*)(AGDATA(view.g[view.activeGraph])))->GraphFileName)+1)*sizeof(char)); + strcpy(_filename,((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->GraphFileName); + + + ((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->Engine=Engine; + create_xdot_for_graph(view.g[view.activeGraph],keeppos); + +#ifdef _WIN32 + input_file = fopen("c:/__tempfile.xdot", "r"); +#else + input_file = fopen("/tmp/__tempfile.xdot", "r"); +#endif + clear_graph(view.g[view.activeGraph]); + agclose(view.g[view.activeGraph]); + if (input_file == NULL) + g_print("temp file Cannot open n"); + else if (view.g[view.activeGraph]= agread(input_file,NIL(Agdisc_t*))) + { + fclose(input_file); + //attaching rec for graph fields + attach_object_custom_data_to_graph(view.g[view.activeGraph]); + //set real file name + ((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->GraphFileName=(char*)malloc((strlen(_filename)+1)*sizeof(char)); + load_graph_params(view.g[view.activeGraph]); //init glparams + strcpy(((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->GraphFileName,_filename); + free(_filename); + //set engine + ((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->Engine=Engine; + ((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->Modified=1; + refreshControls(&view); + return 1; + } + else + { + printf("failed to read temp filen"); + return 0; + } + + + + +} + +void clear_graph(Agraph_t* graph) +//clears custom data binded +{ + + +} + +Agraph_t* loadGraph(char* filename) +{ + Agraph_t *g; + Agnode_t *v; + Agedge_t *e; + Agsym_t *attr; + Dict_t *d; + int cnt; +// mydata *p; + FILE* input_file; + input_file = fopen(filename, "r"); + if (input_file == NULL) + g_print("Cannot open %s\n", filename); + else if (g = agread(input_file,NIL(Agdisc_t*))) + { + printf("%s has been loaded sucessfully\n",filename); + printf("Graph statistics\n"); + printf("----------------\n"); + printf("# of edges %i\n",agnnodes(g)); + printf("# of nodes %i\n",agnedges(g)); + printf("checking xdot data\n"); + printf("binding graph record\n"); + attach_object_custom_data_to_graph(g); + load_graph_params(g); + + if ( + ( !agget(g, "xdotversion")) + && + ( + ( agget(g, "TopView")=="0") + || + !agget(g, "TopView") + ) + + ) + + { + create_xdot_for_graph(g,0); + fclose(input_file); +#ifdef _WIN32 + input_file = fopen("c:/__tempfile.xdot", "r"); +#else + input_file = fopen("/tmp/__tempfile.xdot", "r"); +#endif + while(input_file== NULL) //HACK!!!! + { + input_file = fopen("c:/__tempfile.xdot", "r"); +// g_print("Cannot open xdot error %si\n",strerror(errno)); + + } + g = agread(input_file,NIL(Agdisc_t*)); + g_print("xdot is being loaded\n"); + //attaching rec for graph fields + attach_object_custom_data_to_graph(g); + load_graph_params(g); + // fclose(input_file); + } + ((custom_graph_data*)AGDATA(g))->GraphFileName=(char*)malloc((strlen(filename)+1)*sizeof(char)); + //attaching rec for graph objects + strcpy(((custom_graph_data*)AGDATA(g))->GraphFileName,filename); + printf("topview:%s------",agget(g, "TopView")); + if(strcasecmp(agget(g, "TopView"),"1")==0) + { + if(TopViewNodeCount > 0) + { + Dlg=gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "For Performance issues , this program does not support multiple topview graphs!"); + respond=gtk_dialog_run (Dlg); + gtk_object_destroy (Dlg); + agclose(g); + return 0; + } + else + { + PrepareTopview(g); + } + } + return g; + } + else + { + printf("failed to load %s\n",filename); + return 0; + } + +} +int clear_object_xdot(void* obj) +{ + if (obj) + { + if(agattrsym(obj,"_draw_")) + agset(obj,"_draw_",""); + if(agattrsym(obj,"_ldraw_")) + agset(obj,"_ldraw_",""); + if(agattrsym(obj,"_hdraw_")) + agset(obj,"_hdraw_",""); + if(agattrsym(obj,"_tdraw_")) + agset(obj,"_tdraw_",""); + if(agattrsym(obj,"_hldraw_")) + agset(obj,"_hldraw_",""); + if(agattrsym(obj,"_tldraw_")) + agset(obj,"_tldraw_",""); + return 1; + } + return 0; +} + + +int clear_graph_xdot(Agraph_t* graph) //clears all xdot attributes, used especially before layout change +{ + Agnode_t *n; + Agedge_t *e; + Agraph_t *s; + + + clear_object_xdot(graph); + n = agfstnode(graph); + + for (s = agfstsubg(graph); s; s = agnxtsubg(s)) + clear_object_xdot(s); + + for (n = agfstnode(graph); n; n = agnxtnode(graph, n)) + { + clear_object_xdot(n); + for (e = agfstout(graph,n) ; e ; e = agnxtout (graph,e)) + { + clear_object_xdot(e); + } + } + return 1; + + +} + +/* + +Object Custom Data Functions + +*/ + + +int attach_object_custom_data_to_graph(Agraph_t* graph) +{ + Agnode_t *n; + Agedge_t *e; + Agraph_t *s; + + agbindrec(graph,"custom_graph_data",sizeof(custom_graph_data),TRUE);//graph custom data + init_object_custom_data(graph,graph); //attach to graph itself + + n = agfstnode(graph); + + for (s = agfstsubg(graph); s; s = agnxtsubg(s)) + init_object_custom_data(graph,s); //attach to subgraph + + for (n = agfstnode(graph); n; n = agnxtnode(graph, n)) + { + init_object_custom_data(graph,n); //attach to node + for (e = agfstout(graph,n) ; e ; e = agnxtout (graph,e)) + { + init_object_custom_data(graph,e); //attach to edge + } + } + + +} + + +int init_object_custom_data(Agraph_t* graph,void* obj)//creates a custom_object_data +{ + agdelrec(graph, "custom_object_data"); + agbindrec(obj,"custom_object_data",sizeof(custom_object_data),TRUE); + ((custom_object_data*)AGDATA(obj))->ID=0; + ((custom_object_data*)AGDATA(obj))->ObjName=NULL; + ((custom_object_data*)AGDATA(obj))->ObjType=AGTYPE(obj); + ((custom_object_data*)AGDATA(obj))->Layer=-1; + ((custom_object_data*)AGDATA(obj))->Visible=1; + ((custom_object_data*)AGDATA(obj))->Locked=0; + ((custom_object_data*)AGDATA(obj))->Highlighted=0; + ((custom_object_data*)AGDATA(obj))->NumDataCount=0; + ((custom_object_data*)AGDATA(obj))->NumData=NULL; + ((custom_object_data*)AGDATA(obj))->StrDataCount=0; + ((custom_object_data*)AGDATA(obj))->StrData=NULL; + return 1; +} + + +int clear_object_custom_data(void* obj) //frees memory allocated for cutom object data +{ + return ( (clear_string_data_from_object_custom_data(obj)) || (clear_numeric_data_from_object_custom_data(obj))); +} + +int add_string_data_to_object_custom_data(void* obj,char* data) +{ + if ((obj != NULL) && (data !=NULL)) + { + ((custom_object_data*)AGDATA(obj))->StrData=realloc( ((custom_object_data*)AGDATA(obj))->StrData , sizeof(char*)*(((custom_object_data*)AGDATA(obj))->StrDataCount +1)); + ((custom_object_data*)AGDATA(obj))->StrData[((custom_object_data*)AGDATA(obj))->StrDataCount]=malloc((strlen(data)+1) * sizeof(char)); + strcpy(((custom_object_data*)AGDATA(obj))->StrData[((custom_object_data*)AGDATA(obj))->StrDataCount],data); + ((custom_object_data*)AGDATA(obj))->StrDataCount++; + return 1; + } + return 0; +} + +int add_numeric_data_to_object_custom_data(void* obj,float data) +{ + if (obj != NULL) + { + ((custom_object_data*)AGDATA(obj))->NumData=realloc( ((custom_object_data*)AGDATA(obj))->StrData , sizeof(char*)*(((custom_object_data*)AGDATA(obj))->NumDataCount+1)); + ((custom_object_data*)AGDATA(obj))->NumData[((custom_object_data*)AGDATA(obj))->NumDataCount]=data; + ((custom_object_data*)AGDATA(obj))->NumDataCount++; + return 1; + } + return 0; +} + +int clear_string_data_from_object_custom_data(void* obj) +{ + if(obj != NULL) + { + int ind=0; + for (ind=0; ind < ((custom_object_data*)AGDATA(obj))->StrDataCount;ind ++) + { + free ( ((custom_object_data*)AGDATA(obj))->StrData[ind]); + } + free(((custom_object_data*)AGDATA(obj))->StrData); + return 1; + } + return 0; +} + +int clear_numeric_data_from_object_custom_data(void* obj) +{ + if(obj != NULL) + { + free(((custom_object_data*)AGDATA(obj))->NumData); + return 1; + } + return 0; +} +void move_node(void* obj,float dx,float dy) +{ + char buf[512]; + char buf2[512]; + char* pch; + int a=0; + int i=0; + if( (agget(obj,"pos")) && ( AGTYPE(obj)==AGNODE )) + { + //tokenize + strcpy(buf,agget(obj, "pos")); + printf ("org pos: %s\n",buf); + + pch=strtok (buf,"," ); + while (pch != NULL) + { + if(i==0) + a=sprintf(buf2+a,"%i,",atoi(pch)-(int)dx); + else + a=sprintf(buf2+a,"%i,",atoi(pch)-(int)dy); + pch=strtok (NULL,"," ); + i++; + } + buf2[strlen(buf2)-1]='\0'; + printf ("new pos: %s\n",buf2); + agset(obj,"pos",buf2); + } +} + +void move_nodes(Agraph_t* g) //move selected nodes +{ + Agnode_t* obj; + Agedge_t* e; + + float dx,dy; + xdot* bf; + int i=0; + dx=view.GLx-view.GLx2; + dy=view.GLy-view.GLy2; + + if(((custom_graph_data*)AGDATA(view.g[view.activeGraph]))->TopView == 0) + { + for (i=0;i < ((custom_graph_data*)AGDATA(g))->selectedNodesCount;i++) + { + obj=((custom_graph_data*)AGDATA(g))->selectedNodes[i]; + bf=parseXDot (agget(obj,"_draw_")); + agset(obj,"_draw_",move_xdot(obj,bf,(int)dx,(int)dy,0.00)); + free(bf); + bf=parseXDot (agget(obj,"_ldraw_")); + agset(obj,"_ldraw_",move_xdot(obj,bf,(int)dx,(int)dy,0.00)); + free(bf); + move_node(obj,dx,dy); + //iterate edges + /*for (e = agfstout(g,obj) ; e ; e = agnxtout (g,e)) + { + bf=parseXDot (agget(e,"_tdraw_")); + agset(e,"_tdraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00)); + free(bf); + bf=parseXDot (agget(e,"_tldraw_")); + agset(e,"_tldraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00)); + free(bf); + bf=parseXDot (agget(e,"_draw_")); + agset(e,"_draw_",offset_spline(bf,(int)dx,(int)dy,0.00,0.00,0.00)); + free(bf); + bf=parseXDot (agget(e,"_ldraw_")); + agset(e,"_ldraw_",offset_spline(bf,(int)dx,(int)dy,0.00,0.00,0.00)); + free (bf); + }*/ + /* for (e = agfstin(g,obj) ; e ; e = agnxtin (g,e)) + { + free(bf); + bf=parseXDot (agget(e,"_hdraw_")); + agset(e,"_hdraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00)); + free(bf); + bf=parseXDot (agget(e,"_hldraw_")); + agset(e,"_hldraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00)); + free(bf); + bf=parseXDot (agget(e,"_draw_")); + agset(e,"_draw_",offset_spline(e,bf,(int)dx,(int)dy,0.00,0.00,0.00)); + free(bf); + bf=parseXDot (agget(e,"_ldraw_")); + agset(e,"_ldraw_",offset_spline(e,bf,(int)dx,(int)dy,0.00,0.00,0.00)); + }*/ + } + } +} + + + + +RGBColor GetRGBColor(char* color) +{ + gvcolor_t cl; + RGBColor c; + if(color != '\0') + { + colorxlate(color, &cl, RGBA_DOUBLE); + c.R=cl.u.RGBA[0]; + c.G=cl.u.RGBA[1]; + c.B=cl.u.RGBA[2]; + c.A=cl.u.RGBA[3]; + } + else + { + c.R=view.penColor.R; + c.G=view.penColor.G; + c.B=view.penColor.B; + c.A=view.penColor.A; + } + return c; +} +int SetGdkColor(GdkColor* c,char* color) +{ + gvcolor_t cl; + if (color != '\0') + { + colorxlate(color, &cl, RGBA_DOUBLE); + c->red=cl.u.RGBA[0]*65535; + c->green=cl.u.RGBA[1]*65535; + c->blue=cl.u.RGBA[2]*65535; + return 1; + } + else + return 0; + +} diff --git a/cmd/smyrna/viewport.h b/cmd/smyrna/viewport.h new file mode 100755 index 000000000..eebff1b88 --- /dev/null +++ b/cmd/smyrna/viewport.h @@ -0,0 +1,273 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +//view data structure +#ifndef VIEWPORT_H +#define VIEWPORT_H +#define bool int +#include +#include +#include +#include +#include "xdot.h" +#include +#include +#include +#include +#include "cgraph.h" +#include "selection.h" +#include "draw.h" +#define IS_TEST_MODE_ON 0 +#define DEFAULT_MAGNIFIER_WIDTH 300 +#define DEFAULT_MAGNIFIER_HEIGHT 225 +#define DEFAULT_MAGNIFIER_KTS 10 //x10 +#define DEFAULT_FISHEYE_MAGNIFIER_RADIUS 250; +//======= +#define MAX_ZOOM -1.000033 +#define MIN_ZOOM -89.00000 +#define ZOOM_STEP 1; +//>>>>>>> 1.8 +enum +{ + COL_NAME = 0, + COL_FILENAME, + NUM_COLS +} ; +//atributes +typedef struct _mouse_attr +{ + int mouse_down; + int mouse_mode; + int mouse_X; + int mouse_Y; +}mouse_attr; + + +typedef struct _attribute +{ + char Type; + char* Name; + char* Default; + char ApplyTo[4]; + char Engine[5]; + char** ComboValues; + int ComboValuesCount; + GtkWidget* attrWidget; + +}attribute; + +//bind this to cgraph g +typedef struct _custom_graph_data +{ + Agrec_t h; + char* GraphName; + char* GraphFileName; + int AlwaysShow; //active or not draw it + int TopView; //default 0, 1 for topview data, dots and lines + int Locked; + int Engine; //enum GVEngine{DOT,NEATO,TWOPI,CIRCO,FDP}; + //graph's location, change these to move the whole graph + int Modified; //if graph has been modified after loading + GLfloat offsetx; + GLfloat offsety; + GLfloat offsetz; + + Agraph_t** selectedGraphs; //clusters , subgraphs indeed + Agnode_t** selectedNodes; + Agedge_t** selectedEdges; + + int selectedGraphsCount; + int selectedNodesCount; + int selectedEdgesCount; +} custom_graph_data; + + + +enum GEunit{GEpixels,GEinches,GEmm}; + +typedef struct{ + float R; + float G; + float B; + float A; //Alpha +} RGBColor; + +typedef struct _custom_object_data //has to be attached to every Node, Edge, Graph and cluster +{ + Agrec_t h; + int ID; + char* ObjName; + int ObjType; + int Layer; + int Visible; + int Locked; + int Highlighted; + int Selected; + int Preselected; + int NumDataCount; + float* NumData; + int StrDataCount; + char** StrData; + int selectionflag; + int param; //generic purpose param + int TVRef; //Topview reference + +}custom_object_data; + +typedef struct _selection +{ + int Active; //0 there is no selection need to be applied + char Type; //0 single selection , 1 rectangle , 2 rectangleX + float X,Y,W,H; //selection boundries + int Anti; //subtract selections if 1 + int AlreadySelected; //for single selections to avoid selecting more than one object + RGBColor SelectionColor; + +}selection; +typedef struct _magnifier +{ + GLfloat x,y; + GLfloat kts; //zoom X + GLfloat GLwidth,GLheight; + int width,height; //how big is the magnifier referenced from windows + int active; +} magnifier; + +typedef struct _fisheye_magnifier +{ + GLfloat x,y;//center coords of active circle + GLfloat distortion_factor; //distortion factor ,default 1 + int R; //radius of the magnifier referenced from windows + int active; +} fisheye_magnifier; + +typedef struct _ViewInfo +{ + GLfloat panx; + GLfloat pany; + GLfloat panz; + GLfloat prevpanx; + GLfloat prevpany; + GLfloat prevpanz; + + GLfloat zoom; + + RGBColor bgColor; + RGBColor penColor; + RGBColor fillColor; + RGBColor selectColor; + + + GLfloat LineWidth; + GLfloat grR,grG,grB,grA; //grid color + bool gridVisible; //if the grid sis visible + GLfloat gridSize; //grid cell size + + bool bdVisible; //if borders are visible (boundries of the drawing, + GLuint bdR,bdG,bdB,bdA; //border colors + GLfloat bdxLeft,bdyTop,bdzTop; //border top coordinates + GLfloat bdxRight,bdyBottom,bdzBottom; //border bottom coordinates + + //defaults + enum GEunit unit; //default pixels :0 + //***mouse variables + GLfloat GLx,GLy,GLz; //real GL coordinates of xwin mouse coords + GLfloat GLx2,GLy2,GLz2; //real GL coordinates(second) of win mouse coords + float clipX1,clipX2,clipY1,clipY2,clipZ1,clipZ2; + Agraph_t** g; + int graphCount; //number of graphs loaded + int activeGraph; // + + + + int texture; //boolean , to disable and enable texturing, if graph does not have an embedded image + TextTexture* font_textures; //text textures + int font_texture_count; //count of text textures uploaded to gl engine + float GLDepth; //opengl depth value to convert mouse to GL coords + + GtkWidget* pango_widget; + char* FontName; + float FontSize; + //selection +// int mousedown; //0 down , 1 up , used for selection boxes + mouse_attr mouse; + selection Selection; + magnifier mg; + fisheye_magnifier fmg; + //data attributes are read from graph's attributes DataAttribute1 and DataAttribute2 + char* node_data_attribute1; //for topview graphs this is the node data attribute to put as label + char* node_data_attribute2; //for topview graphs this is the node data attribute to be stored and used for something else + +}ViewInfo; + +extern char* globalString; +extern ViewInfo view; +extern Agraph_t* tempG; //helper graph for default attr values, +extern int SignalBlock; + +extern float TopViewPointsX [50000]; +extern float TopViewPointsY [50000]; + +extern float TopViewEdgesHeadX[50000]; +extern float TopViewEdgesHeadY[50000]; +extern float TopViewEdgesTailX[50000]; +extern float TopViewEdgesTailY[50000]; + +extern int TopViewNodeCount; +extern int TopViewEdgeCount; +extern GtkMessageDialog* Dlg; +extern int respond; + +//ss +void init_viewport(ViewInfo* view); +int add_graph_to_viewport_from_file (char* fileName); //returns 1 if successfull else 0 ++ +int add_new_graph_to_viewport(); //returns graph index , otherwise -1 +int create_xdot_for_graph(Agraph_t* graph,int keeppos); //0 failed , 1 successfull ++ +void update_graph_params(Agraph_t* graph); //adds gledit params ++ +extern Agraph_t* loadGraph(char* filename); //dont use directly, use add_graph_to_viewport_from_file instead +void load_graph_params(Agraph_t* graph); //run once right after loading graph++ +void clear_graph(Agraph_t* graph); //clears custom data binded, +int save_graph(); //save without prompt +int save_as_graph(); //save with prompt +int save_graph_with_file_name(Agraph_t* graph,char* fileName); //saves graph with file name,if file name is NULL save as is ++ + +int do_graph_layout(Agraph_t* graph,int Engine,int keeppos); //changes the layout, all user relocations are reset +void refreshControls(ViewInfo* v); + + +int attach_object_custom_data_to_graph(Agraph_t* graph);//run once or to reset all data !! prev data is removed +// int init_object_custom_data(void* obj);//creates a custom_object_data and return its pointer.obj is used to clear prev data +int clear_object_custom_data(void* obj); //frees memory allocated for cutom object data +int add_string_data_to_object_custom_data(void* obj,char* data); +int add_numeric_data_to_object_custom_data(void* obj,float data); +int clear_string_data_from_object_custom_data(void* obj); +int clear_numeric_data_from_object_custom_data(void* obj); + +int clear_object_xdot(void* obj); //clear single object's xdot info +int clear_graph_xdot(Agraph_t* graph); //clears all xdot attributes, used especially before layout change + +char* get_object_attribute(void* obj,char* attr); //returns an attribute value no matter what, + +void move_node(void* n,float dx,float dy); + + + + +void move_nodes(Agraph_t* g); //move selected nodes +//helper functions +RGBColor GetRGBColor(char* color); +int SetGdkColor(GdkColor* c,char* color); +#endif