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