# HG changeset patch # User hegyi # Date 1132241658 0 # Node ID 0f02ced2e2bacdc1aba05739b1e1e233db9143b7 # Parent 5c5d1574667d1d366fbab6ac7cfc47fa636e0f26 As initial value of a new map expression with ()+-/* operators can be given. These operators work on numbers, or on maps. If maps are given, then the new value for a given graph element will be calculated using the value from the given maps that belong to that graph element. diff -r 5c5d1574667d -r 0f02ced2e2ba gui/graph_displayer_canvas.h --- a/gui/graph_displayer_canvas.h Thu Nov 17 10:46:38 2005 +0000 +++ b/gui/graph_displayer_canvas.h Thu Nov 17 15:34:18 2005 +0000 @@ -143,9 +143,11 @@ ///Group of graphical elements of displayed_graph Gnome::Canvas::Group displayed_graph; +public: ///Here we store the maps that can be displayed through properties. MapStorage & mapstorage; +private: ///Indicates whether the button of mouse is pressed or not int isbutton; @@ -169,9 +171,12 @@ static const int zoom_step = 5; +public: ///We need to store mapwin, to be able to ask the appropriate values for properties of new items. MapWin & mapwin; +private: + ///pointer to the parent window Gtk::Window * parentwin; diff -r 5c5d1574667d -r 0f02ced2e2ba gui/new_map_win.cc --- a/gui/new_map_win.cc Thu Nov 17 10:46:38 2005 +0000 +++ b/gui/new_map_win.cc Thu Nov 17 15:34:18 2005 +0000 @@ -77,41 +77,184 @@ void NewMapWin::buttonPressed() { - bool valid_double=true; - int point_num=0; + double def_val=0; + //get and formulate text std::string def_val_str=default_value.get_text(); - char * def_val_ch=new char [def_val_str.length()]; - for(int i=0;i<(int)(def_val_str.length());i++) - { - if(((def_val_str[i]<'0')||(def_val_str[i]>'9'))&&(def_val_str[i]!='.')) - { - valid_double=false; - } - else - { - if(def_val_str[i]=='.') - { - point_num++; - } - } - def_val_ch[i]=def_val_str[i]; - } - - double def_val=atof(def_val_ch); + std::string polishform=string2Polishform(def_val_str,edge.get_active()); + //get name of text std::string mapname=name.get_text(); - if((point_num<=1)&&(valid_double)&&(!mapname.empty())) + if(!mapname.empty()&&!polishform.empty()) { int abortion=0; if(edge.get_active()) { - abortion=gdc.addNewEdgeMap(def_val,mapname); + //create the new map + Graph::EdgeMap * emptr=new Graph::EdgeMap (gdc.mapstorage.graph); + + std::stack polishstack; + + for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k) + { + for(int i=0;i<(int)polishform.size();i++) + { + double op1, op2; + bool operation=true; + switch(polishform[i]) + { + case '+': + case '-': + case '/': + case '*': + op1=polishstack.top(); + polishstack.pop(); + op2=polishstack.top(); + polishstack.pop(); + break; + default: + //substitute variable + std::map< std::string,Graph::EdgeMap * > ems=gdc.mapstorage.edgemap_storage; + bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end()); + if(itisvar) + { + polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]); + } + else + { + char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())]; + for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++) + { + def_val_ch[j]=ch2var[ polishform[i] ][j]; + } + polishstack.push(atof(def_val_ch)); + } + operation=false; + break; + } + if(operation) + { + double res; + switch(polishform[i]) + { + case '+': + res=op1+op2; + break; + case '-': + res=op2-op1; + break; + case '/': + res=op2/op1; + break; + case '*': + res=op1*op2; + break; + default: + std::cout << "How could we get here?" << std::endl; + break; + } + polishstack.push(res); + } + } + (*emptr)[k]=polishstack.top(); + } + + //if addition was not successful addEdgeMap returns one. + //cause can be that there is already a map named like the new one + if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val)) + { + abortion=1; + } + + //add it to the list of the displayable maps + gdc.mapwin.registerNewEdgeMap(mapname); + + //display it + gdc.changeEdgeText(mapname); } - else + else //!edge.get_active() { - abortion=gdc.addNewNodeMap(def_val,mapname); + //create the new map + Graph::NodeMap * emptr=new Graph::NodeMap (gdc.mapstorage.graph); + + std::stack polishstack; + + for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k) + { + for(int i=0;i<(int)polishform.size();i++) + { + double op1, op2; + bool operation=true; + switch(polishform[i]) + { + case '+': + case '-': + case '/': + case '*': + op1=polishstack.top(); + polishstack.pop(); + op2=polishstack.top(); + polishstack.pop(); + break; + default: + std::map< std::string,Graph::NodeMap * > nms=gdc.mapstorage.nodemap_storage; + bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end()); + if(itisvar) + { + polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]); + } + else + { + char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())]; + for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++) + { + def_val_ch[j]=ch2var[ polishform[i] ][j]; + } + polishstack.push(atof(def_val_ch)); + } + operation=false; + break; + } + if(operation) + { + double res; + switch(polishform[i]) + { + case '+': + res=op1+op2; + break; + case '-': + res=op2-op1; + break; + case '/': + res=op2/op1; + break; + case '*': + res=op1*op2; + break; + default: + std::cout << "How could we get here?" << std::endl; + break; + } + polishstack.push(res); + } + } + (*emptr)[k]=polishstack.top(); + } + + //if addition was not successful addNodeMap returns one. + //cause can be that there is already a map named like the new one + if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val)) + { + abortion=1; + } + + //add it to the list of the displayable maps + gdc.mapwin.registerNewNodeMap(mapname); + + //display it + gdc.changeNodeText(mapname); } if(!abortion) { @@ -124,3 +267,210 @@ } } +std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge) +{ + bool valid_entry=true; + + std::map str2i; + + std::string command; + + std::string variable; + + char index='a'; + + for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++) + { + switch(rawcommand[i]) + { + case '+': + case '-': + case '*': + case '/': + case ')': + case '(': + if(!variable.empty()) + { + valid_entry=validVariable(variable, itisedge); + ch2var[index]=variable; + command+=index; + index++; + variable.erase(0,variable.size()); + } + command+=rawcommand[i]; + break; + default: + variable+=rawcommand[i]; + break; + } + } + + if(!variable.empty()&&valid_entry) + { + valid_entry=validVariable(variable, itisedge); + ch2var[index]=variable; + command+=index; + index++; + variable.erase(0,variable.size()); + } + + if(valid_entry) + { + unsigned int pr=10000; + bool prevmult=false; + unsigned int prev_change; + unsigned int prev_br=10000; + int counter=0; + std::string comm_nobr=""; + std::vector p; + p.resize(counter+1); + + //limits + //6 brackets embedded + //100 operation in a row from the same priority + + for(int i=0;i<(int)command.size();i++) + { + bool put_in_string=true; + switch(command[i]) + { + case '(': + pr=prev_br+10000; + prev_br=pr; + prevmult=false; + put_in_string=false; + break; + case ')': + pr=prev_br-10000; + prev_br=pr; + prevmult=false; + put_in_string=false; + break; + case '+': + case '-': + if(prevmult) + { + pr=prev_change; + } + p[counter]=pr; + pr-=100; + + prevmult=false; + break; + case '/': + case '*': + if(!prevmult) + { + prev_change=pr; + pr+=200; + pr-=1; + } + p[counter]=pr; + pr-=1; + prevmult=true; + break; + default: + p[counter]=65000; + break; + } + if(put_in_string) + { + counter++; + p.resize(counter+1); + comm_nobr=comm_nobr+command[i]; + } + } + + tree_node * root=weightedString2Tree(comm_nobr, p, 0); + + std::string polishform=postOrder(root); + + return polishform; + } + return ""; +} + +NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector & p, int offset) +{ + int min=p[offset]; + int minplace=0; + for(int i=0;i<(int)to_tree.size();i++) + { + if(min>p[offset+i]) + { + min=p[offset+i]; + minplace=i; + } + } + tree_node * act_node=new tree_node; + act_node->ch=to_tree[minplace]; + if(to_tree.size()>=3) + { + act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset); + act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1); + } + else + { + act_node->left_child=NULL; + act_node->right_child=NULL; + } + return act_node; +} + +std::string NewMapWin::postOrder(tree_node * subtree) +{ + std::string subtree_to_string; + if(subtree->left_child) + { + subtree_to_string=postOrder(subtree->left_child); + } + if(subtree->right_child) + { + subtree_to_string=subtree_to_string+postOrder(subtree->right_child); + } + subtree_to_string=subtree_to_string+subtree->ch; + return subtree_to_string; +} + +bool NewMapWin::validVariable(std::string variable, bool itisedge) +{ + bool cancel; + //is it mapname? + if(itisedge) + { + cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end()); + } + else + { + cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.mapstorage.nodemap_storage.end()); + } + //maybe it is number + int point_num=0; + if(cancel) + { + cancel=false; + for(int j=0;(!cancel)&&(j<(int)variable.size());j++) + { + if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.')) + { + cancel=true; + } + else + { + if(variable[j]=='.') + { + point_num++; + if(point_num>1) + { + cancel=true; + } + } + } + } + } + if(cancel) + { + return false; + } + return true; +} diff -r 5c5d1574667d -r 0f02ced2e2ba gui/new_map_win.h --- a/gui/new_map_win.h Thu Nov 17 10:46:38 2005 +0000 +++ b/gui/new_map_win.h Thu Nov 17 15:34:18 2005 +0000 @@ -9,6 +9,7 @@ #include #include #include +#include ///This class is responsible for creating a window, ///on which the parameters of a new map can be set. @@ -21,21 +22,40 @@ ///a function of the \ref GraphDisplayerCanvas will be called. GraphDisplayerCanvas & gdc; - public: +public: + struct tree_node + { + char ch; + tree_node * left_child; + tree_node * right_child; + }; + ///Constructor of NewMapWin creates the widgets shown in NewMapWin. NewMapWin(const std::string& title, GraphDisplayerCanvas &); - + ///Signal on button is connected to this function, ///Therefore this function determines whether to ///call the map/creatort function, and if yes, it //tells it the attributes.(name, default value) virtual void buttonPressed(); - + virtual void showByPreChoose(bool); virtual bool closeIfEscapeIsPressed(GdkEventKey*); + ///Function that creates a tree from an appropriately manipulated string + tree_node * weightedString2Tree(std::string, std::vector &, int); + + ///Function that creates a string from a tree by postorder reading. + std::string postOrder(tree_node *); + + std::string string2Polishform(std::string, bool); + + bool validVariable(std::string, bool); + + std::map ch2var; + Gtk::Entry name, default_value; Gtk::VBox vbox;