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