gui/graph_displayer_canvas-event.cc
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 1883 05b0e8d057a6
child 2063 9535436aaa9f
permissions -rwxr-xr-x
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
     1 #include "graph_displayer_canvas.h"
     2 #include <cmath>
     3 
     4 
     5 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
     6 {
     7   Gnome::Canvas::CanvasAA::on_expose_event(event);
     8   //usleep(10000);
     9   //rezoom();
    10   return true;
    11 }
    12 
    13 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
    14 {
    15   if(actual_tool!=newtool)
    16     {
    17 
    18       actual_handler.disconnect();
    19 
    20       switch(actual_tool)
    21 	{
    22 	case CREATE_EDGE:
    23 	  {
    24 	    GdkEvent * generated=new GdkEvent();
    25 	    generated->type=GDK_BUTTON_RELEASE;
    26 	    generated->button.button=3;
    27 	    createEdgeEventHandler(generated);      
    28 	    break;
    29 	  }
    30 	case EDGE_MAP_EDIT:
    31 	  //has to do the same thing as in the case of NODE_MAP_EDIT
    32 	case NODE_MAP_EDIT:
    33 	  {
    34 	    break;
    35 	  }
    36 	default:
    37 	  break;
    38 	}
    39 
    40       active_item=NULL; 
    41       target_item=NULL; 
    42       active_edge=INVALID;	
    43       active_node=INVALID;	
    44 
    45 
    46       actual_tool=newtool;
    47   
    48       switch(newtool)
    49 	{
    50 	case MOVE:
    51 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
    52 	  break;
    53 
    54 	case CREATE_NODE:
    55 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
    56 	  break;
    57 
    58 	case CREATE_EDGE:
    59 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
    60 	  break;
    61 
    62 	case ERASER:
    63 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
    64 	  break;
    65 
    66 	case EDGE_MAP_EDIT:
    67 	  grab_focus();
    68 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false);
    69 	  break;
    70 
    71 	case NODE_MAP_EDIT:
    72 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false);
    73 	  break;
    74 
    75 	default:
    76 	  break;
    77 	}
    78     }
    79 }
    80 
    81 int GraphDisplayerCanvas::getActualTool()
    82 {
    83   return actual_tool;
    84 }
    85 
    86 bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
    87 {
    88   static Gnome::Canvas::Text *coord_text = 0;
    89   switch(e->type)
    90   {
    91     case GDK_BUTTON_PRESS:
    92       //we mark the location of the event to be able to calculate parameters of dragging
    93       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
    94 
    95       active_item=(get_item_at(clicked_x, clicked_y));
    96       active_node=INVALID;
    97       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
    98 	{
    99 	  if(nodesmap[i]==active_item)
   100 	    {
   101 	      active_node=i;
   102 	    }
   103 	}
   104       switch(e->button.button)
   105 	{
   106 	case 3:      
   107 	  isbutton=3;
   108 	  break;
   109 	default:
   110 	  isbutton=1;
   111 	  break;
   112 	}
   113       break;
   114     case GDK_BUTTON_RELEASE:
   115       if (coord_text)
   116       {
   117         delete coord_text;
   118         coord_text = 0;
   119       }
   120       isbutton=0;
   121       active_item=NULL;
   122       active_node=INVALID;
   123       break;
   124     case GDK_MOTION_NOTIFY:
   125       //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes
   126       if(active_node!=INVALID)
   127       {
   128         (mytab.mapstorage).modified = true;
   129 
   130 	//new coordinates will be the old values,
   131 	//because the item will be moved to the
   132 	//new coordinate therefore the new movement
   133 	//has to be calculated from here
   134 
   135 	double new_x, new_y;
   136 
   137 	window_to_world (e->motion.x, e->motion.y, new_x, new_y);
   138 
   139         double dx=new_x-clicked_x;
   140         double dy=new_y-clicked_y;
   141 
   142 	//repositioning node and its text
   143         active_item->move(dx, dy);
   144 	nodetextmap[active_node]->move(dx, dy);
   145 
   146         // the new coordinates of the centre of the node 
   147         double coord_x = new_x - (clicked_x - (mytab.mapstorage).coords[active_node].x);
   148         double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y);
   149 
   150         // write back the new coordinates to the coords map
   151         (mytab.mapstorage).coords.set(active_node, xy<double>(coord_x, coord_y));
   152 
   153         clicked_x=new_x;
   154         clicked_y=new_y;
   155 
   156         // reposition the coordinates text
   157         std::ostringstream ostr;
   158         ostr << "(" <<
   159           (mytab.mapstorage).coords[active_node].x << ", " <<
   160           (mytab.mapstorage).coords[active_node].y << ")";
   161         double radius =
   162           (nodesmap[active_node]->property_x2().get_value() -
   163           nodesmap[active_node]->property_x1().get_value()) / 2.0;
   164         if (coord_text)
   165         {
   166           coord_text->property_text().set_value(ostr.str());
   167           coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x +
   168               radius);
   169           coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
   170               radius);
   171         }
   172         else
   173         {
   174           coord_text = new Gnome::Canvas::Text(
   175               displayed_graph,
   176               (mytab.mapstorage).coords[active_node].x + radius,
   177               (mytab.mapstorage).coords[active_node].y - radius,
   178               ostr.str());
   179           coord_text->property_fill_color().set_value("black");
   180           coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
   181         }
   182 
   183 	//all the edges connected to the moved point has to be redrawn
   184         for(OutEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
   185         {
   186             XY moved_node_1(coord_x - dx, coord_y - dy);
   187             XY moved_node_2(coord_x, coord_y);
   188             Node target = mytab.mapstorage.graph.target(ei);
   189             XY fix_node(mytab.mapstorage.coords[target].x,
   190                         mytab.mapstorage.coords[target].y);
   191             XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   192 
   193             XY arrow_pos;
   194 	    if(isbutton==3)
   195               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false);
   196 	    else
   197               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true);
   198 
   199             mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   200             edgesmap[ei]->draw();
   201 
   202 	    //reposition of edgetext
   203 	    XY text_pos=mytab.mapstorage.arrow_pos[ei];
   204 	    text_pos+=(XY(10,10));
   205 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   206 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   207         }
   208 
   209         for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
   210         {
   211             XY moved_node_1(coord_x - dx, coord_y - dy);
   212             XY moved_node_2(coord_x, coord_y);
   213             Node source = mytab.mapstorage.graph.source(ei);
   214             XY fix_node(mytab.mapstorage.coords[source].x,
   215                         mytab.mapstorage.coords[source].y);
   216             XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   217 
   218             XY arrow_pos;
   219 	    if(isbutton==3)
   220               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false);
   221 	    else
   222               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true);
   223 
   224             mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   225             edgesmap[ei]->draw();
   226 
   227 	    //reposition of edgetext
   228 	    XY text_pos=mytab.mapstorage.arrow_pos[ei];
   229 	    text_pos+=(XY(10,10));
   230 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   231 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   232         }
   233       }
   234     default: break;
   235   }
   236 
   237   return false;
   238 }
   239 
   240 XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, bool move)
   241 {
   242   if(!move)
   243   {
   244     return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0);
   245   }
   246   else
   247   {
   248     //////////////////////////////////////////////////////////////////////////////////////////////////////
   249     /////////// keeps shape-with scalar multiplication - version 2.
   250     //////////////////////////////////////////////////////////////////////////////////////////////////////
   251 
   252     //old vector from one to the other node - a
   253     xy<double> a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y);
   254     //new vector from one to the other node - b
   255     xy<double> b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y);
   256 
   257     double absa=sqrt(a_v.normSquare());
   258     double absb=sqrt(b_v.normSquare());
   259 
   260     if ((absa == 0.0) || (absb == 0.0))
   261     {
   262       return old_arrow_pos;
   263     }
   264     else
   265     {
   266       //old vector from one node to the breakpoint - c
   267       xy<double> c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y);
   268 
   269       //unit vector with the same direction to a_v
   270       xy<double> a_v_u(a_v.x/absa,a_v.y/absa);
   271 
   272       //normal vector of unit vector with the same direction to a_v
   273       xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
   274 
   275       //unit vector with the same direction to b_v
   276       xy<double> b_v_u(b_v.x/absb,b_v.y/absb);
   277 
   278       //normal vector of unit vector with the same direction to b_v
   279       xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
   280 
   281       //vector c in a_v_u and a_v_u_n co-ordinate system
   282       xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n);
   283 
   284       //new vector from one node to the breakpoint - d - we have to calculate this one
   285       xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
   286 
   287       return XY(d_v.x+fix_node.x,d_v.y+fix_node.y);
   288     }
   289   }
   290 }
   291 
   292 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
   293 {
   294   switch(e->type)
   295   {
   296     //move the new node
   297     case GDK_MOTION_NOTIFY:
   298       {
   299         GdkEvent * generated=new GdkEvent();
   300         generated->motion.x=e->motion.x;
   301         generated->motion.y=e->motion.y;
   302         generated->type=GDK_MOTION_NOTIFY;
   303         moveEventHandler(generated);      
   304         break;
   305       }
   306 
   307     case GDK_BUTTON_RELEASE:
   308       (mytab.mapstorage).modified = true;
   309 
   310       isbutton=1;
   311 
   312       active_node=(mytab.mapstorage).graph.addNode();
   313 
   314       //initiating values corresponding to new node in maps
   315 
   316       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   317 
   318       // update coordinates
   319       (mytab.mapstorage).coords.set(active_node, xy<double>(clicked_x, clicked_y));
   320 
   321       // update all other maps
   322       for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
   323           (mytab.mapstorage).nodemap_storage.begin(); it !=
   324           (mytab.mapstorage).nodemap_storage.end(); ++it)
   325       {
   326         if ((it->first != "coordinates_x") &&
   327             (it->first != "coordinates_y"))
   328         {
   329           (*(it->second))[active_node] =
   330             (mytab.mapstorage).nodemap_default[it->first];
   331         }
   332       }
   333       // increment the id map's default value
   334       (mytab.mapstorage).nodemap_default["id"] += 1.0;
   335 
   336       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
   337           clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
   338       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   339       *(nodesmap[active_node]) <<
   340         Gnome::Canvas::Properties::fill_color("blue");
   341       *(nodesmap[active_node]) <<
   342         Gnome::Canvas::Properties::outline_color("black");
   343       active_item->raise_to_top();
   344 
   345       (nodesmap[active_node])->show();
   346 
   347       nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
   348           clicked_x+node_property_defaults[N_RADIUS]+5,
   349           clicked_y+node_property_defaults[N_RADIUS]+5, "");
   350       nodetextmap[active_node]->property_fill_color().set_value("darkblue");
   351       nodetextmap[active_node]->raise_to_top();
   352 
   353 //       mapwin.updateNode(active_node);
   354       propertyUpdate(active_node);
   355 
   356       isbutton=0;
   357       target_item=NULL;
   358       active_item=NULL;
   359       active_node=INVALID;
   360       break;
   361     default:
   362       break;
   363   }
   364   return false;
   365 }
   366 
   367 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
   368 {
   369   switch(e->type)
   370   {
   371     case GDK_BUTTON_PRESS:
   372       //in edge creation right button has special meaning
   373       if(e->button.button!=3)
   374       {
   375         //there is not yet selected node
   376         if(active_node==INVALID)
   377         {
   378           //we mark the location of the event to be able to calculate parameters of dragging
   379 
   380           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   381 
   382           active_item=(get_item_at(clicked_x, clicked_y));
   383           active_node=INVALID;
   384           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   385           {
   386             if(nodesmap[i]==active_item)
   387             {
   388               active_node=i;
   389             }
   390           }
   391           //the clicked item is really a node
   392           if(active_node!=INVALID)
   393           {
   394             *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   395             isbutton=1;
   396           }
   397           //clicked item was not a node. It could be e.g. edge.
   398           else
   399           {
   400             active_item=NULL;
   401           }
   402         }
   403         //we only have to do sg. if the mouse button
   404         // is pressed already once AND the click was
   405         // on a node that was found in the set of 
   406         //nodes, and now we only search for the second 
   407         //node
   408         else
   409         {
   410           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   411           target_item=(get_item_at(clicked_x, clicked_y));
   412           Node target_node=INVALID;
   413           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   414           {
   415             if(nodesmap[i]==target_item)
   416             {
   417               target_node=i;
   418             }
   419           }
   420           //the clicked item is a node, the edge can be drawn
   421           if(target_node!=INVALID)
   422           {
   423             if(target_node!=active_node)		
   424             {
   425               (mytab.mapstorage).modified = true;
   426 
   427               *(nodesmap[target_node]) <<
   428                 Gnome::Canvas::Properties::fill_color("red");
   429 
   430               //creating new edge
   431               active_edge=(mytab.mapstorage).graph.addEdge(active_node,
   432                   target_node);
   433 
   434               // update maps
   435               for (std::map<std::string,
   436                   Graph::EdgeMap<double>*>::const_iterator it =
   437                   (mytab.mapstorage).edgemap_storage.begin(); it !=
   438                   (mytab.mapstorage).edgemap_storage.end(); ++it)
   439               {
   440                 (*(it->second))[active_edge] =
   441                   (mytab.mapstorage).edgemap_default[it->first];
   442               }
   443               // increment the id map's default value
   444               (mytab.mapstorage).edgemap_default["id"] += 1.0;
   445 
   446               //calculating coordinates of new edge
   447               Gnome::Canvas::Points coos;
   448               double x1, x2, y1, y2;
   449 
   450               active_item->get_bounds(x1, y1, x2, y2);
   451               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   452 
   453               target_item->get_bounds(x1, y1, x2, y2);
   454               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   455 
   456               // set the coordinates of the arrow on the new edge
   457               MapStorage& ms = mytab.mapstorage;
   458               ms.arrow_pos.set(active_edge,
   459                   (ms.coords[ms.graph.source(active_edge)] +
   460                    ms.coords[ms.graph.target(active_edge)])/ 2.0);
   461 
   462               //drawing new edge
   463               edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
   464                   *this);
   465               *(edgesmap[active_edge]) <<
   466                 Gnome::Canvas::Properties::fill_color("green");
   467               edgesmap[active_edge]->property_width_pixels().set_value(10);
   468 
   469               edgesmap[active_edge]->lower_to_bottom();
   470 
   471               //initializing edge-text as well, to empty string
   472               XY text_pos=mytab.mapstorage.arrow_pos[active_edge];
   473               text_pos+=(XY(10,10));
   474 
   475               edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   476                   text_pos.x, text_pos.y, "");
   477               edgetextmap[active_edge]->property_fill_color().set_value(
   478                   "darkgreen");
   479               edgetextmap[active_edge]->raise_to_top();
   480 
   481               //updating its properties
   482 //               mapwin.updateEdge(active_edge);
   483               propertyUpdate(active_edge);
   484             }
   485             else
   486             {
   487               target_node=INVALID;
   488               std::cerr << "Loop edge is not yet implemented!" << std::endl;
   489             }
   490           }
   491           //clicked item was not a node. it could be an e.g. edge. we do not
   492           //deal with it furthermore.
   493           else
   494           {
   495             target_item=NULL;
   496           }
   497         }
   498       }
   499       break;
   500     case GDK_BUTTON_RELEASE:
   501       isbutton=0;
   502       //we clear settings in two cases
   503       //1: the edge is ready (target_item has valid value)
   504       //2: the edge creation is cancelled with right button
   505       if((target_item)||(e->button.button==3))
   506       {
   507         if(active_item)
   508         {
   509           *active_item << Gnome::Canvas::Properties::fill_color("blue");
   510           active_item=NULL;
   511         }
   512         if(target_item)
   513         {
   514           *target_item << Gnome::Canvas::Properties::fill_color("blue");
   515           target_item=NULL;
   516         }
   517         active_node=INVALID;
   518         active_edge=INVALID;
   519       }
   520       break;
   521     default:
   522       break;
   523   }
   524   return false;
   525 }
   526 
   527 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   528 {
   529   switch(e->type)
   530     {
   531     case GDK_BUTTON_PRESS:
   532       //finding the clicked items
   533       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   534       active_item=(get_item_at(clicked_x, clicked_y));
   535       active_node=INVALID;
   536       active_edge=INVALID;
   537       //was it a node?
   538       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   539 	{
   540 	  if(nodesmap[i]==active_item)
   541 	    {
   542 	      active_node=i;
   543 	    }
   544 	}
   545       //or was it an edge?
   546       if(active_node==INVALID)
   547 	{
   548 	  for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   549 	    {
   550 	      if(edgesmap[i]==active_item)
   551 		{
   552 		  active_edge=i;
   553 		}
   554 	    }
   555 	}
   556 
   557       // return if the clicked object is neither an edge nor a node
   558       if (active_edge == INVALID) return false;
   559       
   560       //recolor activated item
   561       if(active_item)
   562 	{
   563 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   564 	}
   565       break;
   566 
   567     case GDK_BUTTON_RELEASE:
   568       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   569       if(active_item)
   570 	{
   571 	  //the cursor was not moved since pressing it
   572 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   573 	    {
   574 	      //a node was found
   575 	      if(active_node!=INVALID)
   576 		{
   577                   (mytab.mapstorage).modified = true;
   578 
   579 		  std::set<Graph::Edge> edges_to_delete;
   580 
   581 		  for(OutEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   582 		    {
   583 		      edges_to_delete.insert(e);
   584 		    }
   585 		  
   586 		  for(InEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   587 		    {
   588 		      edges_to_delete.insert(e);
   589 		    }
   590 		  
   591 		  //deleting collected edges
   592 		  for(std::set<Graph::Edge>::iterator
   593 			edge_set_it=edges_to_delete.begin();
   594 		      edge_set_it!=edges_to_delete.end();
   595 		      ++edge_set_it)
   596 		    {
   597 		      deleteItem(*edge_set_it);
   598 		    }
   599 		  deleteItem(active_node);
   600 		}
   601 	      //a simple edge was chosen
   602 	      else if (active_edge != INVALID)
   603 		{
   604 		  deleteItem(active_edge);
   605 		}
   606 	    }
   607 	  //pointer was moved, deletion is cancelled
   608 	  else
   609 	    {
   610 	      if(active_node!=INVALID)
   611 		{
   612 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   613 		}
   614 	      else if (active_edge != INVALID)
   615 		{
   616 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   617 		}
   618 	    }
   619 	}
   620       //reseting datas
   621       active_item=NULL;
   622       active_edge=INVALID;
   623       active_node=INVALID;
   624       break;
   625 
   626     case GDK_MOTION_NOTIFY:
   627       break;
   628 
   629     default:
   630       break;
   631     }
   632   return false;
   633 }
   634 
   635 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   636 {
   637   if(actual_tool==EDGE_MAP_EDIT)
   638   {
   639     switch(e->type)
   640     {
   641       case GDK_BUTTON_PRESS:
   642         {
   643           //for determine, whether it was an edge
   644           Edge clicked_edge=INVALID;
   645 
   646           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   647           active_item=(get_item_at(clicked_x, clicked_y));
   648 
   649           //find the activated item between texts
   650           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   651           {
   652             //at the same time only one can be active
   653             if(edgetextmap[i]==active_item)
   654             {
   655               clicked_edge=i;
   656             }
   657           }
   658 
   659           //if it was not between texts, search for it between edges
   660           if(clicked_edge==INVALID)
   661           {
   662             for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   663             {
   664               //at the same time only one can be active
   665               if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   666               {
   667                 clicked_edge=i;
   668               }
   669             }
   670           }
   671  
   672           //if it was really an edge...
   673           if(clicked_edge!=INVALID)
   674           {
   675             // the id map is not editable
   676             if (edgemap_to_edit == "id") return 0;
   677 
   678             //and there is activated map
   679             if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   680             {
   681               //activate the general variable for it
   682               active_edge=clicked_edge;
   683 
   684               //create a dialog
   685               Gtk::Dialog dialog("Edit value", true);
   686               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   687               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   688               Gtk::VBox* vbox = dialog.get_vbox();
   689               Gtk::SpinButton spin(0.0, 4);
   690               spin.set_increments(1.0, 10.0);
   691               spin.set_range(-1000000.0, 1000000.0);
   692               spin.set_numeric(true);
   693               vbox->add(spin);
   694               spin.show();
   695               switch (dialog.run())
   696               {
   697                 case Gtk::RESPONSE_NONE:
   698                 case Gtk::RESPONSE_CANCEL:
   699                   break;
   700                 case Gtk::RESPONSE_ACCEPT:
   701                   double new_value = spin.get_value();
   702                   (*(mytab.mapstorage).edgemap_storage[edgemap_to_edit])[active_edge] =
   703                     new_value;
   704                   std::ostringstream ostr;
   705                   ostr << new_value;
   706                   edgetextmap[active_edge]->property_text().set_value(
   707                       ostr.str());
   708                   //mapwin.updateEdge(active_edge);
   709 //                   mapwin.updateEdge(Edge(INVALID));
   710                   propertyUpdate(Edge(INVALID));
   711               }
   712             }
   713           }
   714           break;
   715         }
   716       default:
   717         break;
   718     }
   719   }
   720   return false;  
   721 }
   722 
   723 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   724 {
   725   if(actual_tool==NODE_MAP_EDIT)
   726   {
   727     switch(e->type)
   728     {
   729       case GDK_BUTTON_PRESS:
   730         {
   731           //for determine, whether it was a node
   732           Node clicked_node=INVALID;
   733 
   734           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   735           active_item=(get_item_at(clicked_x, clicked_y));
   736 
   737           //find the activated item between texts
   738           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   739           {
   740             //at the same time only one can be active
   741             if(nodetextmap[i]==active_item)
   742             {
   743               clicked_node=i;
   744             }
   745           }
   746 
   747           //if there was not, search for it between nodes
   748           if(clicked_node==INVALID)
   749           {
   750             for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   751             {
   752               //at the same time only one can be active
   753               if(nodesmap[i]==active_item)
   754               {
   755                 clicked_node=i;
   756               }
   757             }
   758           }
   759 
   760           //if it was really a node...
   761           if(clicked_node!=INVALID)
   762           {
   763             // the id map is not editable
   764             if (nodemap_to_edit == "id") return 0;
   765 
   766             //and there is activated map
   767             if(nodetextmap[clicked_node]->property_text().get_value()!="")
   768             {
   769               //activate the general variable for it
   770               active_node=clicked_node;
   771 
   772               //create a dialog
   773               Gtk::Dialog dialog("Edit value", true);
   774               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   775               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   776               Gtk::VBox* vbox = dialog.get_vbox();
   777               Gtk::SpinButton spin(0.0, 4);
   778               spin.set_increments(1.0, 10.0);
   779               spin.set_range(-1000000.0, 1000000.0);
   780               spin.set_numeric(true);
   781               vbox->add(spin);
   782               spin.show();
   783               switch (dialog.run())
   784               {
   785                 case Gtk::RESPONSE_NONE:
   786                 case Gtk::RESPONSE_CANCEL:
   787                   break;
   788                 case Gtk::RESPONSE_ACCEPT:
   789                   double new_value = spin.get_value();
   790                   (*(mytab.mapstorage).nodemap_storage[nodemap_to_edit])[active_node] =
   791                     new_value;
   792                   std::ostringstream ostr;
   793                   ostr << new_value;
   794                   nodetextmap[active_node]->property_text().set_value(
   795                       ostr.str());
   796                   //mapwin.updateNode(active_node);
   797 //                   mapwin.updateNode(Node(INVALID));
   798                   propertyUpdate(Node(INVALID));
   799               }
   800             }
   801           }
   802           break;
   803         }
   804       default:
   805         break;
   806     }
   807   }
   808   return false;  
   809 }
   810 
   811 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   812 {
   813   delete(nodetextmap[node_to_delete]);
   814   delete(nodesmap[node_to_delete]);
   815   (mytab.mapstorage).graph.erase(node_to_delete);
   816 }
   817 
   818 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   819 {
   820   delete(edgetextmap[edge_to_delete]);
   821   delete(edgesmap[edge_to_delete]);
   822   (mytab.mapstorage).graph.erase(edge_to_delete);
   823 }
   824 
   825 void GraphDisplayerCanvas::textReposition(xy<double> new_place)
   826 {
   827   new_place+=(xy<double>(10,10));
   828   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   829   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   830 }
   831 
   832 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
   833 {
   834   if(on)
   835     {
   836       if(forming_edge!=INVALID)
   837 	{
   838 	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   839 	}
   840       else
   841 	{
   842 	  for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   843 	    {
   844 	      if(edgesmap[i]==active_bre)
   845 		{
   846 		  forming_edge=i;
   847 		}
   848 	    }
   849 	}
   850     }
   851   else
   852     {
   853       if(forming_edge!=INVALID)
   854 	{
   855 	  forming_edge=INVALID;
   856 	}
   857       else
   858 	{
   859 	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   860 	}
   861     }
   862 }