new_map_win.cc
author ladanyi
Tue, 22 Nov 2005 14:35:33 +0000
branchgui
changeset 92 ee2bd58fdc30
parent 89 4042761b21e3
child 94 adfdc2f70548
permissions -rw-r--r--
clean-up
hegyi@42
     1
#include <new_map_win.h>
hegyi@42
     2
hegyi@42
     3
bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e)
hegyi@42
     4
{
hegyi@42
     5
  if(e->keyval==GDK_Escape)
hegyi@42
     6
  {
hegyi@42
     7
    hide();
hegyi@42
     8
  }
hegyi@42
     9
  return true;
hegyi@42
    10
}
hegyi@42
    11
hegyi@90
    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")
hegyi@42
    13
{
hegyi@42
    14
  set_default_size(200, 50);
hegyi@42
    15
hegyi@42
    16
  signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed));
hegyi@42
    17
hegyi@90
    18
  Gtk::VBox * vbox=get_vbox();
hegyi@42
    19
hegyi@42
    20
  //entries
hegyi@42
    21
  table=new Gtk::Table(3, 2, false);
hegyi@42
    22
hegyi@42
    23
  label=new Gtk::Label;
hegyi@42
    24
  label->set_text("Name of new map:");
hegyi@42
    25
  name.set_text("");
hegyi@42
    26
hegyi@42
    27
  (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@42
    28
  (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@42
    29
hegyi@42
    30
  label=new Gtk::Label;
hegyi@42
    31
  label->set_text("Default value in the map:");
hegyi@42
    32
  default_value.set_text("0");
hegyi@42
    33
hegyi@42
    34
  (*table).attach(*label,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@42
    35
  (*table).attach(default_value,1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@42
    36
hegyi@42
    37
  //node vs. edge map selector
hegyi@42
    38
  Gtk::RadioButton::Group group = node.get_group();
hegyi@42
    39
  edge.set_group(group);
hegyi@90
    40
  
hegyi@90
    41
  if(edgenode)
hegyi@90
    42
    {
hegyi@90
    43
      (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@90
    44
      (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
hegyi@90
    45
    }
hegyi@90
    46
  else
hegyi@90
    47
    {
hegyi@90
    48
      if(itisedge)
hegyi@90
    49
	{
hegyi@90
    50
	  edge.set_active();
hegyi@90
    51
	}
hegyi@90
    52
      else
hegyi@90
    53
	{
hegyi@90
    54
	  node.set_active();
hegyi@90
    55
	}
hegyi@90
    56
    }
hegyi@42
    57
hegyi@90
    58
  vbox->pack_start(*table);
hegyi@42
    59
hegyi@42
    60
  //OK button
hegyi@90
    61
  add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
hegyi@42
    62
hegyi@42
    63
  show_all_children();
hegyi@42
    64
hegyi@42
    65
}
hegyi@42
    66
hegyi@90
    67
void NewMapWin::on_response(int response_id)
hegyi@85
    68
{
hegyi@90
    69
  if(response_id==Gtk::RESPONSE_OK)
hegyi@85
    70
    {
hegyi@90
    71
      double def_val=0;
hegyi@85
    72
hegyi@90
    73
      //get and formulate text
hegyi@90
    74
      std::string def_val_str=default_value.get_text();
hegyi@90
    75
      std::string polishform=string2Polishform(def_val_str,edge.get_active());
hegyi@42
    76
hegyi@90
    77
      //get name of text
hegyi@90
    78
      std::string mapname=name.get_text();
hegyi@42
    79
hegyi@90
    80
      if(!mapname.empty()&&!polishform.empty())
hegyi@90
    81
	{
hegyi@90
    82
	  int abortion=0;
hegyi@90
    83
	  if(edge.get_active())
hegyi@90
    84
	    {
hegyi@90
    85
	      //create the new map
hegyi@90
    86
	      Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (gdc.mapstorage.graph);
hegyi@42
    87
hegyi@90
    88
	      std::stack<double> polishstack;
hegyi@88
    89
  
hegyi@90
    90
	      for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
hegyi@88
    91
		{
hegyi@90
    92
		  for(int i=0;i<(int)polishform.size();i++)
hegyi@88
    93
		    {
hegyi@90
    94
		      double op1, op2;
hegyi@90
    95
		      bool operation=true;
hegyi@88
    96
		      switch(polishform[i])
hegyi@88
    97
			{
hegyi@88
    98
			case '+':
hegyi@88
    99
			case '-':
hegyi@88
   100
			case '/':
hegyi@88
   101
			case '*':
hegyi@90
   102
			  op1=polishstack.top();
hegyi@90
   103
			  polishstack.pop();
hegyi@90
   104
			  op2=polishstack.top();
hegyi@90
   105
			  polishstack.pop();
hegyi@88
   106
			  break;
hegyi@88
   107
			default:
hegyi@90
   108
			  //substitute variable
hegyi@90
   109
			  std::map< std::string,Graph::EdgeMap<double> * > ems=gdc.mapstorage.edgemap_storage;
hegyi@90
   110
			  bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
hegyi@90
   111
			  if(itisvar)
hegyi@90
   112
			    {
hegyi@90
   113
			      polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
hegyi@90
   114
			    }
hegyi@90
   115
			  else
hegyi@90
   116
			    {
hegyi@90
   117
			      char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
hegyi@90
   118
			      for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
hegyi@90
   119
				{
hegyi@90
   120
				  def_val_ch[j]=ch2var[ polishform[i] ][j];
hegyi@90
   121
				}
hegyi@90
   122
			      polishstack.push(atof(def_val_ch));
hegyi@90
   123
			    }
hegyi@90
   124
			  operation=false;
hegyi@88
   125
			  break;
hegyi@88
   126
			}
hegyi@90
   127
		      if(operation)
hegyi@90
   128
			{
hegyi@90
   129
			  double res;
hegyi@90
   130
			  switch(polishform[i])
hegyi@90
   131
			    {
hegyi@90
   132
			    case '+':
hegyi@90
   133
			      res=op1+op2;
hegyi@90
   134
			      break;
hegyi@90
   135
			    case '-':
hegyi@90
   136
			      res=op2-op1;
hegyi@90
   137
			      break;
hegyi@90
   138
			    case '/':
hegyi@90
   139
			      res=op2/op1;
hegyi@90
   140
			      break;
hegyi@90
   141
			    case '*':
hegyi@90
   142
			      res=op1*op2;
hegyi@90
   143
			      break;
hegyi@90
   144
			    default:
hegyi@90
   145
			      std::cout << "How could we get here?" << std::endl;
hegyi@90
   146
			      break;
hegyi@90
   147
			    }
hegyi@90
   148
			  polishstack.push(res);
hegyi@90
   149
			}
hegyi@88
   150
		    }
hegyi@90
   151
		  (*emptr)[k]=polishstack.top(); 
hegyi@88
   152
		}
hegyi@90
   153
hegyi@90
   154
	      //if addition was not successful addEdgeMap returns one.
hegyi@90
   155
	      //cause can be that there is already a map named like the new one
hegyi@90
   156
	      if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
hegyi@90
   157
		{
hegyi@90
   158
		  abortion=1;
hegyi@90
   159
		}
hegyi@90
   160
hegyi@90
   161
	      //add it to the list of the displayable maps
hegyi@90
   162
	      gdc.mapwin.registerNewEdgeMap(mapname);
hegyi@90
   163
hegyi@90
   164
	      //display it
hegyi@90
   165
	      gdc.changeEdgeText(mapname);
hegyi@88
   166
	    }
hegyi@90
   167
	  else //!edge.get_active()
hegyi@90
   168
	    {
hegyi@90
   169
	      //create the new map
hegyi@90
   170
	      Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (gdc.mapstorage.graph);
hegyi@88
   171
hegyi@90
   172
	      std::stack<double> polishstack;
hegyi@88
   173
  
hegyi@90
   174
	      for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
hegyi@88
   175
		{
hegyi@90
   176
		  for(int i=0;i<(int)polishform.size();i++)
hegyi@88
   177
		    {
hegyi@90
   178
		      double op1, op2;
hegyi@90
   179
		      bool operation=true;
hegyi@88
   180
		      switch(polishform[i])
hegyi@88
   181
			{
hegyi@88
   182
			case '+':
hegyi@88
   183
			case '-':
hegyi@88
   184
			case '/':
hegyi@88
   185
			case '*':
hegyi@90
   186
			  op1=polishstack.top();
hegyi@90
   187
			  polishstack.pop();
hegyi@90
   188
			  op2=polishstack.top();
hegyi@90
   189
			  polishstack.pop();
hegyi@88
   190
			  break;
hegyi@88
   191
			default:
hegyi@90
   192
			  std::map< std::string,Graph::NodeMap<double> * > nms=gdc.mapstorage.nodemap_storage;
hegyi@90
   193
			  bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
hegyi@90
   194
			  if(itisvar)
hegyi@90
   195
			    {
hegyi@90
   196
			      polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
hegyi@90
   197
			    }
hegyi@90
   198
			  else
hegyi@90
   199
			    {
hegyi@90
   200
			      char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
hegyi@90
   201
			      for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
hegyi@90
   202
				{
hegyi@90
   203
				  def_val_ch[j]=ch2var[ polishform[i] ][j];
hegyi@90
   204
				}
hegyi@90
   205
			      polishstack.push(atof(def_val_ch));
hegyi@90
   206
			    }
hegyi@90
   207
			  operation=false;
hegyi@88
   208
			  break;
hegyi@88
   209
			}
hegyi@90
   210
		      if(operation)
hegyi@90
   211
			{
hegyi@90
   212
			  double res;
hegyi@90
   213
			  switch(polishform[i])
hegyi@90
   214
			    {
hegyi@90
   215
			    case '+':
hegyi@90
   216
			      res=op1+op2;
hegyi@90
   217
			      break;
hegyi@90
   218
			    case '-':
hegyi@90
   219
			      res=op2-op1;
hegyi@90
   220
			      break;
hegyi@90
   221
			    case '/':
hegyi@90
   222
			      res=op2/op1;
hegyi@90
   223
			      break;
hegyi@90
   224
			    case '*':
hegyi@90
   225
			      res=op1*op2;
hegyi@90
   226
			      break;
hegyi@90
   227
			    default:
hegyi@90
   228
			      std::cout << "How could we get here?" << std::endl;
hegyi@90
   229
			      break;
hegyi@90
   230
			    }
hegyi@90
   231
			  polishstack.push(res);
hegyi@90
   232
			}
hegyi@88
   233
		    }
hegyi@90
   234
		  (*emptr)[k]=polishstack.top(); 
hegyi@88
   235
		}
hegyi@90
   236
hegyi@90
   237
	      //if addition was not successful addNodeMap returns one.
hegyi@90
   238
	      //cause can be that there is already a map named like the new one
hegyi@90
   239
	      if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
hegyi@90
   240
		{
hegyi@90
   241
		  abortion=1;
hegyi@90
   242
		}
hegyi@90
   243
hegyi@90
   244
	      //add it to the list of the displayable maps
hegyi@90
   245
	      gdc.mapwin.registerNewNodeMap(mapname);
hegyi@90
   246
hegyi@90
   247
	      //display it
hegyi@90
   248
	      //gdc.changeNodeText(mapname);
hegyi@88
   249
	    }
hegyi@90
   250
	  if(!abortion)
hegyi@88
   251
	    {
hegyi@90
   252
	      name.set_text("");
hegyi@90
   253
	      default_value.set_text("0");
hegyi@90
   254
	      edge.show();
hegyi@90
   255
	      node.show();
hegyi@90
   256
	      hide();
hegyi@88
   257
	    }
hegyi@46
   258
	}
hegyi@42
   259
    }
hegyi@42
   260
}
hegyi@42
   261
hegyi@90
   262
hegyi@88
   263
std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
hegyi@88
   264
{
hegyi@88
   265
  bool valid_entry=true;
hegyi@88
   266
hegyi@88
   267
  std::map<std::string, int> str2i;
hegyi@88
   268
hegyi@88
   269
  std::string command;
hegyi@88
   270
hegyi@88
   271
  std::string variable;
hegyi@88
   272
hegyi@88
   273
  char index='a';
hegyi@88
   274
hegyi@88
   275
  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
hegyi@88
   276
    {
hegyi@88
   277
      switch(rawcommand[i])
hegyi@88
   278
	{
hegyi@88
   279
	case '+':
hegyi@88
   280
	case '-':
hegyi@88
   281
	case '*':
hegyi@88
   282
	case '/':
hegyi@88
   283
	case ')':
hegyi@88
   284
	case '(':
hegyi@88
   285
 	  if(!variable.empty())
hegyi@88
   286
	    {
hegyi@88
   287
	      valid_entry=validVariable(variable, itisedge);
hegyi@88
   288
	      ch2var[index]=variable;
hegyi@88
   289
	      command+=index;
hegyi@88
   290
	      index++;
hegyi@88
   291
	      variable.erase(0,variable.size());	  
hegyi@88
   292
	    }
hegyi@88
   293
	  command+=rawcommand[i];
hegyi@88
   294
	  break;
hegyi@88
   295
	default:
hegyi@88
   296
	  variable+=rawcommand[i];
hegyi@88
   297
	  break;
hegyi@88
   298
	}
hegyi@88
   299
    }
hegyi@88
   300
hegyi@88
   301
  if(!variable.empty()&&valid_entry)
hegyi@88
   302
    {
hegyi@88
   303
      valid_entry=validVariable(variable, itisedge);
hegyi@88
   304
      ch2var[index]=variable;
hegyi@88
   305
      command+=index;
hegyi@88
   306
      index++;
hegyi@88
   307
      variable.erase(0,variable.size());	  
hegyi@88
   308
    }
hegyi@88
   309
hegyi@88
   310
  if(valid_entry)
hegyi@88
   311
    {
hegyi@88
   312
      unsigned int pr=10000;
hegyi@88
   313
      bool prevmult=false;
hegyi@89
   314
      unsigned int prev_change=pr;
hegyi@89
   315
      unsigned int prev_br=pr;
hegyi@88
   316
      int counter=0;
hegyi@88
   317
      std::string comm_nobr="";
hegyi@88
   318
      std::vector<unsigned int> p;
hegyi@88
   319
      p.resize(counter+1);
hegyi@88
   320
      
hegyi@88
   321
      //limits
hegyi@88
   322
      //6 brackets embedded
hegyi@88
   323
      //100 operation in a row from the same priority
hegyi@88
   324
      
hegyi@88
   325
      for(int i=0;i<(int)command.size();i++)
hegyi@88
   326
	{
hegyi@88
   327
	  bool put_in_string=true;
hegyi@88
   328
	  switch(command[i])
hegyi@88
   329
	    {
hegyi@88
   330
	    case '(':
hegyi@88
   331
	      pr=prev_br+10000;
hegyi@88
   332
	      prev_br=pr;
hegyi@88
   333
	      prevmult=false;
hegyi@88
   334
	      put_in_string=false;
hegyi@88
   335
	      break;
hegyi@88
   336
	    case ')':
hegyi@88
   337
	      pr=prev_br-10000;
hegyi@88
   338
	      prev_br=pr;
hegyi@88
   339
	      prevmult=false;
hegyi@88
   340
	      put_in_string=false;
hegyi@88
   341
	      break;
hegyi@88
   342
	    case '+':
hegyi@88
   343
	    case '-':
hegyi@88
   344
	      if(prevmult)
hegyi@88
   345
		{
hegyi@88
   346
		  pr=prev_change;
hegyi@88
   347
		}
hegyi@88
   348
	      p[counter]=pr;
hegyi@88
   349
	      pr-=100;
hegyi@88
   350
hegyi@88
   351
	      prevmult=false;
hegyi@88
   352
	      break;
hegyi@88
   353
	    case '/':
hegyi@88
   354
	    case '*':
hegyi@88
   355
	      if(!prevmult)
hegyi@88
   356
		{
hegyi@88
   357
		  prev_change=pr;
hegyi@88
   358
		  pr+=200;
hegyi@88
   359
		  pr-=1;
hegyi@88
   360
		}
hegyi@88
   361
	      p[counter]=pr;
hegyi@88
   362
	      pr-=1;
hegyi@88
   363
	      prevmult=true;
hegyi@88
   364
	      break;
hegyi@88
   365
	    default:
hegyi@88
   366
	      p[counter]=65000;
hegyi@88
   367
	      break;
hegyi@88
   368
	    }
hegyi@88
   369
	  if(put_in_string)
hegyi@88
   370
	    {
hegyi@88
   371
	      counter++;
hegyi@88
   372
	      p.resize(counter+1);
hegyi@88
   373
	      comm_nobr=comm_nobr+command[i];
hegyi@88
   374
	    }
hegyi@88
   375
	}
hegyi@88
   376
hegyi@88
   377
      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
hegyi@88
   378
hegyi@88
   379
      std::string polishform=postOrder(root);
hegyi@88
   380
hegyi@88
   381
      return polishform;
hegyi@88
   382
    }
hegyi@88
   383
  return "";
hegyi@88
   384
}
hegyi@88
   385
hegyi@88
   386
NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
hegyi@88
   387
{
hegyi@89
   388
  unsigned int min=p[offset];
hegyi@88
   389
  int minplace=0;
hegyi@88
   390
  for(int i=0;i<(int)to_tree.size();i++)
hegyi@88
   391
    {
hegyi@88
   392
      if(min>p[offset+i])
hegyi@88
   393
	{
hegyi@88
   394
	  min=p[offset+i];
hegyi@88
   395
	  minplace=i;
hegyi@88
   396
	}
hegyi@88
   397
    }
hegyi@88
   398
  tree_node * act_node=new tree_node;
hegyi@88
   399
  act_node->ch=to_tree[minplace];
hegyi@88
   400
  if(to_tree.size()>=3)
hegyi@88
   401
    {
hegyi@88
   402
      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
hegyi@88
   403
      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
hegyi@88
   404
    }
hegyi@88
   405
  else
hegyi@88
   406
    {
hegyi@88
   407
      act_node->left_child=NULL;
hegyi@88
   408
      act_node->right_child=NULL;
hegyi@88
   409
    }
hegyi@88
   410
  return act_node;
hegyi@88
   411
}
hegyi@88
   412
hegyi@88
   413
std::string NewMapWin::postOrder(tree_node * subtree)
hegyi@88
   414
{
hegyi@88
   415
  std::string subtree_to_string;
hegyi@88
   416
  if(subtree->left_child)
hegyi@88
   417
    {
hegyi@88
   418
      subtree_to_string=postOrder(subtree->left_child);
hegyi@88
   419
    }
hegyi@88
   420
  if(subtree->right_child)
hegyi@88
   421
    {
hegyi@88
   422
      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
hegyi@88
   423
    }
hegyi@88
   424
  subtree_to_string=subtree_to_string+subtree->ch;
hegyi@88
   425
  return subtree_to_string;
hegyi@88
   426
}
hegyi@88
   427
hegyi@88
   428
bool NewMapWin::validVariable(std::string variable, bool itisedge)
hegyi@88
   429
{
hegyi@88
   430
  bool cancel;
hegyi@88
   431
  //is it mapname?
hegyi@88
   432
  if(itisedge)
hegyi@88
   433
    {
hegyi@88
   434
      cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
hegyi@88
   435
    }
hegyi@88
   436
  else
hegyi@88
   437
    {
hegyi@88
   438
      cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.mapstorage.nodemap_storage.end());
hegyi@88
   439
    }
hegyi@88
   440
  //maybe it is number
hegyi@88
   441
  int point_num=0;
hegyi@88
   442
  if(cancel)
hegyi@88
   443
    {
hegyi@88
   444
      cancel=false;
hegyi@88
   445
      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
hegyi@88
   446
	{
hegyi@88
   447
	  if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
hegyi@88
   448
	    {
hegyi@88
   449
	      cancel=true;
hegyi@88
   450
	    }
hegyi@88
   451
	  else
hegyi@88
   452
	    {
hegyi@88
   453
	      if(variable[j]=='.')
hegyi@88
   454
		{
hegyi@88
   455
		  point_num++;
hegyi@88
   456
		  if(point_num>1)
hegyi@88
   457
		    {
hegyi@88
   458
		      cancel=true;
hegyi@88
   459
		    }
hegyi@88
   460
		}
hegyi@88
   461
	    }
hegyi@88
   462
	}
hegyi@88
   463
    }
hegyi@88
   464
  if(cancel)
hegyi@88
   465
    {
hegyi@88
   466
      return false;
hegyi@88
   467
    }
hegyi@88
   468
  return true;
hegyi@88
   469
}