graph_displayer_canvas-event.cc
author ladanyi
Mon, 25 Sep 2006 07:54:00 +0000
changeset 151 72f1c33f89d4
parent 150 86273bfe0e4d
child 153 d79a71382836
permissions -rwxr-xr-x
LoopEdge improvements.
     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(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 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 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 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 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 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 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 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 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 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(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             (mytab.mapstorage).modified = true;
   413 
   414             *(nodesmap[target_node]) <<
   415               Gnome::Canvas::Properties::fill_color("red");
   416 
   417             //creating new edge
   418             active_edge=(mytab.mapstorage).graph.addEdge(active_node,
   419                 target_node);
   420 
   421             // update maps
   422             for (std::map<std::string,
   423                 Graph::EdgeMap<double>*>::const_iterator it =
   424                 (mytab.mapstorage).edgemap_storage.begin(); it !=
   425                 (mytab.mapstorage).edgemap_storage.end(); ++it)
   426             {
   427               (*(it->second))[active_edge] =
   428                 (mytab.mapstorage).edgemap_default[it->first];
   429             }
   430             // increment the id map's default value
   431             (mytab.mapstorage).edgemap_default["label"] += 1.0;
   432 
   433             if(target_node!=active_node)		
   434             {
   435               // set the coordinates of the arrow on the new edge
   436               MapStorage& ms = mytab.mapstorage;
   437               ms.arrow_pos.set(active_edge,
   438                   (ms.coords[ms.graph.source(active_edge)] +
   439                    ms.coords[ms.graph.target(active_edge)])/ 2.0);
   440 
   441               //drawing new edge
   442               edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
   443                   *this);
   444             }
   445             else
   446             {
   447               // set the coordinates of the arrow on the new edge
   448               MapStorage& ms = mytab.mapstorage;
   449               ms.arrow_pos.set(active_edge,
   450                   (ms.coords[ms.graph.source(active_edge)] +
   451                    XY(0.0, 80.0)));
   452 
   453               //drawing new edge
   454               edgesmap[active_edge]=new LoopEdge(displayed_graph, active_edge,
   455                   *this);
   456             }
   457 
   458             //initializing edge-text as well, to empty string
   459             XY text_pos=mytab.mapstorage.arrow_pos[active_edge];
   460             text_pos+=(XY(10,10));
   461 
   462             edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   463                 text_pos.x, text_pos.y, "");
   464             edgetextmap[active_edge]->property_fill_color().set_value(
   465                 "darkgreen");
   466             edgetextmap[active_edge]->raise_to_top();
   467 
   468             propertyUpdate(active_edge);
   469           }
   470           //clicked item was not a node. it could be an e.g. edge. we do not
   471           //deal with it furthermore.
   472           else
   473           {
   474             target_item=NULL;
   475           }
   476         }
   477       }
   478       break;
   479     case GDK_BUTTON_RELEASE:
   480       isbutton=0;
   481       //we clear settings in two cases
   482       //1: the edge is ready (target_item has valid value)
   483       //2: the edge creation is cancelled with right button
   484       if((target_item)||(e->button.button==3))
   485       {
   486         if(active_item)
   487         {
   488           *active_item << Gnome::Canvas::Properties::fill_color("blue");
   489           active_item=NULL;
   490         }
   491         if(target_item)
   492         {
   493           *target_item << Gnome::Canvas::Properties::fill_color("blue");
   494           target_item=NULL;
   495         }
   496         active_node=INVALID;
   497         active_edge=INVALID;
   498       }
   499       break;
   500     default:
   501       break;
   502   }
   503   return false;
   504 }
   505 
   506 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   507 {
   508   switch(e->type)
   509     {
   510     case GDK_BUTTON_PRESS:
   511       //finding the clicked items
   512       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   513       active_item=(get_item_at(clicked_x, clicked_y));
   514       active_node=INVALID;
   515       active_edge=INVALID;
   516       //was it a node?
   517       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   518 	{
   519 	  if(nodesmap[i]==active_item)
   520 	    {
   521 	      active_node=i;
   522 	    }
   523 	}
   524       //or was it an edge?
   525       if(active_node==INVALID)
   526 	{
   527 	  for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   528 	    {
   529 	      if(edgesmap[i]==active_item)
   530 		{
   531 		  active_edge=i;
   532 		}
   533 	    }
   534 	}
   535 
   536       // return if the clicked object is neither an edge nor a node
   537       if (active_edge == INVALID) return false;
   538       
   539       //recolor activated item
   540       if(active_item)
   541 	{
   542 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   543 	}
   544       break;
   545 
   546     case GDK_BUTTON_RELEASE:
   547       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   548       if(active_item)
   549 	{
   550 	  //the cursor was not moved since pressing it
   551 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   552 	    {
   553 	      //a node was found
   554 	      if(active_node!=INVALID)
   555 		{
   556                   (mytab.mapstorage).modified = true;
   557 
   558 		  std::set<Graph::Edge> edges_to_delete;
   559 
   560 		  for(OutEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   561 		    {
   562 		      edges_to_delete.insert(e);
   563 		    }
   564 		  
   565 		  for(InEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   566 		    {
   567 		      edges_to_delete.insert(e);
   568 		    }
   569 		  
   570 		  //deleting collected edges
   571 		  for(std::set<Graph::Edge>::iterator
   572 			edge_set_it=edges_to_delete.begin();
   573 		      edge_set_it!=edges_to_delete.end();
   574 		      ++edge_set_it)
   575 		    {
   576 		      deleteItem(*edge_set_it);
   577 		    }
   578 		  deleteItem(active_node);
   579 		}
   580 	      //a simple edge was chosen
   581 	      else if (active_edge != INVALID)
   582 		{
   583 		  deleteItem(active_edge);
   584 		}
   585 	    }
   586 	  //pointer was moved, deletion is cancelled
   587 	  else
   588 	    {
   589 	      if(active_node!=INVALID)
   590 		{
   591 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   592 		}
   593 	      else if (active_edge != INVALID)
   594 		{
   595 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   596 		}
   597 	    }
   598 	}
   599       //reseting datas
   600       active_item=NULL;
   601       active_edge=INVALID;
   602       active_node=INVALID;
   603       break;
   604 
   605     case GDK_MOTION_NOTIFY:
   606       break;
   607 
   608     default:
   609       break;
   610     }
   611   return false;
   612 }
   613 
   614 bool GraphDisplayerCanvas::mapEditEventHandler(GdkEvent* e)
   615 {
   616   if(actual_tool==MAP_EDIT)
   617     {
   618       switch(e->type)
   619 	{
   620 	case GDK_BUTTON_PRESS:
   621 	  {
   622 	    //for determine, whether it was an edge
   623 	    Edge clicked_edge=INVALID;
   624 	    //for determine, whether it was a node
   625 	    Node clicked_node=INVALID;
   626 
   627 	    window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   628 	    active_item=(get_item_at(clicked_x, clicked_y));
   629 
   630 	    //find the activated item between text of nodes
   631 	    for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   632 	      {
   633 		//at the same time only one can be active
   634 		if(nodetextmap[i]==active_item)
   635 		  {
   636 		    clicked_node=i;
   637 		  }
   638 	      }
   639 
   640 	    //if there was not, search for it between nodes
   641 	    if(clicked_node==INVALID)
   642 	      {
   643 		for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   644 		  {
   645 		    //at the same time only one can be active
   646 		    if(nodesmap[i]==active_item)
   647 		      {
   648 			clicked_node=i;
   649 		      }
   650 		  }
   651 	      }
   652 
   653 	    if(clicked_node==INVALID)
   654 	      {
   655 		//find the activated item between texts
   656 		for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   657 		  {
   658 		    //at the same time only one can be active
   659 		    if(edgetextmap[i]==active_item)
   660 		      {
   661 			clicked_edge=i;
   662 		      }
   663 		  }
   664 
   665 		//if it was not between texts, search for it between edges
   666 		if(clicked_edge==INVALID)
   667 		  {
   668 		    for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   669 		      {
   670 			//at the same time only one can be active
   671 			if((edgesmap[i]->getLine())==active_item)
   672 			  {
   673 			    clicked_edge=i;
   674 			  }
   675 		      }
   676 		  }
   677 	      }
   678 
   679 	    //if it was really a node...
   680 	    if(clicked_node!=INVALID)
   681 	      {
   682 		// the id map is not editable
   683 		if (nodemap_to_edit == "label") return 0;
   684 
   685 		//and there is activated map
   686 		if(nodetextmap[clicked_node]->property_text().get_value()!="")
   687 		  {
   688 		    //activate the general variable for it
   689 		    active_node=clicked_node;
   690 
   691 		    //create a dialog
   692 		    Gtk::Dialog dialog("Edit value", true);
   693 		    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   694 		    dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   695 		    Gtk::VBox* vbox = dialog.get_vbox();
   696 		    Gtk::SpinButton spin(0.0, 4);
   697 		    spin.set_increments(1.0, 10.0);
   698 		    spin.set_range(-1000000.0, 1000000.0);
   699 		    spin.set_numeric(true);
   700 		    spin.set_value(atof(nodetextmap[active_node]->property_text().get_value().c_str()));
   701 		    vbox->add(spin);
   702 		    spin.show();
   703 		    switch (dialog.run())
   704 		      {
   705 		      case Gtk::RESPONSE_NONE:
   706 		      case Gtk::RESPONSE_CANCEL:
   707 			break;
   708 		      case Gtk::RESPONSE_ACCEPT:
   709 			double new_value = spin.get_value();
   710 			(*(mytab.mapstorage).nodemap_storage[nodemap_to_edit])[active_node] =
   711 			  new_value;
   712 			std::ostringstream ostr;
   713 			ostr << new_value;
   714 			nodetextmap[active_node]->property_text().set_value(ostr.str());
   715 			//mapwin.updateNode(active_node);
   716 			//mapwin.updateNode(Node(INVALID));
   717 			propertyUpdate(Node(INVALID));
   718 		      }
   719 		  }
   720 	      }
   721 	    else
   722 	      //if it was really an edge...
   723 	      if(clicked_edge!=INVALID)
   724 		{
   725 		  // the id map is not editable
   726 		  if (edgemap_to_edit == "label") return 0;
   727 
   728 		  //and there is activated map
   729 		  if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   730 		    {
   731 		      //activate the general variable for it
   732 		      active_edge=clicked_edge;
   733 
   734 		      //create a dialog
   735 		      Gtk::Dialog dialog("Edit value", true);
   736 		      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   737 		      dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   738 		      Gtk::VBox* vbox = dialog.get_vbox();
   739 		      Gtk::SpinButton spin(0.0, 4);
   740 		      spin.set_increments(1.0, 10.0);
   741 		      spin.set_range(-1000000.0, 1000000.0);
   742 		      spin.set_numeric(true);
   743 		      spin.set_value(atof(edgetextmap[active_edge]->property_text().get_value().c_str()));
   744 		      vbox->add(spin);
   745 		      spin.show();
   746 		      switch (dialog.run())
   747 			{
   748 			case Gtk::RESPONSE_NONE:
   749 			case Gtk::RESPONSE_CANCEL:
   750 			  break;
   751 			case Gtk::RESPONSE_ACCEPT:
   752 			  double new_value = spin.get_value();
   753 			  (*(mytab.mapstorage).edgemap_storage[edgemap_to_edit])[active_edge] =
   754 			    new_value;
   755 			  std::ostringstream ostr;
   756 			  ostr << new_value;
   757 			  edgetextmap[active_edge]->property_text().set_value(
   758 									      ostr.str());
   759 			  //mapwin.updateEdge(active_edge);
   760 			  //                   mapwin.updateEdge(Edge(INVALID));
   761 			  propertyUpdate(Edge(INVALID));
   762 			}
   763 		    }
   764 		}
   765 	    break;
   766 	  }
   767 	default:
   768 	  break;
   769 	}
   770     }
   771   return false;  
   772 }
   773 
   774 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   775 {
   776   delete(nodetextmap[node_to_delete]);
   777   delete(nodesmap[node_to_delete]);
   778   (mytab.mapstorage).graph.erase(node_to_delete);
   779 }
   780 
   781 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   782 {
   783   delete(edgetextmap[edge_to_delete]);
   784   delete(edgesmap[edge_to_delete]);
   785   (mytab.mapstorage).graph.erase(edge_to_delete);
   786 }
   787 
   788 void GraphDisplayerCanvas::textReposition(XY new_place)
   789 {
   790   new_place+=(XY(10,10));
   791   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   792   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   793 }
   794 
   795 void GraphDisplayerCanvas::toggleEdgeActivity(EdgeBase* active_bre, bool on)
   796 {
   797   if(on)
   798   {
   799     if(forming_edge!=INVALID)
   800     {
   801       std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   802     }
   803     else
   804     {
   805       for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   806       {
   807         if(edgesmap[i]==active_bre)
   808         {
   809           forming_edge=i;
   810         }
   811       }
   812     }
   813   }
   814   else
   815   {
   816     if(forming_edge!=INVALID)
   817     {
   818       forming_edge=INVALID;
   819     }
   820     else
   821     {
   822       std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   823     }
   824   }
   825 }