graph_displayer_canvas-event.cc
author hegyi
Thu, 05 Jan 2006 12:30:09 +0000
branchgui
changeset 108 bf355fd6563e
parent 96 e664d8aa3f72
child 109 9f8dc346ac6e
permissions -rwxr-xr-x
Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
     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               //drawing new edge
   457               edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
   458                   *this);
   459               *(edgesmap[active_edge]) <<
   460                 Gnome::Canvas::Properties::fill_color("green");
   461               edgesmap[active_edge]->property_width_pixels().set_value(10);
   462 
   463               edgesmap[active_edge]->lower_to_bottom();
   464 
   465               //initializing edge-text as well, to empty string
   466               XY text_pos=mytab.mapstorage.arrow_pos[active_edge];
   467               text_pos+=(XY(10,10));
   468 
   469               edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   470                   text_pos.x, text_pos.y, "");
   471               edgetextmap[active_edge]->property_fill_color().set_value(
   472                   "darkgreen");
   473               edgetextmap[active_edge]->raise_to_top();
   474 
   475               //updating its properties
   476 //               mapwin.updateEdge(active_edge);
   477               propertyUpdate(active_edge);
   478             }
   479             else
   480             {
   481               target_node=INVALID;
   482               std::cerr << "Loop edge is not yet implemented!" << std::endl;
   483             }
   484           }
   485           //clicked item was not a node. it could be an e.g. edge. we do not
   486           //deal with it furthermore.
   487           else
   488           {
   489             target_item=NULL;
   490           }
   491         }
   492       }
   493       break;
   494     case GDK_BUTTON_RELEASE:
   495       isbutton=0;
   496       //we clear settings in two cases
   497       //1: the edge is ready (target_item has valid value)
   498       //2: the edge creation is cancelled with right button
   499       if((target_item)||(e->button.button==3))
   500       {
   501         if(active_item)
   502         {
   503           *active_item << Gnome::Canvas::Properties::fill_color("blue");
   504           active_item=NULL;
   505         }
   506         if(target_item)
   507         {
   508           *target_item << Gnome::Canvas::Properties::fill_color("blue");
   509           target_item=NULL;
   510         }
   511         active_node=INVALID;
   512         active_edge=INVALID;
   513       }
   514       break;
   515     default:
   516       break;
   517   }
   518   return false;
   519 }
   520 
   521 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   522 {
   523   switch(e->type)
   524     {
   525     case GDK_BUTTON_PRESS:
   526       //finding the clicked items
   527       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   528       active_item=(get_item_at(clicked_x, clicked_y));
   529       active_node=INVALID;
   530       active_edge=INVALID;
   531       //was it a node?
   532       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   533 	{
   534 	  if(nodesmap[i]==active_item)
   535 	    {
   536 	      active_node=i;
   537 	    }
   538 	}
   539       //or was it an edge?
   540       if(active_node==INVALID)
   541 	{
   542 	  for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   543 	    {
   544 	      if(edgesmap[i]==active_item)
   545 		{
   546 		  active_edge=i;
   547 		}
   548 	    }
   549 	}
   550 
   551       //recolor activated item
   552       if(active_item)
   553 	{
   554 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   555 	}
   556       break;
   557 
   558     case GDK_BUTTON_RELEASE:
   559       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   560       if(active_item)
   561 	{
   562 	  //the cursor was not moved since pressing it
   563 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   564 	    {
   565 	      //a node was found
   566 	      if(active_node!=INVALID)
   567 		{
   568                   (mytab.mapstorage).modified = true;
   569 
   570 		  std::set<Graph::Edge> edges_to_delete;
   571 
   572 		  for(OutEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   573 		    {
   574 		      edges_to_delete.insert(e);
   575 		    }
   576 		  
   577 		  for(InEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
   578 		    {
   579 		      edges_to_delete.insert(e);
   580 		    }
   581 		  
   582 		  //deleting collected edges
   583 		  for(std::set<Graph::Edge>::iterator
   584 			edge_set_it=edges_to_delete.begin();
   585 		      edge_set_it!=edges_to_delete.end();
   586 		      ++edge_set_it)
   587 		    {
   588 		      deleteItem(*edge_set_it);
   589 		    }
   590 		  deleteItem(active_node);
   591 		}
   592 	      //a simple edge was chosen
   593 	      else
   594 		{
   595 		  deleteItem(active_edge);
   596 		}
   597 	    }
   598 	  //pointer was moved, deletion is cancelled
   599 	  else
   600 	    {
   601 	      if(active_node!=INVALID)
   602 		{
   603 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   604 		}
   605 	      else
   606 		{
   607 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   608 		}
   609 	    }
   610 	}
   611       //reseting datas
   612       active_item=NULL;
   613       active_edge=INVALID;
   614       active_node=INVALID;
   615       break;
   616 
   617     case GDK_MOTION_NOTIFY:
   618       break;
   619 
   620     default:
   621       break;
   622     }
   623   return false;
   624 }
   625 
   626 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   627 {
   628   if(actual_tool==EDGE_MAP_EDIT)
   629   {
   630     switch(e->type)
   631     {
   632       case GDK_BUTTON_PRESS:
   633         {
   634           //for determine, whether it was an edge
   635           Edge clicked_edge=INVALID;
   636 
   637           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   638           active_item=(get_item_at(clicked_x, clicked_y));
   639 
   640           //find the activated item between texts
   641           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   642           {
   643             //at the same time only one can be active
   644             if(edgetextmap[i]==active_item)
   645             {
   646               clicked_edge=i;
   647             }
   648           }
   649 
   650           //if it was not between texts, search for it between edges
   651           if(clicked_edge==INVALID)
   652           {
   653             for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   654             {
   655               //at the same time only one can be active
   656               if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   657               {
   658                 clicked_edge=i;
   659               }
   660             }
   661           }
   662  
   663           //if it was really an edge...
   664           if(clicked_edge!=INVALID)
   665           {
   666             // the id map is not editable
   667             if (edgemap_to_edit == "id") return 0;
   668 
   669             //and there is activated map
   670             if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   671             {
   672               //activate the general variable for it
   673               active_edge=clicked_edge;
   674 
   675               //create a dialog
   676               Gtk::Dialog dialog("Edit value", true);
   677               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   678               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   679               Gtk::VBox* vbox = dialog.get_vbox();
   680               Gtk::SpinButton spin(0.0, 4);
   681               spin.set_increments(1.0, 10.0);
   682               spin.set_range(-1000000.0, 1000000.0);
   683               spin.set_numeric(true);
   684               vbox->add(spin);
   685               spin.show();
   686               switch (dialog.run())
   687               {
   688                 case Gtk::RESPONSE_NONE:
   689                 case Gtk::RESPONSE_CANCEL:
   690                   break;
   691                 case Gtk::RESPONSE_ACCEPT:
   692                   double new_value = spin.get_value();
   693                   (*(mytab.mapstorage).edgemap_storage[edgemap_to_edit])[active_edge] =
   694                     new_value;
   695                   std::ostringstream ostr;
   696                   ostr << new_value;
   697                   edgetextmap[active_edge]->property_text().set_value(
   698                       ostr.str());
   699                   //mapwin.updateEdge(active_edge);
   700 //                   mapwin.updateEdge(Edge(INVALID));
   701                   propertyUpdate(Edge(INVALID));
   702               }
   703             }
   704           }
   705           break;
   706         }
   707       default:
   708         break;
   709     }
   710   }
   711   return false;  
   712 }
   713 
   714 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   715 {
   716   if(actual_tool==NODE_MAP_EDIT)
   717   {
   718     switch(e->type)
   719     {
   720       case GDK_BUTTON_PRESS:
   721         {
   722           //for determine, whether it was a node
   723           Node clicked_node=INVALID;
   724 
   725           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   726           active_item=(get_item_at(clicked_x, clicked_y));
   727 
   728           //find the activated item between texts
   729           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   730           {
   731             //at the same time only one can be active
   732             if(nodetextmap[i]==active_item)
   733             {
   734               clicked_node=i;
   735             }
   736           }
   737 
   738           //if there was not, search for it between nodes
   739           if(clicked_node==INVALID)
   740           {
   741             for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   742             {
   743               //at the same time only one can be active
   744               if(nodesmap[i]==active_item)
   745               {
   746                 clicked_node=i;
   747               }
   748             }
   749           }
   750 
   751           //if it was really a node...
   752           if(clicked_node!=INVALID)
   753           {
   754             // the id map is not editable
   755             if (nodemap_to_edit == "id") return 0;
   756 
   757             //and there is activated map
   758             if(nodetextmap[clicked_node]->property_text().get_value()!="")
   759             {
   760               //activate the general variable for it
   761               active_node=clicked_node;
   762 
   763               //create a dialog
   764               Gtk::Dialog dialog("Edit value", true);
   765               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   766               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   767               Gtk::VBox* vbox = dialog.get_vbox();
   768               Gtk::SpinButton spin(0.0, 4);
   769               spin.set_increments(1.0, 10.0);
   770               spin.set_range(-1000000.0, 1000000.0);
   771               spin.set_numeric(true);
   772               vbox->add(spin);
   773               spin.show();
   774               switch (dialog.run())
   775               {
   776                 case Gtk::RESPONSE_NONE:
   777                 case Gtk::RESPONSE_CANCEL:
   778                   break;
   779                 case Gtk::RESPONSE_ACCEPT:
   780                   double new_value = spin.get_value();
   781                   (*(mytab.mapstorage).nodemap_storage[nodemap_to_edit])[active_node] =
   782                     new_value;
   783                   std::ostringstream ostr;
   784                   ostr << new_value;
   785                   nodetextmap[active_node]->property_text().set_value(
   786                       ostr.str());
   787                   //mapwin.updateNode(active_node);
   788 //                   mapwin.updateNode(Node(INVALID));
   789                   propertyUpdate(Node(INVALID));
   790               }
   791             }
   792           }
   793           break;
   794         }
   795       default:
   796         break;
   797     }
   798   }
   799   return false;  
   800 }
   801 
   802 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   803 {
   804   delete(nodetextmap[node_to_delete]);
   805   delete(nodesmap[node_to_delete]);
   806   (mytab.mapstorage).graph.erase(node_to_delete);
   807 }
   808 
   809 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   810 {
   811   delete(edgetextmap[edge_to_delete]);
   812   delete(edgesmap[edge_to_delete]);
   813   (mytab.mapstorage).graph.erase(edge_to_delete);
   814 }
   815 
   816 void GraphDisplayerCanvas::textReposition(xy<double> new_place)
   817 {
   818   new_place+=(xy<double>(10,10));
   819   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   820   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   821 }
   822 
   823 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
   824 {
   825   if(on)
   826     {
   827       if(forming_edge!=INVALID)
   828 	{
   829 	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   830 	}
   831       else
   832 	{
   833 	  for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   834 	    {
   835 	      if(edgesmap[i]==active_bre)
   836 		{
   837 		  forming_edge=i;
   838 		}
   839 	    }
   840 	}
   841     }
   842   else
   843     {
   844       if(forming_edge!=INVALID)
   845 	{
   846 	  forming_edge=INVALID;
   847 	}
   848       else
   849 	{
   850 	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   851 	}
   852     }
   853 
   854 }
   855 
   856 int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
   857 {
   858   //create the new map
   859   Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> ((mytab.mapstorage).graph, default_value);
   860 
   861   //if addition was not successful addEdgeMap returns one.
   862   //cause can be that there is already a map named like the new one
   863   if((mytab.mapstorage).addEdgeMap(mapname,emptr, default_value))
   864     {
   865       return 1;
   866     }
   867 
   868 
   869   //add it to the list of the displayable maps
   870   mytab.registerNewEdgeMap(mapname);
   871 
   872   //display it
   873   changeEdgeText(mapname);
   874 
   875   return 0;
   876 }
   877 
   878 int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
   879 {
   880   //create the new map
   881   Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> ((mytab.mapstorage).graph,default_value);
   882 
   883   //if addition was not successful addNodeMap returns one.
   884   //cause can be that there is already a map named like the new one
   885   if((mytab.mapstorage).addNodeMap(mapname,emptr, default_value))
   886     {
   887       return 1;
   888     }
   889 
   890   //add it to the list of the displayable maps
   891   mytab.registerNewNodeMap(mapname);
   892 
   893   //display it
   894   changeNodeText(mapname);
   895 
   896   return 0;
   897 }
   898