graph_displayer_canvas-event.cc
author ladanyi
Tue, 23 Aug 2005 15:57:12 +0000
branchgui
changeset 64 7a32d528857f
parent 63 59768817442a
child 65 1b8e20c04704
permissions -rwxr-xr-x
- handle the case when there is no id map in the edgeset section
- do not use ListGraph.id() to determine the id of a new node/edge
     1 #include "graph_displayer_canvas.h"
     2 #include "broken_edge.h"
     3 #include <cmath>
     4 
     5 
     6 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
     7 {
     8   Gnome::Canvas::CanvasAA::on_expose_event(event);
     9   //usleep(10000);
    10   //rezoom();
    11   return true;
    12 }
    13 
    14 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
    15 {
    16   if(actual_tool!=newtool)
    17     {
    18 
    19       actual_handler.disconnect();
    20 
    21       switch(actual_tool)
    22 	{
    23 	case CREATE_EDGE:
    24 	  {
    25 	    GdkEvent * generated=new GdkEvent();
    26 	    generated->type=GDK_BUTTON_RELEASE;
    27 	    generated->button.button=3;
    28 	    createEdgeEventHandler(generated);      
    29 	    break;
    30 	  }
    31 	case EDGE_MAP_EDIT:
    32 	  //has to do the same thing as in the case of NODE_MAP_EDIT
    33 	case NODE_MAP_EDIT:
    34 	  {
    35 	    GdkEvent * generated=new GdkEvent();
    36 	    generated->type=GDK_KEY_PRESS;
    37 	    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
    38 	    entryWidgetChangeHandler(generated);
    39 	    entrywidget.hide();
    40 	    break;
    41 	  }
    42 	default:
    43 	  break;
    44 	}
    45 
    46       active_item=NULL; 
    47       target_item=NULL; 
    48       active_edge=INVALID;	
    49       active_node=INVALID;	
    50 
    51 
    52       actual_tool=newtool;
    53   
    54       switch(newtool)
    55 	{
    56 	case MOVE:
    57 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
    58 	  break;
    59 
    60 	case CREATE_NODE:
    61 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
    62 	  break;
    63 
    64 	case CREATE_EDGE:
    65 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
    66 	  break;
    67 
    68 	case ERASER:
    69 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
    70 	  break;
    71 
    72 	case EDGE_MAP_EDIT:
    73 	  grab_focus();
    74 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false);
    75 	  break;
    76 
    77 	case NODE_MAP_EDIT:
    78 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false);
    79 	  break;
    80 
    81 	default:
    82 	  break;
    83 	}
    84     }
    85 }
    86 
    87 int GraphDisplayerCanvas::getActualTool()
    88 {
    89   return actual_tool;
    90 }
    91 
    92 bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
    93 {
    94   switch(e->type)
    95   {
    96     case GDK_BUTTON_PRESS:
    97       //we mark the location of the event to be able to calculate parameters of dragging
    98       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
    99 
   100       active_item=(get_item_at(clicked_x, clicked_y));
   101       active_node=INVALID;
   102       for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   103 	{
   104 	  if(nodesmap[i]==active_item)
   105 	    {
   106 	      active_node=i;
   107 	    }
   108 	}
   109       switch(e->button.button)
   110 	{
   111 	case 3:      
   112 	  isbutton=3;
   113 	  break;
   114 	default:
   115 	  isbutton=1;
   116 	  break;
   117 	}
   118       break;
   119     case GDK_BUTTON_RELEASE:
   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         mapstorage.modified = true;
   129         mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
   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         clicked_x=new_x;
   147         clicked_y=new_y;
   148 
   149 	//all the edges connected to the moved point has to be redrawn
   150         EdgeIt ei;
   151 
   152         mapstorage.graph.firstOut(ei,active_node);
   153 
   154         for(;ei!=INVALID;mapstorage.graph.nextOut(ei))
   155         {
   156             Gnome::Canvas::Points coos;
   157             double x1, x2, y1, y2;
   158 
   159             nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
   160             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   161 
   162             nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
   163             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   164 
   165 	    if(isbutton==3)
   166 	      {
   167 		edgesmap[ei]->setPoints(coos);
   168 	      }
   169 	    else
   170 	      {
   171 		edgesmap[ei]->setPoints(coos,true);
   172 	      }
   173 
   174 	    //reposition of edgetext
   175 	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
   176 	    text_pos+=(xy<double>(10,10));
   177 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   178 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   179         }
   180 
   181         mapstorage.graph.firstIn(ei,active_node);
   182         for(;ei!=INVALID;mapstorage.graph.nextIn(ei))
   183         {
   184             Gnome::Canvas::Points coos;
   185             double x1, x2, y1, y2;
   186 
   187             nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
   188             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   189 
   190             nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
   191             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   192 
   193 	    if(isbutton==3)
   194 	      {
   195 		edgesmap[ei]->setPoints(coos);
   196 	      }
   197 	    else
   198 	      {
   199 		edgesmap[ei]->setPoints(coos,true);
   200 	      }
   201 
   202 	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
   203 	    text_pos+=(xy<double>(10,10));
   204 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   205 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   206         }
   207       }
   208     default: break;
   209   }
   210 
   211   return false;
   212 }
   213 
   214 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
   215 {
   216   switch(e->type)
   217   {
   218     //move the new node
   219     case GDK_MOTION_NOTIFY:
   220       {
   221         GdkEvent * generated=new GdkEvent();
   222         generated->motion.x=e->motion.x;
   223         generated->motion.y=e->motion.y;
   224         generated->type=GDK_MOTION_NOTIFY;
   225         moveEventHandler(generated);      
   226         break;
   227       }
   228 
   229     case GDK_BUTTON_RELEASE:
   230       mapstorage.modified = true;
   231 
   232       isbutton=1;
   233 
   234       active_node=mapstorage.graph.addNode();
   235 
   236       //initiating values corresponding to new node in maps
   237 
   238       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   239 
   240       // update coordinates
   241       mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
   242 
   243       // update all other maps
   244       for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
   245           mapstorage.nodemap_storage.begin(); it !=
   246           mapstorage.nodemap_storage.end(); ++it)
   247       {
   248         if ((it->first != "coordinates_x") &&
   249             (it->first != "coordinates_y"))
   250         {
   251           (*(it->second))[active_node] =
   252             mapstorage.nodemap_default[it->first];
   253         }
   254       }
   255       // increment the id map's default value
   256       mapstorage.nodemap_default["id"] += 1.0;
   257 
   258       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
   259           clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
   260       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   261       *(nodesmap[active_node]) <<
   262         Gnome::Canvas::Properties::fill_color("blue");
   263       *(nodesmap[active_node]) <<
   264         Gnome::Canvas::Properties::outline_color("black");
   265       active_item->raise_to_top();
   266 
   267       (nodesmap[active_node])->show();
   268 
   269       nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
   270           clicked_x+node_property_defaults[N_RADIUS]+5,
   271           clicked_y+node_property_defaults[N_RADIUS]+5, "");
   272       nodetextmap[active_node]->property_fill_color().set_value("darkblue");
   273       nodetextmap[active_node]->raise_to_top();
   274 
   275       mapwin.updateNode(active_node);
   276 
   277       isbutton=0;
   278       target_item=NULL;
   279       active_item=NULL;
   280       active_node=INVALID;
   281 
   282       break;
   283     default:
   284       break;
   285   }
   286   return false;
   287 }
   288 
   289 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
   290 {
   291   switch(e->type)
   292   {
   293     case GDK_BUTTON_PRESS:
   294       //in edge creation right button has special meaning
   295       if(e->button.button!=3)
   296       {
   297         //there is not yet selected node
   298         if(active_node==INVALID)
   299         {
   300           //we mark the location of the event to be able to calculate parameters of dragging
   301 
   302           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   303 
   304           active_item=(get_item_at(clicked_x, clicked_y));
   305           active_node=INVALID;
   306           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   307           {
   308             if(nodesmap[i]==active_item)
   309             {
   310               active_node=i;
   311             }
   312           }
   313           //the clicked item is really a node
   314           if(active_node!=INVALID)
   315           {
   316             *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   317             isbutton=1;
   318           }
   319           //clicked item was not a node. It could be e.g. edge.
   320           else
   321           {
   322             active_item=NULL;
   323           }
   324         }
   325         //we only have to do sg. if the mouse button
   326         // is pressed already once AND the click was
   327         // on a node that was found in the set of 
   328         //nodes, and now we only search for the second 
   329         //node
   330         else
   331         {
   332           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   333           target_item=(get_item_at(clicked_x, clicked_y));
   334           Node target_node=INVALID;
   335           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   336           {
   337             if(nodesmap[i]==target_item)
   338             {
   339               target_node=i;
   340             }
   341           }
   342           //the clicked item is a node, the edge can be drawn
   343           if(target_node!=INVALID)
   344           {
   345             if(target_node!=active_node)		
   346             {
   347               mapstorage.modified = true;
   348 
   349               *(nodesmap[target_node]) <<
   350                 Gnome::Canvas::Properties::fill_color("red");
   351 
   352               //creating new edge
   353               active_edge=mapstorage.graph.addEdge(active_node,
   354                   target_node);
   355 
   356               // update maps
   357               for (std::map<std::string,
   358                   Graph::EdgeMap<double>*>::const_iterator it =
   359                   mapstorage.edgemap_storage.begin(); it !=
   360                   mapstorage.edgemap_storage.end(); ++it)
   361               {
   362                 (*(it->second))[active_edge] =
   363                   mapstorage.edgemap_default[it->first];
   364               }
   365               // increment the id map's default value
   366               mapstorage.edgemap_default["id"] += 1.0;
   367 
   368               //calculating coordinates of new edge
   369               Gnome::Canvas::Points coos;
   370               double x1, x2, y1, y2;
   371 
   372               active_item->get_bounds(x1, y1, x2, y2);
   373               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   374 
   375               target_item->get_bounds(x1, y1, x2, y2);
   376               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   377 
   378               //drawing new edge
   379               edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos,
   380                   *this);
   381               *(edgesmap[active_edge]) <<
   382                 Gnome::Canvas::Properties::fill_color("green");
   383               edgesmap[active_edge]->property_width_pixels().set_value(10);
   384 
   385               edgesmap[active_edge]->lower_to_bottom();
   386 
   387               //initializing edge-text as well, to empty string
   388               xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
   389               text_pos+=(xy<double>(10,10));
   390 
   391               edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   392                   text_pos.x, text_pos.y, "");
   393               edgetextmap[active_edge]->property_fill_color().set_value(
   394                   "darkgreen");
   395               edgetextmap[active_edge]->raise_to_top();
   396 
   397               //updating its properties
   398               mapwin.updateEdge(active_edge);
   399             }
   400             else
   401             {
   402               target_node=INVALID;
   403               std::cerr << "Loop edge is not yet implemented!" << std::endl;
   404             }
   405           }
   406           //clicked item was not a node. it could be an e.g. edge. we do not
   407           //deal with it furthermore.
   408           else
   409           {
   410             target_item=NULL;
   411           }
   412         }
   413       }
   414       break;
   415     case GDK_BUTTON_RELEASE:
   416       isbutton=0;
   417       //we clear settings in two cases
   418       //1: the edge is ready (target_item has valid value)
   419       //2: the edge creation is cancelled with right button
   420       if((target_item)||(e->button.button==3))
   421       {
   422         if(active_item)
   423         {
   424           *active_item << Gnome::Canvas::Properties::fill_color("blue");
   425           active_item=NULL;
   426         }
   427         if(target_item)
   428         {
   429           *target_item << Gnome::Canvas::Properties::fill_color("blue");
   430           target_item=NULL;
   431         }
   432         active_node=INVALID;
   433         active_edge=INVALID;
   434       }
   435       break;
   436     default:
   437       break;
   438   }
   439   return false;
   440 }
   441 
   442 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   443 {
   444   switch(e->type)
   445     {
   446     case GDK_BUTTON_PRESS:
   447       //finding the clicked items
   448       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   449       active_item=(get_item_at(clicked_x, clicked_y));
   450       active_node=INVALID;
   451       active_edge=INVALID;
   452       //was it a node?
   453       for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   454 	{
   455 	  if(nodesmap[i]==active_item)
   456 	    {
   457 	      active_node=i;
   458 	    }
   459 	}
   460       //or was it an edge?
   461       if(active_node==INVALID)
   462 	{
   463 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   464 	    {
   465 	      if(edgesmap[i]==active_item)
   466 		{
   467 		  active_edge=i;
   468 		}
   469 	    }
   470 	}
   471 
   472       //recolor activated item
   473       if(active_item)
   474 	{
   475 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   476 	}
   477       break;
   478 
   479     case GDK_BUTTON_RELEASE:
   480       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   481       if(active_item)
   482 	{
   483 	  //the cursor was not moved since pressing it
   484 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   485 	    {
   486 	      //a node was found
   487 	      if(active_node!=INVALID)
   488 		{
   489                   mapstorage.modified = true;
   490 
   491 		  //collecting edges to delete
   492 		  EdgeIt e;
   493 		  std::set<Graph::Edge> edges_to_delete;
   494 
   495 		  mapstorage.graph.firstOut(e,active_node);
   496 		  for(;e!=INVALID;mapstorage.graph.nextOut(e))
   497 		    {
   498 		      edges_to_delete.insert(e);
   499 		    }
   500 
   501 		  mapstorage.graph.firstIn(e,active_node);
   502 		  for(;e!=INVALID;mapstorage.graph.nextIn(e))
   503 		    {
   504 		      edges_to_delete.insert(e);
   505 		    }
   506 
   507 		  //deleting collected edges
   508 		  for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
   509 		    {
   510 		      deleteItem(*edge_set_it);
   511 		    }
   512 		  deleteItem(active_node);
   513 		}
   514 	      //a simple edge was chosen
   515 	      else
   516 		{
   517 		  deleteItem(active_edge);
   518 		}
   519 	    }
   520 	  //pointer was moved, deletion is cancelled
   521 	  else
   522 	    {
   523 	      if(active_node!=INVALID)
   524 		{
   525 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   526 		}
   527 	      else
   528 		{
   529 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   530 		}
   531 	    }
   532 	}
   533       //reseting datas
   534       active_item=NULL;
   535       active_edge=INVALID;
   536       active_node=INVALID;
   537       break;
   538 
   539     case GDK_MOTION_NOTIFY:
   540       break;
   541 
   542     default:
   543       break;
   544     }
   545   return false;
   546 }
   547 
   548 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   549 {
   550   if(actual_tool==EDGE_MAP_EDIT)
   551     {
   552       switch(e->type)
   553 	{
   554 	case GDK_KEY_PRESS:
   555 	  //for Escape or Enter hide the displayed widget
   556 	  {
   557 	    nodeMapEditEventHandler(e);
   558 	    break;
   559 	  }
   560 	case GDK_BUTTON_PRESS:
   561 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   562 	  {
   563 	    //for determine, whether it was an edge
   564 	    Edge clicked_edge=INVALID;
   565 
   566 	    //find the activated item between texts
   567 	    active_item=(get_item_at(e->button.x, e->button.y));
   568 	    for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   569 	      {
   570 		if(edgetextmap[i]==active_item)
   571 		  {
   572 		    clicked_edge=i;
   573 		  }
   574 	      }
   575 
   576 	    //if it was not between texts, search for it between edges
   577 	    if(clicked_edge==INVALID)
   578 	      {
   579 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   580 		active_item=(get_item_at(clicked_x, clicked_y));
   581 
   582 		for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   583 		  {
   584 		    //at the same time only one can be active
   585 		    if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   586 		      {
   587 			clicked_edge=i;
   588 		      }
   589 		  }
   590 	      }
   591 	    //if it was really an edge...
   592 	    if(clicked_edge!=INVALID)
   593 	      {
   594                 // the id map is not editable
   595                 if (nodemap_to_edit == "id") return 0;
   596 		//If there is already edited edge, it has to be saved first
   597 		if(entrywidget.is_visible())
   598 		  {
   599 		    GdkEvent * generated=new GdkEvent();
   600 		    generated->type=GDK_KEY_PRESS;
   601 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   602 		    entryWidgetChangeHandler(generated);
   603 		  }
   604 		//If the previous value could be saved, we can go further, otherwise not
   605 		if(!entrywidget.is_visible())
   606 		  {
   607 		    //and there is activated map
   608 		    if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   609 		      {
   610 			//activate the general variable for it
   611 			active_edge=clicked_edge;
   612 			//delete visible widget if there is
   613 			if(canvasentrywidget)
   614 			  {
   615 			    delete(canvasentrywidget);
   616 			  }
   617 
   618 			//initialize the entry
   619 			entrywidget.show();
   620 
   621 			//fill in the correct value
   622 			entrywidget.set_text(edgetextmap[active_edge]->property_text().get_value());
   623 
   624 			//replace and resize the entry to the activated edge and put it in a Canvas::Widget to be able to display it on gdc
   625 			xy<double> entry_coos;
   626 			entry_coos.x=(edgetextmap[active_edge])->property_x().get_value();
   627 			entry_coos.x-=edgetextmap[active_edge]->property_text_width().get_value()/2;
   628 			entry_coos.y=(edgetextmap[active_edge])->property_y().get_value();
   629 			entry_coos.y-=edgetextmap[active_edge]->property_text_height().get_value()*1.5/2;
   630 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   631 			canvasentrywidget->property_width().set_value(edgetextmap[active_edge]->property_text_width().get_value()*4);
   632 			canvasentrywidget->property_height().set_value(edgetextmap[active_edge]->property_text_height().get_value()*1.5);
   633 
   634 			//setting the focus to newly created widget
   635 			parentwin->set_focus(entrywidget);
   636 			parentwin->activate_focus();
   637 		      }
   638 		  }
   639 	      }
   640 	    //if it was not an edge...
   641 	    else
   642 	      {
   643 		//In this case the click did not happen on an edge
   644 		//if there is visible entry we save the value in it
   645 		//we pretend like an Enter was presse din the Entry widget
   646 		GdkEvent * generated=new GdkEvent();
   647 		generated->type=GDK_KEY_PRESS;
   648 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   649 		entryWidgetChangeHandler(generated);
   650 	      }
   651 	    break;
   652 	  }
   653 	default:
   654 	  break;
   655 	}
   656     }
   657   return false;  
   658 }
   659 
   660 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   661 {
   662   if(actual_tool==NODE_MAP_EDIT)
   663     {
   664       switch(e->type)
   665 	{
   666 	case GDK_KEY_PRESS:
   667 	  //for Escape or Enter hide the displayed widget
   668 	  {
   669 	    switch(((GdkEventKey*)e)->keyval)
   670 	      {
   671 	      case GDK_Escape:
   672 		entrywidget.hide();
   673 		break;
   674 	      case GDK_Return:
   675 	      case GDK_KP_Enter:
   676 		entrywidget.hide();
   677 		break;
   678 	      default:
   679 		break;
   680 	      }
   681   
   682 	    break;
   683 	  }
   684 	case GDK_BUTTON_PRESS:
   685 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   686 	  {
   687 	    //for determine, whether it was a node
   688 	    Node clicked_node=INVALID;
   689 
   690 	    //find the activated item between texts
   691 	    active_item=(get_item_at(e->button.x, e->button.y));
   692 	    for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   693 	      {
   694 		//at the same time only one can be active
   695 		if(nodetextmap[i]==active_item)
   696 		  {
   697 		    clicked_node=i;
   698 		  }
   699 	      }
   700 
   701 	    //if there was not, search for it between nodes
   702 	    if(clicked_node==INVALID)
   703 	      {
   704 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   705 		active_item=(get_item_at(clicked_x, clicked_y));
   706 
   707 		for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   708 		  {
   709 		    //at the same time only one can be active
   710 		    if(nodesmap[i]==active_item)
   711 		      {
   712 			clicked_node=i;
   713 		      }
   714 		  }
   715 	      }
   716 	    //if it was really an edge...
   717 	    if(clicked_node!=INVALID)
   718 	      {
   719                 // the id map is not editable
   720                 if (nodemap_to_edit == "id") return 0;
   721 		//If there is already edited edge, it has to be saved first
   722 		if(entrywidget.is_visible())
   723 		  {
   724 		    GdkEvent * generated=new GdkEvent();
   725 		    generated->type=GDK_KEY_PRESS;
   726 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   727 		    entryWidgetChangeHandler(generated);
   728 		  }
   729 		//If the previous value could be saved, we can go further, otherwise not
   730 		if(!entrywidget.is_visible())
   731 		  {
   732 		    //and there is activated map
   733 		    if(nodetextmap[clicked_node]->property_text().get_value()!="")
   734 		      {
   735 			//activate the general variable for it
   736 			active_node=clicked_node;
   737 			//delete visible widget if there is
   738 			if(canvasentrywidget)
   739 			  {
   740 			    delete(canvasentrywidget);
   741 			  }
   742 
   743 			//initialize the entry
   744 			entrywidget.show();
   745 
   746 			//fill in the correct value
   747 			entrywidget.set_text(nodetextmap[active_node]->property_text().get_value());
   748 
   749 			//replace and resize the entry to the activated node and put it in a Canvas::Widget to be able to display it on gdc
   750 			xy<double> entry_coos;
   751 			entry_coos.x=(nodetextmap[active_node])->property_x().get_value();
   752 			entry_coos.x-=nodetextmap[active_node]->property_text_width().get_value()/2;
   753 			entry_coos.y=(nodetextmap[active_node])->property_y().get_value();
   754 			entry_coos.y-=nodetextmap[active_node]->property_text_height().get_value()*1.5/2;
   755 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   756 			canvasentrywidget->property_width().set_value(nodetextmap[active_node]->property_text_width().get_value()*4);
   757 			canvasentrywidget->property_height().set_value(nodetextmap[active_node]->property_text_height().get_value()*1.5);
   758 		      }
   759 		  }
   760 	      }
   761 	    //if it was not an edge...
   762 	    else
   763 	      {
   764 		//In this case the click did not happen on an edge
   765 		//if there is visible entry we save the value in it
   766 		//we pretend like an Enter was presse din the Entry widget
   767 		GdkEvent * generated=new GdkEvent();
   768 		generated->type=GDK_KEY_PRESS;
   769 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   770 		entryWidgetChangeHandler(generated);
   771 	      }
   772 	    break;
   773 	  }
   774 	default:
   775 	  break;
   776 	}
   777     }
   778   return false;  
   779 }
   780 
   781 bool GraphDisplayerCanvas::entryWidgetChangeHandler(GdkEvent* e)
   782 {
   783   if(entrywidget.is_visible())
   784     {
   785       if(e->type==GDK_KEY_PRESS)
   786 	{
   787 	  switch(((GdkEventKey*)e)->keyval)
   788 	    {
   789 	    case GDK_Escape:
   790 	      entrywidget.hide();
   791 	      break;
   792 	    case GDK_KP_Enter:
   793 	    case GDK_Return:
   794 	      {
   795 		//these variables check whether the text in the entry is valid
   796 		bool valid_double=true;
   797 		int point_num=0;
   798 
   799 		//getting the value from the entry and converting it to double
   800 		Glib::ustring mapvalue_str = entrywidget.get_text();
   801 
   802 		char * mapvalue_ch=new char [mapvalue_str.length()];
   803 		for(int i=0;i<(int)(mapvalue_str.length());i++)
   804 		  {
   805 		    if(((mapvalue_str[i]<'0')||(mapvalue_str[i]>'9'))&&(mapvalue_str[i]!='.'))
   806 		      {
   807 			valid_double=false;
   808 		      }
   809 		    else
   810 		      {
   811 			if(mapvalue_str[i]=='.')
   812 			  {
   813 			    point_num++;
   814 			  }
   815 		      }
   816 		    mapvalue_ch[i]=mapvalue_str[i];
   817 		  }
   818   	      
   819 		//if the text in the entry was correct
   820 		if((point_num<=1)&&(valid_double))
   821 		  {
   822 		    double mapvalue_d=atof(mapvalue_ch);
   823 
   824 		    //reconvert the double to string for the correct format
   825 		    std::ostringstream ostr;
   826 		    ostr << mapvalue_d;
   827 
   828 		    //save the value to the correct place
   829 		    switch(actual_tool)
   830 		      {
   831 		      case EDGE_MAP_EDIT:
   832 			edgetextmap[active_edge]->property_text().set_value(ostr.str());
   833 			(*(mapstorage.edgemap_storage)[edgemap_to_edit])[active_edge]=mapvalue_d;
   834 			mapwin.updateEdge(active_edge);
   835 			break;
   836 		      case NODE_MAP_EDIT:
   837 			nodetextmap[active_node]->property_text().set_value(ostr.str());
   838 			(*(mapstorage.nodemap_storage)[nodemap_to_edit])[active_node]=mapvalue_d;
   839 			mapwin.updateNode(active_node);
   840 			break;
   841 		      default:
   842 			break;
   843 		      }
   844 		    entrywidget.hide();
   845 		  }
   846 		//the text in the entry was not correct for a double
   847 		else
   848 		  {
   849 		    std::cerr << "ERROR: only handling of double values is implemented yet!" << std::endl;
   850 		  }
   851 
   852 		break;
   853 	      }
   854 	    default:
   855 	      break;
   856 	    }
   857 	}
   858     }
   859   return false;
   860 }
   861 
   862 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   863 {
   864   delete(nodetextmap[node_to_delete]);
   865   delete(nodesmap[node_to_delete]);
   866   mapstorage.graph.erase(node_to_delete);
   867 }
   868 
   869 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   870 {
   871   delete(edgetextmap[edge_to_delete]);
   872   delete(edgesmap[edge_to_delete]);
   873   mapstorage.graph.erase(edge_to_delete);
   874 }
   875 
   876 void GraphDisplayerCanvas::textReposition(xy<double> new_place)
   877 {
   878   new_place+=(xy<double>(10,10));
   879   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   880   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   881 }
   882 
   883 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
   884 {
   885   if(on)
   886     {
   887       if(forming_edge!=INVALID)
   888 	{
   889 	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   890 	}
   891       else
   892 	{
   893 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   894 	    {
   895 	      if(edgesmap[i]==active_bre)
   896 		{
   897 		  forming_edge=i;
   898 		}
   899 	    }
   900 	}
   901     }
   902   else
   903     {
   904       if(forming_edge!=INVALID)
   905 	{
   906 	  forming_edge=INVALID;
   907 	}
   908       else
   909 	{
   910 	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   911 	}
   912     }
   913 
   914 }
   915 
   916 int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
   917 {
   918   //create the new map
   919   Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mapstorage.graph, default_value);
   920 
   921   //if addition was not successful addEdgeMap returns one.
   922   //cause can be that there is already a map named like the new one
   923   if(mapstorage.addEdgeMap(mapname,emptr, default_value))
   924     {
   925       return 1;
   926     }
   927 
   928 
   929   //add it to the list of the displayable maps
   930   mapwin.registerNewEdgeMap(mapname);
   931 
   932   //display it
   933   changeEdgeText(mapname);
   934 
   935   return 0;
   936 }
   937 
   938 int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
   939 {
   940   //create the new map
   941   Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mapstorage.graph,default_value);
   942 
   943   //if addition was not successful addNodeMap returns one.
   944   //cause can be that there is already a map named like the new one
   945   if(mapstorage.addNodeMap(mapname,emptr, default_value))
   946     {
   947       return 1;
   948     }
   949 
   950   //add it to the list of the displayable maps
   951   mapwin.registerNewNodeMap(mapname);
   952 
   953   //display it
   954   changeNodeText(mapname);
   955 
   956   return 0;
   957 }
   958