gui/new_map_win.cc
author alpar
Tue, 21 Feb 2006 12:37:00 +0000
changeset 1977 8ef02f0c4245
parent 1887 22fdc00894aa
permissions -rw-r--r--
RefPtr: a reference counted pointer class
     1 #include <new_map_win.h>
     2 
     3 bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e)
     4 {
     5   if(e->keyval==GDK_Escape)
     6   {
     7     hide();
     8   }
     9   return true;
    10 }
    11 
    12 NewMapWin::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 
    67 void 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 
   278 std::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 
   403 void 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 
   416 NewMapWin::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 
   443 std::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 
   458 bool 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 }