gui/new_map_win.cc
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1819 fd82adfbe905
child 1837 8dd6160ff699
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     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, GraphDisplayerCanvas & grdispc, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),gdc(grdispc),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> (gdc.mapstorage.graph);
    87 
    88 	      std::stack<double> polishstack;
    89   
    90 	      for(EdgeIt k(gdc.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=gdc.mapstorage.edgemap_storage;
   110 			  bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
   111 			  if(itisvar)
   112 			    {
   113 			      polishstack.push( (*(gdc.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(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
   157 		{
   158 		  abortion=1;
   159 		}
   160 
   161 	      //add it to the list of the displayable maps
   162 	      gdc.mapwin.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> (gdc.mapstorage.graph);
   171 
   172 	      std::stack<double> polishstack;
   173   
   174 	      for(NodeIt k(gdc.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=gdc.mapstorage.nodemap_storage;
   193 			  bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
   194 			  if(itisvar)
   195 			    {
   196 			      polishstack.push( (*(gdc.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(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
   240 		{
   241 		  abortion=1;
   242 		}
   243 
   244 	      //add it to the list of the displayable maps
   245 	      gdc.mapwin.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 
   263 std::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 
   386 NewMapWin::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 
   413 std::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 
   428 bool NewMapWin::validVariable(std::string variable, bool itisedge)
   429 {
   430   bool cancel;
   431   //is it mapname?
   432   if(itisedge)
   433     {
   434       cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
   435     }
   436   else
   437     {
   438       cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.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 }