graph_displayer_canvas-event.cc
author alpar
Thu, 18 Aug 2005 13:33:49 +0000
branchgui
changeset 62 80eefca04b1e
parent 59 c38925cc6a4d
child 63 59768817442a
permissions -rwxr-xr-x
- The number of gcc-4.0 warnings has significantly decreases.
- Some code clean-up in gui
     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 
   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=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 	      Node 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]) <<
   358 			Gnome::Canvas::Properties::fill_color("red");
   359 
   360 		      //creating new edge
   361 		      active_edge=mapstorage.graph.addEdge(active_node,
   362 							   target_node);
   363 
   364 		      //initiating values corresponding to new edge in maps
   365 		      mapstorage.initMapsForEdge(active_edge);
   366                       (*mapstorage.edgemap_storage["id"])[active_edge] = 
   367 			mapstorage.graph.id(active_edge);
   368 	  
   369 		      //calculating coordinates of new edge
   370 		      Gnome::Canvas::Points coos;
   371 		      double x1, x2, y1, y2;
   372 	  
   373 		      active_item->get_bounds(x1, y1, x2, y2);
   374 		      coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   375 
   376 		      target_item->get_bounds(x1, y1, x2, y2);
   377 		      coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   378 
   379 		      //drawing new edge
   380 		      edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos, *this);
   381 		      *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green");
   382 		      edgesmap[active_edge]->property_width_pixels().set_value(10);
   383 
   384 		      //redraw nodes to blank terminations of the new edge
   385 		      target_item->raise_to_top();
   386 		      active_item->raise_to_top();
   387 
   388 		      //initializing edge-text as well, to empty string
   389 		      xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
   390 		      text_pos+=(xy<double>(10,10));
   391 
   392 		      edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
   393 		      edgetextmap[active_edge]->property_fill_color().set_value("darkgreen");
   394 
   395 		      //updating its properties
   396 		      mapwin.updateEdge(active_edge);
   397 		    }
   398 		  else
   399 		    {
   400 		      target_node=INVALID;
   401 		      std::cerr << "Loop edge is not yet implemented!" << std::endl;
   402 		    }
   403 		}
   404 	      //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore.
   405 	      else
   406 		{
   407 		  target_item=NULL;
   408 		}
   409 	    }
   410 	}
   411       break;
   412     case GDK_BUTTON_RELEASE:
   413       isbutton=0;
   414       //we clear settings in two cases
   415       //1: the edge is ready (target_item has valid value)
   416       //2: the edge creation is cancelled with right button
   417       if((target_item)||(e->button.button==3))
   418 	{
   419 	  if(active_item)
   420 	    {
   421 	      *active_item << Gnome::Canvas::Properties::fill_color("blue");
   422 	      active_item=NULL;
   423 	    }
   424 	  if(target_item)
   425 	    {
   426 	      *target_item << Gnome::Canvas::Properties::fill_color("blue");
   427 	      target_item=NULL;
   428 	    }
   429 	  active_node=INVALID;
   430 	  active_edge=INVALID;
   431 	}
   432       break;
   433     default:
   434       break;
   435     }
   436   return false;
   437 }
   438 
   439 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   440 {
   441   switch(e->type)
   442     {
   443     case GDK_BUTTON_PRESS:
   444       //finding the clicked items
   445       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   446       active_item=(get_item_at(clicked_x, clicked_y));
   447       active_node=INVALID;
   448       active_edge=INVALID;
   449       //was it a node?
   450       for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   451 	{
   452 	  if(nodesmap[i]==active_item)
   453 	    {
   454 	      active_node=i;
   455 	    }
   456 	}
   457       //or was it an edge?
   458       if(active_node==INVALID)
   459 	{
   460 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   461 	    {
   462 	      if(edgesmap[i]==active_item)
   463 		{
   464 		  active_edge=i;
   465 		}
   466 	    }
   467 	}
   468 
   469       //recolor activated item
   470       if(active_item)
   471 	{
   472 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   473 	}
   474       break;
   475 
   476     case GDK_BUTTON_RELEASE:
   477       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   478       if(active_item)
   479 	{
   480 	  //the cursor was not moved since pressing it
   481 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   482 	    {
   483 	      //a node was found
   484 	      if(active_node!=INVALID)
   485 		{
   486                   mapstorage.modified = true;
   487 
   488 		  //collecting edges to delete
   489 		  EdgeIt e;
   490 		  std::set<Graph::Edge> edges_to_delete;
   491 
   492 		  mapstorage.graph.firstOut(e,active_node);
   493 		  for(;e!=INVALID;mapstorage.graph.nextOut(e))
   494 		    {
   495 		      edges_to_delete.insert(e);
   496 		    }
   497 
   498 		  mapstorage.graph.firstIn(e,active_node);
   499 		  for(;e!=INVALID;mapstorage.graph.nextIn(e))
   500 		    {
   501 		      edges_to_delete.insert(e);
   502 		    }
   503 
   504 		  //deleting collected edges
   505 		  for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
   506 		    {
   507 		      deleteItem(*edge_set_it);
   508 		    }
   509 		  deleteItem(active_node);
   510 		}
   511 	      //a simple edge was chosen
   512 	      else
   513 		{
   514 		  deleteItem(active_edge);
   515 		}
   516 	    }
   517 	  //pointer was moved, deletion is cancelled
   518 	  else
   519 	    {
   520 	      if(active_node!=INVALID)
   521 		{
   522 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   523 		}
   524 	      else
   525 		{
   526 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   527 		}
   528 	    }
   529 	}
   530       //reseting datas
   531       active_item=NULL;
   532       active_edge=INVALID;
   533       active_node=INVALID;
   534       break;
   535 
   536     case GDK_MOTION_NOTIFY:
   537       break;
   538 
   539     default:
   540       break;
   541     }
   542   return false;
   543 }
   544 
   545 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   546 {
   547   if(actual_tool==EDGE_MAP_EDIT)
   548     {
   549       switch(e->type)
   550 	{
   551 	case GDK_KEY_PRESS:
   552 	  //for Escape or Enter hide the displayed widget
   553 	  {
   554 	    nodeMapEditEventHandler(e);
   555 	    break;
   556 	  }
   557 	case GDK_BUTTON_PRESS:
   558 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   559 	  {
   560 	    //for determine, whether it was an edge
   561 	    Edge clicked_edge=INVALID;
   562 
   563 	    //find the activated item between texts
   564 	    active_item=(get_item_at(e->button.x, e->button.y));
   565 	    for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   566 	      {
   567 		if(edgetextmap[i]==active_item)
   568 		  {
   569 		    clicked_edge=i;
   570 		  }
   571 	      }
   572 
   573 	    //if it was not between texts, search for it between edges
   574 	    if(clicked_edge==INVALID)
   575 	      {
   576 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   577 		active_item=(get_item_at(clicked_x, clicked_y));
   578 
   579 		for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   580 		  {
   581 		    //at the same time only one can be active
   582 		    if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   583 		      {
   584 			clicked_edge=i;
   585 		      }
   586 		  }
   587 	      }
   588 	    //if it was really an edge...
   589 	    if(clicked_edge!=INVALID)
   590 	      {
   591 		//If there is already edited edge, it has to be saved first
   592 		if(entrywidget.is_visible())
   593 		  {
   594 		    GdkEvent * generated=new GdkEvent();
   595 		    generated->type=GDK_KEY_PRESS;
   596 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   597 		    entryWidgetChangeHandler(generated);
   598 		  }
   599 		//If the previous value could be saved, we can go further, otherwise not
   600 		if(!entrywidget.is_visible())
   601 		  {
   602 		    //and there is activated map
   603 		    if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   604 		      {
   605 			//activate the general variable for it
   606 			active_edge=clicked_edge;
   607 			//delete visible widget if there is
   608 			if(canvasentrywidget)
   609 			  {
   610 			    delete(canvasentrywidget);
   611 			  }
   612 
   613 			//initialize the entry
   614 			entrywidget.show();
   615 
   616 			//fill in the correct value
   617 			entrywidget.set_text(edgetextmap[active_edge]->property_text().get_value());
   618 
   619 			//replace and resize the entry to the activated edge and put it in a Canvas::Widget to be able to display it on gdc
   620 			xy<double> entry_coos;
   621 			entry_coos.x=(edgetextmap[active_edge])->property_x().get_value();
   622 			entry_coos.x-=edgetextmap[active_edge]->property_text_width().get_value()/2;
   623 			entry_coos.y=(edgetextmap[active_edge])->property_y().get_value();
   624 			entry_coos.y-=edgetextmap[active_edge]->property_text_height().get_value()*1.5/2;
   625 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   626 			canvasentrywidget->property_width().set_value(edgetextmap[active_edge]->property_text_width().get_value()*4);
   627 			canvasentrywidget->property_height().set_value(edgetextmap[active_edge]->property_text_height().get_value()*1.5);
   628 
   629 			//setting the focus to newly created widget
   630 			parentwin->set_focus(entrywidget);
   631 			parentwin->activate_focus();
   632 		      }
   633 		  }
   634 	      }
   635 	    //if it was not an edge...
   636 	    else
   637 	      {
   638 		//In this case the click did not happen on an edge
   639 		//if there is visible entry we save the value in it
   640 		//we pretend like an Enter was presse din the Entry widget
   641 		GdkEvent * generated=new GdkEvent();
   642 		generated->type=GDK_KEY_PRESS;
   643 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   644 		entryWidgetChangeHandler(generated);
   645 	      }
   646 	    break;
   647 	  }
   648 	default:
   649 	  break;
   650 	}
   651     }
   652   return false;  
   653 }
   654 
   655 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   656 {
   657   if(actual_tool==NODE_MAP_EDIT)
   658     {
   659       switch(e->type)
   660 	{
   661 	case GDK_KEY_PRESS:
   662 	  //for Escape or Enter hide the displayed widget
   663 	  {
   664 	    switch(((GdkEventKey*)e)->keyval)
   665 	      {
   666 	      case GDK_Escape:
   667 		entrywidget.hide();
   668 		break;
   669 	      case GDK_Return:
   670 	      case GDK_KP_Enter:
   671 		entrywidget.hide();
   672 		break;
   673 	      default:
   674 		break;
   675 	      }
   676   
   677 	    break;
   678 	  }
   679 	case GDK_BUTTON_PRESS:
   680 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   681 	  {
   682 	    //for determine, whether it was a node
   683 	    Node clicked_node=INVALID;
   684 
   685 	    //find the activated item between texts
   686 	    active_item=(get_item_at(e->button.x, e->button.y));
   687 	    for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   688 	      {
   689 		//at the same time only one can be active
   690 		if(nodetextmap[i]==active_item)
   691 		  {
   692 		    clicked_node=i;
   693 		  }
   694 	      }
   695 
   696 	    //if there was not, search for it between nodes
   697 	    if(clicked_node==INVALID)
   698 	      {
   699 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   700 		active_item=(get_item_at(clicked_x, clicked_y));
   701 
   702 		for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   703 		  {
   704 		    //at the same time only one can be active
   705 		    if(nodesmap[i]==active_item)
   706 		      {
   707 			clicked_node=i;
   708 		      }
   709 		  }
   710 	      }
   711 	    //if it was really an edge...
   712 	    if(clicked_node!=INVALID)
   713 	      {
   714 		//If there is already edited edge, it has to be saved first
   715 		if(entrywidget.is_visible())
   716 		  {
   717 		    GdkEvent * generated=new GdkEvent();
   718 		    generated->type=GDK_KEY_PRESS;
   719 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   720 		    entryWidgetChangeHandler(generated);
   721 		  }
   722 		//If the previous value could be saved, we can go further, otherwise not
   723 		if(!entrywidget.is_visible())
   724 		  {
   725 		    //and there is activated map
   726 		    if(nodetextmap[clicked_node]->property_text().get_value()!="")
   727 		      {
   728 			//activate the general variable for it
   729 			active_node=clicked_node;
   730 			//delete visible widget if there is
   731 			if(canvasentrywidget)
   732 			  {
   733 			    delete(canvasentrywidget);
   734 			  }
   735 
   736 			//initialize the entry
   737 			entrywidget.show();
   738 
   739 			//fill in the correct value
   740 			entrywidget.set_text(nodetextmap[active_node]->property_text().get_value());
   741 
   742 			//replace and resize the entry to the activated node and put it in a Canvas::Widget to be able to display it on gdc
   743 			xy<double> entry_coos;
   744 			entry_coos.x=(nodetextmap[active_node])->property_x().get_value();
   745 			entry_coos.x-=nodetextmap[active_node]->property_text_width().get_value()/2;
   746 			entry_coos.y=(nodetextmap[active_node])->property_y().get_value();
   747 			entry_coos.y-=nodetextmap[active_node]->property_text_height().get_value()*1.5/2;
   748 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   749 			canvasentrywidget->property_width().set_value(nodetextmap[active_node]->property_text_width().get_value()*4);
   750 			canvasentrywidget->property_height().set_value(nodetextmap[active_node]->property_text_height().get_value()*1.5);
   751 		      }
   752 		  }
   753 	      }
   754 	    //if it was not an edge...
   755 	    else
   756 	      {
   757 		//In this case the click did not happen on an edge
   758 		//if there is visible entry we save the value in it
   759 		//we pretend like an Enter was presse din the Entry widget
   760 		GdkEvent * generated=new GdkEvent();
   761 		generated->type=GDK_KEY_PRESS;
   762 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   763 		entryWidgetChangeHandler(generated);
   764 	      }
   765 	    break;
   766 	  }
   767 	default:
   768 	  break;
   769 	}
   770     }
   771   return false;  
   772 }
   773 
   774 bool GraphDisplayerCanvas::entryWidgetChangeHandler(GdkEvent* e)
   775 {
   776   if(entrywidget.is_visible())
   777     {
   778       if(e->type==GDK_KEY_PRESS)
   779 	{
   780 	  switch(((GdkEventKey*)e)->keyval)
   781 	    {
   782 	    case GDK_Escape:
   783 	      entrywidget.hide();
   784 	      break;
   785 	    case GDK_KP_Enter:
   786 	    case GDK_Return:
   787 	      {
   788 		//these variables check whether the text in the entry is valid
   789 		bool valid_double=true;
   790 		int point_num=0;
   791 
   792 		//getting the value from the entry and converting it to double
   793 		Glib::ustring mapvalue_str = entrywidget.get_text();
   794 
   795 		char * mapvalue_ch=new char [mapvalue_str.length()];
   796 		for(int i=0;i<(int)(mapvalue_str.length());i++)
   797 		  {
   798 		    if(((mapvalue_str[i]<'0')||(mapvalue_str[i]>'9'))&&(mapvalue_str[i]!='.'))
   799 		      {
   800 			valid_double=false;
   801 		      }
   802 		    else
   803 		      {
   804 			if(mapvalue_str[i]=='.')
   805 			  {
   806 			    point_num++;
   807 			  }
   808 		      }
   809 		    mapvalue_ch[i]=mapvalue_str[i];
   810 		  }
   811   	      
   812 		//if the text in the entry was correct
   813 		if((point_num<=1)&&(valid_double))
   814 		  {
   815 		    double mapvalue_d=atof(mapvalue_ch);
   816 
   817 		    //reconvert the double to string for the correct format
   818 		    std::ostringstream ostr;
   819 		    ostr << mapvalue_d;
   820 
   821 		    //save the value to the correct place
   822 		    switch(actual_tool)
   823 		      {
   824 		      case EDGE_MAP_EDIT:
   825 			edgetextmap[active_edge]->property_text().set_value(ostr.str());
   826 			(*(mapstorage.edgemap_storage)[edgemap_to_edit])[active_edge]=mapvalue_d;
   827 			mapwin.updateEdge(active_edge);
   828 			break;
   829 		      case NODE_MAP_EDIT:
   830 			nodetextmap[active_node]->property_text().set_value(ostr.str());
   831 			(*(mapstorage.nodemap_storage)[nodemap_to_edit])[active_node]=mapvalue_d;
   832 			mapwin.updateNode(active_node);
   833 			break;
   834 		      default:
   835 			break;
   836 		      }
   837 		    entrywidget.hide();
   838 		  }
   839 		//the text in the entry was not correct for a double
   840 		else
   841 		  {
   842 		    std::cerr << "ERROR: only handling of double values is implemented yet!" << std::endl;
   843 		  }
   844 
   845 		break;
   846 	      }
   847 	    default:
   848 	      break;
   849 	    }
   850 	}
   851     }
   852   return false;
   853 }
   854 
   855 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   856 {
   857   delete(nodetextmap[node_to_delete]);
   858   delete(nodesmap[node_to_delete]);
   859   mapstorage.graph.erase(node_to_delete);
   860 }
   861 
   862 void GraphDisplayerCanvas::deleteItem(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