COIN-OR::LEMON - Graph Library

source: glemon-0.x/new_map_win.cc @ 94:adfdc2f70548

gui
Last change on this file since 94:adfdc2f70548 was 94:adfdc2f70548, checked in by Hegyi Péter, 15 years ago

Structure of GUI is now more clear-cut 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, MainWin & mw, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),mainwin(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      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> (mainwin.mapstorage.graph);
87
88              std::stack<double> polishstack;
89 
90              for(EdgeIt k(mainwin.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=mainwin.mapstorage.edgemap_storage;
110                          bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
111                          if(itisvar)
112                            {
113                              polishstack.push( (*(mainwin.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(mainwin.mapstorage.addEdgeMap(mapname, emptr, def_val))
157                {
158                  abortion=1;
159                }
160
161              //add it to the list of the displayable maps
162              mainwin.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> (mainwin.mapstorage.graph);
171
172              std::stack<double> polishstack;
173 
174              for(NodeIt k(mainwin.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=mainwin.mapstorage.nodemap_storage;
193                          bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
194                          if(itisvar)
195                            {
196                              polishstack.push( (*(mainwin.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(mainwin.mapstorage.addNodeMap(mapname,emptr, def_val))
240                {
241                  abortion=1;
242                }
243
244              //add it to the list of the displayable maps
245              mainwin.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=(mainwin.mapstorage.edgemap_storage.find(variable)==mainwin.mapstorage.edgemap_storage.end());
435    }
436  else
437    {
438      cancel=(mainwin.mapstorage.nodemap_storage.find(variable)==mainwin.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.