new_map_win.cc
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
branchgui
changeset 90 e9f8f44f12a3
parent 89 4042761b21e3
child 94 adfdc2f70548
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.
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
}