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