new_map_win.cc
author hegyi
Thu, 05 Jan 2006 12:30:09 +0000
branchgui
changeset 108 bf355fd6563e
parent 96 e664d8aa3f72
child 109 9f8dc346ac6e
permissions -rw-r--r--
Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
     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       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> (mytab.mapstorage.graph);
    87 
    88 	      std::stack<double> polishstack;
    89   
    90 	      for(EdgeIt k(mytab.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=mytab.mapstorage.edgemap_storage;
   110 			  bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
   111 			  if(itisvar)
   112 			    {
   113 			      polishstack.push( (*(mytab.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(mytab.mapstorage.addEdgeMap(mapname, emptr, def_val))
   157 		{
   158 		  abortion=1;
   159 		}
   160 
   161 	      //add it to the list of the displayable maps
   162 	      //furthermore it is done by signals
   163 	      //mytab.registerNewEdgeMap(mapname);
   164 
   165 	      //display it
   166 	      //gdc.changeEdgeText(mapname);
   167 	    }
   168 	  else //!edge.get_active()
   169 	    {
   170 	      //create the new map
   171 	      Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mytab.mapstorage.graph);
   172 
   173 	      std::stack<double> polishstack;
   174   
   175 	      for(NodeIt k(mytab.mapstorage.graph); k!=INVALID; ++k)
   176 		{
   177 		  for(int i=0;i<(int)polishform.size();i++)
   178 		    {
   179 		      double op1, op2;
   180 		      bool operation=true;
   181 		      switch(polishform[i])
   182 			{
   183 			case '+':
   184 			case '-':
   185 			case '/':
   186 			case '*':
   187 			  op1=polishstack.top();
   188 			  polishstack.pop();
   189 			  op2=polishstack.top();
   190 			  polishstack.pop();
   191 			  break;
   192 			default:
   193 			  std::map< std::string,Graph::NodeMap<double> * > nms=mytab.mapstorage.nodemap_storage;
   194 			  bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
   195 			  if(itisvar)
   196 			    {
   197 			      polishstack.push( (*(mytab.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
   198 			    }
   199 			  else
   200 			    {
   201 			      char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
   202 			      for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
   203 				{
   204 				  def_val_ch[j]=ch2var[ polishform[i] ][j];
   205 				}
   206 			      polishstack.push(atof(def_val_ch));
   207 			    }
   208 			  operation=false;
   209 			  break;
   210 			}
   211 		      if(operation)
   212 			{
   213 			  double res;
   214 			  switch(polishform[i])
   215 			    {
   216 			    case '+':
   217 			      res=op1+op2;
   218 			      break;
   219 			    case '-':
   220 			      res=op2-op1;
   221 			      break;
   222 			    case '/':
   223 			      res=op2/op1;
   224 			      break;
   225 			    case '*':
   226 			      res=op1*op2;
   227 			      break;
   228 			    default:
   229 			      std::cout << "How could we get here?" << std::endl;
   230 			      break;
   231 			    }
   232 			  polishstack.push(res);
   233 			}
   234 		    }
   235 		  (*emptr)[k]=polishstack.top(); 
   236 		}
   237 
   238 	      //if addition was not successful addNodeMap returns one.
   239 	      //cause can be that there is already a map named like the new one
   240 	      if(mytab.mapstorage.addNodeMap(mapname,emptr, def_val))
   241 		{
   242 		  abortion=1;
   243 		}
   244 
   245 	      //add it to the list of the displayable maps
   246 	      //furthermore it is done by signals
   247 	      //mytab.registerNewNodeMap(mapname);
   248 
   249 	      //display it
   250 	      //gdc.changeNodeText(mapname);
   251 	    }
   252 	  if(!abortion)
   253 	    {
   254 	      name.set_text("");
   255 	      default_value.set_text("0");
   256 	      edge.show();
   257 	      node.show();
   258 	      hide();
   259 	    }
   260 	}
   261     }
   262 }
   263 
   264 
   265 std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
   266 {
   267   bool valid_entry=true;
   268 
   269   std::map<std::string, int> str2i;
   270 
   271   std::string command;
   272 
   273   std::string variable;
   274 
   275   char index='a';
   276 
   277   for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
   278     {
   279       switch(rawcommand[i])
   280 	{
   281 	case '+':
   282 	case '-':
   283 	case '*':
   284 	case '/':
   285 	case ')':
   286 	case '(':
   287  	  if(!variable.empty())
   288 	    {
   289 	      valid_entry=validVariable(variable, itisedge);
   290 	      ch2var[index]=variable;
   291 	      command+=index;
   292 	      index++;
   293 	      variable.erase(0,variable.size());	  
   294 	    }
   295 	  command+=rawcommand[i];
   296 	  break;
   297 	default:
   298 	  variable+=rawcommand[i];
   299 	  break;
   300 	}
   301     }
   302 
   303   if(!variable.empty()&&valid_entry)
   304     {
   305       valid_entry=validVariable(variable, itisedge);
   306       ch2var[index]=variable;
   307       command+=index;
   308       index++;
   309       variable.erase(0,variable.size());	  
   310     }
   311 
   312   if(valid_entry)
   313     {
   314       unsigned int pr=10000;
   315       bool prevmult=false;
   316       unsigned int prev_change=pr;
   317       unsigned int prev_br=pr;
   318       int counter=0;
   319       std::string comm_nobr="";
   320       std::vector<unsigned int> p;
   321       p.resize(counter+1);
   322       
   323       //limits
   324       //6 brackets embedded
   325       //100 operation in a row from the same priority
   326       
   327       for(int i=0;i<(int)command.size();i++)
   328 	{
   329 	  bool put_in_string=true;
   330 	  switch(command[i])
   331 	    {
   332 	    case '(':
   333 	      pr=prev_br+10000;
   334 	      prev_br=pr;
   335 	      prevmult=false;
   336 	      put_in_string=false;
   337 	      break;
   338 	    case ')':
   339 	      pr=prev_br-10000;
   340 	      prev_br=pr;
   341 	      prevmult=false;
   342 	      put_in_string=false;
   343 	      break;
   344 	    case '+':
   345 	    case '-':
   346 	      if(prevmult)
   347 		{
   348 		  pr=prev_change;
   349 		}
   350 	      p[counter]=pr;
   351 	      pr-=100;
   352 
   353 	      prevmult=false;
   354 	      break;
   355 	    case '/':
   356 	    case '*':
   357 	      if(!prevmult)
   358 		{
   359 		  prev_change=pr;
   360 		  pr+=200;
   361 		  pr-=1;
   362 		}
   363 	      p[counter]=pr;
   364 	      pr-=1;
   365 	      prevmult=true;
   366 	      break;
   367 	    default:
   368 	      p[counter]=65000;
   369 	      break;
   370 	    }
   371 	  if(put_in_string)
   372 	    {
   373 	      counter++;
   374 	      p.resize(counter+1);
   375 	      comm_nobr=comm_nobr+command[i];
   376 	    }
   377 	}
   378 
   379       tree_node * root=weightedString2Tree(comm_nobr, p, 0);
   380 
   381       std::string polishform=postOrder(root);
   382 
   383       return polishform;
   384     }
   385   return "";
   386 }
   387 
   388 NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
   389 {
   390   unsigned int min=p[offset];
   391   int minplace=0;
   392   for(int i=0;i<(int)to_tree.size();i++)
   393     {
   394       if(min>p[offset+i])
   395 	{
   396 	  min=p[offset+i];
   397 	  minplace=i;
   398 	}
   399     }
   400   tree_node * act_node=new tree_node;
   401   act_node->ch=to_tree[minplace];
   402   if(to_tree.size()>=3)
   403     {
   404       act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
   405       act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
   406     }
   407   else
   408     {
   409       act_node->left_child=NULL;
   410       act_node->right_child=NULL;
   411     }
   412   return act_node;
   413 }
   414 
   415 std::string NewMapWin::postOrder(tree_node * subtree)
   416 {
   417   std::string subtree_to_string;
   418   if(subtree->left_child)
   419     {
   420       subtree_to_string=postOrder(subtree->left_child);
   421     }
   422   if(subtree->right_child)
   423     {
   424       subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
   425     }
   426   subtree_to_string=subtree_to_string+subtree->ch;
   427   return subtree_to_string;
   428 }
   429 
   430 bool NewMapWin::validVariable(std::string variable, bool itisedge)
   431 {
   432   bool cancel;
   433   //is it mapname?
   434   if(itisedge)
   435     {
   436       cancel=(mytab.mapstorage.edgemap_storage.find(variable)==mytab.mapstorage.edgemap_storage.end());
   437     }
   438   else
   439     {
   440       cancel=(mytab.mapstorage.nodemap_storage.find(variable)==mytab.mapstorage.nodemap_storage.end());
   441     }
   442   //maybe it is number
   443   int point_num=0;
   444   if(cancel)
   445     {
   446       cancel=false;
   447       for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
   448 	{
   449 	  if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
   450 	    {
   451 	      cancel=true;
   452 	    }
   453 	  else
   454 	    {
   455 	      if(variable[j]=='.')
   456 		{
   457 		  point_num++;
   458 		  if(point_num>1)
   459 		    {
   460 		      cancel=true;
   461 		    }
   462 		}
   463 	    }
   464 	}
   465     }
   466   if(cancel)
   467     {
   468       return false;
   469     }
   470   return true;
   471 }