gui/new_map_win.cc
author deba
Wed, 01 Mar 2006 10:17:25 +0000
changeset 1990 15fb7a4ea6be
parent 1887 22fdc00894aa
permissions -rw-r--r--
Some classes assumed that the GraphMaps should be inherited
from an ObserverBase. These classes parents replaced with
DefaultMap which cause that the graph maps should not be
inherited from the ObserverBase.
     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 }