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.
1.1 --- a/gui/graph_displayer_canvas.h Thu Nov 17 10:46:38 2005 +0000
1.2 +++ b/gui/graph_displayer_canvas.h Thu Nov 17 15:34:18 2005 +0000
1.3 @@ -143,9 +143,11 @@
1.4 ///Group of graphical elements of displayed_graph
1.5 Gnome::Canvas::Group displayed_graph;
1.6
1.7 +public:
1.8 ///Here we store the maps that can be displayed through properties.
1.9 MapStorage & mapstorage;
1.10
1.11 +private:
1.12 ///Indicates whether the button of mouse is pressed or not
1.13 int isbutton;
1.14
1.15 @@ -169,9 +171,12 @@
1.16
1.17 static const int zoom_step = 5;
1.18
1.19 +public:
1.20 ///We need to store mapwin, to be able to ask the appropriate values for properties of new items.
1.21 MapWin & mapwin;
1.22
1.23 +private:
1.24 +
1.25 ///pointer to the parent window
1.26 Gtk::Window * parentwin;
1.27
2.1 --- a/gui/new_map_win.cc Thu Nov 17 10:46:38 2005 +0000
2.2 +++ b/gui/new_map_win.cc Thu Nov 17 15:34:18 2005 +0000
2.3 @@ -77,41 +77,184 @@
2.4
2.5 void NewMapWin::buttonPressed()
2.6 {
2.7 - bool valid_double=true;
2.8 - int point_num=0;
2.9 + double def_val=0;
2.10
2.11 + //get and formulate text
2.12 std::string def_val_str=default_value.get_text();
2.13 - char * def_val_ch=new char [def_val_str.length()];
2.14 - for(int i=0;i<(int)(def_val_str.length());i++)
2.15 - {
2.16 - if(((def_val_str[i]<'0')||(def_val_str[i]>'9'))&&(def_val_str[i]!='.'))
2.17 - {
2.18 - valid_double=false;
2.19 - }
2.20 - else
2.21 - {
2.22 - if(def_val_str[i]=='.')
2.23 - {
2.24 - point_num++;
2.25 - }
2.26 - }
2.27 - def_val_ch[i]=def_val_str[i];
2.28 - }
2.29 -
2.30 - double def_val=atof(def_val_ch);
2.31 + std::string polishform=string2Polishform(def_val_str,edge.get_active());
2.32
2.33 + //get name of text
2.34 std::string mapname=name.get_text();
2.35
2.36 - if((point_num<=1)&&(valid_double)&&(!mapname.empty()))
2.37 + if(!mapname.empty()&&!polishform.empty())
2.38 {
2.39 int abortion=0;
2.40 if(edge.get_active())
2.41 {
2.42 - abortion=gdc.addNewEdgeMap(def_val,mapname);
2.43 + //create the new map
2.44 + Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (gdc.mapstorage.graph);
2.45 +
2.46 + std::stack<double> polishstack;
2.47 +
2.48 + for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
2.49 + {
2.50 + for(int i=0;i<(int)polishform.size();i++)
2.51 + {
2.52 + double op1, op2;
2.53 + bool operation=true;
2.54 + switch(polishform[i])
2.55 + {
2.56 + case '+':
2.57 + case '-':
2.58 + case '/':
2.59 + case '*':
2.60 + op1=polishstack.top();
2.61 + polishstack.pop();
2.62 + op2=polishstack.top();
2.63 + polishstack.pop();
2.64 + break;
2.65 + default:
2.66 + //substitute variable
2.67 + std::map< std::string,Graph::EdgeMap<double> * > ems=gdc.mapstorage.edgemap_storage;
2.68 + bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
2.69 + if(itisvar)
2.70 + {
2.71 + polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
2.72 + }
2.73 + else
2.74 + {
2.75 + char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
2.76 + for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
2.77 + {
2.78 + def_val_ch[j]=ch2var[ polishform[i] ][j];
2.79 + }
2.80 + polishstack.push(atof(def_val_ch));
2.81 + }
2.82 + operation=false;
2.83 + break;
2.84 + }
2.85 + if(operation)
2.86 + {
2.87 + double res;
2.88 + switch(polishform[i])
2.89 + {
2.90 + case '+':
2.91 + res=op1+op2;
2.92 + break;
2.93 + case '-':
2.94 + res=op2-op1;
2.95 + break;
2.96 + case '/':
2.97 + res=op2/op1;
2.98 + break;
2.99 + case '*':
2.100 + res=op1*op2;
2.101 + break;
2.102 + default:
2.103 + std::cout << "How could we get here?" << std::endl;
2.104 + break;
2.105 + }
2.106 + polishstack.push(res);
2.107 + }
2.108 + }
2.109 + (*emptr)[k]=polishstack.top();
2.110 + }
2.111 +
2.112 + //if addition was not successful addEdgeMap returns one.
2.113 + //cause can be that there is already a map named like the new one
2.114 + if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
2.115 + {
2.116 + abortion=1;
2.117 + }
2.118 +
2.119 + //add it to the list of the displayable maps
2.120 + gdc.mapwin.registerNewEdgeMap(mapname);
2.121 +
2.122 + //display it
2.123 + gdc.changeEdgeText(mapname);
2.124 }
2.125 - else
2.126 + else //!edge.get_active()
2.127 {
2.128 - abortion=gdc.addNewNodeMap(def_val,mapname);
2.129 + //create the new map
2.130 + Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (gdc.mapstorage.graph);
2.131 +
2.132 + std::stack<double> polishstack;
2.133 +
2.134 + for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
2.135 + {
2.136 + for(int i=0;i<(int)polishform.size();i++)
2.137 + {
2.138 + double op1, op2;
2.139 + bool operation=true;
2.140 + switch(polishform[i])
2.141 + {
2.142 + case '+':
2.143 + case '-':
2.144 + case '/':
2.145 + case '*':
2.146 + op1=polishstack.top();
2.147 + polishstack.pop();
2.148 + op2=polishstack.top();
2.149 + polishstack.pop();
2.150 + break;
2.151 + default:
2.152 + std::map< std::string,Graph::NodeMap<double> * > nms=gdc.mapstorage.nodemap_storage;
2.153 + bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
2.154 + if(itisvar)
2.155 + {
2.156 + polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
2.157 + }
2.158 + else
2.159 + {
2.160 + char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
2.161 + for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
2.162 + {
2.163 + def_val_ch[j]=ch2var[ polishform[i] ][j];
2.164 + }
2.165 + polishstack.push(atof(def_val_ch));
2.166 + }
2.167 + operation=false;
2.168 + break;
2.169 + }
2.170 + if(operation)
2.171 + {
2.172 + double res;
2.173 + switch(polishform[i])
2.174 + {
2.175 + case '+':
2.176 + res=op1+op2;
2.177 + break;
2.178 + case '-':
2.179 + res=op2-op1;
2.180 + break;
2.181 + case '/':
2.182 + res=op2/op1;
2.183 + break;
2.184 + case '*':
2.185 + res=op1*op2;
2.186 + break;
2.187 + default:
2.188 + std::cout << "How could we get here?" << std::endl;
2.189 + break;
2.190 + }
2.191 + polishstack.push(res);
2.192 + }
2.193 + }
2.194 + (*emptr)[k]=polishstack.top();
2.195 + }
2.196 +
2.197 + //if addition was not successful addNodeMap returns one.
2.198 + //cause can be that there is already a map named like the new one
2.199 + if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
2.200 + {
2.201 + abortion=1;
2.202 + }
2.203 +
2.204 + //add it to the list of the displayable maps
2.205 + gdc.mapwin.registerNewNodeMap(mapname);
2.206 +
2.207 + //display it
2.208 + gdc.changeNodeText(mapname);
2.209 }
2.210 if(!abortion)
2.211 {
2.212 @@ -124,3 +267,210 @@
2.213 }
2.214 }
2.215
2.216 +std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
2.217 +{
2.218 + bool valid_entry=true;
2.219 +
2.220 + std::map<std::string, int> str2i;
2.221 +
2.222 + std::string command;
2.223 +
2.224 + std::string variable;
2.225 +
2.226 + char index='a';
2.227 +
2.228 + for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
2.229 + {
2.230 + switch(rawcommand[i])
2.231 + {
2.232 + case '+':
2.233 + case '-':
2.234 + case '*':
2.235 + case '/':
2.236 + case ')':
2.237 + case '(':
2.238 + if(!variable.empty())
2.239 + {
2.240 + valid_entry=validVariable(variable, itisedge);
2.241 + ch2var[index]=variable;
2.242 + command+=index;
2.243 + index++;
2.244 + variable.erase(0,variable.size());
2.245 + }
2.246 + command+=rawcommand[i];
2.247 + break;
2.248 + default:
2.249 + variable+=rawcommand[i];
2.250 + break;
2.251 + }
2.252 + }
2.253 +
2.254 + if(!variable.empty()&&valid_entry)
2.255 + {
2.256 + valid_entry=validVariable(variable, itisedge);
2.257 + ch2var[index]=variable;
2.258 + command+=index;
2.259 + index++;
2.260 + variable.erase(0,variable.size());
2.261 + }
2.262 +
2.263 + if(valid_entry)
2.264 + {
2.265 + unsigned int pr=10000;
2.266 + bool prevmult=false;
2.267 + unsigned int prev_change;
2.268 + unsigned int prev_br=10000;
2.269 + int counter=0;
2.270 + std::string comm_nobr="";
2.271 + std::vector<unsigned int> p;
2.272 + p.resize(counter+1);
2.273 +
2.274 + //limits
2.275 + //6 brackets embedded
2.276 + //100 operation in a row from the same priority
2.277 +
2.278 + for(int i=0;i<(int)command.size();i++)
2.279 + {
2.280 + bool put_in_string=true;
2.281 + switch(command[i])
2.282 + {
2.283 + case '(':
2.284 + pr=prev_br+10000;
2.285 + prev_br=pr;
2.286 + prevmult=false;
2.287 + put_in_string=false;
2.288 + break;
2.289 + case ')':
2.290 + pr=prev_br-10000;
2.291 + prev_br=pr;
2.292 + prevmult=false;
2.293 + put_in_string=false;
2.294 + break;
2.295 + case '+':
2.296 + case '-':
2.297 + if(prevmult)
2.298 + {
2.299 + pr=prev_change;
2.300 + }
2.301 + p[counter]=pr;
2.302 + pr-=100;
2.303 +
2.304 + prevmult=false;
2.305 + break;
2.306 + case '/':
2.307 + case '*':
2.308 + if(!prevmult)
2.309 + {
2.310 + prev_change=pr;
2.311 + pr+=200;
2.312 + pr-=1;
2.313 + }
2.314 + p[counter]=pr;
2.315 + pr-=1;
2.316 + prevmult=true;
2.317 + break;
2.318 + default:
2.319 + p[counter]=65000;
2.320 + break;
2.321 + }
2.322 + if(put_in_string)
2.323 + {
2.324 + counter++;
2.325 + p.resize(counter+1);
2.326 + comm_nobr=comm_nobr+command[i];
2.327 + }
2.328 + }
2.329 +
2.330 + tree_node * root=weightedString2Tree(comm_nobr, p, 0);
2.331 +
2.332 + std::string polishform=postOrder(root);
2.333 +
2.334 + return polishform;
2.335 + }
2.336 + return "";
2.337 +}
2.338 +
2.339 +NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
2.340 +{
2.341 + int min=p[offset];
2.342 + int minplace=0;
2.343 + for(int i=0;i<(int)to_tree.size();i++)
2.344 + {
2.345 + if(min>p[offset+i])
2.346 + {
2.347 + min=p[offset+i];
2.348 + minplace=i;
2.349 + }
2.350 + }
2.351 + tree_node * act_node=new tree_node;
2.352 + act_node->ch=to_tree[minplace];
2.353 + if(to_tree.size()>=3)
2.354 + {
2.355 + act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
2.356 + act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
2.357 + }
2.358 + else
2.359 + {
2.360 + act_node->left_child=NULL;
2.361 + act_node->right_child=NULL;
2.362 + }
2.363 + return act_node;
2.364 +}
2.365 +
2.366 +std::string NewMapWin::postOrder(tree_node * subtree)
2.367 +{
2.368 + std::string subtree_to_string;
2.369 + if(subtree->left_child)
2.370 + {
2.371 + subtree_to_string=postOrder(subtree->left_child);
2.372 + }
2.373 + if(subtree->right_child)
2.374 + {
2.375 + subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
2.376 + }
2.377 + subtree_to_string=subtree_to_string+subtree->ch;
2.378 + return subtree_to_string;
2.379 +}
2.380 +
2.381 +bool NewMapWin::validVariable(std::string variable, bool itisedge)
2.382 +{
2.383 + bool cancel;
2.384 + //is it mapname?
2.385 + if(itisedge)
2.386 + {
2.387 + cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
2.388 + }
2.389 + else
2.390 + {
2.391 + cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.mapstorage.nodemap_storage.end());
2.392 + }
2.393 + //maybe it is number
2.394 + int point_num=0;
2.395 + if(cancel)
2.396 + {
2.397 + cancel=false;
2.398 + for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
2.399 + {
2.400 + if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
2.401 + {
2.402 + cancel=true;
2.403 + }
2.404 + else
2.405 + {
2.406 + if(variable[j]=='.')
2.407 + {
2.408 + point_num++;
2.409 + if(point_num>1)
2.410 + {
2.411 + cancel=true;
2.412 + }
2.413 + }
2.414 + }
2.415 + }
2.416 + }
2.417 + if(cancel)
2.418 + {
2.419 + return false;
2.420 + }
2.421 + return true;
2.422 +}
3.1 --- a/gui/new_map_win.h Thu Nov 17 10:46:38 2005 +0000
3.2 +++ b/gui/new_map_win.h Thu Nov 17 15:34:18 2005 +0000
3.3 @@ -9,6 +9,7 @@
3.4 #include <graph_displayer_canvas.h>
3.5 #include <libgnomecanvasmm.h>
3.6 #include <libgnomecanvasmm/polygon.h>
3.7 +#include <stack>
3.8
3.9 ///This class is responsible for creating a window,
3.10 ///on which the parameters of a new map can be set.
3.11 @@ -21,21 +22,40 @@
3.12 ///a function of the \ref GraphDisplayerCanvas will be called.
3.13 GraphDisplayerCanvas & gdc;
3.14
3.15 - public:
3.16 +public:
3.17 + struct tree_node
3.18 + {
3.19 + char ch;
3.20 + tree_node * left_child;
3.21 + tree_node * right_child;
3.22 + };
3.23 +
3.24 ///Constructor of NewMapWin creates the widgets shown in NewMapWin.
3.25 NewMapWin(const std::string& title, GraphDisplayerCanvas &);
3.26
3.27 -
3.28 +
3.29 ///Signal on button is connected to this function,
3.30 ///Therefore this function determines whether to
3.31 ///call the map/creatort function, and if yes, it
3.32 //tells it the attributes.(name, default value)
3.33 virtual void buttonPressed();
3.34 -
3.35 +
3.36 virtual void showByPreChoose(bool);
3.37
3.38 virtual bool closeIfEscapeIsPressed(GdkEventKey*);
3.39
3.40 + ///Function that creates a tree from an appropriately manipulated string
3.41 + tree_node * weightedString2Tree(std::string, std::vector<unsigned int> &, int);
3.42 +
3.43 + ///Function that creates a string from a tree by postorder reading.
3.44 + std::string postOrder(tree_node *);
3.45 +
3.46 + std::string string2Polishform(std::string, bool);
3.47 +
3.48 + bool validVariable(std::string, bool);
3.49 +
3.50 + std::map<char, std::string> ch2var;
3.51 +
3.52 Gtk::Entry name, default_value;
3.53
3.54 Gtk::VBox vbox;