COIN-OR::LEMON - Graph Library

source: glemon-0.x/new_map_win.cc @ 139:56dd34430f07

gui
Last change on this file since 139:56dd34430f07 was 118:cfd49e5c8723, checked in by Hegyi Péter, 18 years ago

If default value of a new map is constant, the newly created elements will get that value as well. Documentation is added to BrokenEdge?, MapStorage? and GraphDisplazCanvas? classes.

File size: 10.6 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, NoteBookTab & mw, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),mytab(mw),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
76      bool only_nums=true;
77      for(int i=0;i<(int)def_val_str.size() && only_nums;i++)
78        {
79          if( def_val_str[i]<'0' || def_val_str[i]>'9' )
80            {
81              only_nums=false;
82            }
83        }
84      std::string polishform;
85
86      if(only_nums)
87        {
88          def_val=atof(def_val_str.c_str());
89        }
90      else
91        {
92          polishform=string2Polishform(def_val_str,edge.get_active());
93        }
94
95      //get name of text
96      std::string mapname=name.get_text();
97     
98      if(!mapname.empty()&&(!polishform.empty()||only_nums))
99        {
100          int abortion=0;
101          if(edge.get_active())
102            {
103              //create the new map
104              Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mytab.mapstorage.graph, def_val);
105             
106              if(!only_nums)
107                {
108                  std::stack<double> polishstack;
109                 
110                  for(EdgeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
111                    {
112                      for(int i=0;i<(int)polishform.size();i++)
113                        {
114                          double op1=0, op2=0;
115                          bool operation=true;
116                          switch(polishform[i])
117                            {
118                            case '+':
119                            case '-':
120                            case '/':
121                            case '*':
122                              op1=polishstack.top();
123                              polishstack.pop();
124                              op2=polishstack.top();
125                              polishstack.pop();
126                              break;
127                            default:
128                              //substitute variable
129                              std::map< std::string,Graph::EdgeMap<double> * > ems=mytab.mapstorage.edgemap_storage;
130                              bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
131                              if(itisvar)
132                                {
133                                  polishstack.push( (*(mytab.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
134                                }
135                              else
136                                {
137                                  polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
138                                }
139                              operation=false;
140                              break;
141                            }
142                          if(operation)
143                            {
144                              double res;
145                              switch(polishform[i])
146                                {
147                                case '+':
148                                  res=op1+op2;
149                                  break;
150                                case '-':
151                                  res=op2-op1;
152                                  break;
153                                case '/':
154                                  res=op2/op1;
155                                  break;
156                                case '*':
157                                  res=op1*op2;
158                                  break;
159                                default:
160                                  std::cout << "How could we get here?" << std::endl;
161                                  break;
162                                }
163                              polishstack.push(res);
164                            }
165                        }//foreach letter in polishform
166                      (*emptr)[k]=polishstack.top();
167                    }//foreach edge
168                }//!only_nums
169
170              //if addition was not successful addEdgeMap returns one.
171              //cause can be that there is already a map named like the new one
172              if(mytab.mapstorage.addEdgeMap(mapname, emptr, def_val))
173                {
174                  abortion=1;
175                }
176
177              //add it to the list of the displayable maps
178              //furthermore it is done by signals
179              //mytab.registerNewEdgeMap(mapname);
180
181              //display it
182              //gdc.changeEdgeText(mapname);
183            }
184          else //!edge.get_active()
185            {
186              //create the new map
187              Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mytab.mapstorage.graph, def_val);
188
189              if(!only_nums)
190                {
191                  std::stack<double> polishstack;
192 
193                  for(NodeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
194                    {
195                      for(int i=0;i<(int)polishform.size();i++)
196                        {
197                          double op1=0, op2=0;
198                          bool operation=true;
199                          switch(polishform[i])
200                            {
201                            case '+':
202                            case '-':
203                            case '/':
204                            case '*':
205                              op1=polishstack.top();
206                              polishstack.pop();
207                              op2=polishstack.top();
208                              polishstack.pop();
209                              break;
210                            default:
211                              std::map< std::string,Graph::NodeMap<double> * > nms=mytab.mapstorage.nodemap_storage;
212                              bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
213                              if(itisvar)
214                                {
215                                  polishstack.push( (*(mytab.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
216                                }
217                              else
218                                {
219                                  polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
220                                }
221                              operation=false;
222                              break;
223                            }
224                          if(operation)
225                            {
226                              double res;
227                              switch(polishform[i])
228                                {
229                                case '+':
230                                  res=op1+op2;
231                                  break;
232                                case '-':
233                                  res=op2-op1;
234                                  break;
235                                case '/':
236                                  res=op2/op1;
237                                  break;
238                                case '*':
239                                  res=op1*op2;
240                                  break;
241                                default:
242                                  std::cout << "How could we get here?" << std::endl;
243                                  break;
244                                }
245                              polishstack.push(res);
246                            }
247                        }
248                      (*emptr)[k]=polishstack.top();
249                    }
250                }
251              //if addition was not successful addNodeMap returns one.
252              //cause can be that there is already a map named like the new one
253              if(mytab.mapstorage.addNodeMap(mapname,emptr, def_val))
254                {
255                  abortion=1;
256                }
257
258              //add it to the list of the displayable maps
259              //furthermore it is done by signals
260              //mytab.registerNewNodeMap(mapname);
261
262              //display it
263              //gdc.changeNodeText(mapname);
264            }
265          if(!abortion)
266            {
267              name.set_text("");
268              default_value.set_text("0");
269              edge.show();
270              node.show();
271              hide();
272            }
273        }
274    }
275}
276
277
278std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
279{
280  bool valid_entry=true;
281
282  std::map<std::string, int> str2i;
283
284  std::string command;
285
286  std::string variable;
287
288  char index='a';
289
290  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
291    {
292      switch(rawcommand[i])
293        {
294        case '+':
295        case '-':
296        case '*':
297        case '/':
298        case ')':
299        case '(':
300          if(!variable.empty())
301            {
302              valid_entry=validVariable(variable, itisedge);
303              ch2var[index]=variable;
304              command+=index;
305              index++;
306              variable.erase(0,variable.size());         
307            }
308          command+=rawcommand[i];
309          break;
310        default:
311          variable+=rawcommand[i];
312          break;
313        }
314    }
315
316  if(!variable.empty()&&valid_entry)
317    {
318      valid_entry=validVariable(variable, itisedge);
319      ch2var[index]=variable;
320      command+=index;
321      index++;
322      variable.erase(0,variable.size());         
323    }
324
325  if(valid_entry)
326    {
327      unsigned int pr=10000;
328      bool prevmult=false;
329      unsigned int prev_change=pr;
330      unsigned int prev_br=pr;
331      int counter=0;
332      std::string comm_nobr="";
333      std::vector<unsigned int> p;
334      p.resize(counter+1);
335     
336      //limits
337      //6 brackets embedded
338      //100 operation in a row from the same priority
339     
340      for(int i=0;i<(int)command.size();i++)
341        {
342          bool put_in_string=true;
343          switch(command[i])
344            {
345            case '(':
346              pr=prev_br+10000;
347              prev_br=pr;
348              prevmult=false;
349              put_in_string=false;
350              break;
351            case ')':
352              pr=prev_br-10000;
353              prev_br=pr;
354              prevmult=false;
355              put_in_string=false;
356              break;
357            case '+':
358            case '-':
359              if(prevmult)
360                {
361                  pr=prev_change;
362                }
363              p[counter]=pr;
364              pr-=100;
365
366              prevmult=false;
367              break;
368            case '/':
369            case '*':
370              if(!prevmult)
371                {
372                  prev_change=pr;
373                  pr+=200;
374                  pr-=1;
375                }
376              p[counter]=pr;
377              pr-=1;
378              prevmult=true;
379              break;
380            default:
381              p[counter]=65000;
382              break;
383            }
384          if(put_in_string)
385            {
386              counter++;
387              p.resize(counter+1);
388              comm_nobr=comm_nobr+command[i];
389            }
390        }
391
392      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
393
394      std::string polishform=postOrder(root);
395
396      deleteTree(root);
397
398      return polishform;
399    }
400  return "";
401}
402
403void NewMapWin::deleteTree(NewMapWin::tree_node * node)
404{
405  if(node->left_child!=NULL)
406    {
407      deleteTree(node->left_child);
408    }
409  if(node->right_child!=NULL)
410    {
411      deleteTree(node->right_child);
412    }
413  delete node;
414}
415
416NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
417{
418  unsigned int min=p[offset];
419  int minplace=0;
420  for(int i=0;i<(int)to_tree.size();i++)
421    {
422      if(min>p[offset+i])
423        {
424          min=p[offset+i];
425          minplace=i;
426        }
427    }
428  tree_node * act_node=new tree_node;
429  act_node->ch=to_tree[minplace];
430  if(to_tree.size()>=3)
431    {
432      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
433      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
434    }
435  else
436    {
437      act_node->left_child=NULL;
438      act_node->right_child=NULL;
439    }
440  return act_node;
441}
442
443std::string NewMapWin::postOrder(tree_node * subtree)
444{
445  std::string subtree_to_string;
446  if(subtree->left_child)
447    {
448      subtree_to_string=postOrder(subtree->left_child);
449    }
450  if(subtree->right_child)
451    {
452      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
453    }
454  subtree_to_string=subtree_to_string+subtree->ch;
455  return subtree_to_string;
456}
457
458bool NewMapWin::validVariable(std::string variable, bool itisedge)
459{
460  bool cancel;
461  //is it mapname?
462  if(itisedge)
463    {
464      cancel=(mytab.mapstorage.edgemap_storage.find(variable)==mytab.mapstorage.edgemap_storage.end());
465    }
466  else
467    {
468      cancel=(mytab.mapstorage.nodemap_storage.find(variable)==mytab.mapstorage.nodemap_storage.end());
469    }
470  //maybe it is number
471  int point_num=0;
472  if(cancel)
473    {
474      cancel=false;
475      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
476        {
477          if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
478            {
479              cancel=true;
480            }
481          else
482            {
483              if(variable[j]=='.')
484                {
485                  point_num++;
486                  if(point_num>1)
487                    {
488                      cancel=true;
489                    }
490                }
491            }
492        }
493    }
494  if(cancel)
495    {
496      return false;
497    }
498  return true;
499}
Note: See TracBrowser for help on using the repository browser.