graph_displayer_canvas-event.cc
author ladanyi
Tue, 23 Aug 2005 16:27:59 +0000
branchgui
changeset 65 1b8e20c04704
parent 64 7a32d528857f
child 66 4ca5a537ef07
permissions -rwxr-xr-x
bugfix
     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             window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   568             active_item=(get_item_at(clicked_x, clicked_y));
   569 	    for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   570 	      {
   571 		if(edgetextmap[i]==active_item)
   572 		  {
   573 		    clicked_edge=i;
   574 		  }
   575 	      }
   576 
   577 	    //if it was not between texts, search for it between edges
   578 	    if(clicked_edge==INVALID)
   579 	      {
   580 		for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   581 		  {
   582 		    //at the same time only one can be active
   583 		    if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   584 		      {
   585 			clicked_edge=i;
   586 		      }
   587 		  }
   588 	      }
   589 	    //if it was really an edge...
   590 	    if(clicked_edge!=INVALID)
   591 	      {
   592                 // the id map is not editable
   593                 if (edgemap_to_edit == "id") return 0;
   594 
   595 		//If there is already edited edge, it has to be saved first
   596 		if(entrywidget.is_visible())
   597 		  {
   598 		    GdkEvent * generated=new GdkEvent();
   599 		    generated->type=GDK_KEY_PRESS;
   600 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   601 		    entryWidgetChangeHandler(generated);
   602 		  }
   603 		//If the previous value could be saved, we can go further, otherwise not
   604 		if(!entrywidget.is_visible())
   605 		  {
   606 		    //and there is activated map
   607 		    if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   608 		      {
   609 			//activate the general variable for it
   610 			active_edge=clicked_edge;
   611 			//delete visible widget if there is
   612 			if(canvasentrywidget)
   613 			  {
   614 			    delete(canvasentrywidget);
   615 			  }
   616 
   617 			//initialize the entry
   618 			entrywidget.show();
   619 
   620 			//fill in the correct value
   621 			entrywidget.set_text(edgetextmap[active_edge]->property_text().get_value());
   622 
   623 			//replace and resize the entry to the activated edge and put it in a Canvas::Widget to be able to display it on gdc
   624 			xy<double> entry_coos;
   625 			entry_coos.x=(edgetextmap[active_edge])->property_x().get_value();
   626 			entry_coos.x-=edgetextmap[active_edge]->property_text_width().get_value()/2;
   627 			entry_coos.y=(edgetextmap[active_edge])->property_y().get_value();
   628 			entry_coos.y-=edgetextmap[active_edge]->property_text_height().get_value()*1.5/2;
   629 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   630 			canvasentrywidget->property_width().set_value(edgetextmap[active_edge]->property_text_width().get_value()*4);
   631 			canvasentrywidget->property_height().set_value(edgetextmap[active_edge]->property_text_height().get_value()*1.5);
   632 
   633 			//setting the focus to newly created widget
   634 			parentwin->set_focus(entrywidget);
   635 			parentwin->activate_focus();
   636 		      }
   637 		  }
   638 	      }
   639 	    //if it was not an edge...
   640 	    else
   641 	      {
   642 		//In this case the click did not happen on an edge
   643 		//if there is visible entry we save the value in it
   644 		//we pretend like an Enter was presse din the Entry widget
   645 		GdkEvent * generated=new GdkEvent();
   646 		generated->type=GDK_KEY_PRESS;
   647 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   648 		entryWidgetChangeHandler(generated);
   649 	      }
   650 	    break;
   651 	  }
   652 	default:
   653 	  break;
   654 	}
   655     }
   656   return false;  
   657 }
   658 
   659 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   660 {
   661   if(actual_tool==NODE_MAP_EDIT)
   662     {
   663       switch(e->type)
   664 	{
   665 	case GDK_KEY_PRESS:
   666 	  //for Escape or Enter hide the displayed widget
   667 	  {
   668 	    switch(((GdkEventKey*)e)->keyval)
   669 	      {
   670 	      case GDK_Escape:
   671 		entrywidget.hide();
   672 		break;
   673 	      case GDK_Return:
   674 	      case GDK_KP_Enter:
   675 		entrywidget.hide();
   676 		break;
   677 	      default:
   678 		break;
   679 	      }
   680   
   681 	    break;
   682 	  }
   683 	case GDK_BUTTON_PRESS:
   684 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   685 	  {
   686 	    //for determine, whether it was a node
   687 	    Node clicked_node=INVALID;
   688 
   689 	    //find the activated item between texts
   690 	    active_item=(get_item_at(e->button.x, e->button.y));
   691 	    for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   692 	      {
   693 		//at the same time only one can be active
   694 		if(nodetextmap[i]==active_item)
   695 		  {
   696 		    clicked_node=i;
   697 		  }
   698 	      }
   699 
   700 	    //if there was not, search for it between nodes
   701 	    if(clicked_node==INVALID)
   702 	      {
   703 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   704 		active_item=(get_item_at(clicked_x, clicked_y));
   705 
   706 		for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   707 		  {
   708 		    //at the same time only one can be active
   709 		    if(nodesmap[i]==active_item)
   710 		      {
   711 			clicked_node=i;
   712 		      }
   713 		  }
   714 	      }
   715 	    //if it was really an edge...
   716 	    if(clicked_node!=INVALID)
   717 	      {
   718                 // the id map is not editable
   719                 if (nodemap_to_edit == "id") return 0;
   720 		//If there is already edited edge, it has to be saved first
   721 		if(entrywidget.is_visible())
   722 		  {
   723 		    GdkEvent * generated=new GdkEvent();
   724 		    generated->type=GDK_KEY_PRESS;
   725 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   726 		    entryWidgetChangeHandler(generated);
   727 		  }
   728 		//If the previous value could be saved, we can go further, otherwise not
   729 		if(!entrywidget.is_visible())
   730 		  {
   731 		    //and there is activated map
   732 		    if(nodetextmap[clicked_node]->property_text().get_value()!="")
   733 		      {
   734 			//activate the general variable for it
   735 			active_node=clicked_node;
   736 			//delete visible widget if there is
   737 			if(canvasentrywidget)
   738 			  {
   739 			    delete(canvasentrywidget);
   740 			  }
   741 
   742 			//initialize the entry
   743 			entrywidget.show();
   744 
   745 			//fill in the correct value
   746 			entrywidget.set_text(nodetextmap[active_node]->property_text().get_value());
   747 
   748 			//replace and resize the entry to the activated node and put it in a Canvas::Widget to be able to display it on gdc
   749 			xy<double> entry_coos;
   750 			entry_coos.x=(nodetextmap[active_node])->property_x().get_value();
   751 			entry_coos.x-=nodetextmap[active_node]->property_text_width().get_value()/2;
   752 			entry_coos.y=(nodetextmap[active_node])->property_y().get_value();
   753 			entry_coos.y-=nodetextmap[active_node]->property_text_height().get_value()*1.5/2;
   754 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   755 			canvasentrywidget->property_width().set_value(nodetextmap[active_node]->property_text_width().get_value()*4);
   756 			canvasentrywidget->property_height().set_value(nodetextmap[active_node]->property_text_height().get_value()*1.5);
   757 		      }
   758 		  }
   759 	      }
   760 	    //if it was not an edge...
   761 	    else
   762 	      {
   763 		//In this case the click did not happen on an edge
   764 		//if there is visible entry we save the value in it
   765 		//we pretend like an Enter was presse din the Entry widget
   766 		GdkEvent * generated=new GdkEvent();
   767 		generated->type=GDK_KEY_PRESS;
   768 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   769 		entryWidgetChangeHandler(generated);
   770 	      }
   771 	    break;
   772 	  }
   773 	default:
   774 	  break;
   775 	}
   776     }
   777   return false;  
   778 }
   779 
   780 bool GraphDisplayerCanvas::entryWidgetChangeHandler(GdkEvent* e)
   781 {
   782   if(entrywidget.is_visible())
   783     {
   784       if(e->type==GDK_KEY_PRESS)
   785 	{
   786 	  switch(((GdkEventKey*)e)->keyval)
   787 	    {
   788 	    case GDK_Escape:
   789 	      entrywidget.hide();
   790 	      break;
   791 	    case GDK_KP_Enter:
   792 	    case GDK_Return:
   793 	      {
   794 		//these variables check whether the text in the entry is valid
   795 		bool valid_double=true;
   796 		int point_num=0;
   797 
   798 		//getting the value from the entry and converting it to double
   799 		Glib::ustring mapvalue_str = entrywidget.get_text();
   800 
   801 		char * mapvalue_ch=new char [mapvalue_str.length()];
   802 		for(int i=0;i<(int)(mapvalue_str.length());i++)
   803 		  {
   804 		    if(((mapvalue_str[i]<'0')||(mapvalue_str[i]>'9'))&&(mapvalue_str[i]!='.'))
   805 		      {
   806 			valid_double=false;
   807 		      }
   808 		    else
   809 		      {
   810 			if(mapvalue_str[i]=='.')
   811 			  {
   812 			    point_num++;
   813 			  }
   814 		      }
   815 		    mapvalue_ch[i]=mapvalue_str[i];
   816 		  }
   817   	      
   818 		//if the text in the entry was correct
   819 		if((point_num<=1)&&(valid_double))
   820 		  {
   821 		    double mapvalue_d=atof(mapvalue_ch);
   822 
   823 		    //reconvert the double to string for the correct format
   824 		    std::ostringstream ostr;
   825 		    ostr << mapvalue_d;
   826 
   827 		    //save the value to the correct place
   828 		    switch(actual_tool)
   829 		      {
   830 		      case EDGE_MAP_EDIT:
   831 			edgetextmap[active_edge]->property_text().set_value(ostr.str());
   832 			(*(mapstorage.edgemap_storage)[edgemap_to_edit])[active_edge]=mapvalue_d;
   833 			mapwin.updateEdge(active_edge);
   834 			break;
   835 		      case NODE_MAP_EDIT:
   836 			nodetextmap[active_node]->property_text().set_value(ostr.str());
   837 			(*(mapstorage.nodemap_storage)[nodemap_to_edit])[active_node]=mapvalue_d;
   838 			mapwin.updateNode(active_node);
   839 			break;
   840 		      default:
   841 			break;
   842 		      }
   843 		    entrywidget.hide();
   844 		  }
   845 		//the text in the entry was not correct for a double
   846 		else
   847 		  {
   848 		    std::cerr << "ERROR: only handling of double values is implemented yet!" << std::endl;
   849 		  }
   850 
   851 		break;
   852 	      }
   853 	    default:
   854 	      break;
   855 	    }
   856 	}
   857     }
   858   return false;
   859 }
   860 
   861 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   862 {
   863   delete(nodetextmap[node_to_delete]);
   864   delete(nodesmap[node_to_delete]);
   865   mapstorage.graph.erase(node_to_delete);
   866 }
   867 
   868 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   869 {
   870   delete(edgetextmap[edge_to_delete]);
   871   delete(edgesmap[edge_to_delete]);
   872   mapstorage.graph.erase(edge_to_delete);
   873 }
   874 
   875 void GraphDisplayerCanvas::textReposition(xy<double> new_place)
   876 {
   877   new_place+=(xy<double>(10,10));
   878   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   879   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   880 }
   881 
   882 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
   883 {
   884   if(on)
   885     {
   886       if(forming_edge!=INVALID)
   887 	{
   888 	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   889 	}
   890       else
   891 	{
   892 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   893 	    {
   894 	      if(edgesmap[i]==active_bre)
   895 		{
   896 		  forming_edge=i;
   897 		}
   898 	    }
   899 	}
   900     }
   901   else
   902     {
   903       if(forming_edge!=INVALID)
   904 	{
   905 	  forming_edge=INVALID;
   906 	}
   907       else
   908 	{
   909 	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   910 	}
   911     }
   912 
   913 }
   914 
   915 int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
   916 {
   917   //create the new map
   918   Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mapstorage.graph, default_value);
   919 
   920   //if addition was not successful addEdgeMap returns one.
   921   //cause can be that there is already a map named like the new one
   922   if(mapstorage.addEdgeMap(mapname,emptr, default_value))
   923     {
   924       return 1;
   925     }
   926 
   927 
   928   //add it to the list of the displayable maps
   929   mapwin.registerNewEdgeMap(mapname);
   930 
   931   //display it
   932   changeEdgeText(mapname);
   933 
   934   return 0;
   935 }
   936 
   937 int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
   938 {
   939   //create the new map
   940   Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mapstorage.graph,default_value);
   941 
   942   //if addition was not successful addNodeMap returns one.
   943   //cause can be that there is already a map named like the new one
   944   if(mapstorage.addNodeMap(mapname,emptr, default_value))
   945     {
   946       return 1;
   947     }
   948 
   949   //add it to the list of the displayable maps
   950   mapwin.registerNewNodeMap(mapname);
   951 
   952   //display it
   953   changeNodeText(mapname);
   954 
   955   return 0;
   956 }
   957