COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/new_map_win.cc @ 1825:535d2eccfc03

Last change on this file since 1825:535d2eccfc03 was 1823:cb082cdf3667, checked in by Hegyi Péter, 18 years ago

NewMapWin? has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.

File size: 10.2 KB
Line 
1#include <new_map_win.h>
2
3bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e)
4{
5  if(e->keyval==GDK_Escape)
6  {
7    hide();
8  }
9  return true;
10}
11
12NewMapWin::NewMapWin(const std::string& title, GraphDisplayerCanvas & grdispc, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),gdc(grdispc),node("Create NodeMap"),edge("Create EdgeMap")
13{
14  set_default_size(200, 50);
15
16  signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed));
17
18  Gtk::VBox * vbox=get_vbox();
19
20  //entries
21  table=new Gtk::Table(3, 2, false);
22
23  label=new Gtk::Label;
24  label->set_text("Name of new map:");
25  name.set_text("");
26
27  (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
28  (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
29
30  label=new Gtk::Label;
31  label->set_text("Default value in the map:");
32  default_value.set_text("0");
33
34  (*table).attach(*label,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
35  (*table).attach(default_value,1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
36
37  //node vs. edge map selector
38  Gtk::RadioButton::Group group = node.get_group();
39  edge.set_group(group);
40 
41  if(edgenode)
42    {
43      (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
44      (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
45    }
46  else
47    {
48      if(itisedge)
49        {
50          edge.set_active();
51        }
52      else
53        {
54          node.set_active();
55        }
56    }
57
58  vbox->pack_start(*table);
59
60  //OK button
61  add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
62
63  show_all_children();
64
65}
66
67void NewMapWin::on_response(int response_id)
68{
69  if(response_id==Gtk::RESPONSE_OK)
70    {
71      double def_val=0;
72
73      //get and formulate text
74      std::string def_val_str=default_value.get_text();
75      std::string polishform=string2Polishform(def_val_str,edge.get_active());
76
77      //get name of text
78      std::string mapname=name.get_text();
79
80      if(!mapname.empty()&&!polishform.empty())
81        {
82          int abortion=0;
83          if(edge.get_active())
84            {
85              //create the new map
86              Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (gdc.mapstorage.graph);
87
88              std::stack<double> polishstack;
89 
90              for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
91                {
92                  for(int i=0;i<(int)polishform.size();i++)
93                    {
94                      double op1, op2;
95                      bool operation=true;
96                      switch(polishform[i])
97                        {
98                        case '+':
99                        case '-':
100                        case '/':
101                        case '*':
102                          op1=polishstack.top();
103                          polishstack.pop();
104                          op2=polishstack.top();
105                          polishstack.pop();
106                          break;
107                        default:
108                          //substitute variable
109                          std::map< std::string,Graph::EdgeMap<double> * > ems=gdc.mapstorage.edgemap_storage;
110                          bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
111                          if(itisvar)
112                            {
113                              polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
114                            }
115                          else
116                            {
117                              char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
118                              for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
119                                {
120                                  def_val_ch[j]=ch2var[ polishform[i] ][j];
121                                }
122                              polishstack.push(atof(def_val_ch));
123                            }
124                          operation=false;
125                          break;
126                        }
127                      if(operation)
128                        {
129                          double res;
130                          switch(polishform[i])
131                            {
132                            case '+':
133                              res=op1+op2;
134                              break;
135                            case '-':
136                              res=op2-op1;
137                              break;
138                            case '/':
139                              res=op2/op1;
140                              break;
141                            case '*':
142                              res=op1*op2;
143                              break;
144                            default:
145                              std::cout << "How could we get here?" << std::endl;
146                              break;
147                            }
148                          polishstack.push(res);
149                        }
150                    }
151                  (*emptr)[k]=polishstack.top();
152                }
153
154              //if addition was not successful addEdgeMap returns one.
155              //cause can be that there is already a map named like the new one
156              if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
157                {
158                  abortion=1;
159                }
160
161              //add it to the list of the displayable maps
162              gdc.mapwin.registerNewEdgeMap(mapname);
163
164              //display it
165              gdc.changeEdgeText(mapname);
166            }
167          else //!edge.get_active()
168            {
169              //create the new map
170              Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (gdc.mapstorage.graph);
171
172              std::stack<double> polishstack;
173 
174              for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
175                {
176                  for(int i=0;i<(int)polishform.size();i++)
177                    {
178                      double op1, op2;
179                      bool operation=true;
180                      switch(polishform[i])
181                        {
182                        case '+':
183                        case '-':
184                        case '/':
185                        case '*':
186                          op1=polishstack.top();
187                          polishstack.pop();
188                          op2=polishstack.top();
189                          polishstack.pop();
190                          break;
191                        default:
192                          std::map< std::string,Graph::NodeMap<double> * > nms=gdc.mapstorage.nodemap_storage;
193                          bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
194                          if(itisvar)
195                            {
196                              polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
197                            }
198                          else
199                            {
200                              char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
201                              for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
202                                {
203                                  def_val_ch[j]=ch2var[ polishform[i] ][j];
204                                }
205                              polishstack.push(atof(def_val_ch));
206                            }
207                          operation=false;
208                          break;
209                        }
210                      if(operation)
211                        {
212                          double res;
213                          switch(polishform[i])
214                            {
215                            case '+':
216                              res=op1+op2;
217                              break;
218                            case '-':
219                              res=op2-op1;
220                              break;
221                            case '/':
222                              res=op2/op1;
223                              break;
224                            case '*':
225                              res=op1*op2;
226                              break;
227                            default:
228                              std::cout << "How could we get here?" << std::endl;
229                              break;
230                            }
231                          polishstack.push(res);
232                        }
233                    }
234                  (*emptr)[k]=polishstack.top();
235                }
236
237              //if addition was not successful addNodeMap returns one.
238              //cause can be that there is already a map named like the new one
239              if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
240                {
241                  abortion=1;
242                }
243
244              //add it to the list of the displayable maps
245              gdc.mapwin.registerNewNodeMap(mapname);
246
247              //display it
248              //gdc.changeNodeText(mapname);
249            }
250          if(!abortion)
251            {
252              name.set_text("");
253              default_value.set_text("0");
254              edge.show();
255              node.show();
256              hide();
257            }
258        }
259    }
260}
261
262
263std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
264{
265  bool valid_entry=true;
266
267  std::map<std::string, int> str2i;
268
269  std::string command;
270
271  std::string variable;
272
273  char index='a';
274
275  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
276    {
277      switch(rawcommand[i])
278        {
279        case '+':
280        case '-':
281        case '*':
282        case '/':
283        case ')':
284        case '(':
285          if(!variable.empty())
286            {
287              valid_entry=validVariable(variable, itisedge);
288              ch2var[index]=variable;
289              command+=index;
290              index++;
291              variable.erase(0,variable.size());         
292            }
293          command+=rawcommand[i];
294          break;
295        default:
296          variable+=rawcommand[i];
297          break;
298        }
299    }
300
301  if(!variable.empty()&&valid_entry)
302    {
303      valid_entry=validVariable(variable, itisedge);
304      ch2var[index]=variable;
305      command+=index;
306      index++;
307      variable.erase(0,variable.size());         
308    }
309
310  if(valid_entry)
311    {
312      unsigned int pr=10000;
313      bool prevmult=false;
314      unsigned int prev_change=pr;
315      unsigned int prev_br=pr;
316      int counter=0;
317      std::string comm_nobr="";
318      std::vector<unsigned int> p;
319      p.resize(counter+1);
320     
321      //limits
322      //6 brackets embedded
323      //100 operation in a row from the same priority
324     
325      for(int i=0;i<(int)command.size();i++)
326        {
327          bool put_in_string=true;
328          switch(command[i])
329            {
330            case '(':
331              pr=prev_br+10000;
332              prev_br=pr;
333              prevmult=false;
334              put_in_string=false;
335              break;
336            case ')':
337              pr=prev_br-10000;
338              prev_br=pr;
339              prevmult=false;
340              put_in_string=false;
341              break;
342            case '+':
343            case '-':
344              if(prevmult)
345                {
346                  pr=prev_change;
347                }
348              p[counter]=pr;
349              pr-=100;
350
351              prevmult=false;
352              break;
353            case '/':
354            case '*':
355              if(!prevmult)
356                {
357                  prev_change=pr;
358                  pr+=200;
359                  pr-=1;
360                }
361              p[counter]=pr;
362              pr-=1;
363              prevmult=true;
364              break;
365            default:
366              p[counter]=65000;
367              break;
368            }
369          if(put_in_string)
370            {
371              counter++;
372              p.resize(counter+1);
373              comm_nobr=comm_nobr+command[i];
374            }
375        }
376
377      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
378
379      std::string polishform=postOrder(root);
380
381      return polishform;
382    }
383  return "";
384}
385
386NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
387{
388  unsigned int min=p[offset];
389  int minplace=0;
390  for(int i=0;i<(int)to_tree.size();i++)
391    {
392      if(min>p[offset+i])
393        {
394          min=p[offset+i];
395          minplace=i;
396        }
397    }
398  tree_node * act_node=new tree_node;
399  act_node->ch=to_tree[minplace];
400  if(to_tree.size()>=3)
401    {
402      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
403      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
404    }
405  else
406    {
407      act_node->left_child=NULL;
408      act_node->right_child=NULL;
409    }
410  return act_node;
411}
412
413std::string NewMapWin::postOrder(tree_node * subtree)
414{
415  std::string subtree_to_string;
416  if(subtree->left_child)
417    {
418      subtree_to_string=postOrder(subtree->left_child);
419    }
420  if(subtree->right_child)
421    {
422      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
423    }
424  subtree_to_string=subtree_to_string+subtree->ch;
425  return subtree_to_string;
426}
427
428bool NewMapWin::validVariable(std::string variable, bool itisedge)
429{
430  bool cancel;
431  //is it mapname?
432  if(itisedge)
433    {
434      cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
435    }
436  else
437    {
438      cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.mapstorage.nodemap_storage.end());
439    }
440  //maybe it is number
441  int point_num=0;
442  if(cancel)
443    {
444      cancel=false;
445      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
446        {
447          if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
448            {
449              cancel=true;
450            }
451          else
452            {
453              if(variable[j]=='.')
454                {
455                  point_num++;
456                  if(point_num>1)
457                    {
458                      cancel=true;
459                    }
460                }
461            }
462        }
463    }
464  if(cancel)
465    {
466      return false;
467    }
468  return true;
469}
Note: See TracBrowser for help on using the repository browser.