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