Index: Makefile.am
===================================================================
--- Makefile.am	(revision 142)
+++ Makefile.am	(revision 160)
@@ -43,5 +43,7 @@
 	guipixbufs.h \
 	i18n.h \
-	gettext.h
+	gettext.h \
+	design_win.h \
+	design_win.cc
 
 glemon_CXXFLAGS = $(GTK_CFLAGS) $(LEMON_CFLAGS)
Index: graph_displayer_canvas-event.cc
===================================================================
--- graph_displayer_canvas-event.cc	(revision 153)
+++ graph_displayer_canvas-event.cc	(revision 160)
@@ -82,9 +82,9 @@
   static Gnome::Canvas::Text *coord_text = 0;
   switch(e->type)
-  {
+    {
     case GDK_BUTTON_PRESS:
       //we mark the location of the event to be able to calculate parameters of dragging
       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
-
+      
       active_item=(get_item_at(clicked_x, clicked_y));
       active_node=INVALID;
@@ -100,8 +100,8 @@
     case GDK_BUTTON_RELEASE:
       if (coord_text)
-      {
-        delete coord_text;
-        coord_text = 0;
-      }
+	{
+	  delete coord_text;
+	  coord_text = 0;
+	}
       isbutton=0;
       active_item=NULL;
@@ -111,120 +111,57 @@
       //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
       if(active_node!=INVALID)
-      {
-        (mytab.mapstorage).modified = true;
-
-	//new coordinates will be the old values,
-	//because the item will be moved to the
-	//new coordinate therefore the new movement
-	//has to be calculated from here
-
-	double new_x, new_y;
-
-	window_to_world (e->motion.x, e->motion.y, new_x, new_y);
-
-        double dx=new_x-clicked_x;
-        double dy=new_y-clicked_y;
-
-	//repositioning node and its text
-        active_item->move(dx, dy);
-	nodetextmap[active_node]->move(dx, dy);
-
-        // the new coordinates of the centre of the node 
-        double coord_x = new_x - (clicked_x - (mytab.mapstorage).coords[active_node].x);
-        double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y);
-
-        // write back the new coordinates to the coords map
-        (mytab.mapstorage).coords.set(active_node, XY(coord_x, coord_y));
-
-        clicked_x=new_x;
-        clicked_y=new_y;
-
-        // reposition the coordinates text
-        std::ostringstream ostr;
-        ostr << "(" <<
-          (mytab.mapstorage).coords[active_node].x << ", " <<
-          (mytab.mapstorage).coords[active_node].y << ")";
-        double radius =
-          (nodesmap[active_node]->property_x2().get_value() -
-          nodesmap[active_node]->property_x1().get_value()) / 2.0;
-        if (coord_text)
-        {
-          coord_text->property_text().set_value(ostr.str());
-          coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x +
-              radius);
-          coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
-              radius);
-        }
-        else
-        {
-          coord_text = new Gnome::Canvas::Text(
-              displayed_graph,
-              (mytab.mapstorage).coords[active_node].x + radius,
-              (mytab.mapstorage).coords[active_node].y - radius,
-              ostr.str());
-          coord_text->property_fill_color().set_value("black");
-          coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
-        }
-
-	//all the edges connected to the moved point has to be redrawn
-        for(OutEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
-        {
-          XY arrow_pos;
-
-          if (mytab.mapstorage.graph.source(ei) == mytab.mapstorage.graph.target(ei))
-          {
-            arrow_pos = mytab.mapstorage.arrow_pos[ei] + XY(dx, dy);
-          }
-          else
-          {
-            XY moved_node_1(coord_x - dx, coord_y - dy);
-            XY moved_node_2(coord_x, coord_y);
-            Node target = mytab.mapstorage.graph.target(ei);
-            XY fix_node(mytab.mapstorage.coords[target].x,
-                mytab.mapstorage.coords[target].y);
-            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
-
-            arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
-          }
-
-          mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
-          edgesmap[ei]->draw();
-
-          //reposition of edgetext
-          XY text_pos=mytab.mapstorage.arrow_pos[ei];
-          text_pos+=(XY(10,10));
-          edgetextmap[ei]->property_x().set_value(text_pos.x);
-          edgetextmap[ei]->property_y().set_value(text_pos.y);
-        }
-
-        for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
-        {
-          if (mytab.mapstorage.graph.source(ei) != mytab.mapstorage.graph.target(ei))
-          {
-            XY moved_node_1(coord_x - dx, coord_y - dy);
-            XY moved_node_2(coord_x, coord_y);
-            Node source = mytab.mapstorage.graph.source(ei);
-            XY fix_node(mytab.mapstorage.coords[source].x,
-                mytab.mapstorage.coords[source].y);
-            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
-
-            XY arrow_pos;
-            arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
-
-            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
-            edgesmap[ei]->draw();
-
-            //reposition of edgetext
-            XY text_pos=mytab.mapstorage.arrow_pos[ei];
-            text_pos+=(XY(10,10));
-            edgetextmap[ei]->property_x().set_value(text_pos.x);
-            edgetextmap[ei]->property_y().set_value(text_pos.y);
-          }
-        }
-      }
+	{
+	  (mytab.mapstorage).modified = true;
+	  
+	  //new coordinates will be the old values,
+	  //because the item will be moved to the
+	  //new coordinate therefore the new movement
+	  //has to be calculated from here
+	  
+	  double new_x, new_y;
+	  
+	  window_to_world (e->motion.x, e->motion.y, new_x, new_y);
+	  
+	  double dx=new_x-clicked_x;
+	  double dy=new_y-clicked_y;
+	  
+	  moveNode(dx, dy);
+
+	  clicked_x=new_x;
+	  clicked_y=new_y;
+
+	  // reposition the coordinates text
+	  std::ostringstream ostr;
+	  ostr << "(" <<
+	    (mytab.mapstorage).coords[active_node].x << ", " <<
+	    (mytab.mapstorage).coords[active_node].y << ")";
+	  double radius =
+	    (nodesmap[active_node]->property_x2().get_value() -
+	     nodesmap[active_node]->property_x1().get_value()) / 2.0;
+	  if (coord_text)
+	    {
+	      coord_text->property_text().set_value(ostr.str());
+	      coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x +
+						 radius);
+	      coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
+						 radius);
+	    }
+	  else
+	    {
+	      coord_text = new Gnome::Canvas::Text(
+						   displayed_graph,
+						   (mytab.mapstorage).coords[active_node].x + radius,
+						   (mytab.mapstorage).coords[active_node].y - radius,
+						   ostr.str());
+	      coord_text->property_fill_color().set_value("black");
+	      coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
+	    }
+
+
+	}
     default: break;
-  }
-
-  return false;
+    }
+
+return false;
 }
 
@@ -824,13 +761,96 @@
   }
   else
-  {
-    if(forming_edge!=INVALID)
-    {
-      forming_edge=INVALID;
-    }
-    else
-    {
-      std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
-    }
-  }
-}
+    {
+      if(forming_edge!=INVALID)
+	{
+	  forming_edge=INVALID;
+	}
+      else
+	{
+	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
+	}
+    }
+}
+
+void GraphDisplayerCanvas::moveNode(double dx, double dy, Gnome::Canvas::Item * item, Node node)
+{
+  Gnome::Canvas::Item * moved_item=item;
+  Node moved_node=node;
+
+  if(item==NULL && node==INVALID)
+    {
+      moved_item=active_item;
+      moved_node=active_node;
+    }
+  else
+    {
+      isbutton=1;
+    }
+
+  //repositioning node and its text
+  moved_item->move(dx, dy);
+  nodetextmap[moved_node]->move(dx, dy);
+
+  // the new coordinates of the centre of the node 
+  double coord_x = dx + (mytab.mapstorage).coords[moved_node].x;
+  double coord_y = dy + (mytab.mapstorage).coords[moved_node].y;
+
+  // write back the new coordinates to the coords map
+  (mytab.mapstorage).coords.set(moved_node, XY(coord_x, coord_y));
+
+  //all the edges connected to the moved point has to be redrawn
+  for(OutEdgeIt ei((mytab.mapstorage).graph,moved_node);ei!=INVALID;++ei)
+    {
+      XY arrow_pos;
+
+      if (mytab.mapstorage.graph.source(ei) == mytab.mapstorage.graph.target(ei))
+	{
+	  arrow_pos = mytab.mapstorage.arrow_pos[ei] + XY(dx, dy);
+	}
+      else
+	{
+	  XY moved_node_1(coord_x - dx, coord_y - dy);
+	  XY moved_node_2(coord_x, coord_y);
+	  Node target = mytab.mapstorage.graph.target(ei);
+	  XY fix_node(mytab.mapstorage.coords[target].x,
+		      mytab.mapstorage.coords[target].y);
+	  XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
+
+	  arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
+	}
+
+      mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
+      edgesmap[ei]->draw();
+
+      //reposition of edgetext
+      XY text_pos=mytab.mapstorage.arrow_pos[ei];
+      text_pos+=(XY(10,10));
+      edgetextmap[ei]->property_x().set_value(text_pos.x);
+      edgetextmap[ei]->property_y().set_value(text_pos.y);
+    }
+
+  for(InEdgeIt ei((mytab.mapstorage).graph,moved_node);ei!=INVALID;++ei)
+    {
+      if (mytab.mapstorage.graph.source(ei) != mytab.mapstorage.graph.target(ei))
+	{
+	  XY moved_node_1(coord_x - dx, coord_y - dy);
+	  XY moved_node_2(coord_x, coord_y);
+	  Node source = mytab.mapstorage.graph.source(ei);
+	  XY fix_node(mytab.mapstorage.coords[source].x,
+		      mytab.mapstorage.coords[source].y);
+	  XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
+
+	  XY arrow_pos;
+	  arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
+
+	  mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
+	  edgesmap[ei]->draw();
+
+	  //reposition of edgetext
+	  XY text_pos=mytab.mapstorage.arrow_pos[ei];
+	  text_pos+=(XY(10,10));
+	  edgetextmap[ei]->property_x().set_value(text_pos.x);
+	  edgetextmap[ei]->property_y().set_value(text_pos.y);
+	}
+    }
+}
Index: graph_displayer_canvas.cc
===================================================================
--- graph_displayer_canvas.cc	(revision 157)
+++ graph_displayer_canvas.cc	(revision 160)
@@ -6,5 +6,6 @@
   nodetextmap(mainw.mapstorage.graph), displayed_graph(*(root()), 0, 0),
   isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""),
-  edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10), mytab(mainw)
+  edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10),
+  iterations(20), attraction(0.05), propulsation(40000), mytab(mainw)
 {
   //base event handler is move tool
@@ -252,2 +253,116 @@
   radius_p=radius_size;
 }
+
+void GraphDisplayerCanvas::reDesignGraph()
+{
+  double min_dist=40;
+
+  //iteration counter
+  for(int l=0;l<iterations;l++)
+    {
+      Graph::NodeMap<double> x(mytab.mapstorage.graph);
+      Graph::NodeMap<double> y(mytab.mapstorage.graph);
+      XYMap<Graph::NodeMap<double> > actual_forces;
+      actual_forces.setXMap(x);
+      actual_forces.setYMap(y);
+
+      lemon::dim2::Point<double> delta;
+
+      //count actual force for each nodes
+      for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
+	{
+	  //propulsation of nodes
+	  for (NodeIt j((mytab.mapstorage).graph); j!=INVALID; ++j)
+	    {
+	      if(i!=j)
+		{
+		  delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[j]);
+
+		  double length_sqr=delta.normSquare();
+		  double length=sqrt(length_sqr);
+		  if(length_sqr<min_dist)
+		    {
+		      length_sqr=min_dist;
+		    }
+
+		  //normalize vector
+		  delta/=length;
+
+		  //calculating propulsation strength
+		  //greater distance menas smaller propulsation strength
+		  delta*=propulsation/length_sqr;
+		    
+		  actual_forces.set(i,(actual_forces[i]+delta));
+		}
+	    }
+	  //attraction of nodes, to which actual node is bound
+	  for(OutEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
+	    {
+	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.target(ei)]);
+
+	      double length_sqr=delta.normSquare();
+	      double length=sqrt(length_sqr);
+	      if(length_sqr<min_dist)
+		{
+		  length_sqr=min_dist;
+		}
+
+	      //normalize vector
+	      delta/=length;
+
+	      //calculating attraction strength
+	      //greater distance means greater strength
+	      delta*=attraction*length;
+
+	      actual_forces.set(i,actual_forces[i]-delta);
+	    }
+	  for(InEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
+	    {
+	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.source(ei)]);
+
+	      double length_sqr=delta.normSquare();
+	      double length=sqrt(length_sqr);
+	      if(length_sqr<min_dist)
+		{
+		  length_sqr=min_dist;
+		}
+
+	      //normalize vector
+	      delta/=length;
+
+	      //calculating attraction strength
+	      //greater distance means greater strength
+	      delta*=attraction*length;
+
+	      actual_forces.set(i,actual_forces[i]-delta);
+	    }
+	}
+      for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
+	{
+	  moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
+	}
+    }
+}
+
+void GraphDisplayerCanvas::get_design_data(double & attraction_p, double & propulsation_p, int & iterations_p)
+{
+  attraction_p=attraction;
+  propulsation_p=propulsation;
+  iterations_p=iterations;
+}
+
+void GraphDisplayerCanvas::set_attraction(double attraction_p)
+{
+  attraction=attraction_p;
+}
+
+void GraphDisplayerCanvas::set_propulsation(double propulsation_p)
+{
+  propulsation=propulsation_p;
+}
+
+void GraphDisplayerCanvas::set_iteration(int iterations_p)
+{
+  iterations=iterations_p;
+}
+
Index: graph_displayer_canvas.h
===================================================================
--- graph_displayer_canvas.h	(revision 157)
+++ graph_displayer_canvas.h	(revision 160)
@@ -269,4 +269,8 @@
   bool mapEditEventHandler(GdkEvent*);
 
+private:
+  ///moves node according to the given parameters
+  void moveNode(double, double,  Gnome::Canvas::Item * item=NULL, Node node=INVALID);
+
 public:
   ///Moves the text to new place
@@ -314,4 +318,11 @@
   ///\param mapname name of new map
   int addNewEdgeMap(double init,std::string mapname);
+
+  void reDesignGraph();
+
+  void get_design_data(double &, double &, int &);
+  void set_attraction(double);
+  void set_propulsation(double);
+  void set_iteration(int);
 
 private:
@@ -399,4 +410,13 @@
   double edge_width;
 
+  ///Iteration number during graph design
+  int iterations;
+
+  ///Attraction factor during graph design
+  double attraction;
+
+  ///Propulsation factor during graph design
+  double propulsation;
+  
 private:
 
Index: main_win.cc
===================================================================
--- main_win.cc	(revision 158)
+++ main_win.cc	(revision 160)
@@ -100,4 +100,6 @@
   ag->add( Gtk::Action::create("ShowMaps", _("_Maps")),
 	   sigc::mem_fun(*this, &MainWin::createMapWin));
+  ag->add( Gtk::Action::create("ShowDesign", _("_Design")),
+	   sigc::mem_fun(*this, &MainWin::createDesignWin));
 
   ag->add( Gtk::Action::create("AlgoMenu", _("_Algorithms")) );
@@ -122,4 +124,7 @@
   ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap")),
       sigc::mem_fun ( *this , &MainWin::createNewMapWin ) );
+
+  ag->add( Gtk::Action::create("DesignGraph", Gtk::Stock::REFRESH),
+      sigc::mem_fun ( *this , &MainWin::reDesignGraph ) );
 
   uim=Gtk::UIManager::create();
@@ -150,4 +155,5 @@
       "    <menu action='ShowMenu'>"
       "      <menuitem action='ShowMaps'/>"
+      "      <menuitem action='ShowDesign'/>"
       "    </menu>"
       "    <menu action='AlgoMenu'>"
@@ -174,4 +180,5 @@
       "    <separator />"
       "    <toolitem action='AddMap' />"
+      "    <toolitem action='DesignGraph' />"
       "  </toolbar>"
       "</ui>";
@@ -449,4 +456,12 @@
 }
 
+void MainWin::createDesignWin()
+{
+  if(active_tab!=-1)
+    {
+      tabs[active_tab]->createDesignWin(tabnames[active_tab]);
+    }
+}
+
 void MainWin::createAlgoWin(int algoid)
 {
@@ -537,2 +552,7 @@
   tabs[active_tab]->setView(autoscale, zoomtrack, width, radius);
 }
+
+void MainWin::reDesignGraph()
+{
+  tabs[active_tab]->reDesignGraph();
+}
Index: main_win.h
===================================================================
--- main_win.h	(revision 157)
+++ main_win.h	(revision 160)
@@ -145,4 +145,10 @@
   ///\ref NoteBookTab
   virtual void createMapWin();
+
+  ///Callback for Show Design menupoint.
+
+  ///It calls the appropriate function in
+  ///\ref NoteBookTab
+  virtual void createDesignWin();
 
   ///Pops up an Algorithm window.
@@ -238,4 +244,6 @@
 
   virtual void nodeViewChanged();
+
+  virtual void reDesignGraph();
 };
 
Index: nbtab.cc
===================================================================
--- nbtab.cc	(revision 157)
+++ nbtab.cc	(revision 160)
@@ -1,5 +1,5 @@
 #include <nbtab.h>
 
-NoteBookTab::NoteBookTab():mapwinexists(false)
+NoteBookTab::NoteBookTab():mapwinexists(false), designwinexists(false)
 {
   Gtk::ScrolledWindow *pScrolledWindow = manage(new Gtk::ScrolledWindow);
@@ -208,4 +208,25 @@
 }
 
+void NoteBookTab::createDesignWin(std::string name)
+{
+  if(!designwinexists)
+    {
+      double attraction, propulsation;
+      int iterations;
+      gd_canvas->get_design_data(attraction, propulsation, iterations);
+      designwin=new DesignWin("Design Setup - "+name, attraction, propulsation, iterations);
+
+      designwin->signal_attraction().connect(sigc::mem_fun(*this, &NoteBookTab::attraction_ch));
+      designwin->signal_propulsation().connect(sigc::mem_fun(*this, &NoteBookTab::propulsation_ch));
+      designwin->signal_iteration().connect(sigc::mem_fun(*gd_canvas, &GraphDisplayerCanvas::set_iteration));
+      designwin->close_run().connect(sigc::mem_fun(*gd_canvas, &GraphDisplayerCanvas::reDesignGraph));
+
+      designwin->signal_delete_event().connect(sigc::mem_fun(*this, &NoteBookTab::closeDesignWin));
+
+      designwin->show();
+      designwinexists=true;
+    }
+}
+
 void NoteBookTab::closeMapWin()
 {
@@ -214,4 +235,13 @@
 }
 
+bool NoteBookTab::closeDesignWin(GdkEventAny * e)
+{
+  if(e->type==GDK_DELETE)
+    {
+      designwinexists=false;
+      delete designwin;
+    }
+}
+
 sigc::signal<void, std::string> NoteBookTab::signal_title_ch()
 {
@@ -228,2 +258,23 @@
   gd_canvas->getView(autoscale, zoomtrack, width, radius);
 }
+
+void NoteBookTab::reDesignGraph()
+{
+  gd_canvas->reDesignGraph();
+}
+
+void NoteBookTab::attraction_ch(double v)
+{
+  gd_canvas->set_attraction(v);
+}
+
+void NoteBookTab::propulsation_ch(double v)
+{
+  gd_canvas->set_propulsation(v);
+}
+
+void NoteBookTab::iteration_ch(int v)
+{
+  gd_canvas->set_iteration(v);
+}
+
Index: nbtab.h
===================================================================
--- nbtab.h	(revision 157)
+++ nbtab.h	(revision 160)
@@ -8,4 +8,5 @@
 #include "mapstorage.h"
 #include "map_win.h"
+#include "design_win.h"
 #include "graph_displayer_canvas.h"
 #include <libgnomecanvasmm.h>
@@ -78,4 +79,7 @@
   bool mapwinexists;
 
+  ///Indicates whether the \ref DesignWin is opened or not. See \ref designwin.
+  bool designwinexists;
+
   ///Address of the only \ref MapWin that the \ref NoteBookTab can open.
 
@@ -86,4 +90,12 @@
   MapWin * mapwin;
     
+  ///Address of the only \ref DesignWin that the \ref NoteBookTab can open.
+
+  ///Only one of this window can be opened at the same time (\ref designwinexists), 
+  ///because there is no need for more, one per tab is enough.
+  ///There won't be benefit of more than one, but it would be
+  ///more complicated to synchronize them.
+  DesignWin * designwin;
+
 public:
   ///Callback for 'FileNew' action.
@@ -152,4 +164,10 @@
   void createMapWin(std::string);
 
+  ///Pops up and registrates the \ref DesignWin of \ref NoteBookTab.
+  
+  ///See also
+  ///\ref mapwin.
+  void createDesignWin(std::string);
+
   ///Closes and deregistrates the \ref MapWin of \ref NoteBookTab.
   
@@ -158,4 +176,6 @@
   void closeMapWin();
 
+  bool closeDesignWin(GdkEventAny *);
+
   ///Sets node representation settings
   void setView(bool, bool, double, double);
@@ -163,4 +183,12 @@
   ///Gets node representation settings
   void getView(bool &, bool &, double&, double&);
+
+  void reDesignGraph();
+
+  void attraction_ch(double);
+
+  void propulsation_ch(double);
+
+  void iteration_ch(int);
 };
 
