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