[Lemon-commits] [lemon_svn] hegyi: r2361 - hugo/trunk/gui

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:52:03 CET 2006


Author: hegyi
Date: Thu Nov 17 16:34:18 2005
New Revision: 2361

Modified:
   hugo/trunk/gui/graph_displayer_canvas.h
   hugo/trunk/gui/new_map_win.cc
   hugo/trunk/gui/new_map_win.h

Log:
As initial value of a new map expression with ()+-/* operators can be given. These operators work on numbers, or on maps. If maps are given, then the new value for a given graph element will be calculated using the value from the given maps that belong to that graph element.

Modified: hugo/trunk/gui/graph_displayer_canvas.h
==============================================================================
--- hugo/trunk/gui/graph_displayer_canvas.h	(original)
+++ hugo/trunk/gui/graph_displayer_canvas.h	Thu Nov 17 16:34:18 2005
@@ -143,9 +143,11 @@
   ///Group of graphical elements of displayed_graph
   Gnome::Canvas::Group displayed_graph;
 
+public:
   ///Here we store the maps that can be displayed through properties.
   MapStorage & mapstorage;
 
+private:
   ///Indicates whether the button of mouse is pressed or not
   int isbutton;
 
@@ -169,9 +171,12 @@
 
   static const int zoom_step = 5;
 
+public:
   ///We need to store mapwin, to be able to ask the appropriate values for properties of new items.
   MapWin & mapwin;
 
+private:
+
   ///pointer to the parent window
   Gtk::Window * parentwin;
 

Modified: hugo/trunk/gui/new_map_win.cc
==============================================================================
--- hugo/trunk/gui/new_map_win.cc	(original)
+++ hugo/trunk/gui/new_map_win.cc	Thu Nov 17 16:34:18 2005
@@ -77,41 +77,184 @@
 
 void NewMapWin::buttonPressed()
 {
-  bool valid_double=true;
-  int point_num=0;
+  double def_val=0;
 
+  //get and formulate text
   std::string def_val_str=default_value.get_text();
-  char * def_val_ch=new char [def_val_str.length()];
-  for(int i=0;i<(int)(def_val_str.length());i++)
-    {
-      if(((def_val_str[i]<'0')||(def_val_str[i]>'9'))&&(def_val_str[i]!='.'))
-	{
-	  valid_double=false;
-	}
-      else
-	{
-	  if(def_val_str[i]=='.')
-	    {
-	      point_num++;
-	    }
-	}
-      def_val_ch[i]=def_val_str[i];
-    }
-  
-  double def_val=atof(def_val_ch);
+  std::string polishform=string2Polishform(def_val_str,edge.get_active());
 
+  //get name of text
   std::string mapname=name.get_text();
 
-  if((point_num<=1)&&(valid_double)&&(!mapname.empty()))
+  if(!mapname.empty()&&!polishform.empty())
     {
       int abortion=0;
       if(edge.get_active())
 	{
-	  abortion=gdc.addNewEdgeMap(def_val,mapname);
+	  //create the new map
+	  Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (gdc.mapstorage.graph);
+
+	  std::stack<double> polishstack;
+  
+	  for(EdgeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
+	    {
+	      for(int i=0;i<(int)polishform.size();i++)
+		{
+		  double op1, op2;
+		  bool operation=true;
+		  switch(polishform[i])
+		    {
+		    case '+':
+		    case '-':
+		    case '/':
+		    case '*':
+		      op1=polishstack.top();
+		      polishstack.pop();
+		      op2=polishstack.top();
+		      polishstack.pop();
+		      break;
+		    default:
+		      //substitute variable
+		      std::map< std::string,Graph::EdgeMap<double> * > ems=gdc.mapstorage.edgemap_storage;
+		      bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
+		      if(itisvar)
+			{
+			  polishstack.push( (*(gdc.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
+			}
+		      else
+			{
+			  char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
+			  for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
+			    {
+			      def_val_ch[j]=ch2var[ polishform[i] ][j];
+			    }
+			  polishstack.push(atof(def_val_ch));
+			}
+		      operation=false;
+		      break;
+		    }
+		  if(operation)
+		    {
+		      double res;
+		      switch(polishform[i])
+			{
+			case '+':
+			  res=op1+op2;
+			  break;
+			case '-':
+			  res=op2-op1;
+			  break;
+			case '/':
+			  res=op2/op1;
+			  break;
+			case '*':
+			  res=op1*op2;
+			  break;
+			default:
+			  std::cout << "How could we get here?" << std::endl;
+			  break;
+			}
+		      polishstack.push(res);
+		    }
+		}
+	      (*emptr)[k]=polishstack.top(); 
+	    }
+
+	  //if addition was not successful addEdgeMap returns one.
+	  //cause can be that there is already a map named like the new one
+	  if(gdc.mapstorage.addEdgeMap(mapname, emptr, def_val))
+	    {
+	      abortion=1;
+	    }
+
+	  //add it to the list of the displayable maps
+	  gdc.mapwin.registerNewEdgeMap(mapname);
+
+	  //display it
+	  gdc.changeEdgeText(mapname);
 	}
-      else
+      else //!edge.get_active()
 	{
-	  abortion=gdc.addNewNodeMap(def_val,mapname);
+	  //create the new map
+	  Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (gdc.mapstorage.graph);
+
+	  std::stack<double> polishstack;
+  
+	  for(NodeIt k(gdc.mapstorage.graph); k!=INVALID; ++k)
+	    {
+	      for(int i=0;i<(int)polishform.size();i++)
+		{
+		  double op1, op2;
+		  bool operation=true;
+		  switch(polishform[i])
+		    {
+		    case '+':
+		    case '-':
+		    case '/':
+		    case '*':
+		      op1=polishstack.top();
+		      polishstack.pop();
+		      op2=polishstack.top();
+		      polishstack.pop();
+		      break;
+		    default:
+		      std::map< std::string,Graph::NodeMap<double> * > nms=gdc.mapstorage.nodemap_storage;
+		      bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
+		      if(itisvar)
+			{
+			  polishstack.push( (*(gdc.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
+			}
+		      else
+			{
+			  char * def_val_ch=new char [(int)(ch2var[ polishform[i] ].length())];
+			  for(int j=0;j<(int)(ch2var[ polishform[i] ].length());j++)
+			    {
+			      def_val_ch[j]=ch2var[ polishform[i] ][j];
+			    }
+			  polishstack.push(atof(def_val_ch));
+			}
+		      operation=false;
+		      break;
+		    }
+		  if(operation)
+		    {
+		      double res;
+		      switch(polishform[i])
+			{
+			case '+':
+			  res=op1+op2;
+			  break;
+			case '-':
+			  res=op2-op1;
+			  break;
+			case '/':
+			  res=op2/op1;
+			  break;
+			case '*':
+			  res=op1*op2;
+			  break;
+			default:
+			  std::cout << "How could we get here?" << std::endl;
+			  break;
+			}
+		      polishstack.push(res);
+		    }
+		}
+	      (*emptr)[k]=polishstack.top(); 
+	    }
+
+	  //if addition was not successful addNodeMap returns one.
+	  //cause can be that there is already a map named like the new one
+	  if(gdc.mapstorage.addNodeMap(mapname,emptr, def_val))
+	    {
+	      abortion=1;
+	    }
+
+	  //add it to the list of the displayable maps
+	  gdc.mapwin.registerNewNodeMap(mapname);
+
+	  //display it
+	  gdc.changeNodeText(mapname);
 	}
       if(!abortion)
 	{
@@ -124,3 +267,210 @@
     }
 }
 
+std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge)
+{
+  bool valid_entry=true;
+
+  std::map<std::string, int> str2i;
+
+  std::string command;
+
+  std::string variable;
+
+  char index='a';
+
+  for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
+    {
+      switch(rawcommand[i])
+	{
+	case '+':
+	case '-':
+	case '*':
+	case '/':
+	case ')':
+	case '(':
+ 	  if(!variable.empty())
+	    {
+	      valid_entry=validVariable(variable, itisedge);
+	      ch2var[index]=variable;
+	      command+=index;
+	      index++;
+	      variable.erase(0,variable.size());	  
+	    }
+	  command+=rawcommand[i];
+	  break;
+	default:
+	  variable+=rawcommand[i];
+	  break;
+	}
+    }
+
+  if(!variable.empty()&&valid_entry)
+    {
+      valid_entry=validVariable(variable, itisedge);
+      ch2var[index]=variable;
+      command+=index;
+      index++;
+      variable.erase(0,variable.size());	  
+    }
+
+  if(valid_entry)
+    {
+      unsigned int pr=10000;
+      bool prevmult=false;
+      unsigned int prev_change;
+      unsigned int prev_br=10000;
+      int counter=0;
+      std::string comm_nobr="";
+      std::vector<unsigned int> p;
+      p.resize(counter+1);
+      
+      //limits
+      //6 brackets embedded
+      //100 operation in a row from the same priority
+      
+      for(int i=0;i<(int)command.size();i++)
+	{
+	  bool put_in_string=true;
+	  switch(command[i])
+	    {
+	    case '(':
+	      pr=prev_br+10000;
+	      prev_br=pr;
+	      prevmult=false;
+	      put_in_string=false;
+	      break;
+	    case ')':
+	      pr=prev_br-10000;
+	      prev_br=pr;
+	      prevmult=false;
+	      put_in_string=false;
+	      break;
+	    case '+':
+	    case '-':
+	      if(prevmult)
+		{
+		  pr=prev_change;
+		}
+	      p[counter]=pr;
+	      pr-=100;
+
+	      prevmult=false;
+	      break;
+	    case '/':
+	    case '*':
+	      if(!prevmult)
+		{
+		  prev_change=pr;
+		  pr+=200;
+		  pr-=1;
+		}
+	      p[counter]=pr;
+	      pr-=1;
+	      prevmult=true;
+	      break;
+	    default:
+	      p[counter]=65000;
+	      break;
+	    }
+	  if(put_in_string)
+	    {
+	      counter++;
+	      p.resize(counter+1);
+	      comm_nobr=comm_nobr+command[i];
+	    }
+	}
+
+      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
+
+      std::string polishform=postOrder(root);
+
+      return polishform;
+    }
+  return "";
+}
+
+NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector<unsigned int> & p, int offset)
+{
+  int min=p[offset];
+  int minplace=0;
+  for(int i=0;i<(int)to_tree.size();i++)
+    {
+      if(min>p[offset+i])
+	{
+	  min=p[offset+i];
+	  minplace=i;
+	}
+    }
+  tree_node * act_node=new tree_node;
+  act_node->ch=to_tree[minplace];
+  if(to_tree.size()>=3)
+    {
+      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
+      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
+    }
+  else
+    {
+      act_node->left_child=NULL;
+      act_node->right_child=NULL;
+    }
+  return act_node;
+}
+
+std::string NewMapWin::postOrder(tree_node * subtree)
+{
+  std::string subtree_to_string;
+  if(subtree->left_child)
+    {
+      subtree_to_string=postOrder(subtree->left_child);
+    }
+  if(subtree->right_child)
+    {
+      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
+    }
+  subtree_to_string=subtree_to_string+subtree->ch;
+  return subtree_to_string;
+}
+
+bool NewMapWin::validVariable(std::string variable, bool itisedge)
+{
+  bool cancel;
+  //is it mapname?
+  if(itisedge)
+    {
+      cancel=(gdc.mapstorage.edgemap_storage.find(variable)==gdc.mapstorage.edgemap_storage.end());
+    }
+  else
+    {
+      cancel=(gdc.mapstorage.nodemap_storage.find(variable)==gdc.mapstorage.nodemap_storage.end());
+    }
+  //maybe it is number
+  int point_num=0;
+  if(cancel)
+    {
+      cancel=false;
+      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
+	{
+	  if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
+	    {
+	      cancel=true;
+	    }
+	  else
+	    {
+	      if(variable[j]=='.')
+		{
+		  point_num++;
+		  if(point_num>1)
+		    {
+		      cancel=true;
+		    }
+		}
+	    }
+	}
+    }
+  if(cancel)
+    {
+      return false;
+    }
+  return true;
+}

Modified: hugo/trunk/gui/new_map_win.h
==============================================================================
--- hugo/trunk/gui/new_map_win.h	(original)
+++ hugo/trunk/gui/new_map_win.h	Thu Nov 17 16:34:18 2005
@@ -9,6 +9,7 @@
 #include <graph_displayer_canvas.h>
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include <stack>
 
 ///This class is responsible for creating a window,
 ///on which the parameters of a new map can be set.
@@ -21,21 +22,40 @@
   ///a function of the \ref GraphDisplayerCanvas will be called.
   GraphDisplayerCanvas & gdc;
 
- public:
+public:
+  struct tree_node
+  {
+    char ch;
+    tree_node * left_child;
+    tree_node * right_child;
+  };
+  
   ///Constructor of NewMapWin creates the widgets shown in NewMapWin.
   NewMapWin(const std::string& title, GraphDisplayerCanvas &);
 
-
+  
   ///Signal on button is connected to this function,
   ///Therefore this function determines whether to
   ///call the map/creatort function, and if yes, it
   //tells it the attributes.(name, default value)
   virtual void buttonPressed();
-
+  
   virtual void showByPreChoose(bool);
 
   virtual bool closeIfEscapeIsPressed(GdkEventKey*);
 
+  ///Function that creates a tree from an appropriately manipulated string
+  tree_node * weightedString2Tree(std::string, std::vector<unsigned int> &, int);
+
+  ///Function  that creates a string from a tree by postorder reading.
+  std::string postOrder(tree_node *);
+
+  std::string string2Polishform(std::string, bool);
+
+  bool validVariable(std::string, bool);
+
+  std::map<char, std::string> ch2var;
+
   Gtk::Entry name, default_value;
 
   Gtk::VBox vbox;



More information about the Lemon-commits mailing list