#include bool NewMapWin::closeIfEscapeIsPressed(GdkEventKey* e) { if(e->keyval==GDK_Escape) { hide(); } return true; } 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") { set_default_size(200, 50); signal_key_press_event().connect(sigc::mem_fun(*this, &NewMapWin::closeIfEscapeIsPressed)); Gtk::VBox * vbox=get_vbox(); //entries table=new Gtk::Table(3, 2, false); label=new Gtk::Label; label->set_text("Name of new map:"); name.set_text(""); (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3); (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3); label=new Gtk::Label; label->set_text("Default value in the map:"); default_value.set_text("0"); (*table).attach(*label,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3); (*table).attach(default_value,1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3); //node vs. edge map selector Gtk::RadioButton::Group group = node.get_group(); edge.set_group(group); if(edgenode) { (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3); (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3); } else { if(itisedge) { edge.set_active(); } else { node.set_active(); } } vbox->pack_start(*table); //OK button add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); show_all_children(); } void NewMapWin::on_response(int response_id) { if(response_id==Gtk::RESPONSE_OK) { double def_val=0; //get and formulate text std::string def_val_str=default_value.get_text(); std::string polishform=string2Polishform(def_val_str,edge.get_active()); //get name of text std::string mapname=name.get_text(); if(!mapname.empty()&&!polishform.empty()) { int abortion=0; if(edge.get_active()) { //create the new map Graph::EdgeMap * emptr=new Graph::EdgeMap (mytab.mapstorage.graph); std::stack polishstack; for(EdgeIt k(mytab.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 * > ems=mytab.mapstorage.edgemap_storage; bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end()); if(itisvar) { polishstack.push( (*(mytab.mapstorage.edgemap_storage[ ch2var[ polishform[i] ] ]))[k]); } else { polishstack.push(atof(ch2var[ polishform[i] ].c_str())); } 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(mytab.mapstorage.addEdgeMap(mapname, emptr, def_val)) { abortion=1; } //add it to the list of the displayable maps //furthermore it is done by signals //mytab.registerNewEdgeMap(mapname); //display it //gdc.changeEdgeText(mapname); } else //!edge.get_active() { //create the new map Graph::NodeMap * emptr=new Graph::NodeMap (mytab.mapstorage.graph); std::stack polishstack; for(NodeIt k(mytab.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 * > nms=mytab.mapstorage.nodemap_storage; bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end()); if(itisvar) { polishstack.push( (*(mytab.mapstorage.nodemap_storage[ ch2var[ polishform[i] ] ]))[k]); } else { polishstack.push(atof(ch2var[ polishform[i] ].c_str())); } 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(mytab.mapstorage.addNodeMap(mapname,emptr, def_val)) { abortion=1; } //add it to the list of the displayable maps //furthermore it is done by signals //mytab.registerNewNodeMap(mapname); //display it //gdc.changeNodeText(mapname); } if(!abortion) { name.set_text(""); default_value.set_text("0"); edge.show(); node.show(); hide(); } } } } std::string NewMapWin::string2Polishform(std::string rawcommand, bool itisedge) { bool valid_entry=true; std::map 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=pr; unsigned int prev_br=pr; int counter=0; std::string comm_nobr=""; std::vector 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); deleteTree(root); return polishform; } return ""; } void NewMapWin::deleteTree(NewMapWin::tree_node * node) { if(node->left_child!=NULL) { deleteTree(node->left_child); } if(node->right_child!=NULL) { deleteTree(node->right_child); } delete node; } NewMapWin::tree_node * NewMapWin::weightedString2Tree(std::string to_tree, std::vector & p, int offset) { unsigned 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=(mytab.mapstorage.edgemap_storage.find(variable)==mytab.mapstorage.edgemap_storage.end()); } else { cancel=(mytab.mapstorage.nodemap_storage.find(variable)==mytab.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; }