[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