[Lemon-commits] ladanyi: r3432 - glemon/trunk

Lemon SVN svn at lemon.cs.elte.hu
Wed Jan 2 22:03:14 CET 2008


Author: ladanyi
Date: Wed Jan  2 22:03:09 2008
New Revision: 3432

Added:
   glemon/trunk/file_import_dialog.cc
   glemon/trunk/file_import_dialog.h
   glemon/trunk/io_helper.cc
   glemon/trunk/io_helper.h
   glemon/trunk/map_value.cc
   glemon/trunk/map_value.h
   glemon/trunk/map_value_map.cc
   glemon/trunk/map_value_map.h
   glemon/trunk/save_details_dialog.cc
   glemon/trunk/save_details_dialog.h
   glemon/trunk/save_details_widget.cc
   glemon/trunk/save_details_widget.h
Modified:
   glemon/trunk/Makefile.am
   glemon/trunk/algobox.cc
   glemon/trunk/algobox.h
   glemon/trunk/all_include.h
   glemon/trunk/configure.ac
   glemon/trunk/dijkstrabox.cc
   glemon/trunk/eps_win.cc
   glemon/trunk/eps_win.h
   glemon/trunk/gdc-broken_edge.cc
   glemon/trunk/graph-displayer.cc
   glemon/trunk/graph_displayer_canvas-edge.cc
   glemon/trunk/graph_displayer_canvas-event.cc
   glemon/trunk/graph_displayer_canvas-node.cc
   glemon/trunk/graph_displayer_canvas.cc
   glemon/trunk/gui_reader.cc
   glemon/trunk/gui_reader.h
   glemon/trunk/gui_writer.cc
   glemon/trunk/kruskalbox.cc
   glemon/trunk/main_win.cc
   glemon/trunk/main_win.h
   glemon/trunk/map_win.cc
   glemon/trunk/map_win.h
   glemon/trunk/mapselector.cc
   glemon/trunk/mapselector.h
   glemon/trunk/mapstorage.cc
   glemon/trunk/mapstorage.h
   glemon/trunk/nbtab.cc
   glemon/trunk/nbtab.h
   glemon/trunk/new_map_win.cc
   glemon/trunk/new_map_win.h
   glemon/trunk/xml.h

Log:
Merge branches/akos to trunk.


Modified: glemon/trunk/Makefile.am
==============================================================================
--- glemon/trunk/Makefile.am	(original)
+++ glemon/trunk/Makefile.am	Wed Jan  2 22:03:09 2008
@@ -47,6 +47,18 @@
 	design_win.cc \
 	dijkstrabox.h \
 	dijkstrabox.cc \
+	file_import_dialog.h \
+	file_import_dialog.cc \
+	map_value.h \
+	map_value.cc \
+	map_value_map.h \
+	map_value_map.cc \
+	save_details_widget.h \
+	save_details_widget.cc \
+	save_details_dialog.h \
+	save_details_dialog.cc \
+	io_helper.h \
+	io_helper.cc \
 	background_chooser_dialog.h \
 	background_chooser_dialog.cc \
 	eps_win.h \

Modified: glemon/trunk/algobox.cc
==============================================================================
--- glemon/trunk/algobox.cc	(original)
+++ glemon/trunk/algobox.cc	Wed Jan  2 22:03:09 2008
@@ -82,41 +82,45 @@
 void AlgoBox::update_maplist(MapStorage * ms)
 {
   mapstorage=ms;
-  std::vector<std::string> nml;
-  std::vector<std::string> eml;
+  std::vector<std::string> n_nml;
+  std::vector<std::string> s_nml;
+  std::vector<std::string> n_eml;
+  std::vector<std::string> s_eml;
   if(mapstorage!=NULL)
     {
       mapstorage->signal_node_map_ch().connect(sigc::mem_fun(*this, &AlgoBox::nodemaplist_changed));
       mapstorage->signal_edge_map_ch().connect(sigc::mem_fun(*this, &AlgoBox::edgemaplist_changed));
-      nml=mapstorage->getNodeMapList();
-      eml=mapstorage->getEdgeMapList();
+      n_nml=mapstorage->getNodeMapList(NUM);
+      s_nml=mapstorage->getNodeMapList(STR);
+      n_eml=mapstorage->getEdgeMapList(NUM);
+      s_eml=mapstorage->getEdgeMapList(STR);
     }
   for(int i=0;i<(int)nodemapcbts.size();i++)
     {
-      (nodemapcbts[i])->update_list(nml);
+      (nodemapcbts[i])->update_list(n_nml, s_nml);
       //update_cbt(nml, *(nodemapcbts[i]));
     }
   for(int i=0;i<(int)edgemapcbts.size();i++)
     {
-      (edgemapcbts[i])->update_list(eml);
+      (edgemapcbts[i])->update_list(n_eml, s_eml);
       //update_cbt(eml, *(edgemapcbts[i]));
     }
   signal_maplist_updated.emit();
 }
 
-void AlgoBox::nodemaplist_changed(std::string newmap)
+void AlgoBox::nodemaplist_changed(std::string newmap, MapValue::Type type)
 {
   for(int i=0;i<(int)nodemapcbts.size();i++)
     {
-      (nodemapcbts[i])->append_text(newmap);
+      (nodemapcbts[i])->append_text(newmap, type);
     }
 }
 
-void AlgoBox::edgemaplist_changed(std::string newmap)
+void AlgoBox::edgemaplist_changed(std::string newmap, MapValue::Type type)
 {
   for(int i=0;i<(int)edgemapcbts.size();i++)
     {
-      (edgemapcbts[i])->append_text(newmap);
+      (edgemapcbts[i])->append_text(newmap, type);
     }
 }
 
@@ -160,11 +164,11 @@
   pack_start(*(new Gtk::HSeparator()));
 }
 
-void AlgoBox::addMapSelector(std::string inputname, bool itisedge)
+void AlgoBox::addMapSelector(std::string inputname, bool itisedge, MapType type)
 {
   std::vector<std::string> empty_vector;
 
-  MapSelector * msp=new MapSelector(empty_vector,"",inputname,itisedge, false);
+  MapSelector * msp=new MapSelector(empty_vector,empty_vector,"",inputname,itisedge, false, type);
 
   if(itisedge)
     {

Modified: glemon/trunk/algobox.h
==============================================================================
--- glemon/trunk/algobox.h	(original)
+++ glemon/trunk/algobox.h	Wed Jan  2 22:03:09 2008
@@ -25,6 +25,7 @@
 #include <all_include.h>
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include "map_value.h"
 
 ///Ancestor class of algorithm graphical interface classes.
 
@@ -138,14 +139,14 @@
   ///If new map was added to \ref MapStorage of currently selected \ref NoteBookTab
   ///a signal is emitted by it. This signal is connected to this function, so \ref MapSelector s
   ///in \ref nodemapcbts can be notified, and those can registrate the new map. (\ref MapSelector::append_text)
-  void nodemaplist_changed(std::string);
+  void nodemaplist_changed(std::string, MapValue::Type);
 
   ///Interface, through which \ref AlgoBox can be notified about edgemap addition.
 
   ///If new map was added to \ref MapStorage of currently selected \ref NoteBookTab
   ///a signal is emitted by it. This signal is connected to this function, so \ref MapSelector s
   ///in \ref edgemapcbts can be notified, and those can registrate the new map. (\ref MapSelector::append_text)
-  void edgemaplist_changed(std::string);
+  void edgemaplist_changed(std::string, MapValue::Type);
 
   ///Aid function to provide data for a given entry.
 
@@ -183,6 +184,6 @@
 
   ///\param label label to show in \ref MapSelector
   ///\param itisedge whether edge or nodemaps stored in \ref MapSelector
-  void addMapSelector(std::string label, bool itisedge);
+  void addMapSelector(std::string label, bool itisedge, MapType type = ALL);
 };
 #endif //ALGOBOX_H

Modified: glemon/trunk/all_include.h
==============================================================================
--- glemon/trunk/all_include.h	(original)
+++ glemon/trunk/all_include.h	Wed Jan  2 22:03:09 2008
@@ -65,4 +65,11 @@
 
 const std::string prog_name = "LEMON Graph Editor";
 
+enum MapType
+{
+  NUM  = 1 << 0,
+  STR  = 1 << 1,
+  ALL  = (1 << 0) | (1 << 1)
+};
+
 #endif // ALL_INCLUDE_H

Modified: glemon/trunk/configure.ac
==============================================================================
--- glemon/trunk/configure.ac	(original)
+++ glemon/trunk/configure.ac	Wed Jan  2 22:03:09 2008
@@ -26,33 +26,13 @@
 dnl Checks for libraries.
 PKG_CHECK_MODULES([GTK], [libgnomecanvasmm-2.6 >= 2.6.0 gtkmm-2.4 >= 2.6])
 
-AC_ARG_WITH([lemon-prefix],
-AS_HELP_STRING([--with-lemon-prefix@<:@=PREFIX@:>@], [search for LEMON under PREFIX]), [], [with_lemon_prefix=no])
-if test x"$with_lemon_prefix" != x"no"; then
-  export PKG_CONFIG_PATH="$with_lemon_prefix/lib/pkgconfig/:$PKG_CONFIG_PATH"
+AC_ARG_WITH([lemon],
+AS_HELP_STRING([--with-lemon@<:@=PREFIX@:>@], [search for LEMON under PREFIX]), [], [with_lemon=no])
+if test x"$with_lemon" != x"no"; then
+  export PKG_CONFIG_PATH="$with_lemon/lib/pkgconfig/:$PKG_CONFIG_PATH"
 fi
 
-PKG_CHECK_MODULES([LEMON_0_5], [lemon >= 0.5],
-  [lemon_0_5_found=yes], [
-    AC_MSG_RESULT([no])
-    lemon_0_5_found=no])
-PKG_CHECK_MODULES([LEMON_SVNHEAD], [lemon = svnhead],
-  [lemon_svn_head_found=yes], [
-    AC_MSG_RESULT([no])
-    lemon_svn_head_found=no])
-if test x"$lemon_0_5_found" = x"no" -a x"$lemon_svn_head_found" = x"no"; then
-  AC_MSG_ERROR([LEMON not found.])
-else
-  if test x"$lemon_svn_head_found" = x"yes"; then
-    LEMON_CFLAGS="$LEMON_SVNHEAD_CFLAGS"
-    LEMON_LIBS="$LEMON_SVNHEAD_LIBS"
-  else
-    LEMON_CFLAGS="$LEMON_0_5_CFLAGS"
-    LEMON_LIBS="$LEMON_0_5_LIBS"
-  fi
-  AC_SUBST(LEMON_CFLAGS)
-  AC_SUBST(LEMON_LIBS)
-fi
+PKG_CHECK_MODULES([LEMON], [lemon >= 0.6.90])
 
 dnl Checks for header files.
 AC_CHECK_HEADERS([libintl.h locale.h])

Modified: glemon/trunk/dijkstrabox.cc
==============================================================================
--- glemon/trunk/dijkstrabox.cc	(original)
+++ glemon/trunk/dijkstrabox.cc	Wed Jan  2 22:03:09 2008
@@ -52,63 +52,64 @@
 void DijkstraBox::run()
 {
   if(
-     tabcbt.get_active_text()!="" &&
-     (edgemapcbts[INPUT])->get_active_text()!="" &&
-     (edgemapcbts[OUTPUT])->get_active_text()!="" &&
-     source.get_active_text()!="" &&
-     target.get_active_text()!=""
-     )
-    {
-      const Graph &g=mapstorage->graph;
-      Node from, to;
+      tabcbt.get_active_text()!="" &&
+      (edgemapcbts[INPUT])->get_active_text()!="" &&
+      (edgemapcbts[OUTPUT])->get_active_text()!="" &&
+      source.get_active_text()!="" &&
+      target.get_active_text()!=""
+    )
+  {
+    const Graph &g=mapstorage->graph;
+    Node from, to;
 
-      get_from_to(from, to, (Graph&)g);
+    get_from_to(from, to, (Graph&)g);
 
-      std::ostringstream o;
+    std::ostringstream o;
 
-      if(!(from==to))
-	{
-	  Graph::EdgeMap<double> * inputmap=
-	    (mapstorage->edgemap_storage)[(edgemapcbts[INPUT])->get_active_text()];
-	  Graph::EdgeMap<double> * outputmap=
-	    (mapstorage->edgemap_storage)[(edgemapcbts[OUTPUT])->get_active_text()];
+    if(!(from==to))
+    {
+      std::string inputmapName = edgemapcbts[INPUT]->get_active_text();
+      std::string outputmapName = edgemapcbts[OUTPUT]->get_active_text();
 
-	  //zero out output map
-	  for (EdgeIt i(g); i!=INVALID; ++i)
-	    {
-	      (*outputmap)[i]=0;
-	    }
-	  
-	  Dijkstra<Graph, Graph::EdgeMap<double> > dijkstra(g, *inputmap);
-	  dijkstra.run(from, to);
-	  
-	  if(dijkstra.reached(to))
-	    {
-	      Node n=to;
-	      int length=0;
-	      while (n!=INVALID && n!=from)
-		{
-		  Edge e=dijkstra.predEdge(n);
-		  (*outputmap)[e]=1;
-		  n=dijkstra.predNode(n);
-		  length++;
-		}
-	      o << "Result: " << length << " long path, with cost " << dijkstra.dist(to);
-	    }
-	  else
-	    {
-	      o << "Result: failed to find shortest path between ";
-	      o << source.get_active_text() << " and " << target.get_active_text();
-	    }
-	  resultlabel.set_text(o.str());
-	  
-	  mapstorage->mapChanged(true, (edgemapcbts[OUTPUT])->get_active_text());
-	  //   mapstorage->changeActiveMap(true, E_COLOR,
-	  // 			      (edgemapcbts[OUTPUT])->get_active_text());
-	  //   mapstorage->changeActiveMap(true, E_TEXT,
-	  // 			      (edgemapcbts[INPUT])->get_active_text());
-	}
+      MapStorage::NumericEdgeMap& inputmap = mapstorage->getNumericEdgeMap(inputmapName);
+      MapStorage::NumericEdgeMap& outputmap = mapstorage->getNumericEdgeMap(outputmapName);
+
+      //zero out output map
+      for (EdgeIt i(g); i!=INVALID; ++i)
+      {
+        outputmap[i]=0;
+      }
+
+      Dijkstra<Graph, MapStorage::NumericEdgeMap > dijkstra(g, inputmap);
+      dijkstra.run(from, to);
+
+      if(dijkstra.reached(to))
+      {
+        Node n=to;
+        int length=0;
+        while (n!=INVALID && n!=from)
+        {
+          Edge e=dijkstra.predEdge(n);
+          outputmap[e]=1;
+          n=dijkstra.predNode(n);
+          length++;
+        }
+        o << "Result: " << length << " long path, with cost " << dijkstra.dist(to);
+      }
+      else
+      {
+        o << "Result: failed to find shortest path between ";
+        o << source.get_active_text() << " and " << target.get_active_text();
+      }
+      resultlabel.set_text(o.str());
+
+      mapstorage->mapChanged(true, (edgemapcbts[OUTPUT])->get_active_text());
+      //   mapstorage->changeActiveMap(true, E_COLOR,
+      // 			      (edgemapcbts[OUTPUT])->get_active_text());
+      //   mapstorage->changeActiveMap(true, E_TEXT,
+      // 			      (edgemapcbts[INPUT])->get_active_text());
     }
+  }
 }
 
 void SuurballeBox::run()
@@ -130,18 +131,18 @@
 
       if(!(from==to))
 	{
-	  Graph::EdgeMap<double> * inputmap=
-	    (mapstorage->edgemap_storage)[(edgemapcbts[INPUT])->get_active_text()];
-	  Graph::EdgeMap<double> * outputmap=
-	    (mapstorage->edgemap_storage)[(edgemapcbts[OUTPUT])->get_active_text()];
+          MapStorage::NumericEdgeMap& inputmap=
+	    mapstorage->getNumericEdgeMap(edgemapcbts[INPUT]->get_active_text());
+          MapStorage::NumericEdgeMap& outputmap=
+	    mapstorage->getNumericEdgeMap(edgemapcbts[OUTPUT]->get_active_text());
 
 	  //zero out output map
 	  for (EdgeIt i(g); i!=INVALID; ++i)
 	    {
-	      (*outputmap)[i]=0;
+	      outputmap[i]=0;
 	    }
 	  
-	  Suurballe<Graph, Graph::EdgeMap<double> > sb((Graph&)g, *inputmap, from, to);
+	  Suurballe<Graph, MapStorage::NumericEdgeMap > sb((Graph&)g, inputmap, from, to);
 	  
 	  int found=sb.run(num_set->get_value_as_int());
 	  if(found)
@@ -152,7 +153,7 @@
 		  path=sb.path(j);
 		  for(int k=0;k<path.length();k++)
 		    {
-		      (*outputmap)[path.nth(k)]=j+1;
+		      outputmap[path.nth(k)]=j+1;
 		    }
 		}
 	      o << "Result: found " << found << " paths between ";
@@ -180,8 +181,8 @@
   //this can be done after the maps are loaded into ComboBoxes
   signal_upon_maplist_updated().connect(sigc::mem_fun(*this, &DijkstraBox::maplists_updated));
 
-  addMapSelector("Cost map: ", true);
-  addMapSelector("Edges of path here: ", true);
+  addMapSelector("Cost map: ", true, NUM);
+  addMapSelector("Edges of path here: ", true, NUM);
 
   Gtk::Label * source_label=new Gtk::Label("Source: ");
   Gtk::Label * target_label=new Gtk::Label("Target: ");
@@ -212,7 +213,7 @@
       for (NodeIt i(g); i!=INVALID; ++i)
 	{
 	  std::ostringstream text;
-	  text << (*((mapstorage->nodemap_storage)["label"]))[i];
+	  text << mapstorage->getLabel(i);
 	  source.prepend_text(text.str());
 	  target.prepend_text(text.str());
 	}
@@ -225,7 +226,7 @@
   for (NodeIt i(g); (i!=INVALID) && (assigned<2); ++i)
     {
       std::ostringstream text;
-      text << (*((mapstorage->nodemap_storage)["label"]))[i];
+      text << mapstorage->getLabel(i);
       if(!(text.str().compare(source.get_active_text())))
 	{
 	  from=i;

Modified: glemon/trunk/eps_win.cc
==============================================================================
--- glemon/trunk/eps_win.cc	(original)
+++ glemon/trunk/eps_win.cc	Wed Jan  2 22:03:09 2008
@@ -31,7 +31,7 @@
   return true;
 }
 
-EpsWin::EpsWin(const std::string& title, std::vector<std::string> nml):Gtk::Dialog(title, true, true)
+EpsWin::EpsWin(const std::string& title, std::vector<std::string> n_nml, std::vector<std::string> s_nml):Gtk::Dialog(title, true, true)
 {
   set_default_size(200, 50);
 
@@ -57,7 +57,7 @@
       (*table).attach(*(options[i]),0,1,i,i+1,Gtk::FILL,Gtk::SHRINK,10,3);
     }
 
-  mapselector=new MapSelector(nml, "", "Nodeshapes", false);
+  mapselector=new MapSelector(n_nml, s_nml, "", "Nodeshapes", false, true, NUM);
   mapselector->signal_newmapwin_needed().connect(sigc::mem_fun(*this, &EpsWin::newMapWinNeeded));
 
   hbox.pack_start(*(new Gtk::Label("Filename")));
@@ -104,7 +104,7 @@
   signal_new_map.emit(false);
 }
 
-void EpsWin::registerNewNodeMap(std::string newmapname)
+void EpsWin::registerNewNodeMap(std::string newmapname, MapValue::Type type)
 {
-    mapselector->append_text((Glib::ustring)newmapname);
+    mapselector->append_text((Glib::ustring)newmapname, type);
 }

Modified: glemon/trunk/eps_win.h
==============================================================================
--- glemon/trunk/eps_win.h	(original)
+++ glemon/trunk/eps_win.h	Wed Jan  2 22:03:09 2008
@@ -24,6 +24,7 @@
 #include <all_include.h>
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include "map_value.h"
 
 ///Graph visualization setup window.
 
@@ -61,7 +62,7 @@
   ///\param eml edgemap list
   ///\param nml nodemap list
   ///\param mw the owner \ref NoteBookTab (\ref mytab)
-  EpsWin(const std::string& title, std::vector<std::string>);
+  EpsWin(const std::string& title, std::vector<std::string>, std::vector<std::string>);
 
   ///Deregistrates \ref EpsWin in its \ref NoteBookTab (\ref mytab)
   virtual bool on_delete_event(GdkEventAny *);
@@ -102,7 +103,7 @@
 
   ///\param new_name
   ///name of new map
-  void registerNewNodeMap(std::string new_name);
+  void registerNewNodeMap(std::string new_name, MapValue::Type type);
 };
 
 #endif //EPS_WIN_H

Added: glemon/trunk/file_import_dialog.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/file_import_dialog.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,928 @@
+#include "file_import_dialog.h"
+#include <gtkmm/dialog.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/messagedialog.h>
+#include <gtkmm/frame.h>
+#include <iostream>
+
+FileImportDialog::FileImportDialog(ImportData* d) :
+  p_data(d)
+{
+  add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+  add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
+
+  Gtk::VBox* pVBox = get_vbox();
+
+  Gtk::Notebook* nb = Gtk::manage(new Gtk::Notebook);
+  pVBox->pack_start(*nb, Gtk::PACK_EXPAND_WIDGET);
+
+  Gtk::VBox* vbNodeMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbNodeMaps->set_border_width(12);
+
+  Gtk::VBox* vbEdgeMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbEdgeMaps->set_border_width(12);
+
+  Gtk::VBox* vbSpecMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbSpecMaps->set_border_width(12);
+
+  nb->append_page(*vbSpecMaps, "Special Maps");
+  nb->append_page(*vbNodeMaps, "Node Maps");
+  nb->append_page(*vbEdgeMaps, "Edge Maps");
+
+  // child widgets of vbSpecMaps
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    {
+      Gtk::Label* label1 =
+        Gtk::manage(new Gtk::Label("<b>Node Coordinates</b>"));
+      label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+      label1->set_use_markup();
+      box1->pack_start(*label1);
+
+      Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+      box1->pack_start(*box2);
+
+      Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+      box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox);
+      box2->pack_start(*box3);
+
+      Gtk::VBox* box13 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box13);
+
+      rbNodeCoordNone.set_label("None");
+      Gtk::RadioButtonGroup group = rbNodeCoordNone.get_group();
+      box13->pack_start(rbNodeCoordNone);
+
+      Gtk::VBox* box4 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box4);
+
+      rbNodeCoordOneMap.set_label("One Map");
+      rbNodeCoordOneMap.set_group(group);
+      box4->pack_start(rbNodeCoordOneMap);
+
+      Gtk::HBox* box5 = Gtk::manage(new Gtk::HBox);
+      box4->pack_start(*box5);
+
+      Gtk::Label* fill2 = Gtk::manage(new Gtk::Label("    "));
+      box5->pack_start(*fill2, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box6 = Gtk::manage(new Gtk::VBox);
+      box5->pack_start(*box6);
+
+      Gtk::HBox* box7 = Gtk::manage(new Gtk::HBox);
+      box6->pack_start(*box7);
+
+      Gtk::Label* label2 = Gtk::manage(new Gtk::Label("(X, Y)"));
+      box7->pack_start(*label2, Gtk::PACK_SHRINK, 4);
+
+      box7->pack_start(cbNodeCoordOneMap, Gtk::PACK_EXPAND_WIDGET);
+
+
+      Gtk::VBox* box8 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box8);
+
+      rbNodeCoordTwoMaps.set_label("Two Maps");
+      rbNodeCoordTwoMaps.set_group(group);
+      box8->pack_start(rbNodeCoordTwoMaps);
+
+      Gtk::HBox* box9 = Gtk::manage(new Gtk::HBox);
+      box8->pack_start(*box9);
+
+      Gtk::Label* fill3 = Gtk::manage(new Gtk::Label("    "));
+      box9->pack_start(*fill3, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box10 = Gtk::manage(new Gtk::VBox);
+      box9->pack_start(*box10);
+
+      Gtk::HBox* box11 = Gtk::manage(new Gtk::HBox);
+      box10->pack_start(*box11);
+
+      Gtk::Label* label3 = Gtk::manage(new Gtk::Label("X"));
+      box11->pack_start(*label3, Gtk::PACK_SHRINK, 4);
+
+      box11->pack_start(cbNodeCoordTwoMaps1, Gtk::PACK_EXPAND_WIDGET);
+
+      Gtk::HBox* box12 = Gtk::manage(new Gtk::HBox);
+      box10->pack_start(*box12);
+
+      Gtk::Label* label4 = Gtk::manage(new Gtk::Label("Y"));
+      box12->pack_start(*label4, Gtk::PACK_SHRINK, 4);
+
+      box12->pack_start(cbNodeCoordTwoMaps2, Gtk::PACK_EXPAND_WIDGET);
+
+      cbNodeCoordOneMap.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onNodeCoordOneMapChanged));
+      cbNodeCoordTwoMaps1.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onNodeCoordTwoMaps1Changed));
+      cbNodeCoordTwoMaps2.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onNodeCoordTwoMaps2Changed));
+    }
+
+    {
+      Gtk::Label* label1 =
+        Gtk::manage(new Gtk::Label("<b>Arrow Coordinates</b>"));
+      label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+      label1->set_use_markup();
+      box1->pack_start(*label1);
+
+      Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+      box1->pack_start(*box2);
+
+      Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+      box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox);
+      box2->pack_start(*box3);
+
+      Gtk::VBox* box13 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box13);
+
+      rbArrowCoordNone.set_label("None");
+      Gtk::RadioButtonGroup group = rbArrowCoordNone.get_group();
+      box13->pack_start(rbArrowCoordNone);
+
+      Gtk::VBox* box4 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box4);
+
+      rbArrowCoordOneMap.set_label("One Map");
+      rbArrowCoordOneMap.set_group(group);
+      box4->pack_start(rbArrowCoordOneMap);
+
+      Gtk::HBox* box5 = Gtk::manage(new Gtk::HBox);
+      box4->pack_start(*box5);
+
+      Gtk::Label* fill2 = Gtk::manage(new Gtk::Label("    "));
+      box5->pack_start(*fill2, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box6 = Gtk::manage(new Gtk::VBox);
+      box5->pack_start(*box6);
+
+      Gtk::HBox* box7 = Gtk::manage(new Gtk::HBox);
+      box6->pack_start(*box7);
+
+      Gtk::Label* label2 = Gtk::manage(new Gtk::Label("(X, Y)"));
+      box7->pack_start(*label2, Gtk::PACK_SHRINK, 4);
+
+      box7->pack_start(cbArrowCoordOneMap, Gtk::PACK_EXPAND_WIDGET);
+
+
+      Gtk::VBox* box8 = Gtk::manage(new Gtk::VBox);
+      box3->pack_start(*box8);
+
+      rbArrowCoordTwoMaps.set_label("Two Maps");
+      rbArrowCoordTwoMaps.set_group(group);
+      box8->pack_start(rbArrowCoordTwoMaps);
+
+      Gtk::HBox* box9 = Gtk::manage(new Gtk::HBox);
+      box8->pack_start(*box9);
+
+      Gtk::Label* fill3 = Gtk::manage(new Gtk::Label("    "));
+      box9->pack_start(*fill3, Gtk::PACK_SHRINK);
+
+      Gtk::VBox* box10 = Gtk::manage(new Gtk::VBox);
+      box9->pack_start(*box10);
+
+      Gtk::HBox* box11 = Gtk::manage(new Gtk::HBox);
+      box10->pack_start(*box11);
+
+      Gtk::Label* label3 = Gtk::manage(new Gtk::Label("X"));
+      box11->pack_start(*label3, Gtk::PACK_SHRINK, 4);
+
+      box11->pack_start(cbArrowCoordTwoMaps1, Gtk::PACK_EXPAND_WIDGET);
+
+      Gtk::HBox* box12 = Gtk::manage(new Gtk::HBox);
+      box10->pack_start(*box12);
+
+      Gtk::Label* label4 = Gtk::manage(new Gtk::Label("Y"));
+      box12->pack_start(*label4, Gtk::PACK_SHRINK, 4);
+
+      box12->pack_start(cbArrowCoordTwoMaps2, Gtk::PACK_EXPAND_WIDGET);
+
+      cbArrowCoordOneMap.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onArrowCoordOneMapChanged));
+      cbArrowCoordTwoMaps1.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onArrowCoordTwoMaps1Changed));
+      cbArrowCoordTwoMaps2.signal_changed().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onArrowCoordTwoMaps2Changed));
+    }
+  }
+
+  // child widgets of vbNodeMaps
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbNodeMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* label1 =
+      Gtk::manage(new Gtk::Label("<b>Element type</b>"));
+    label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    label1->set_use_markup();
+    box1->pack_start(*label1, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);
+    box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
+
+    Gtk::ScrolledWindow* swNodeMaps = Gtk::manage(new Gtk::ScrolledWindow);
+    frame->add(*swNodeMaps);
+
+    swNodeMaps->add(twNodeMaps);
+
+    refNodeMapStore = Gtk::ListStore::create(NodeMapColumns);
+
+    for (std::vector<std::string>::const_iterator it =
+        p_data->node_map_names.begin(); it != p_data->node_map_names.end();
+        ++it)
+    {
+      node_tree_view_records.push_back(
+          tree_view_record(*it, false, false, true));
+    }
+
+    twNodeMaps.set_model(refNodeMapStore);
+    twNodeMaps.append_column("Name", NodeMapColumns.colName);
+    {
+      int col = twNodeMaps.append_column_editable("Numeric",
+          NodeMapColumns.colReadAsNumeric);
+      Gtk::CellRendererToggle* pRenderer =
+        static_cast<Gtk::CellRendererToggle*>(
+            twNodeMaps.get_column_cell_renderer(col-1));
+      pRenderer->signal_toggled().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onNodeMapNumericToggled));
+    }
+    {
+      int col = twNodeMaps.append_column_editable("String",
+          NodeMapColumns.colReadAsString);
+      Gtk::CellRendererToggle* pRenderer =
+        static_cast<Gtk::CellRendererToggle*>(
+            twNodeMaps.get_column_cell_renderer(col-1));
+      pRenderer->signal_toggled().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onNodeMapStringToggled));
+    }
+
+    swNodeMaps->set_size_request(-1, 200);
+    swNodeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+  }
+
+  // child widgets of vbEdgeMaps
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbEdgeMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* label1 =
+      Gtk::manage(new Gtk::Label("<b>Element type</b>"));
+    label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    label1->set_use_markup();
+    box1->pack_start(*label1, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);
+    box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
+
+    Gtk::ScrolledWindow* swEdgeMaps = Gtk::manage(new Gtk::ScrolledWindow);
+    frame->add(*swEdgeMaps);
+
+    swEdgeMaps->add(twEdgeMaps);
+
+    refEdgeMapStore = Gtk::ListStore::create(EdgeMapColumns);
+
+    for (std::vector<std::string>::const_iterator it =
+        p_data->edge_map_names.begin(); it != p_data->edge_map_names.end();
+        ++it)
+    {
+      edge_tree_view_records.push_back(
+          tree_view_record(*it, false, false, true));
+    }
+
+    twEdgeMaps.set_model(refEdgeMapStore);
+    twEdgeMaps.append_column("Name", EdgeMapColumns.colName);
+    {
+      int col = twEdgeMaps.append_column_editable("Numeric",
+          EdgeMapColumns.colReadAsNumeric);
+      Gtk::CellRendererToggle* pRenderer =
+        static_cast<Gtk::CellRendererToggle*>(
+            twEdgeMaps.get_column_cell_renderer(col-1));
+      pRenderer->signal_toggled().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onEdgeMapNumericToggled));
+    }
+    {
+      int col = twEdgeMaps.append_column_editable("String",
+          EdgeMapColumns.colReadAsString);
+      Gtk::CellRendererToggle* pRenderer =
+        static_cast<Gtk::CellRendererToggle*>(
+            twEdgeMaps.get_column_cell_renderer(col-1));
+      pRenderer->signal_toggled().connect(
+          sigc::mem_fun(*this, &FileImportDialog::onEdgeMapStringToggled));
+    }
+
+    swEdgeMaps->set_size_request(-1, 200);
+    swEdgeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+  }
+
+  // fill in the ComboBoxes
+  typedef std::vector<std::string> StrVec;
+  for (StrVec::const_iterator it = p_data->node_map_names.begin();
+      it != p_data->node_map_names.end(); ++it)
+  {
+    cbNodeCoordTwoMaps1.append_text(*it);
+    cbNodeCoordTwoMaps2.append_text(*it);
+  }
+  for (StrVec::const_iterator it = p_data->edge_map_names.begin();
+      it != p_data->edge_map_names.end(); ++it)
+  {
+    cbArrowCoordTwoMaps1.append_text(*it);
+    cbArrowCoordTwoMaps2.append_text(*it);
+  }
+  for (StrVec::const_iterator it = p_data->xy_node_map_names.begin();
+      it != p_data->xy_node_map_names.end(); ++it)
+  {
+    cbNodeCoordOneMap.append_text(*it);
+  }
+  for (StrVec::const_iterator it = p_data->xy_edge_map_names.begin();
+      it != p_data->xy_edge_map_names.end(); ++it)
+  {
+    cbArrowCoordOneMap.append_text(*it);
+  }
+
+  if (p_data->isXYNodeMap("coord"))
+  {
+    cbNodeCoordOneMap.set_active_text("coord");
+  }
+  else if (p_data->isXYNodeMap("coords"))
+  {
+    cbNodeCoordOneMap.set_active_text("coords");
+  }
+  else if (p_data->isNodeMap("coord_x") &&
+           p_data->isNodeMap("coord_y"))
+  {
+    cbNodeCoordTwoMaps1.set_active_text("coord_x");
+    cbNodeCoordTwoMaps2.set_active_text("coord_y");
+  }
+  else if (p_data->isNodeMap("coords_x") &&
+           p_data->isNodeMap("coords_y"))
+  {
+    cbNodeCoordTwoMaps1.set_active_text("coords_x");
+    cbNodeCoordTwoMaps2.set_active_text("coords_y");
+  }
+  else if (p_data->isNodeMap("x") &&
+           p_data->isNodeMap("y"))
+  {
+    cbNodeCoordTwoMaps1.set_active_text("x");
+    cbNodeCoordTwoMaps2.set_active_text("y");
+  }
+
+  if (p_data->isXYEdgeMap("arrow"))
+  {
+    cbArrowCoordOneMap.set_active_text("arrow");
+  }
+  else if (p_data->isXYEdgeMap("arrows"))
+  {
+    cbArrowCoordOneMap.set_active_text("arrows");
+  }
+  else if (p_data->isXYEdgeMap("midpoint"))
+  {
+    cbArrowCoordOneMap.set_active_text("midpoint");
+  }
+  else if (p_data->isXYEdgeMap("midpoints"))
+  {
+    cbArrowCoordOneMap.set_active_text("midpoints");
+  }
+  else if (p_data->isXYEdgeMap("mid"))
+  {
+    cbArrowCoordOneMap.set_active_text("mid");
+  }
+  else if (p_data->isXYEdgeMap("mids"))
+  {
+    cbArrowCoordOneMap.set_active_text("mids");
+  }
+  else if (p_data->isEdgeMap("arrow_x") &&
+           p_data->isEdgeMap("arrow_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("arrow_x");
+    cbArrowCoordTwoMaps2.set_active_text("arrow_y");
+  }
+  else if (p_data->isEdgeMap("arrows_x") &&
+           p_data->isEdgeMap("arrows_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("arrows_x");
+    cbArrowCoordTwoMaps2.set_active_text("arrows_y");
+  }
+  else if (p_data->isEdgeMap("midpoint_x") &&
+           p_data->isEdgeMap("midpoint_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("midpoint_x");
+    cbArrowCoordTwoMaps2.set_active_text("midpoint_y");
+  }
+  else if (p_data->isEdgeMap("midpoints_x") &&
+           p_data->isEdgeMap("midpoints_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("midpoints_x");
+    cbArrowCoordTwoMaps2.set_active_text("midpoints_y");
+  }
+  else if (p_data->isEdgeMap("mid_x") &&
+           p_data->isEdgeMap("mid_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("mid_x");
+    cbArrowCoordTwoMaps2.set_active_text("mid_y");
+  }
+  else if (p_data->isEdgeMap("mids_x") &&
+           p_data->isEdgeMap("mids_y"))
+  {
+    cbArrowCoordTwoMaps1.set_active_text("mids_x");
+    cbArrowCoordTwoMaps2.set_active_text("mids_y");
+  }
+
+  {
+    if (cbNodeCoordOneMap.get_active_text() != "")
+      rbNodeCoordOneMap.set_active();
+    else if (cbNodeCoordTwoMaps1.get_active_text() != "")
+      rbNodeCoordTwoMaps.set_active();
+    else
+      rbNodeCoordNone.set_active();
+
+    if (cbArrowCoordOneMap.get_active_text() != "")
+      rbArrowCoordOneMap.set_active();
+    else if (cbArrowCoordTwoMaps1.get_active_text() != "")
+      rbArrowCoordTwoMaps.set_active();
+    else
+      rbArrowCoordNone.set_active();
+
+    onNodeCoordMapNumToggled();
+    onArrowCoordMapNumToggled();
+
+    rbNodeCoordOneMap.signal_toggled().connect(
+        sigc::mem_fun(*this, &FileImportDialog::onNodeCoordMapNumToggled));
+    rbNodeCoordTwoMaps.signal_toggled().connect(
+        sigc::mem_fun(*this, &FileImportDialog::onNodeCoordMapNumToggled));
+    rbArrowCoordOneMap.signal_toggled().connect(
+        sigc::mem_fun(*this, &FileImportDialog::onArrowCoordMapNumToggled));
+    rbArrowCoordTwoMaps.signal_toggled().connect(
+        sigc::mem_fun(*this, &FileImportDialog::onArrowCoordMapNumToggled));
+  }
+
+  signal_response().connect(
+      sigc::mem_fun(*this, &FileImportDialog::onResponse));
+
+  update_node_tree_view();
+  update_edge_tree_view();
+
+  show_all_children();
+}
+
+void FileImportDialog::onNodeCoordMapNumToggled()
+{
+  if (rbNodeCoordOneMap.get_active())
+  {
+    cbNodeCoordOneMap.get_parent()->set_sensitive(true);
+    cbNodeCoordTwoMaps1.get_parent()->set_sensitive(false);
+    cbNodeCoordTwoMaps2.get_parent()->set_sensitive(false);
+
+    p_data->node_coord_load_from = ImportData::ONE_MAP;
+  }
+  else if (rbNodeCoordTwoMaps.get_active())
+  {
+    cbNodeCoordOneMap.get_parent()->set_sensitive(false);
+    cbNodeCoordTwoMaps1.get_parent()->set_sensitive(true);
+    cbNodeCoordTwoMaps2.get_parent()->set_sensitive(true);
+
+    p_data->node_coord_load_from = ImportData::TWO_MAPS;
+  }
+  else if (rbNodeCoordNone.get_active())
+  {
+    cbNodeCoordOneMap.get_parent()->set_sensitive(false);
+    cbNodeCoordTwoMaps1.get_parent()->set_sensitive(false);
+    cbNodeCoordTwoMaps2.get_parent()->set_sensitive(false);
+
+    p_data->node_coord_load_from = ImportData::DONT_READ;
+  }
+  update_node_tree_view();
+}
+
+void FileImportDialog::onArrowCoordMapNumToggled()
+{
+  if (rbArrowCoordOneMap.get_active())
+  {
+    cbArrowCoordOneMap.get_parent()->set_sensitive(true);
+    cbArrowCoordTwoMaps1.get_parent()->set_sensitive(false);
+    cbArrowCoordTwoMaps2.get_parent()->set_sensitive(false);
+
+    p_data->arrow_coord_load_from = ImportData::ONE_MAP;
+  }
+  else if (rbArrowCoordTwoMaps.get_active())
+  {
+    cbArrowCoordOneMap.get_parent()->set_sensitive(false);
+    cbArrowCoordTwoMaps1.get_parent()->set_sensitive(true);
+    cbArrowCoordTwoMaps2.get_parent()->set_sensitive(true);
+
+    p_data->arrow_coord_load_from = ImportData::TWO_MAPS;
+  }
+  else if (rbArrowCoordNone.get_active())
+  {
+    cbArrowCoordOneMap.get_parent()->set_sensitive(false);
+    cbArrowCoordTwoMaps1.get_parent()->set_sensitive(false);
+    cbArrowCoordTwoMaps2.get_parent()->set_sensitive(false);
+
+    p_data->arrow_coord_load_from = ImportData::DONT_READ;
+  }
+  update_edge_tree_view();
+}
+
+FileImportDialog::~FileImportDialog()
+{
+}
+
+void FileImportDialog::onResponse(int id)
+{
+  if (id == Gtk::RESPONSE_OK)
+  {
+    if ((rbNodeCoordOneMap.get_active() &&
+          cbNodeCoordOneMap.get_active_text() == "") ||
+        (rbNodeCoordTwoMaps.get_active() &&
+         (cbNodeCoordTwoMaps1.get_active_text() == "" ||
+          cbNodeCoordTwoMaps2.get_active_text() == "")))
+    {
+      Gtk::MessageDialog mdialog("No node map selected.",
+          false, Gtk::MESSAGE_ERROR);
+      mdialog.run();
+      return;
+    }
+    else if (rbNodeCoordTwoMaps.get_active() &&
+             cbNodeCoordTwoMaps1.get_active_text() == 
+             cbNodeCoordTwoMaps2.get_active_text())
+    {
+      Gtk::MessageDialog mdialog(
+          "Same node map selected for both coordinates.",
+          false, Gtk::MESSAGE_ERROR);
+      mdialog.run();
+      return;
+    }
+    if ((rbArrowCoordOneMap.get_active() &&
+          cbArrowCoordOneMap.get_active_text() == "") ||
+        (rbArrowCoordTwoMaps.get_active() &&
+         (cbArrowCoordTwoMaps1.get_active_text() == "" ||
+          cbArrowCoordTwoMaps2.get_active_text() == "")))
+    {
+      Gtk::MessageDialog mdialog("No edge map selected.",
+          false, Gtk::MESSAGE_ERROR);
+      mdialog.run();
+      return;
+    }
+    else if (rbArrowCoordTwoMaps.get_active() &&
+             cbArrowCoordTwoMaps1.get_active_text() == 
+             cbArrowCoordTwoMaps2.get_active_text())
+    {
+      Gtk::MessageDialog mdialog(
+          "Same edge map selected for both coordinates.",
+          false, Gtk::MESSAGE_ERROR);
+      mdialog.run();
+      return;
+    }
+
+    for (std::vector<tree_view_record>::const_iterator it =
+        node_tree_view_records.begin(); it != node_tree_view_records.end();
+        ++it)
+    {
+      if (it->visible)
+      {
+        if (it->numeric)
+          p_data->numeric_node_map_names.push_back(it->name);
+        if (it->string)
+          p_data->string_node_map_names.push_back(it->name);
+      }
+    }
+
+    for (std::vector<tree_view_record>::const_iterator it =
+        edge_tree_view_records.begin(); it != edge_tree_view_records.end();
+        ++it)
+    {
+      if (it->visible)
+      {
+        if (it->numeric)
+          p_data->numeric_edge_map_names.push_back(it->name);
+        if (it->string)
+          p_data->string_edge_map_names.push_back(it->name);
+      }
+    }
+  }
+}
+
+FileImportDialog::ImportData::ImportData(
+    const std::vector<std::string>& _node_map_names,
+    const std::vector<std::string>& _edge_map_names) :
+  node_map_names(_node_map_names),
+  edge_map_names(_edge_map_names)
+{
+  typedef std::vector<std::string> StrVec;
+  {
+    StrVec xMaps;
+    StrVec yMaps;
+    // collect map names ending with ":x" and ":y"
+    for (StrVec::const_iterator it = node_map_names.begin();
+        it != node_map_names.end(); ++it)
+    {
+      if ((it->length() >= 3) &&
+          (it->substr(it->length()-2, it->length())  == ":x"))
+      {
+        xMaps.push_back(it->substr(0, it->length()-2));
+      }
+      if ((it->length() >= 3) &&
+          (it->substr(it->length()-2, it->length())  == ":y"))
+      {
+        yMaps.push_back(it->substr(0, it->length()-2));
+      }
+    }
+
+    for (StrVec::const_iterator it1 = xMaps.begin();
+        it1 != xMaps.end(); ++it1)
+    {
+      for (StrVec::const_iterator it2 = yMaps.begin();
+          it2 != yMaps.end(); ++it2)
+      {
+        if (*it1 == *it2) xy_node_map_names.push_back(*it1);
+      }
+    }
+  }
+  {
+    StrVec xMaps;
+    StrVec yMaps;
+    // collect map names ending with ":x" and ":y"
+    for (StrVec::const_iterator it = edge_map_names.begin();
+        it != edge_map_names.end(); ++it)
+    {
+      if ((it->length() >= 3) &&
+          (it->substr(it->length()-2, it->length())  == ":x"))
+      {
+        xMaps.push_back(it->substr(0, it->length()-2));
+      }
+      if ((it->length() >= 3) &&
+          (it->substr(it->length()-2, it->length())  == ":y"))
+      {
+        yMaps.push_back(it->substr(0, it->length()-2));
+      }
+    }
+
+    for (StrVec::const_iterator it1 = xMaps.begin();
+        it1 != xMaps.end(); ++it1)
+    {
+      for (StrVec::const_iterator it2 = yMaps.begin();
+          it2 != yMaps.end(); ++it2)
+      {
+        if (*it1 == *it2) xy_edge_map_names.push_back(*it1);
+      }
+    }
+  }
+}
+
+FileImportDialog::ImportData::~ImportData()
+{
+}
+
+bool FileImportDialog::ImportData::isXYNodeMap(const std::string& name)
+{
+  if (isNodeMap(name + ":x") && isNodeMap(name + ":y")) return true;
+  return false;
+}
+
+bool FileImportDialog::ImportData::isXYEdgeMap(const std::string& name)
+{
+  if (isEdgeMap(name + ":x") && isEdgeMap(name + ":y")) return true;
+  return false;
+}
+
+bool FileImportDialog::ImportData::isNodeMap(const std::string& name)
+{
+  if (contains(node_map_names, name)) return true;
+  return false;
+}
+
+bool FileImportDialog::ImportData::isEdgeMap(const std::string& name)
+{
+  if (contains(edge_map_names, name)) return true;
+  return false;
+}
+
+bool FileImportDialog::ImportData::contains(const std::vector<std::string>& vec,
+    const std::string& str)
+{
+  for (std::vector<std::string>::const_iterator it = vec.begin();
+      it != vec.end(); ++it)
+  {
+    if (*it == str) return true;
+  }
+  return false;
+}
+
+void FileImportDialog::onNodeCoordOneMapChanged()
+{
+  p_data->node_coord_one_map_name = cbNodeCoordOneMap.get_active_text();
+  update_node_tree_view();
+}
+
+void FileImportDialog::onNodeCoordTwoMaps1Changed()
+{
+  p_data->node_coord_two_maps_1_name = cbNodeCoordTwoMaps1.get_active_text();
+  update_node_tree_view();
+}
+
+void FileImportDialog::onNodeCoordTwoMaps2Changed()
+{
+  p_data->node_coord_two_maps_2_name = cbNodeCoordTwoMaps2.get_active_text();
+  update_node_tree_view();
+}
+
+void FileImportDialog::onArrowCoordOneMapChanged()
+{
+  p_data->arrow_coord_one_map_name = cbArrowCoordOneMap.get_active_text();
+  update_edge_tree_view();
+}
+
+void FileImportDialog::onArrowCoordTwoMaps1Changed()
+{
+  p_data->arrow_coord_two_maps_1_name = cbArrowCoordTwoMaps1.get_active_text();
+  update_edge_tree_view();
+}
+
+void FileImportDialog::onArrowCoordTwoMaps2Changed()
+{
+  p_data->arrow_coord_two_maps_2_name = cbArrowCoordTwoMaps2.get_active_text();
+  update_edge_tree_view();
+}
+
+void FileImportDialog::onNodeMapNumericToggled(const Glib::ustring& path)
+{
+  Gtk::TreeModel::iterator iter = refNodeMapStore->get_iter(
+      Gtk::TreeModel::Path(path));
+  Gtk::TreeModel::Row row = *iter;
+  std::vector<tree_view_record>::iterator it;
+  for (it = node_tree_view_records.begin();
+      it != node_tree_view_records.end(); ++it)
+  {
+    if (it->name == row[NodeMapColumns.colName]) break;
+  }
+  if (row[NodeMapColumns.colReadAsNumeric])
+  {
+    row[NodeMapColumns.colReadAsString] = false;
+    it->string = false;
+    it->numeric = true;
+  }
+}
+
+void FileImportDialog::onNodeMapStringToggled(const Glib::ustring& path)
+{
+  Gtk::TreeModel::iterator iter = refNodeMapStore->get_iter(
+      Gtk::TreeModel::Path(path));
+  Gtk::TreeModel::Row row = *iter;
+  std::vector<tree_view_record>::iterator it;
+  for (it = node_tree_view_records.begin();
+      it != node_tree_view_records.end(); ++it)
+  {
+    if (it->name == row[NodeMapColumns.colName]) break;
+  }
+  if (row[NodeMapColumns.colReadAsString])
+  {
+    row[NodeMapColumns.colReadAsNumeric] = false;
+    it->string = true;
+    it->numeric = false;
+  }
+}
+
+void FileImportDialog::update_node_tree_view()
+{
+  for (std::vector<tree_view_record>::iterator it =
+      node_tree_view_records.begin(); it != node_tree_view_records.end(); ++it)
+  {
+    it->visible = true;
+  }
+  switch (p_data->node_coord_load_from)
+  {
+    case ImportData::ONE_MAP:
+      for (std::vector<tree_view_record>::iterator it =
+          node_tree_view_records.begin(); it !=
+          node_tree_view_records.end(); ++it)
+      {
+        if (it->name == p_data->node_coord_one_map_name)
+          it->visible = false;
+      }
+      break;
+    case ImportData::TWO_MAPS:
+      for (std::vector<tree_view_record>::iterator it =
+          node_tree_view_records.begin(); it !=
+          node_tree_view_records.end(); ++it)
+      {
+        if ((it->name == p_data->node_coord_two_maps_1_name) ||
+            (it->name == p_data->node_coord_two_maps_2_name))
+          it->visible = false;
+      }
+      break;
+    case ImportData::DONT_READ:
+      break;
+  }
+  refNodeMapStore->clear();
+  for (std::vector<tree_view_record>::iterator it =
+      node_tree_view_records.begin(); it != node_tree_view_records.end(); ++it)
+  {
+    if (it->visible)
+    {
+      Gtk::TreeModel::Row row = *(refNodeMapStore->append());
+      row[NodeMapColumns.colName] = it->name;
+      row[NodeMapColumns.colReadAsNumeric] = it->numeric;
+      row[NodeMapColumns.colReadAsString] = it->string;
+    }
+  }
+}
+
+void FileImportDialog::onEdgeMapNumericToggled(const Glib::ustring& path)
+{
+  Gtk::TreeModel::iterator iter = refEdgeMapStore->get_iter(
+      Gtk::TreeModel::Path(path));
+  Gtk::TreeModel::Row row = *iter;
+  std::vector<tree_view_record>::iterator it;
+  for (it = edge_tree_view_records.begin();
+      it != edge_tree_view_records.end(); ++it)
+  {
+    if (it->name == row[EdgeMapColumns.colName]) break;
+  }
+  if (row[EdgeMapColumns.colReadAsNumeric])
+  {
+    row[EdgeMapColumns.colReadAsString] = false;
+    it->string = false;
+    it->numeric = true;
+  }
+}
+
+void FileImportDialog::onEdgeMapStringToggled(const Glib::ustring& path)
+{
+  Gtk::TreeModel::iterator iter = refEdgeMapStore->get_iter(
+      Gtk::TreeModel::Path(path));
+  Gtk::TreeModel::Row row = *iter;
+  std::vector<tree_view_record>::iterator it;
+  for (it = edge_tree_view_records.begin();
+      it != edge_tree_view_records.end(); ++it)
+  {
+    if (it->name == row[EdgeMapColumns.colName]) break;
+  }
+  if (row[EdgeMapColumns.colReadAsString])
+  {
+    row[EdgeMapColumns.colReadAsNumeric] = false;
+    it->string = true;
+    it->numeric = false;
+  }
+}
+
+void FileImportDialog::update_edge_tree_view()
+{
+  for (std::vector<tree_view_record>::iterator it =
+      edge_tree_view_records.begin(); it != edge_tree_view_records.end(); ++it)
+  {
+    it->visible = true;
+  }
+  switch (p_data->arrow_coord_load_from)
+  {
+    case ImportData::ONE_MAP:
+      for (std::vector<tree_view_record>::iterator it =
+          edge_tree_view_records.begin(); it !=
+          edge_tree_view_records.end(); ++it)
+      {
+        if (it->name == p_data->arrow_coord_one_map_name)
+          it->visible = false;
+      }
+      break;
+    case ImportData::TWO_MAPS:
+      for (std::vector<tree_view_record>::iterator it =
+          edge_tree_view_records.begin(); it !=
+          edge_tree_view_records.end(); ++it)
+      {
+        if ((it->name == p_data->arrow_coord_two_maps_1_name) ||
+            (it->name == p_data->arrow_coord_two_maps_2_name))
+          it->visible = false;
+      }
+      break;
+    case ImportData::DONT_READ:
+      break;
+  }
+  refEdgeMapStore->clear();
+  for (std::vector<tree_view_record>::iterator it =
+      edge_tree_view_records.begin(); it != edge_tree_view_records.end(); ++it)
+  {
+    if (it->visible)
+    {
+      Gtk::TreeModel::Row row = *(refEdgeMapStore->append());
+      row[EdgeMapColumns.colName] = it->name;
+      row[EdgeMapColumns.colReadAsNumeric] = it->numeric;
+      row[EdgeMapColumns.colReadAsString] = it->string;
+    }
+  }
+}

Added: glemon/trunk/file_import_dialog.h
==============================================================================
--- (empty file)
+++ glemon/trunk/file_import_dialog.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,137 @@
+#ifndef FILE_IMPORT_DIALOG
+#define FILE_IMPORT_DIALOG
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/sizegroup.h>
+#include <gtkmm/treemodel.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/scrolledwindow.h>
+
+class FileImportDialog : public Gtk::Dialog
+{
+  public:
+    struct ImportData
+    {
+        ImportData(
+            const std::vector<std::string>& _node_map_names,
+            const std::vector<std::string>& _edge_map_names);
+
+        ~ImportData();
+
+        std::vector<std::string> node_map_names;
+        std::vector<std::string> edge_map_names;
+
+        std::vector<std::string> xy_node_map_names;
+        std::vector<std::string> xy_edge_map_names;
+
+        bool contains(
+            const std::vector<std::string>& vec,
+            const std::string& str);
+
+        std::string node_coord_one_map_name;
+        std::string node_coord_two_maps_1_name;
+        std::string node_coord_two_maps_2_name;
+        std::string arrow_coord_one_map_name;
+        std::string arrow_coord_two_maps_1_name;
+        std::string arrow_coord_two_maps_2_name;
+
+        enum ReadOpts { ONE_MAP, TWO_MAPS, DONT_READ };
+        ReadOpts node_coord_load_from;
+        ReadOpts arrow_coord_load_from;
+
+        bool isXYNodeMap(const std::string& name);
+        bool isXYEdgeMap(const std::string& name);
+        bool isNodeMap(const std::string& name);
+        bool isEdgeMap(const std::string& name);
+
+        std::vector<std::string> numeric_node_map_names;
+        std::vector<std::string> string_node_map_names;
+        std::vector<std::string> numeric_edge_map_names;
+        std::vector<std::string> string_edge_map_names;
+    };
+
+    ImportData* p_data;
+
+    Gtk::RadioButton rbNodeCoordNone;
+    Gtk::RadioButton rbNodeCoordOneMap;
+    Gtk::RadioButton rbNodeCoordTwoMaps;
+
+    Gtk::RadioButton rbArrowCoordNone;
+    Gtk::RadioButton rbArrowCoordOneMap;
+    Gtk::RadioButton rbArrowCoordTwoMaps;
+
+    Gtk::ComboBoxText cbNodeCoordOneMap;
+    Gtk::ComboBoxText cbNodeCoordTwoMaps1;
+    Gtk::ComboBoxText cbNodeCoordTwoMaps2;
+
+    Gtk::ComboBoxText cbArrowCoordOneMap;
+    Gtk::ComboBoxText cbArrowCoordTwoMaps1;
+    Gtk::ComboBoxText cbArrowCoordTwoMaps2;
+
+    void onNodeCoordMapNumToggled();
+    void onArrowCoordMapNumToggled();
+
+    void onResponse(int id);
+
+    void onNodeCoordOneMapChanged();
+    void onNodeCoordTwoMaps1Changed();
+    void onNodeCoordTwoMaps2Changed();
+
+    void onArrowCoordOneMapChanged();
+    void onArrowCoordTwoMaps1Changed();
+    void onArrowCoordTwoMaps2Changed();
+
+    struct MapModelColumns : public Gtk::TreeModel::ColumnRecord
+    {
+      MapModelColumns()
+      {
+        add(colName);
+        add(colReadAsNumeric);
+        add(colReadAsString);
+      }
+      Gtk::TreeModelColumn<Glib::ustring> colName;
+      Gtk::TreeModelColumn<bool> colReadAsNumeric;
+      Gtk::TreeModelColumn<bool> colReadAsString;
+    };
+
+    Gtk::TreeView twNodeMaps;
+    MapModelColumns NodeMapColumns;
+    Glib::RefPtr<Gtk::ListStore> refNodeMapStore;
+    void onNodeMapNumericToggled(const Glib::ustring& path);
+    void onNodeMapStringToggled(const Glib::ustring& path);
+
+    Gtk::TreeView twEdgeMaps;
+    MapModelColumns EdgeMapColumns;
+    Glib::RefPtr<Gtk::ListStore> refEdgeMapStore;
+    void onEdgeMapNumericToggled(const Glib::ustring& path);
+    void onEdgeMapStringToggled(const Glib::ustring& path);
+
+    struct tree_view_record
+    {
+      tree_view_record(const std::string& _name, bool _numeric, bool _string,
+          bool _visible) :
+        name(_name),
+        numeric(_numeric),
+        string(_string),
+        visible(_visible) {}
+      std::string name;
+      bool numeric;
+      bool string;
+      bool visible;
+    };
+
+    std::vector<tree_view_record> node_tree_view_records;
+    void update_node_tree_view();
+
+    std::vector<tree_view_record> edge_tree_view_records;
+    void update_edge_tree_view();
+
+  public:
+    FileImportDialog(ImportData* d);
+    ~FileImportDialog();
+};
+
+#endif

Modified: glemon/trunk/gdc-broken_edge.cc
==============================================================================
--- glemon/trunk/gdc-broken_edge.cc	(original)
+++ glemon/trunk/gdc-broken_edge.cc	Wed Jan  2 22:03:09 2008
@@ -36,7 +36,7 @@
 void GraphDisplayerCanvas::EdgeBase::drawArrow(XY unit_vector_in_dir)
 {
   MapStorage& ms = *canvas.mytab.mapstorage;
-  XY center(ms.arrow_pos[edge]);
+  XY center(ms.getArrowCoords(edge));
   XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
 
   //       /\       // top
@@ -89,8 +89,8 @@
   MapStorage& ms = *canvas.mytab.mapstorage;
 
   //calculating coordinates of the direction indicator arrow
-  XY head(ms.coords[ms.graph.target(edge)]);
-  XY center(ms.arrow_pos[edge]);
+  XY head(ms.getNodeCoords(ms.graph.target(edge)));
+  XY center(ms.getArrowCoords(edge));
 
   XY unit_vector_in_dir(head-center);
   double length=sqrt( unit_vector_in_dir.normSquare() );
@@ -107,12 +107,12 @@
   Gnome::Canvas::Points points;
   Node source = ms.graph.source(edge);
   Node target = ms.graph.target(edge);
-  points.push_back(Gnome::Art::Point(ms.coords[source].x,
-        ms.coords[source].y));
-  points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
-        ms.arrow_pos[edge].y));
-  points.push_back(Gnome::Art::Point(ms.coords[target].x,
-        ms.coords[target].y));
+  points.push_back(Gnome::Art::Point(ms.getNodeCoords(source).x,
+        ms.getNodeCoords(source).y));
+  points.push_back(Gnome::Art::Point(ms.getArrowCoords(edge).x,
+        ms.getArrowCoords(edge).y));
+  points.push_back(Gnome::Art::Point(ms.getNodeCoords(target).x,
+        ms.getNodeCoords(target).y));
   line.property_points().set_value(points);
 }
 
@@ -152,10 +152,10 @@
 
         Gnome::Canvas::Points points_new;
 
-        canvas.mytab.mapstorage->arrow_pos.set(edge, canvas.mytab.mapstorage->arrow_pos[edge] + XY(dx, dy));
+        canvas.mytab.mapstorage->setArrowCoords(edge, canvas.mytab.mapstorage->getArrowCoords(edge) + XY(dx, dy));
 
         draw();
-        canvas.textReposition(canvas.mytab.mapstorage->arrow_pos[edge]);
+        canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(edge));
 
         clicked_x=e->motion.x;
         clicked_y=e->motion.y;
@@ -199,16 +199,16 @@
   MapStorage& ms = *canvas.mytab.mapstorage;
 
   Node node = ms.graph.source(edge);
-  XY center = (ms.coords[node] + ms.arrow_pos[edge]) / 2.0;
+  XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(edge)) / 2.0;
 
-  XY unit_vector_in_dir(rot90(center - ms.arrow_pos[edge]));
+  XY unit_vector_in_dir(rot90(center - ms.getArrowCoords(edge)));
   double length = sqrt(unit_vector_in_dir.normSquare());
   unit_vector_in_dir /= length;
 
   drawArrow(unit_vector_in_dir);
 
   double radius =
-    sqrt((ms.arrow_pos[edge] - ms.coords[node]).normSquare()) / 2.0;
+    sqrt((ms.getArrowCoords(edge) - ms.getNodeCoords(node)).normSquare()) / 2.0;
 
   XY p1 = center + XY(-radius,  radius);
   XY p2 = center + XY( radius, -radius);
@@ -249,10 +249,10 @@
     case GDK_MOTION_NOTIFY:
       if(isbutton)
       {
-        canvas.mytab.mapstorage->arrow_pos.set(edge, XY(e->motion.x, e->motion.y));
+        canvas.mytab.mapstorage->setArrowCoords(edge, XY(e->motion.x, e->motion.y));
 
         draw();
-        canvas.textReposition(canvas.mytab.mapstorage->arrow_pos[edge]);
+        canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(edge));
       }
     default: break;
   }

Modified: glemon/trunk/graph-displayer.cc
==============================================================================
--- glemon/trunk/graph-displayer.cc	(original)
+++ glemon/trunk/graph-displayer.cc	Wed Jan  2 22:03:09 2008
@@ -95,15 +95,15 @@
 //       mytab.readFile(argv[1]);
 //     }
   if(argc>=2)
+  {
+    for(int i=1;i<argc;i++)
     {
-      for(int i=1;i<argc;i++)
-	{
-	  if(Glib::file_test(argv[i], Glib::FILE_TEST_IS_REGULAR))
-	    {
-	      mytab.readFile(argv[i]);
-	    }
-	}
+      if(Glib::file_test(argv[i], Glib::FILE_TEST_IS_REGULAR))
+      {
+        mytab.readFile(argv[i]);
+      }
     }
+  }
   else
     {
       mytab.newTab();

Modified: glemon/trunk/graph_displayer_canvas-edge.cc
==============================================================================
--- glemon/trunk/graph_displayer_canvas-edge.cc	(original)
+++ glemon/trunk/graph_displayer_canvas-edge.cc	Wed Jan  2 22:03:09 2008
@@ -25,126 +25,143 @@
 
 int GraphDisplayerCanvas::resetEdgeWidth (Edge edge)
 {
+  MapStorage& ms = *mytab.mapstorage;
   double min, max;
 
   min=edge_property_defaults[E_WIDTH];
   max=edge_property_defaults[E_WIDTH];
-  Graph::EdgeMap<double> actual_map((mytab.mapstorage)->graph,edge_property_defaults[E_WIDTH]);
-  
+  Graph::EdgeMap<double> actual_map(ms.graph,edge_property_defaults[E_WIDTH]);
+
   if(edge==INVALID)
+  {
+    for (EdgeIt i(ms.graph); i!=INVALID; ++i)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  double v=fabs(actual_map[i]);
-	  int w;
-	  if(min==max)
-	    {
-	      w=(int)(edge_property_defaults[E_WIDTH]);
-	    }
-	  else
-	    {
-	      w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH));
-	    }
-	  if(zoomtrack)
-	    {
-	      double actual_ppu=get_pixels_per_unit();
-	      w=(int)(w/actual_ppu*fixed_zoom_factor);
-	    }
-	  edgesmap[i]->setLineWidth(w);
-	}
+      double v=fabs(actual_map[i]);
+      int w;
+      if(min==max)
+      {
+        w=(int)(edge_property_defaults[E_WIDTH]);
+      }
+      else
+      {
+        w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH));
+      }
+      if(zoomtrack)
+      {
+        double actual_ppu=get_pixels_per_unit();
+        w=(int)(w/actual_ppu*fixed_zoom_factor);
+      }
+      edgesmap[i]->setLineWidth(w);
     }
+  }
   else
+  {
+    int w=(int)actual_map[edge];
+    if(w>=0)
     {
-      int w=(int)actual_map[edge];
-      if(w>=0)
-	{
-	  edgesmap[edge]->setLineWidth(w);
-	}
+      edgesmap[edge]->setLineWidth(w);
     }
+  }
   return 0;
 }
 
 
 int GraphDisplayerCanvas::changeEdgeWidth (std::string mapname, Edge edge)
 {
-  Graph::EdgeMap<double> * actual_map;
+  MapStorage& ms = *mytab.mapstorage;
   double min, max;
 
-  min=(mytab.mapstorage)->minOfEdgeMap(mapname);
-  max=(mytab.mapstorage)->maxOfEdgeMap(mapname);
-  actual_map=((mytab.mapstorage)->edgemap_storage)[mapname];
+  {
+    EdgeIt e(ms.graph);
+    min = max = ms.get(mapname, e);
+    for (; e != INVALID; ++e)
+    {
+      if (static_cast<double>(ms.get(mapname, e)) > max)
+        max = ms.get(mapname, e);
+      if (static_cast<double>(ms.get(mapname, e)) < min)
+        min = ms.get(mapname, e);
+    }
+  }
 
   if(edge==INVALID)
+  {
+    for (EdgeIt i(ms.graph); i!=INVALID; ++i)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  double v=(*actual_map)[i];
-	  int w;
-	  if(autoscale)
-	    {
-	      if(min==max)
-		{
-		  w=(int)(edge_property_defaults[E_WIDTH]);
-		}
-	      else
-		{
-		  w=(int)(minimum_edge_width+(v-min)/(max-min)*(edge_width-minimum_edge_width));
-		}
-	    }
-	  else
-	    {
-	      w=(int)(v*edge_width);
-	    }
-	  if(w<0)
-	    {
-	      edgesmap[i]->hide();
-	    }
-	  else
-	    {
-	      edgesmap[i]->show();
-	      if(w<minimum_edge_width)
-		{
-		  w=minimum_edge_width;
-		}
-	      if(zoomtrack)
-		{
-		  double actual_ppu=get_pixels_per_unit();
-		  w=(int)(w/actual_ppu*fixed_zoom_factor);
-		}
-	      edgesmap[i]->setLineWidth(w);
-	    }
-	}
+      double v=ms.get(mapname, i);
+      int w;
+      if(autoscale)
+      {
+        if(min==max)
+        {
+          w=(int)(edge_property_defaults[E_WIDTH]);
+        }
+        else
+        {
+          w=(int)(minimum_edge_width+(v-min)/(max-min)*(edge_width-minimum_edge_width));
+        }
+      }
+      else
+      {
+        w=(int)(v*edge_width);
+      }
+      if(w<0)
+      {
+        edgesmap[i]->hide();
+      }
+      else
+      {
+        edgesmap[i]->show();
+        if(w<minimum_edge_width)
+        {
+          w=minimum_edge_width;
+        }
+        if(zoomtrack)
+        {
+          double actual_ppu=get_pixels_per_unit();
+          w=(int)(w/actual_ppu*fixed_zoom_factor);
+        }
+        edgesmap[i]->setLineWidth(w);
+      }
     }
+  }
   else
+  {
+    int w=(int)ms.get(mapname, edge);
+    if(w>=0)
     {
-      int w=(int)(*actual_map)[edge];
-      if(w>=0)
-	{
-	  edgesmap[edge]->setLineWidth(w);
-	}
+      edgesmap[edge]->setLineWidth(w);
     }
+  }
   return 0;
 };
 
 int GraphDisplayerCanvas::changeEdgeColor (std::string mapname, Edge edge)
 {  
+  MapStorage& ms = *mytab.mapstorage;
 
   //function maps the range of the maximum and
   //the minimum of the nodemap to the range of
   //green in RGB
-  Graph::EdgeMap<double> * actual_map;
-  actual_map=((mytab.mapstorage)->edgemap_storage)[mapname];
 
   double max, min;
 
-  max=(mytab.mapstorage)->maxOfEdgeMap(mapname);
-  min=(mytab.mapstorage)->minOfEdgeMap(mapname);
+  {
+    EdgeIt e(ms.graph);
+    min = max = ms.get(mapname, e);
+    for (; e != INVALID; ++e)
+    {
+      if (static_cast<double>(ms.get(mapname, e)) > max)
+        max = ms.get(mapname, e);
+      if (static_cast<double>(ms.get(mapname, e)) < min)
+        min = ms.get(mapname, e);
+    }
+  }
 
   if(edge==INVALID)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (EdgeIt i(ms.graph); i!=INVALID; ++i)
 	{
-	  double w=(*actual_map)[i];
+	  double w=ms.get(mapname, i);
 
 	  Gdk::Color color;
 	  if(max!=min)
@@ -162,7 +179,7 @@
     {
       Gdk::Color color;
 
-      double w=(*actual_map)[edge];
+      double w=ms.get(mapname, edge);
 
       if(max!=min)
 	{
@@ -180,11 +197,12 @@
 
 int GraphDisplayerCanvas::resetEdgeColor (Edge edge)
 {  
+  MapStorage& ms = *mytab.mapstorage;
 
   //function maps the range of the maximum and
   //the minimum of the nodemap to the range of
   //green in RGB
-  Graph::EdgeMap<double> actual_map((mytab.mapstorage)->graph,edge_property_defaults[E_COLOR]);
+  Graph::EdgeMap<double> actual_map(ms.graph,edge_property_defaults[E_COLOR]);
 
   double max, min;
 
@@ -192,99 +210,93 @@
   min=edge_property_defaults[E_COLOR];
 
   if(edge==INVALID)
+  {
+    for (EdgeIt i(ms.graph); i!=INVALID; ++i)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  double w=actual_map[i];
+      double w=actual_map[i];
 
-	  Gdk::Color color;
-	  if(max!=min)
-	    {
-	      color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
-	    }
-	  else
-	    {
-	      color.set_rgb_p (0, 100, 0);
-	    }
-	  edgesmap[i]->setFillColor(color);
-	}
-    }
-  else
-    {
       Gdk::Color color;
-
-      double w=actual_map[edge];
-
       if(max!=min)
-	{
-	  color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
-	}
+      {
+        color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
+      }
       else
-	{
-	  color.set_rgb_p (0, 100, 0);
-	}
+      {
+        color.set_rgb_p (0, 100, 0);
+      }
+      edgesmap[i]->setFillColor(color);
+    }
+  }
+  else
+  {
+    Gdk::Color color;
 
-      edgesmap[edge]->setFillColor(color);
+    double w=actual_map[edge];
+
+    if(max!=min)
+    {
+      color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
+    }
+    else
+    {
+      color.set_rgb_p (0, 100, 0);
     }
+
+    edgesmap[edge]->setFillColor(color);
+  }
   return 0;
 };
 
 int GraphDisplayerCanvas::changeEdgeText (std::string mapname, Edge edge)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   //the number in the map will be written on the edge
   //EXCEPT when the name of the map is Default, because
   //in that case empty string will be written, because
   //that is the deleter map
-  
+
   if(edge==INVALID)
+  {
+    for (EdgeIt i(ms.graph); i!=INVALID; ++i)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  edgemap_to_edit=mapname;
-	  double number=(*((mytab.mapstorage)->edgemap_storage)[mapname])[i];
-	  
-	  std::ostringstream ostr;
-	  ostr << number;
-	  
-	  edgetextmap[i]->property_text().set_value(ostr.str());
-	}
+      edgemap_to_edit=mapname;
 
+      edgetextmap[i]->property_text().set_value(
+          static_cast<std::string>(ms.get(mapname, i)));
     }
-  else
-    {
-	  double number=(*((mytab.mapstorage)->edgemap_storage)[mapname])[edge];
 
-	  std::ostringstream ostr;
-	  ostr << number;
-	  
-	  edgetextmap[edge]->property_text().set_value(ostr.str());
-    }
+  }
+  else
+  {
+    edgetextmap[edge]->property_text().set_value(
+        static_cast<std::string>(ms.get(mapname, edge)));
+  }
 
   return 0;
-
 };
 
 int GraphDisplayerCanvas::resetEdgeText (Edge edge)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   //the number in the map will be written on the edge
   //EXCEPT when the name of the map is Default, because
   //in that case empty string will be written, because
   //that is the deleter map
-  
+
   if(edge==INVALID)
+  {
+    for (EdgeIt i(ms.graph); i!=INVALID; ++i)
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  edgemap_to_edit="";
-	  edgetextmap[i]->property_text().set_value("");
-	}
-
+      edgemap_to_edit="";
+      edgetextmap[i]->property_text().set_value("");
     }
+  }
   else
-    {
-      edgetextmap[edge]->property_text().set_value("");
-    }
+  {
+    edgetextmap[edge]->property_text().set_value("");
+  }
 
   return 0;
-
 };

Modified: glemon/trunk/graph_displayer_canvas-event.cc
==============================================================================
--- glemon/trunk/graph_displayer_canvas-event.cc	(original)
+++ glemon/trunk/graph_displayer_canvas-event.cc	Wed Jan  2 22:03:09 2008
@@ -33,63 +33,63 @@
 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
 {
   if(actual_tool!=newtool)
+  {
+
+    actual_handler.disconnect();
+
+    switch(actual_tool)
     {
+      case CREATE_EDGE:
+        {
+          GdkEvent * generated=new GdkEvent();
+          generated->type=GDK_BUTTON_RELEASE;
+          generated->button.button=3;
+          createEdgeEventHandler(generated);      
+          break;
+        }
+      case MAP_EDIT:
+        {
+          break;
+        }
+      default:
+        break;
+    }
 
-      actual_handler.disconnect();
+    active_item=NULL; 
+    target_item=NULL; 
+    active_edge=INVALID;	
+    active_node=INVALID;	
 
-      switch(actual_tool)
-	{
-	case CREATE_EDGE:
-	  {
-	    GdkEvent * generated=new GdkEvent();
-	    generated->type=GDK_BUTTON_RELEASE;
-	    generated->button.button=3;
-	    createEdgeEventHandler(generated);      
-	    break;
-	  }
-	case MAP_EDIT:
-	  {
-	    break;
-	  }
-	default:
-	  break;
-	}
 
-      active_item=NULL; 
-      target_item=NULL; 
-      active_edge=INVALID;	
-      active_node=INVALID;	
+    actual_tool=newtool;
 
+    switch(newtool)
+    {
+      case MOVE:
+        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
+        break;
 
-      actual_tool=newtool;
-  
-      switch(newtool)
-	{
-	case MOVE:
-	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
-	  break;
-
-	case CREATE_NODE:
-	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
-	  break;
-
-	case CREATE_EDGE:
-	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
-	  break;
-
-	case ERASER:
-	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
-	  break;
-
-	case MAP_EDIT:
-	  grab_focus();
-	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
-	  break;
+      case CREATE_NODE:
+        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
+        break;
 
-	default:
-	  break;
-	}
+      case CREATE_EDGE:
+        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
+        break;
+
+      case ERASER:
+        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
+        break;
+
+      case MAP_EDIT:
+        grab_focus();
+        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
+        break;
+
+      default:
+        break;
     }
+  }
 }
 
 int GraphDisplayerCanvas::getActualTool()
@@ -138,30 +138,32 @@
 
 bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   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;
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  if(nodesmap[i]==active_item)
-	    {
-	      active_node=i;
-	    }
-	}
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
+      {
+        if(nodesmap[i]==active_item)
+        {
+          active_node=i;
+        }
+      }
       isbutton=e->button.button;
       break;
     case GDK_BUTTON_RELEASE:
       if (coord_text)
-	{
-	  delete coord_text;
-	  coord_text = 0;
-	}
+      {
+        delete coord_text;
+        coord_text = 0;
+      }
       isbutton=0;
       active_item=NULL;
       active_node=INVALID;
@@ -169,65 +171,65 @@
     case GDK_MOTION_NOTIFY:
       //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;
-	  
-	  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);
-	    }
+      {
+        ms.setModified();
+
+        //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 << "(" <<
+          ms.getNodeCoords(active_node).x << ", " <<
+          ms.getNodeCoords(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(
+              ms.getNodeCoords(active_node).x + radius);
+          coord_text->property_y().set_value(
+              ms.getNodeCoords(active_node).y - radius);
+        }
+        else
+        {
+          coord_text = new Gnome::Canvas::Text(
+              displayed_graph,
+              ms.getNodeCoords(active_node).x + radius,
+              ms.getNodeCoords(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;
 }
 
 XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, int move_code)
 {
   switch(move_code)
-    {
+  {
     case 1:
       return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0);
       break;
@@ -236,57 +238,59 @@
       break;
     case 3:
       {
-	//////////////////////////////////////////////////////////////////////////////////////////////////////
-	/////////// keeps shape-with scalar multiplication - version 2.
-	//////////////////////////////////////////////////////////////////////////////////////////////////////
-
-	//old vector from one to the other node - a
-	XY a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y);
-	//new vector from one to the other node - b
-	XY b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y);
-
-	double absa=sqrt(a_v.normSquare());
-	double absb=sqrt(b_v.normSquare());
-
-	if ((absa == 0.0) || (absb == 0.0))
-	  {
-	    return old_arrow_pos;
-	  }
-	else
-	  {
-	    //old vector from one node to the breakpoint - c
-	    XY c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y);
-
-	    //unit vector with the same direction to a_v
-	    XY a_v_u(a_v.x/absa,a_v.y/absa);
-
-	    //normal vector of unit vector with the same direction to a_v
-	    XY a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
-
-	    //unit vector with the same direction to b_v
-	    XY b_v_u(b_v.x/absb,b_v.y/absb);
-
-	    //normal vector of unit vector with the same direction to b_v
-	    XY b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
-
-	    //vector c in a_v_u and a_v_u_n co-ordinate system
-	    XY c_a(c_v*a_v_u,c_v*a_v_u_n);
-
-	    //new vector from one node to the breakpoint - d - we have to calculate this one
-	    XY d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
-
-	    return XY(d_v.x+fix_node.x,d_v.y+fix_node.y);
-	  }
-	break;
+        //////////////////////////////////////////////////////////////////////////////////////////////////////
+        /////////// keeps shape-with scalar multiplication - version 2.
+        //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+        //old vector from one to the other node - a
+        XY a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y);
+        //new vector from one to the other node - b
+        XY b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y);
+
+        double absa=sqrt(a_v.normSquare());
+        double absb=sqrt(b_v.normSquare());
+
+        if ((absa == 0.0) || (absb == 0.0))
+        {
+          return old_arrow_pos;
+        }
+        else
+        {
+          //old vector from one node to the breakpoint - c
+          XY c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y);
+
+          //unit vector with the same direction to a_v
+          XY a_v_u(a_v.x/absa,a_v.y/absa);
+
+          //normal vector of unit vector with the same direction to a_v
+          XY a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
+
+          //unit vector with the same direction to b_v
+          XY b_v_u(b_v.x/absb,b_v.y/absb);
+
+          //normal vector of unit vector with the same direction to b_v
+          XY b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
+
+          //vector c in a_v_u and a_v_u_n co-ordinate system
+          XY c_a(c_v*a_v_u,c_v*a_v_u_n);
+
+          //new vector from one node to the breakpoint - d - we have to calculate this one
+          XY d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
+
+          return XY(d_v.x+fix_node.x,d_v.y+fix_node.y);
+        }
+        break;
       }
     default:
       break;
-    }
+  }
 }
 
 
 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   switch(e->type)
   {
     //move the new node
@@ -301,35 +305,15 @@
       }
 
     case GDK_BUTTON_RELEASE:
-      (mytab.mapstorage)->modified = true;
+      ms.setModified();
 
       is_drawn=true;
 
       isbutton=1;
 
-      active_node=(mytab.mapstorage)->graph.addNode();
-
-      //initiating values corresponding to new node in maps
-
       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
 
-      // update coordinates
-      (mytab.mapstorage)->coords.set(active_node, XY(clicked_x, clicked_y));
-
-      // update all other maps
-      for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
-          (mytab.mapstorage)->nodemap_storage.begin(); it !=
-          (mytab.mapstorage)->nodemap_storage.end(); ++it)
-      {
-        if ((it->first != "coordinates_x") &&
-            (it->first != "coordinates_y"))
-        {
-          (*(it->second))[active_node] =
-            (mytab.mapstorage)->nodemap_default[it->first];
-        }
-      }
-      // increment the id map's default value
-      (mytab.mapstorage)->nodemap_default["label"] += 1.0;
+      active_node = ms.addNode(XY(clicked_x, clicked_y));
 
       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
           clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
@@ -348,7 +332,7 @@
       nodetextmap[active_node]->property_fill_color().set_value("darkblue");
       nodetextmap[active_node]->raise_to_top();
 
-//       mapwin.updateNode(active_node);
+      //       mapwin.updateNode(active_node);
       propertyUpdate(active_node);
 
       isbutton=0;
@@ -364,6 +348,8 @@
 
 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   switch(e->type)
   {
     case GDK_BUTTON_PRESS:
@@ -379,7 +365,7 @@
 
           active_item=(get_item_at(clicked_x, clicked_y));
           active_node=INVALID;
-          for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+          for (NodeIt i(ms.graph); i!=INVALID; ++i)
           {
             if(nodesmap[i]==active_item)
             {
@@ -408,7 +394,7 @@
           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
           target_item=(get_item_at(clicked_x, clicked_y));
           Node target_node=INVALID;
-          for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+          for (NodeIt i(ms.graph); i!=INVALID; ++i)
           {
             if(nodesmap[i]==target_item)
             {
@@ -418,54 +404,24 @@
           //the clicked item is a node, the edge can be drawn
           if(target_node!=INVALID)
           {
-            (mytab.mapstorage)->modified = true;
+            ms.setModified();
 
             *(nodesmap[target_node]) <<
               Gnome::Canvas::Properties::fill_color("red");
 
-            //creating new edge
-            active_edge=(mytab.mapstorage)->graph.addEdge(active_node,
-                target_node);
-
-            // update maps
-            for (std::map<std::string,
-                Graph::EdgeMap<double>*>::const_iterator it =
-                (mytab.mapstorage)->edgemap_storage.begin(); it !=
-                (mytab.mapstorage)->edgemap_storage.end(); ++it)
-            {
-              (*(it->second))[active_edge] =
-                (mytab.mapstorage)->edgemap_default[it->first];
-            }
-            // increment the id map's default value
-            (mytab.mapstorage)->edgemap_default["label"] += 1.0;
+            active_edge = ms.addEdge(active_node, target_node);
 
             if(target_node!=active_node)		
             {
-              // set the coordinates of the arrow on the new edge
-              MapStorage& ms = *mytab.mapstorage;
-              ms.arrow_pos.set(active_edge,
-                  (ms.coords[ms.graph.source(active_edge)] +
-                   ms.coords[ms.graph.target(active_edge)])/ 2.0);
-
-              //drawing new edge
-              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
-                  *this);
+              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge, *this);
             }
             else
             {
-              // set the coordinates of the arrow on the new edge
-              MapStorage& ms = *mytab.mapstorage;
-              ms.arrow_pos.set(active_edge,
-                  (ms.coords[ms.graph.source(active_edge)] +
-                   XY(0.0, 80.0)));
-
-              //drawing new edge
-              edgesmap[active_edge]=new LoopEdge(displayed_graph, active_edge,
-                  *this);
+              edgesmap[active_edge]=new LoopEdge(displayed_graph, active_edge, *this);
             }
 
             //initializing edge-text as well, to empty string
-            XY text_pos=mytab.mapstorage->arrow_pos[active_edge];
+            XY text_pos=ms.getArrowCoords(active_edge);
             text_pos+=(XY(10,10));
 
             edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
@@ -494,12 +450,12 @@
       {
         if(active_item)
         {
-	  propertyUpdate(active_node,N_COLOR);
+          propertyUpdate(active_node,N_COLOR);
           active_item=NULL;
         }
         if(target_item)
         {
-	  propertyUpdate((mytab.mapstorage)->graph.target(active_edge),N_COLOR);
+          propertyUpdate(ms.graph.target(active_edge),N_COLOR);
           target_item=NULL;
         }
         active_node=INVALID;
@@ -514,8 +470,10 @@
 
 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   switch(e->type)
-    {
+  {
     case GDK_BUTTON_PRESS:
       //finding the clicked items
       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
@@ -523,88 +481,88 @@
       active_node=INVALID;
       active_edge=INVALID;
       //was it a node?
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	{
-	  if(nodesmap[i]==active_item)
-	    {
-	      active_node=i;
-	    }
-	}
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
+      {
+        if(nodesmap[i]==active_item)
+        {
+          active_node=i;
+        }
+      }
       //or was it an edge?
       if(active_node==INVALID)
-	{
-	  for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	    {
-	      if(edgesmap[i]->getLine()==active_item)
-		{
-		  active_edge=i;
-		}
-	    }
-	}
+      {
+        for (EdgeIt i(ms.graph); i!=INVALID; ++i)
+        {
+          if(edgesmap[i]->getLine()==active_item)
+          {
+            active_edge=i;
+          }
+        }
+      }
 
       // return if the clicked object is neither an edge nor a node
       if (active_edge == INVALID) return false;
-      
+
       //recolor activated item
       if(active_item)
-	{
-	  *active_item << Gnome::Canvas::Properties::fill_color("red");
-	}
+      {
+        *active_item << Gnome::Canvas::Properties::fill_color("red");
+      }
       break;
 
     case GDK_BUTTON_RELEASE:
       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
       if(active_item)
-	{
-	  //the cursor was not moved since pressing it
-	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
-	    {
-	      //a node was found
-	      if(active_node!=INVALID)
-		{
-                  (mytab.mapstorage)->modified = true;
-
-		  std::set<Graph::Edge> edges_to_delete;
-
-		  for(OutEdgeIt e((mytab.mapstorage)->graph,active_node);e!=INVALID;++e)
-		    {
-		      edges_to_delete.insert(e);
-		    }
-		  
-		  for(InEdgeIt e((mytab.mapstorage)->graph,active_node);e!=INVALID;++e)
-		    {
-		      edges_to_delete.insert(e);
-		    }
-		  
-		  //deleting collected edges
-		  for(std::set<Graph::Edge>::iterator
-			edge_set_it=edges_to_delete.begin();
-		      edge_set_it!=edges_to_delete.end();
-		      ++edge_set_it)
-		    {
-		      deleteItem(*edge_set_it);
-		    }
-		  deleteItem(active_node);
-		}
-	      //a simple edge was chosen
-	      else if (active_edge != INVALID)
-		{
-		  deleteItem(active_edge);
-		}
-	    }
-	  //pointer was moved, deletion is cancelled
-	  else
-	    {
-	      if(active_node!=INVALID)
-		{
-		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
-		}
-	      else if (active_edge != INVALID)
-		{
-		  *active_item << Gnome::Canvas::Properties::fill_color("green");
-		}
-	    }
-	}
+      {
+        //the cursor was not moved since pressing it
+        if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
+        {
+          //a node was found
+          if(active_node!=INVALID)
+          {
+            ms.setModified();
+
+            std::set<Graph::Edge> edges_to_delete;
+
+            for(OutEdgeIt e(ms.graph,active_node);e!=INVALID;++e)
+            {
+              edges_to_delete.insert(e);
+            }
+
+            for(InEdgeIt e(ms.graph,active_node);e!=INVALID;++e)
+            {
+              edges_to_delete.insert(e);
+            }
+
+            //deleting collected edges
+            for(std::set<Graph::Edge>::iterator
+                edge_set_it=edges_to_delete.begin();
+                edge_set_it!=edges_to_delete.end();
+                ++edge_set_it)
+            {
+              deleteItem(*edge_set_it);
+            }
+            deleteItem(active_node);
+          }
+          //a simple edge was chosen
+          else if (active_edge != INVALID)
+          {
+            deleteItem(active_edge);
+          }
+        }
+        //pointer was moved, deletion is cancelled
+        else
+        {
+          if(active_node!=INVALID)
+          {
+            *active_item << Gnome::Canvas::Properties::fill_color("blue");
+          }
+          else if (active_edge != INVALID)
+          {
+            *active_item << Gnome::Canvas::Properties::fill_color("green");
+          }
+        }
+      }
       //reseting datas
       active_item=NULL;
       active_edge=INVALID;
@@ -616,167 +574,201 @@
 
     default:
       break;
-    }
+  }
   return false;
 }
 
 bool GraphDisplayerCanvas::mapEditEventHandler(GdkEvent* e)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   if(actual_tool==MAP_EDIT)
+  {
+    switch(e->type)
     {
-      switch(e->type)
-	{
-	case GDK_BUTTON_PRESS:
-	  {
-	    //for determine, whether it was an edge
-	    Edge clicked_edge=INVALID;
-	    //for determine, whether it was a node
-	    Node clicked_node=INVALID;
-
-	    window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
-	    active_item=(get_item_at(clicked_x, clicked_y));
-
-	    //find the activated item between text of nodes
-	    for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-	      {
-		//at the same time only one can be active
-		if(nodetextmap[i]==active_item)
-		  {
-		    clicked_node=i;
-		  }
-	      }
-
-	    //if there was not, search for it between nodes
-	    if(clicked_node==INVALID)
-	      {
-		for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-		  {
-		    //at the same time only one can be active
-		    if(nodesmap[i]==active_item)
-		      {
-			clicked_node=i;
-		      }
-		  }
-	      }
-
-	    if(clicked_node==INVALID)
-	      {
-		//find the activated item between texts
-		for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-		  {
-		    //at the same time only one can be active
-		    if(edgetextmap[i]==active_item)
-		      {
-			clicked_edge=i;
-		      }
-		  }
-
-		//if it was not between texts, search for it between edges
-		if(clicked_edge==INVALID)
-		  {
-		    for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
-		      {
-			//at the same time only one can be active
-			if((edgesmap[i]->getLine())==active_item)
-			  {
-			    clicked_edge=i;
-			  }
-		      }
-		  }
-	      }
-
-	    //if it was really a node...
-	    if(clicked_node!=INVALID)
-	      {
-		// the id map is not editable
-		if (nodemap_to_edit == "label") return 0;
-
-		//and there is activated map
-		if(nodetextmap[clicked_node]->property_text().get_value()!="")
-		  {
-		    //activate the general variable for it
-		    active_node=clicked_node;
-
-		    //create a dialog
-		    Gtk::Dialog dialog("Edit value", true);
-		    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-		    dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
-		    Gtk::VBox* vbox = dialog.get_vbox();
-		    Gtk::SpinButton spin(0.0, 4);
-		    spin.set_increments(1.0, 10.0);
-		    spin.set_range(-1000000.0, 1000000.0);
-		    spin.set_numeric(true);
-		    spin.set_value(atof(nodetextmap[active_node]->property_text().get_value().c_str()));
-		    vbox->add(spin);
-		    spin.show();
-		    switch (dialog.run())
-		      {
-		      case Gtk::RESPONSE_NONE:
-		      case Gtk::RESPONSE_CANCEL:
-			break;
-		      case Gtk::RESPONSE_ACCEPT:
-			double new_value = spin.get_value();
-			(*(mytab.mapstorage)->nodemap_storage[nodemap_to_edit])[active_node] =
-			  new_value;
-			std::ostringstream ostr;
-			ostr << new_value;
-			nodetextmap[active_node]->property_text().set_value(ostr.str());
-			//mapwin.updateNode(active_node);
-			//mapwin.updateNode(Node(INVALID));
-			propertyUpdate(Node(INVALID));
-		      }
-		  }
-	      }
-	    else
-	      //if it was really an edge...
-	      if(clicked_edge!=INVALID)
-		{
-		  // the id map is not editable
-		  if (edgemap_to_edit == "label") return 0;
-
-		  //and there is activated map
-		  if(edgetextmap[clicked_edge]->property_text().get_value()!="")
-		    {
-		      //activate the general variable for it
-		      active_edge=clicked_edge;
-
-		      //create a dialog
-		      Gtk::Dialog dialog("Edit value", true);
-		      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-		      dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
-		      Gtk::VBox* vbox = dialog.get_vbox();
-		      Gtk::SpinButton spin(0.0, 4);
-		      spin.set_increments(1.0, 10.0);
-		      spin.set_range(-1000000.0, 1000000.0);
-		      spin.set_numeric(true);
-		      spin.set_value(atof(edgetextmap[active_edge]->property_text().get_value().c_str()));
-		      vbox->add(spin);
-		      spin.show();
-		      switch (dialog.run())
-			{
-			case Gtk::RESPONSE_NONE:
-			case Gtk::RESPONSE_CANCEL:
-			  break;
-			case Gtk::RESPONSE_ACCEPT:
-			  double new_value = spin.get_value();
-			  (*(mytab.mapstorage)->edgemap_storage[edgemap_to_edit])[active_edge] =
-			    new_value;
-			  std::ostringstream ostr;
-			  ostr << new_value;
-			  edgetextmap[active_edge]->property_text().set_value(
-									      ostr.str());
-			  //mapwin.updateEdge(active_edge);
-			  //                   mapwin.updateEdge(Edge(INVALID));
-			  propertyUpdate(Edge(INVALID));
-			}
-		    }
-		}
-	    break;
-	  }
-	default:
-	  break;
-	}
+      case GDK_BUTTON_PRESS:
+        {
+          //for determine, whether it was an edge
+          Edge clicked_edge=INVALID;
+          //for determine, whether it was a node
+          Node clicked_node=INVALID;
+
+          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
+          active_item=(get_item_at(clicked_x, clicked_y));
+
+          //find the activated item between text of nodes
+          for (NodeIt i(ms.graph); i!=INVALID; ++i)
+          {
+            //at the same time only one can be active
+            if(nodetextmap[i]==active_item)
+            {
+              clicked_node=i;
+            }
+          }
+
+          //if there was not, search for it between nodes
+          if(clicked_node==INVALID)
+          {
+            for (NodeIt i(ms.graph); i!=INVALID; ++i)
+            {
+              //at the same time only one can be active
+              if(nodesmap[i]==active_item)
+              {
+                clicked_node=i;
+              }
+            }
+          }
+
+          if(clicked_node==INVALID)
+          {
+            //find the activated item between texts
+            for (EdgeIt i(ms.graph); i!=INVALID; ++i)
+            {
+              //at the same time only one can be active
+              if(edgetextmap[i]==active_item)
+              {
+                clicked_edge=i;
+              }
+            }
+
+            //if it was not between texts, search for it between edges
+            if(clicked_edge==INVALID)
+            {
+              for (EdgeIt i(ms.graph); i!=INVALID; ++i)
+              {
+                //at the same time only one can be active
+                if((edgesmap[i]->getLine())==active_item)
+                {
+                  clicked_edge=i;
+                }
+              }
+            }
+          }
+
+          //if it was really a node...
+          if(clicked_node!=INVALID)
+          {
+            // the id map is not editable
+            if (nodemap_to_edit == "label") return 0;
+
+            //and there is activated map
+            if(nodetextmap[clicked_node]->property_text().get_value()!="")
+            {
+              //activate the general variable for it
+              active_node=clicked_node;
+
+              //create a dialog
+              Gtk::Dialog dialog("Edit value", true);
+              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
+              Gtk::VBox* vbox = dialog.get_vbox();
+
+              /*
+              Gtk::SpinButton spin(0.0, 4);
+              spin.set_increments(1.0, 10.0);
+              spin.set_range(-1000000.0, 1000000.0);
+              spin.set_numeric(true);
+              spin.set_value(atof(nodetextmap[active_node]->property_text().get_value().c_str()));
+              vbox->add(spin);
+              spin.show();
+              */
+              Gtk::Entry entry;
+              entry.set_text(nodetextmap[active_node]->property_text().get_value());
+              vbox->add(entry);
+              entry.show();
+
+              switch (dialog.run())
+              {
+                case Gtk::RESPONSE_NONE:
+                case Gtk::RESPONSE_CANCEL:
+                  break;
+                case Gtk::RESPONSE_ACCEPT:
+                  switch (ms.getNodeMapElementType(nodemap_to_edit))
+                  {
+                    case MapValue::NUMERIC:
+                      ms.set(nodemap_to_edit, active_node,
+                          atof(entry.get_text().c_str()));
+                      break;
+                    case MapValue::STRING:
+                      ms.set(nodemap_to_edit, active_node,
+                          static_cast<std::string>(entry.get_text()));
+                      break;
+                  }
+                  nodetextmap[active_node]->property_text().set_value(
+                      static_cast<std::string>(ms.get(nodemap_to_edit, active_node)));
+
+                  //mapwin.updateNode(active_node);
+                  //mapwin.updateNode(Node(INVALID));
+                  propertyUpdate(Node(INVALID));
+              }
+            }
+          }
+          else
+            //if it was really an edge...
+            if(clicked_edge!=INVALID)
+            {
+              // the id map is not editable
+              if (edgemap_to_edit == "label") return 0;
+
+              //and there is activated map
+              if(edgetextmap[clicked_edge]->property_text().get_value()!="")
+              {
+                //activate the general variable for it
+                active_edge=clicked_edge;
+
+                //create a dialog
+                Gtk::Dialog dialog("Edit value", true);
+                dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+                dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
+                Gtk::VBox* vbox = dialog.get_vbox();
+
+                /*
+                Gtk::SpinButton spin(0.0, 4);
+                spin.set_increments(1.0, 10.0);
+                spin.set_range(-1000000.0, 1000000.0);
+                spin.set_numeric(true);
+                spin.set_value(atof(edgetextmap[active_edge]->property_text().get_value().c_str()));
+                vbox->add(spin);
+                spin.show();
+                */
+                Gtk::Entry entry;
+                entry.set_text(edgetextmap[active_edge]->property_text().get_value());
+                vbox->add(entry);
+                entry.show();
+
+                std::cout << edgemap_to_edit << std::endl;
+                switch (dialog.run())
+                {
+                  case Gtk::RESPONSE_NONE:
+                  case Gtk::RESPONSE_CANCEL:
+                    break;
+                  case Gtk::RESPONSE_ACCEPT:
+                    switch (ms.getEdgeMapElementType(edgemap_to_edit))
+                    {
+                      case MapValue::NUMERIC:
+                        ms.set(edgemap_to_edit, active_edge,
+                            atof(entry.get_text().c_str()));
+                        break;
+                      case MapValue::STRING:
+                        ms.set(edgemap_to_edit, active_edge,
+                            static_cast<std::string>(entry.get_text()));
+                        break;
+                    }
+                    edgetextmap[active_edge]->property_text().set_value(
+                        static_cast<std::string>(ms.get(edgemap_to_edit, active_edge)));
+
+                    //mapwin.updateEdge(active_edge);
+                    //                   mapwin.updateEdge(Edge(INVALID));
+                    propertyUpdate(Edge(INVALID));
+                }
+              }
+            }
+          break;
+        }
+      default:
+        break;
     }
+  }
   return false;  
 }
 
@@ -784,14 +776,14 @@
 {
   delete(nodetextmap[node_to_delete]);
   delete(nodesmap[node_to_delete]);
-  (mytab.mapstorage)->graph.erase(node_to_delete);
+  mytab.mapstorage->graph.erase(node_to_delete);
 }
 
 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
 {
   delete(edgetextmap[edge_to_delete]);
   delete(edgesmap[edge_to_delete]);
-  (mytab.mapstorage)->graph.erase(edge_to_delete);
+  mytab.mapstorage->graph.erase(edge_to_delete);
 }
 
 void GraphDisplayerCanvas::textReposition(XY new_place)
@@ -811,7 +803,7 @@
     }
     else
     {
-      for (EdgeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (EdgeIt i(mytab.mapstorage->graph); i!=INVALID; ++i)
       {
         if(edgesmap[i]==active_bre)
         {
@@ -821,99 +813,99 @@
     }
   }
   else
+  {
+    if(forming_edge!=INVALID)
     {
-      if(forming_edge!=INVALID)
-	{
-	  forming_edge=INVALID;
-	}
-      else
-	{
-	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
-	}
+      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)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   Gnome::Canvas::Item * moved_item=item;
   Node moved_node=node;
 
   if(item==NULL && node==INVALID)
-    {
-      moved_item=active_item;
-      moved_node=active_node;
-    }
+  {
+    moved_item=active_item;
+    moved_node=active_node;
+  }
   else
-    {
-      isbutton=1;
-    }
+  {
+    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;
+  double coord_x = dx + ms.getNodeCoords(moved_node).x;
+  double coord_y = dy + ms.getNodeCoords(moved_node).y;
 
   // write back the new coordinates to the coords map
-  (mytab.mapstorage)->coords.set(moved_node, XY(coord_x, coord_y));
+  ms.setNodeCoords(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)
+  for(OutEdgeIt ei(ms.graph,moved_node);ei!=INVALID;++ei)
+  {
+    XY arrow_pos;
+
+    if (ms.graph.source(ei) == ms.graph.target(ei))
     {
-      XY arrow_pos;
+      arrow_pos = ms.getArrowCoords(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 = ms.graph.target(ei);
+      XY fix_node = ms.getNodeCoords(target);
+      XY old_arrow_pos(ms.getArrowCoords(ei));
+
+      arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
+    }
+
+    ms.setArrowCoords(ei, arrow_pos);
+    edgesmap[ei]->draw();
+
+    //reposition of edgetext
+    XY text_pos=ms.getArrowCoords(ei);
+    text_pos+=(XY(10,10));
+    edgetextmap[ei]->property_x().set_value(text_pos.x);
+    edgetextmap[ei]->property_y().set_value(text_pos.y);
+  }
 
-      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]);
+  for(InEdgeIt ei(ms.graph,moved_node);ei!=INVALID;++ei)
+  {
+    if (ms.graph.source(ei) != ms.graph.target(ei))
+    {
+      XY moved_node_1(coord_x - dx, coord_y - dy);
+      XY moved_node_2(coord_x, coord_y);
+      Node source = ms.graph.source(ei);
+      XY fix_node = ms.getNodeCoords(source);
+      XY old_arrow_pos(ms.getArrowCoords(ei));
 
-	  arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
-	}
+      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);
+      ms.setArrowCoords(ei, arrow_pos);
       edgesmap[ei]->draw();
 
       //reposition of edgetext
-      XY text_pos=mytab.mapstorage->arrow_pos[ei];
+      XY text_pos=ms.getArrowCoords(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);
-	}
-    }
+  }
 }
 
 Gdk::Color GraphDisplayerCanvas::rainbowColorCounter(double min, double max, double w)
@@ -928,48 +920,48 @@
   //first we determine the phase, in which
   //the actual value belongs to
   for (int i=0;i<=5;i++)
+  {
+    if(((double)i/6<pos)&&(pos<=(double(i+1)/6)))
     {
-      if(((double)i/6<pos)&&(pos<=(double(i+1)/6)))
-	{
-	  phase=i;
-	}
+      phase=i;
     }
+  }
   if(phase<6)
-    {
-      //within its 1/6 long phase the relativ position
-      //determines the power of the color changed in
-      //that phase
-      //we normalize that to one, to be able to give percentage
-      //value for the function
-      double rel_pos=(pos-(phase/6.0))*6.0;
+  {
+    //within its 1/6 long phase the relativ position
+    //determines the power of the color changed in
+    //that phase
+    //we normalize that to one, to be able to give percentage
+    //value for the function
+    double rel_pos=(pos-(phase/6.0))*6.0;
 
-      switch(phase)
-	{
-	case 0:
-	  color.set_rgb_p (1, 0, 1-rel_pos);
-	  break;
-	case 1:
-	  color.set_rgb_p (1, rel_pos, 0);
-	  break;
-	case 2:
-	  color.set_rgb_p (1-rel_pos, 1, 0);
-	  break;
-	case 3:
-	  color.set_rgb_p (0, 1, rel_pos);
-	  break;
-	case 4:
-	  color.set_rgb_p (0, 1-rel_pos, 1);
-	  break;
-	case 5:
-	  color.set_rgb_p ((rel_pos/3.0), 0, 1);
-	  break;
-	default:
-	  std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
-	}
-    }
-  else
+    switch(phase)
     {
-      std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
+      case 0:
+        color.set_rgb_p (1, 0, 1-rel_pos);
+        break;
+      case 1:
+        color.set_rgb_p (1, rel_pos, 0);
+        break;
+      case 2:
+        color.set_rgb_p (1-rel_pos, 1, 0);
+        break;
+      case 3:
+        color.set_rgb_p (0, 1, rel_pos);
+        break;
+      case 4:
+        color.set_rgb_p (0, 1-rel_pos, 1);
+        break;
+      case 5:
+        color.set_rgb_p ((rel_pos/3.0), 0, 1);
+        break;
+      default:
+        std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
     }
+  }
+  else
+  {
+    std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
+  }
   return color;
 }

Modified: glemon/trunk/graph_displayer_canvas-node.cc
==============================================================================
--- glemon/trunk/graph_displayer_canvas-node.cc	(original)
+++ glemon/trunk/graph_displayer_canvas-node.cc	Wed Jan  2 22:03:09 2008
@@ -25,17 +25,27 @@
 
 int GraphDisplayerCanvas::changeNodeRadius (std::string mapname, Node node)
 {
-  Graph::NodeMap<double> * actual_map;
+  MapStorage& ms = *mytab.mapstorage;
+
   double min, max;
-  min=(mytab.mapstorage)->minOfNodeMap(mapname);
-  max=(mytab.mapstorage)->maxOfNodeMap(mapname);
-  actual_map=((mytab.mapstorage)->nodemap_storage)[mapname];
+
+  {
+    NodeIt n(ms.graph);
+    min = max = ms.get(mapname, n);
+    for (; n != INVALID; ++n)
+    {
+      if (static_cast<double>(ms.get(mapname, n)) > max)
+        max = ms.get(mapname, n);
+      if (static_cast<double>(ms.get(mapname, n)) < min)
+        min = ms.get(mapname, n);
+    }
+  }
 
   if(node==INVALID)
     {
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
-	  double v=fabs((*actual_map)[i]);
+	  double v=fabs(ms.get(mapname,i));
 	  int w;
 	  if(autoscale)
 	    {
@@ -102,14 +112,16 @@
 
 int GraphDisplayerCanvas::resetNodeRadius (Node node)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   double min, max;
   min=node_property_defaults[N_RADIUS];
   max=node_property_defaults[N_RADIUS];
-  Graph::NodeMap<double> actual_map((mytab.mapstorage)->graph,node_property_defaults[N_RADIUS]);
+  Graph::NodeMap<double> actual_map(ms.graph,node_property_defaults[N_RADIUS]);
   
   if(node==INVALID)
     {
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
 	  double v=fabs(actual_map[i]);
 	  int w;
@@ -163,27 +175,34 @@
 
 int GraphDisplayerCanvas::changeNodeColor (std::string mapname, Node node)
 {  
+  MapStorage& ms = *mytab.mapstorage;
 
   //function maps the range of the maximum and
   //the minimum of the nodemap to the range of
   //green in RGB
 
-  Graph::NodeMap<double> * actual_map;
-  actual_map=((mytab.mapstorage)->nodemap_storage)[mapname];
-
   double max, min;
 
-  max=(mytab.mapstorage)->maxOfNodeMap(mapname);
-  min=(mytab.mapstorage)->minOfNodeMap(mapname);
+  {
+    NodeIt n(ms.graph);
+    min = max = ms.get(mapname, n);
+    for (; n != INVALID; ++n)
+    {
+      if (static_cast<double>(ms.get(mapname, n)) > max)
+        max = ms.get(mapname, n);
+      if (static_cast<double>(ms.get(mapname, n)) < min)
+        min = ms.get(mapname, n);
+    }
+  }
 
   if(node==INVALID)
     {
 
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
 	  Gdk::Color color;
 
-	  double w=(*actual_map)[i];
+	  double w=ms.get(mapname, i);
 
 	  if(max!=min)
 	    {
@@ -201,7 +220,7 @@
     {
       Gdk::Color color;
 
-      double w=(*actual_map)[node];
+      double w=ms.get(mapname, node);
 
       if(max!=min)
 	{
@@ -219,12 +238,13 @@
 
 int GraphDisplayerCanvas::resetNodeColor (Node node)
 {  
+  MapStorage& ms = *mytab.mapstorage;
 
   //function maps the range of the maximum and
   //the minimum of the nodemap to the range of
   //green in RGB
 
-  Graph::NodeMap<double> actual_map((mytab.mapstorage)->graph,node_property_defaults[N_COLOR]);
+  Graph::NodeMap<double> actual_map(ms.graph,node_property_defaults[N_COLOR]);
 
   double max, min;
 
@@ -234,7 +254,7 @@
   if(node==INVALID)
     {
 
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
 	  Gdk::Color color;
 
@@ -274,42 +294,34 @@
 
 int GraphDisplayerCanvas::changeNodeText (std::string mapname, Node node)
 {
+  MapStorage& ms = *mytab.mapstorage;
 
   //the number in the map will be written on the node
   //EXCEPT when the name of the map is Text, because
   //in that case empty string will be written, because
   //that is the deleter map
 
-  Graph::NodeMap<double> * actual_map=NULL;
-  actual_map=((mytab.mapstorage)->nodemap_storage)[mapname];
-
   if(node==INVALID)
     {
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
 	  nodemap_to_edit=mapname;
-	  double number=(*actual_map)[i];
 
-	  std::ostringstream ostr;
-	  ostr << number;
-	      
-	  nodetextmap[i]->property_text().set_value(ostr.str());
+	  nodetextmap[i]->property_text().set_value(
+              static_cast<std::string>(ms.get(mapname, i)));
 	}
     }
   else
     {
-      double number=(*actual_map)[node];
-
-      std::ostringstream ostr;
-      ostr << number;
-	      
-      nodetextmap[node]->property_text().set_value(ostr.str());
+      nodetextmap[node]->property_text().set_value(
+          static_cast<std::string>(ms.get(mapname, node)));
     }
   return 0;
 };
 
 int GraphDisplayerCanvas::resetNodeText (Node node)
 {
+  MapStorage& ms = *mytab.mapstorage;
 
   //the number in the map will be written on the node
   //EXCEPT when the name of the map is Text, because
@@ -318,7 +330,7 @@
 
   if(node==INVALID)
     {
-      for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+      for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	{
 	  nodemap_to_edit="";
 	  nodetextmap[i]->property_text().set_value("");

Modified: glemon/trunk/graph_displayer_canvas.cc
==============================================================================
--- glemon/trunk/graph_displayer_canvas.cc	(original)
+++ glemon/trunk/graph_displayer_canvas.cc	Wed Jan  2 22:03:09 2008
@@ -117,46 +117,57 @@
   std::string mapname=mytab.getActiveNodeMap(prop);
 
   if(is_drawn)
+  {
+    if(mapname!="")
     {
-      if(mapname!="")
-	{
-	  if( ( ((mytab.mapstorage)->nodemap_storage).find(mapname) != ((mytab.mapstorage)->nodemap_storage).end() ) )
-	    {
-	      switch(prop)
-		{
-		case N_RADIUS:
-		  changeNodeRadius(mapname, node);
-		  break;
-		case N_COLOR:
-		  changeNodeColor(mapname, node);
-		  break;
-		case N_TEXT:
-		  changeNodeText(mapname, node);
-		  break;
-		default:
-		  std::cerr<<"Error\n";
-		}
-	    }
-	}
-      else //mapname==""
-	{
-	  Node node=INVALID;	
-	  switch(prop)
-	    {
-	    case N_RADIUS:
-	      resetNodeRadius(node);
-	      break;
-	    case N_COLOR:
-	      resetNodeColor(node);
-	      break;
-	    case N_TEXT:
-	      resetNodeText(node);
-	      break;
-	    default:
-	      std::cerr<<"Error\n";
-	    }
-	}
+      std::vector<std::string> nodemaps = mytab.mapstorage->getNodeMapList();
+      bool found = false;
+      for (std::vector<std::string>::const_iterator it = nodemaps.begin();
+          it != nodemaps.end(); ++it)
+      {
+        if (*it == mapname)
+        {
+          found = true;
+          break;
+        }
+      }
+      if (found)
+      {
+        switch(prop)
+        {
+          case N_RADIUS:
+            changeNodeRadius(mapname, node);
+            break;
+          case N_COLOR:
+            changeNodeColor(mapname, node);
+            break;
+          case N_TEXT:
+            changeNodeText(mapname, node);
+            break;
+          default:
+            std::cerr<<"Error\n";
+        }
+      }
+    }
+    else //mapname==""
+    {
+      Node node=INVALID;
+      switch(prop)
+      {
+        case N_RADIUS:
+          resetNodeRadius(node);
+          break;
+        case N_COLOR:
+          resetNodeColor(node);
+          break;
+        case N_TEXT:
+          resetNodeText(node);
+          break;
+        default:
+          std::cerr<<"Error\n";
+      }
     }
+  }
 }
 
 void GraphDisplayerCanvas::propertyUpdate(Edge edge, int prop)
@@ -164,45 +175,56 @@
   std::string mapname=mytab.getActiveEdgeMap(prop);
 
   if(is_drawn)
+  {
+    if(mapname!="")
     {
-      if(mapname!="")
-	{
-	  if( ( ((mytab.mapstorage)->edgemap_storage).find(mapname) != ((mytab.mapstorage)->edgemap_storage).end() ) )
-	    {
-	      switch(prop)
-		{
-		case E_WIDTH:
-		  changeEdgeWidth(mapname, edge);
-		  break;
-		case E_COLOR:
-		  changeEdgeColor(mapname, edge);
-		  break;
-		case E_TEXT:
-		  changeEdgeText(mapname, edge);
-		  break;
-		default:
-		  std::cerr<<"Error\n";
-		}
-	    }
-	}
-      else //mapname==""
-	{
-	  switch(prop)
-	    {
-	    case E_WIDTH:
-	      resetEdgeWidth(edge);
-	      break;
-	    case E_COLOR:
-	      resetEdgeColor(edge);
-	      break;
-	    case E_TEXT:
-	      resetEdgeText(edge);
-	      break;
-	    default:
-	      std::cerr<<"Error\n";
-	    }
-	}
+      std::vector<std::string> edgemaps = mytab.mapstorage->getEdgeMapList();
+      bool found = false;
+      for (std::vector<std::string>::const_iterator it = edgemaps.begin();
+          it != edgemaps.end(); ++it)
+      {
+        if (*it == mapname)
+        {
+          found = true;
+          break;
+        }
+      }
+      if (found)
+      {
+        switch(prop)
+        {
+          case E_WIDTH:
+            changeEdgeWidth(mapname, edge);
+            break;
+          case E_COLOR:
+            changeEdgeColor(mapname, edge);
+            break;
+          case E_TEXT:
+            changeEdgeText(mapname, edge);
+            break;
+          default:
+            std::cerr<<"Error\n";
+        }
+      }
     }
+    else //mapname==""
+    {
+      switch(prop)
+      {
+        case E_WIDTH:
+          resetEdgeWidth(edge);
+          break;
+        case E_COLOR:
+          resetEdgeColor(edge);
+          break;
+        case E_TEXT:
+          resetEdgeText(edge);
+          break;
+        default:
+          std::cerr<<"Error\n";
+      }
+    }
+  }
 }
 
 void GraphDisplayerCanvas::drawGraph()
@@ -221,7 +243,7 @@
     }
     //initializing edge-text as well, to empty string
 
-    XY text_pos=mytab.mapstorage->arrow_pos[i];
+    XY text_pos=mytab.mapstorage->getArrowCoords(i);
     text_pos+=(XY(10,10));
 
     edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
@@ -238,10 +260,10 @@
 
     nodesmap[i]=new Gnome::Canvas::Ellipse(
         displayed_graph,
-        (mytab.mapstorage)->coords[i].x-20,
-        (mytab.mapstorage)->coords[i].y-20,
-        (mytab.mapstorage)->coords[i].x+20,
-        (mytab.mapstorage)->coords[i].y+20);
+        mytab.mapstorage->getNodeCoords(i).x-20,
+        mytab.mapstorage->getNodeCoords(i).y-20,
+        mytab.mapstorage->getNodeCoords(i).x+20,
+        mytab.mapstorage->getNodeCoords(i).y+20);
     *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
     *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
     nodesmap[i]->raise_to_top();
@@ -249,8 +271,8 @@
     //initializing edge-text as well, to empty string
 
     XY text_pos(
-        ((mytab.mapstorage)->coords[i].x+node_property_defaults[N_RADIUS]+5),
-        ((mytab.mapstorage)->coords[i].y+node_property_defaults[N_RADIUS]+5));
+        (mytab.mapstorage->getNodeCoords(i).x+node_property_defaults[N_RADIUS]+5),
+        (mytab.mapstorage->getNodeCoords(i).y+node_property_defaults[N_RADIUS]+5));
 
     nodetextmap[i]=new Gnome::Canvas::Text(displayed_graph,
         text_pos.x, text_pos.y, "");
@@ -325,7 +347,8 @@
 
 void GraphDisplayerCanvas::reDesignGraph()
 {
-  NodeIt firstnode((mytab.mapstorage)->graph);
+  MapStorage& ms = *mytab.mapstorage;
+  NodeIt firstnode(ms.graph);
   //is it not an empty graph?
   if(firstnode!=INVALID)
     {
@@ -335,7 +358,7 @@
 
       if(!was_redesigned)
 	{
-	  NodeIt i((mytab.mapstorage)->graph);
+	  NodeIt i(ms.graph);
 
 	  dim2::Point<double> init(init_vector_length*rnd(),
 				   init_vector_length*rnd());
@@ -347,28 +370,28 @@
       double propulsation;
       int iterations;
 
-      (mytab.mapstorage)->get_design_data(attraction, propulsation, iterations);
+      ms.get_design_data(attraction, propulsation, iterations);
 
       //iteration counter
       for(int l=0;l<iterations;l++)
 	{
-	  Graph::NodeMap<double> x(mytab.mapstorage->graph);
-	  Graph::NodeMap<double> y(mytab.mapstorage->graph);
+	  Graph::NodeMap<double> x(ms.graph);
+	  Graph::NodeMap<double> y(ms.graph);
 	  XYMap<Graph::NodeMap<double> > actual_forces;
 	  actual_forces.setXMap(x);
 	  actual_forces.setYMap(y);
 
 	  //count actual force for each nodes
-	  for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+	  for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	    {
 	      //propulsation of nodes
-	      for (NodeIt j((mytab.mapstorage)->graph); j!=INVALID; ++j)
+	      for (NodeIt j(ms.graph); j!=INVALID; ++j)
 		{
 		  if(i!=j)
 		    {
 		      lemon::dim2::Point<double> delta =
-			((mytab.mapstorage)->coords[i]-
-			 (mytab.mapstorage)->coords[j]);
+			(ms.getNodeCoords(i)-
+			 ms.getNodeCoords(j));
 
 		      const double length_sqr=std::max(delta.normSquare(),min_dist);
 
@@ -382,55 +405,53 @@
 		      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)
-		{
-		  lemon::dim2::Point<double> delta =
-		    ((mytab.mapstorage)->coords[i]-
-		     (mytab.mapstorage)->coords[mytab.mapstorage->
-					       graph.target(ei)]);
-		
-		  //calculating attraction strength
-		  //greater distance means greater strength
-		  delta*=attraction;
-		
-		  actual_forces.set(i,actual_forces[i]-delta);
-		}
-	      for(InEdgeIt ei((mytab.mapstorage)->graph,i);ei!=INVALID;++ei)
-		{
-		  lemon::dim2::Point<double> delta =
-		    ((mytab.mapstorage)->coords[i]-
-		     (mytab.mapstorage)->coords[mytab.mapstorage->
-					       graph.source(ei)]);
-		
-		  //calculating attraction strength
-		  //greater distance means greater strength
-		  delta*=attraction;
-		
-		  actual_forces.set(i,actual_forces[i]-delta);
-		}
+            //attraction of nodes, to which actual node is bound
+            for(OutEdgeIt ei(ms.graph,i);ei!=INVALID;++ei)
+              {
+                lemon::dim2::Point<double> delta =
+                  (ms.getNodeCoords(i)-
+                   ms.getNodeCoords(ms.graph.target(ei)));
+
+                //calculating attraction strength
+                //greater distance means greater strength
+                delta*=attraction;
+
+                actual_forces.set(i,actual_forces[i]-delta);
+              }
+                    for(InEdgeIt ei(ms.graph,i);ei!=INVALID;++ei)
+              {
+                lemon::dim2::Point<double> delta =
+                  (ms.getNodeCoords(i)-
+                   ms.getNodeCoords(ms.graph.source(ei)));
+
+                //calculating attraction strength
+                //greater distance means greater strength
+                delta*=attraction;
+
+                actual_forces.set(i,actual_forces[i]-delta);
+              }
 	    }
-	  for (NodeIt i((mytab.mapstorage)->graph); i!=INVALID; ++i)
+	  for (NodeIt i(ms.graph); i!=INVALID; ++i)
 	    {
-	      if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x>max_coord)
+	      if((ms.getNodeCoords(i).x)+actual_forces[i].x>max_coord)
 		{
-		  actual_forces[i].x=max_coord-((mytab.mapstorage)->coords[i].x);
-		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl;
+		  actual_forces[i].x=max_coord-(ms.getNodeCoords(i).x);
+		  std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl;
 		}
-	      else if(((mytab.mapstorage)->coords[i].x)+actual_forces[i].x<(0-max_coord))
+	      else if((ms.getNodeCoords(i).x)+actual_forces[i].x<(0-max_coord))
 		{
-		  actual_forces[i].x=0-max_coord-((mytab.mapstorage)->coords[i].x);
-		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].x)+actual_forces[i].x) << std::endl;
+		  actual_forces[i].x=0-max_coord-(ms.getNodeCoords(i).x);
+		  std::cout << "Correction! " << ((ms.getNodeCoords(i).x)+actual_forces[i].x) << std::endl;
 		}
-	      if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y>max_coord)
+	      if((ms.getNodeCoords(i).y)+actual_forces[i].y>max_coord)
 		{
-		  actual_forces[i].y=max_coord-((mytab.mapstorage)->coords[i].y);
-		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl;
+		  actual_forces[i].y=max_coord-(ms.getNodeCoords(i).y);
+		  std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl;
 		}
-	      else if(((mytab.mapstorage)->coords[i].y)+actual_forces[i].y<(0-max_coord))
+	      else if((ms.getNodeCoords(i).y)+actual_forces[i].y<(0-max_coord))
 		{
-		  actual_forces[i].y=0-max_coord-((mytab.mapstorage)->coords[i].y);
-		  std::cout << "Correction! " << (((mytab.mapstorage)->coords[i].y)+actual_forces[i].y) << std::endl;
+		  actual_forces[i].y=0-max_coord-(ms.getNodeCoords(i).y);
+		  std::cout << "Correction! " << ((ms.getNodeCoords(i).y)+actual_forces[i].y) << std::endl;
 		}
 	      moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
 	    }

Modified: glemon/trunk/gui_reader.cc
==============================================================================
--- glemon/trunk/gui_reader.cc	(original)
+++ glemon/trunk/gui_reader.cc	Wed Jan  2 22:03:09 2008
@@ -20,6 +20,7 @@
 #include <mapstorage.h>
 
 #include <xml.h>
+#include "io_helper.h"
 #include <lemon/dim2.h>
 #include <vector>
 
@@ -33,34 +34,139 @@
 
 void GuiReader::read(std::istream& is)
 {
+  using std::vector;
+  using std::string;
+  using std::pair;
+  using std::make_pair;
+  using std::string;
+  using std::map;
+
   XmlIo x(is);
-  std::map<int, XY > m;
-  x("arrow_pos", m);
 
-  if ((int)m.size() == countEdges(mapstorage->graph))
+  { x("main_node_map_names", gui_data.main_node_map_names); }
+  { x("gui_node_map_names", gui_data.gui_node_map_names); }
+
+  { x("node_map_types", gui_data.node_map_types); }
+
+  { x("main_edge_map_names", gui_data.main_edge_map_names); }
+  { x("gui_edge_map_names", gui_data.gui_edge_map_names); }
+
+  { x("edge_map_types", gui_data.edge_map_types); }
+
+  for (vector<string>::const_iterator it = gui_data.gui_node_map_names.begin();
+      it != gui_data.gui_node_map_names.end(); ++it)
+  {
+    MapValue::Type type = gui_data.node_map_types[*it];
+    switch (type)
+    {
+      case MapValue::NUMERIC:
+        {
+          map<int, double>* p_map_data =
+            new map<int, double>;
+          gui_data.numeric_node_maps[*it] = p_map_data;
+          { x(*it, *p_map_data); }
+        }
+        break;
+      case MapValue::STRING:
+        {
+          map<int, string>* p_map_data =
+            new map<int, string>;
+          gui_data.string_node_maps[*it] = p_map_data;
+          { x(*it, *p_map_data); }
+        }
+        break;
+    }
+  }
+
+  for (vector<string>::const_iterator it = gui_data.gui_edge_map_names.begin();
+      it != gui_data.gui_edge_map_names.end(); ++it)
+  {
+    MapValue::Type type = gui_data.edge_map_types[*it];
+    switch (type)
+    {
+      case MapValue::NUMERIC:
+        {
+          map<int, double>* p_map_data =
+            new map<int, double>;
+          gui_data.numeric_edge_maps[*it] = p_map_data;
+          { x(*it, *p_map_data); }
+        }
+        break;
+      case MapValue::STRING:
+        {
+          map<int, string>* p_map_data =
+            new map<int, string>;
+          gui_data.string_edge_maps[*it] = p_map_data;
+          { x(*it, *p_map_data); }
+        }
+        break;
+    }
+  }
+
+  {
+    std::string node_coords_save_dest;
+    { x("node_coords_save_dest", node_coords_save_dest); }
+    if (node_coords_save_dest == "gui_sect")
+    {
+      // read the node coorinates
+      gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::GUI_SECT;
+      { x("node_coord_map", gui_data.node_coord_map); }
+    }
+    else if (node_coords_save_dest == "nodeset_sect_1_map")
+    {
+      gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT;
+      gui_data.node_coords_save_map_num = MapStorage::SpecMapSaveOpts::ONE_MAP;
+      { x("map_name", gui_data.node_coords_one_map_name); }
+    }
+    else if (node_coords_save_dest == "nodeset_sect_2_maps")
     {
-      for (EdgeIt e(mapstorage->graph); e != INVALID; ++e)
-	{
-	  int edgeid = (int)(*mapstorage->edgemap_storage["label"])[e];
-	  mapstorage->arrow_pos.set(e, m[edgeid]);
-	}
-      mapstorage->ArrowPosReadOK();
+      gui_data.node_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT;
+      gui_data.node_coords_save_map_num = MapStorage::SpecMapSaveOpts::TWO_MAPS;
+      { x("map1_name", gui_data.node_coords_two_maps_1_name); }
+      { x("map2_name", gui_data.node_coords_two_maps_2_name); }
     }
-  
+  }
+
+  {
+    std::string arrow_coords_save_dest;
+    { x("arrow_coords_save_dest", arrow_coords_save_dest); }
+    if (arrow_coords_save_dest == "gui_sect")
+    {
+      // read the arrow coorinates
+      gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::GUI_SECT;
+      { x("arrow_coord_map", gui_data.arrow_coord_map); }
+    }
+    else if (arrow_coords_save_dest == "edgeset_sect_1_map")
+    {
+      gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT;
+      gui_data.arrow_coords_save_map_num = MapStorage::SpecMapSaveOpts::ONE_MAP;
+      { x("map_name", gui_data.arrow_coords_one_map_name); }
+    }
+    else if (arrow_coords_save_dest == "edgeset_sect_2_maps")
+    {
+      gui_data.arrow_coords_save_dest = MapStorage::SpecMapSaveOpts::NESET_SECT;
+      gui_data.arrow_coords_save_map_num = MapStorage::SpecMapSaveOpts::TWO_MAPS;
+      { x("map1_name", gui_data.arrow_coords_two_maps_1_name); }
+      { x("map2_name", gui_data.arrow_coords_two_maps_2_name); }
+    }
+  }
+
+
+
   std::map<int, std::string> nm;
   x("active_nodemaps", nm);
 
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
-    {
-      mapstorage->changeActiveMap(false, i, nm[i]);
-    }
+  {
+    mapstorage->changeActiveMap(false, i, nm[i]);
+  }
 
   std::map<int, std::string> em;
   x("active_edgemaps", em);
   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
-    {
-      mapstorage->changeActiveMap(true, i, em[i]);
-    }
+  {
+    mapstorage->changeActiveMap(true, i, em[i]);
+  }
 
   double attraction;
   double propulsation;
@@ -77,6 +183,10 @@
   mapstorage->redesign_data_changed();
 }
 
-GuiReader::GuiReader(LemonReader& reader, MapStorage* ms) : Parent(reader), mapstorage(ms)
+GuiReader::GuiReader(LemonReader& reader, MapStorage* _mapstorage,
+    MapStorage::GUISectData& _gui_data) :
+  Parent(reader),
+  mapstorage(_mapstorage),
+  gui_data(_gui_data)
 {
 }

Modified: glemon/trunk/gui_reader.h
==============================================================================
--- glemon/trunk/gui_reader.h	(original)
+++ glemon/trunk/gui_reader.h	Wed Jan  2 22:03:09 2008
@@ -20,7 +20,7 @@
 #define GUI_READER_H
 #include <lemon/lemon_reader.h>
 
-class MapStorage;
+#include "mapstorage.h"
 
 using lemon::LemonReader;
 
@@ -28,12 +28,13 @@
 {
   private:
     MapStorage* mapstorage;
+    MapStorage::GUISectData& gui_data;
   protected:
     virtual bool header(const std::string&);
     virtual void read(std::istream&);
   public:
     typedef LemonReader::SectionReader Parent;
-    GuiReader(LemonReader&, MapStorage*);
+    GuiReader(LemonReader&, MapStorage*, MapStorage::GUISectData&);
 };
 
 #endif

Modified: glemon/trunk/gui_writer.cc
==============================================================================
--- glemon/trunk/gui_writer.cc	(original)
+++ glemon/trunk/gui_writer.cc	Wed Jan  2 22:03:09 2008
@@ -16,7 +16,10 @@
  *
  */
 
-#include <xml.h>
+#include "gui_writer.h"
+#include "io_helper.h"
+#include "mapstorage.h"
+#include "xml.h"
 #include <lemon/dim2.h>
 #include <vector>
 
@@ -30,28 +33,232 @@
 
 void GuiWriter::write(std::ostream& os)
 {
+  using std::vector;
+  using std::string;
+  using std::map;
+  using std::string;
+
   XmlIo x(os);
-  std::map<int, XY > m;
-  for (EdgeIt e(mapstorage->graph); e != INVALID; ++e)
+
+  vector<string> all_node_map_names = mapstorage->getNodeMapList();
+  // name of the maps saved to the nodeset section
+  vector<string> main_node_map_names;
+  // name of the maps saved to the gui section
+  vector<string> gui_node_map_names;
+
+  for (vector<string>::const_iterator it = all_node_map_names.begin();
+      it != all_node_map_names.end(); ++it)
+  {
+    if (mapstorage->getNodeMapSaveDest(*it) == MapStorage::NESET_SECT)
+      main_node_map_names.push_back(*it);
+    else if (mapstorage->getNodeMapSaveDest(*it) == MapStorage::GUI_SECT)
+      gui_node_map_names.push_back(*it);
+  }
+
+  { x("main_node_map_names", main_node_map_names); }
+  { x("gui_node_map_names", gui_node_map_names); }
+
+  map<string, MapValue::Type> node_map_types;
+  for (vector<string>::const_iterator it = main_node_map_names.begin();
+      it != main_node_map_names.end(); ++it)
+  {
+    node_map_types[*it] = mapstorage->getNodeMapElementType(*it);
+  }
+  for (vector<string>::const_iterator it = gui_node_map_names.begin();
+      it != gui_node_map_names.end(); ++it)
+  {
+    node_map_types[*it] = mapstorage->getNodeMapElementType(*it);
+  }
+
+  { x("node_map_types", node_map_types); }
+
+
+  vector<string> all_edge_map_names = mapstorage->getEdgeMapList();
+  // name of the maps saved to the edgeset section
+  vector<string> main_edge_map_names;
+  // name of the maps saved to the gui section
+  vector<string> gui_edge_map_names;
+
+  for (vector<string>::const_iterator it = all_edge_map_names.begin();
+      it != all_edge_map_names.end(); ++it)
   {
-    int edgeid = (int)(*(mapstorage->edgemap_storage["label"]))[e];
-    m[edgeid] = mapstorage->arrow_pos[e];
+    if (mapstorage->getEdgeMapSaveDest(*it) == MapStorage::NESET_SECT)
+      main_edge_map_names.push_back(*it);
+    if (mapstorage->getEdgeMapSaveDest(*it) == MapStorage::GUI_SECT)
+      gui_edge_map_names.push_back(*it);
   }
-  x("arrow_pos", m);
+
+  { x("main_edge_map_names", main_edge_map_names); }
+  { x("gui_edge_map_names", gui_edge_map_names); }
+
+  map<string, MapValue::Type> edge_map_types;
+  for (vector<string>::const_iterator it = main_edge_map_names.begin();
+      it != main_edge_map_names.end(); ++it)
+  {
+    edge_map_types[*it] = mapstorage->getEdgeMapElementType(*it);
+  }
+  for (vector<string>::const_iterator it = gui_edge_map_names.begin();
+      it != gui_edge_map_names.end(); ++it)
+  {
+    edge_map_types[*it] = mapstorage->getEdgeMapElementType(*it);
+  }
+
+  { x("edge_map_types", edge_map_types); }
+
+  // write the gui node maps
+  for (vector<string>::const_iterator it = gui_node_map_names.begin();
+      it != gui_node_map_names.end(); ++it)
+  {
+    MapValue::Type type = mapstorage->getNodeMapElementType(*it);
+    const MapStorage::NodeLabelMap& labels = mapstorage->getNodeLabelMap();
+    switch (type)
+    {
+      case MapValue::NUMERIC:
+        {
+          std::map<int, double> map_data;
+          MapStorage::NumericNodeMap& map =
+            mapstorage->getNumericNodeMap(*it);
+          for (NodeIt n(mapstorage->getGraph()); n != INVALID; ++n)
+          {
+            map_data[labels[n]] = map[n];
+          }
+          { x(*it, map_data); }
+        }
+        break;
+      case MapValue::STRING:
+        {
+          std::map<int, std::string> map_data;
+          MapStorage::StringNodeMap& map =
+            mapstorage->getStringNodeMap(*it);
+          for (NodeIt n(mapstorage->getGraph()); n != INVALID; ++n)
+          {
+            map_data[labels[n]] = map[n];
+          }
+          { x(*it, map_data); }
+        }
+        break;
+    }
+  }
+
+  // write the gui edge maps
+  for (vector<string>::const_iterator it = gui_edge_map_names.begin();
+      it != gui_edge_map_names.end(); ++it)
+  {
+    MapValue::Type type = mapstorage->getEdgeMapElementType(*it);
+    const MapStorage::EdgeLabelMap& labels = mapstorage->getEdgeLabelMap();
+    switch (type)
+    {
+      case MapValue::NUMERIC:
+        {
+          std::map<int, double> map_data;
+          MapStorage::NumericEdgeMap& map =
+            mapstorage->getNumericEdgeMap(*it);
+          for (EdgeIt e(mapstorage->getGraph()); e != INVALID; ++e)
+          {
+            map_data[labels[e]] = map[e];
+          }
+          { x(*it, map_data); }
+        }
+        break;
+      case MapValue::STRING:
+        {
+          std::map<int, std::string> map_data;
+          MapStorage::StringEdgeMap& map =
+            mapstorage->getStringEdgeMap(*it);
+          for (EdgeIt e(mapstorage->getGraph()); e != INVALID; ++e)
+          {
+            map_data[labels[e]] = map[e];
+          }
+          { x(*it, map_data); }
+        }
+        break;
+    }
+  }
+
+  {
+    switch (mapstorage->getNodeCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        { x("node_coords_save_dest", string("gui_sect")); }
+        // write the node coorinates
+        {
+          const MapStorage::NodeLabelMap& labels =
+            mapstorage->getNodeLabelMap();
+          std::map<int, XY> node_coord_map;
+          MapStorage::NodeCoordMap& map = mapstorage->getNodeCoordMap();
+          for (NodeIt n(mapstorage->getGraph()); n != INVALID; ++n)
+          {
+            node_coord_map[labels[n]] = map[n];
+          }
+          { x("node_coord_map", node_coord_map); }
+        }
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        switch (mapstorage->getNodeCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            { x("node_coords_save_dest", string("nodeset_sect_1_map")); }
+            { x("map_name", mapstorage->getNodeCoordsOneMapName()); }
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            { x("node_coords_save_dest", string("nodeset_sect_2_maps")); }
+            { x("map1_name", mapstorage->getNodeCoordsTwoMaps1Name()); }
+            { x("map2_name", mapstorage->getNodeCoordsTwoMaps2Name()); }
+            break;
+        }
+        break;
+    }
+  }
+
+  {
+    switch (mapstorage->getArrowCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        { x("arrow_coords_save_dest", string("gui_sect")); }
+        // write the arrow coorinates
+        {
+          const MapStorage::EdgeLabelMap& labels =
+            mapstorage->getEdgeLabelMap();
+          std::map<int, XY> arrow_coord_map;
+          MapStorage::ArrowCoordMap& map = mapstorage->getArrowCoordMap();
+          for (EdgeIt e(mapstorage->getGraph()); e != INVALID; ++e)
+          {
+            arrow_coord_map[labels[e]] = map[e];
+          }
+          { x("arrow_coord_map", arrow_coord_map); }
+        }
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        switch (mapstorage->getArrowCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            { x("arrow_coords_save_dest", string("edgeset_sect_1_map")); }
+            { x("map_name", mapstorage->getArrowCoordsOneMapName()); }
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            { x("arrow_coords_save_dest", string("edgeset_sect_2_maps")); }
+            { x("map1_name", mapstorage->getArrowCoordsTwoMaps1Name()); }
+            { x("map2_name", mapstorage->getArrowCoordsTwoMaps2Name()); }
+            break;
+        }
+        break;
+    }
+  }
+
 
   std::map<int, std::string> nm;
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
     {
       nm[i]=mapstorage->active_nodemaps[i];
     }
-  x("active_nodemaps", nm);
+  { x("active_nodemaps", nm); }
 
   std::map<int, std::string> em;
   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
     {
       em[i]=mapstorage->active_edgemaps[i];
     }
-  x("active_edgemaps", em);
+  { x("active_edgemaps", em); }
 
   double attraction;
   double propulsation;
@@ -59,11 +266,13 @@
 
   mapstorage->get_design_data(attraction, propulsation, iteration);
 
-  x("redesign-attraction", attraction);
-  x("redesign-propulsation", propulsation);
-  x("redesign-iteration", iteration);
+  { x("redesign-attraction", attraction); }
+  { x("redesign-propulsation", propulsation); }
+  { x("redesign-iteration", iteration); }
 }
 
-GuiWriter::GuiWriter(LemonWriter& writer, MapStorage* ms) : Parent(writer), mapstorage(ms)
+GuiWriter::GuiWriter(LemonWriter& writer, MapStorage* ms) :
+  Parent(writer),
+  mapstorage(ms)
 {
 }

Added: glemon/trunk/io_helper.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/io_helper.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,34 @@
+#include "io_helper.h"
+
+namespace lemon {
+  void xml(XmlIo &x, MapValue::Type& v)
+  {
+    if(x.write()) {
+      switch (v)
+      {
+        case MapValue::NUMERIC:
+          { x("type", std::string("numeric")); }
+          break;
+        case MapValue::STRING:
+          { x("type", std::string("string")); }
+          break;
+      }
+    }
+    else {
+      std::string type;
+      { x("type", type); }
+      if (type == "numeric")
+      {
+        v = MapValue::NUMERIC;
+      }
+      else if (type == "string")
+      {
+        v = MapValue::STRING;
+      }
+      else
+      {
+        throw DataFormatError("Bad format");
+      }
+    }
+  }
+};

Added: glemon/trunk/io_helper.h
==============================================================================
--- (empty file)
+++ glemon/trunk/io_helper.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,11 @@
+#ifndef IO_HELPER
+#define IO_HELPER
+
+#include "xml.h"
+#include "map_value.h"
+
+namespace lemon {
+  void xml(XmlIo &x, MapValue::Type& v);
+};
+
+#endif

Modified: glemon/trunk/kruskalbox.cc
==============================================================================
--- glemon/trunk/kruskalbox.cc	(original)
+++ glemon/trunk/kruskalbox.cc	Wed Jan  2 22:03:09 2008
@@ -33,51 +33,50 @@
 void KruskalBox::run()
 {
   if(
-     tabcbt.get_active_text()!="" &&
-     (edgemapcbts[INPUT])->get_active_text()!="" &&
-     (edgemapcbts[OUTPUT])->get_active_text()!=""
-     )
-    {
+      tabcbt.get_active_text()!="" &&
+      (edgemapcbts[INPUT])->get_active_text()!="" &&
+      (edgemapcbts[OUTPUT])->get_active_text()!=""
+    )
+  {
+
+    const Graph &g=mapstorage->getGraph();
+    std::string input_map_name = edgemapcbts[INPUT]->get_active_text();
+    Graph::EdgeMap<bool> outputmap(g);
+    const MapStorage::NumericEdgeMap& inputmap=
+      mapstorage->getNumericEdgeMap(input_map_name);
+    double res=kruskal(g, inputmap, outputmap);
 
-      const Graph &g=mapstorage->graph;
-      Graph::EdgeMap<double> * inputmap=
-	((mapstorage->edgemap_storage)[(edgemapcbts[INPUT])->get_active_text()]);
-      Graph::EdgeMap<bool> outputmap(g);
-      double res=kruskal(g, *inputmap, outputmap);
-
-      for (EdgeIt i(g); i!=INVALID; ++i)
-	{
-	  if(outputmap[i])
-	    {
-	      (*((mapstorage->edgemap_storage)[(edgemapcbts[OUTPUT])->
-					       get_active_text()]))[i]=1;
-	    }
-	  else
-	    {
-	      (*((mapstorage->edgemap_storage)[(edgemapcbts[OUTPUT])->
-					       get_active_text()]))[i]=0;
-	    }
-	}
-
-      std::ostringstream o;
-      o << "Result: " << res;
-      resultlabel.set_text(o.str());
-
-      mapstorage->mapChanged(true, (edgemapcbts[OUTPUT])->get_active_text());
-      //   mapstorage->changeActiveMap(true, E_COLOR,
-      // 			      (edgemapcbts[OUTPUT])->get_active_text());
-      //   mapstorage->changeActiveMap(true, E_TEXT,
-      // 			      (edgemapcbts[INPUT])->get_active_text());
-  
+    for (EdgeIt i(g); i!=INVALID; ++i)
+    {
+      if(outputmap[i])
+      {
+        mapstorage->set(edgemapcbts[OUTPUT]->get_active_text(), i, 1.0);
+      }
+      else
+      {
+        mapstorage->set(edgemapcbts[OUTPUT]->get_active_text(), i, 0.0);
+      }
     }
+
+    std::ostringstream o;
+    o << "Result: " << res;
+    resultlabel.set_text(o.str());
+
+    mapstorage->mapChanged(true, (edgemapcbts[OUTPUT])->get_active_text());
+    //   mapstorage->changeActiveMap(true, E_COLOR,
+    // 			      (edgemapcbts[OUTPUT])->get_active_text());
+    //   mapstorage->changeActiveMap(true, E_TEXT,
+    // 			      (edgemapcbts[INPUT])->get_active_text());
+
+  }
 }
     
 void KruskalBox::build_box()
 {
   std::vector<std::string> empty_vector;
 
-  addMapSelector("Edgecosts: ", true);
-  addMapSelector("Edges of tree here: ", true);
+  addMapSelector("Edgecosts: ", true, NUM);
+  addMapSelector("Edges of tree here: ", true, NUM);
 
   resultlabel.set_text("Result: algorithm is not run yet.");
   pack_start(resultlabel);

Modified: glemon/trunk/main_win.cc
==============================================================================
--- glemon/trunk/main_win.cc	(original)
+++ glemon/trunk/main_win.cc	Wed Jan  2 22:03:09 2008
@@ -20,9 +20,10 @@
 #include <config.h>
 #endif
 
-#include <main_win.h>
-#include <guipixbufs.h>
-#include <background_chooser_dialog.h>
+#include "main_win.h"
+#include "guipixbufs.h"
+#include "save_details_dialog.h"
+#include "background_chooser_dialog.h"
 
 #include <mapstorage.h>
 #include <graph_displayer_canvas.h>
@@ -114,6 +115,8 @@
       sigc::mem_fun(*this, &MainWin::saveFile));
   ag->add( Gtk::Action::create("FileSaveAs", Gtk::Stock::SAVE_AS),
       sigc::mem_fun(*this, &MainWin::saveFileAs));
+  ag->add( Gtk::Action::create("SaveDetails", _("Save _Details...")),
+	   sigc::mem_fun(*this, &MainWin::createSaveDetailsDialog));
   ag->add( Gtk::Action::create("Close", Gtk::Stock::CLOSE),
       sigc::mem_fun(*this, &MainWin::closeTab));
   ag->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
@@ -160,13 +163,13 @@
   ag->add( Gtk::RadioAction::create(tool_group, "EditEdgeMap", Gtk::StockID("gd-editlink"), _("Edit edge map")),
       sigc::bind( sigc::mem_fun ( *this, &MainWin::changeEditorialTool ), 4) );
 
-  ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap")),
+  ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap"), "New map"),
       sigc::mem_fun ( *this , &MainWin::createNewMapWin ) );
 
   ag->add( Gtk::Action::create("DesignGraph", Gtk::Stock::REFRESH),
       sigc::mem_fun ( *this , &MainWin::reDesignGraph ) );
 
-  ag->add( Gtk::Action::create("Eps", Gtk::StockID("gd-eps")),
+  ag->add( Gtk::Action::create("Eps", Gtk::StockID("gd-eps"), "Export to EPS"),
       sigc::mem_fun ( *this , &MainWin::exportToEPS ) );
 
   uim=Gtk::UIManager::create();
@@ -185,6 +188,7 @@
       "      <menuitem action='FileClearTab'/>"
       "      <menuitem action='FileSave'/>"
       "      <menuitem action='FileSaveAs'/>"
+      "      <menuitem action='SaveDetails'/>"
       "      <menuitem action='Close'/>"
       "      <menuitem action='Quit'/>"
       "    </menu>"
@@ -370,7 +374,7 @@
 {
   if(active_tab!=-1)
     {
-      if (tabs[active_tab]->mapstorage->modified)
+      if (tabs[active_tab]->mapstorage->getModified())
 	{
 	  Gtk::MessageDialog mdialog(_("<b>Save changes before closing?</b>"), true, 
 				     Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
@@ -628,6 +632,12 @@
   tabs[active_tab]->reDesignGraph();
 }
 
+void MainWin::createSaveDetailsDialog()
+{
+  SaveDetailsDialog dialog(tabs[active_tab]->mapstorage);
+  dialog.run();
+}
+
 void MainWin::exportToEPS()
 {
   if(active_tab!=-1)

Modified: glemon/trunk/main_win.h
==============================================================================
--- glemon/trunk/main_win.h	(original)
+++ glemon/trunk/main_win.h	Wed Jan  2 22:03:09 2008
@@ -260,6 +260,9 @@
 
   virtual void reDesignGraph();
 
+  /// Pops up a SaveDetailsDialog.
+  void createSaveDetailsDialog();
+
   virtual void exportToEPS();
 
   void createBackgroundChooser();

Added: glemon/trunk/map_value.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/map_value.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,153 @@
+#include "map_value.h"
+#include <sstream>
+#include <iostream>
+
+MapValue::MapValue()
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  has_value = false;
+}
+
+MapValue::MapValue(double d)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  p_value = new double(d);
+  type = NUMERIC;
+  has_value = true;
+}
+
+MapValue::MapValue(std::string str)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  p_value = new std::string(str);
+  type = STRING;
+  has_value = true;
+}
+
+MapValue::MapValue(const char* str)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  p_value = new std::string(str);
+  type = STRING;
+  has_value = true;
+}
+
+MapValue::operator double() const
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (!has_value) throw IllegalOperation();
+  if (type == NUMERIC)
+    return *(static_cast<double*>(p_value));
+  else
+    throw IllegalOperation();
+}
+
+MapValue::operator std::string() const
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (!has_value) throw IllegalOperation();
+  std::string ret;
+  switch (type)
+  {
+    case NUMERIC:
+      {
+        double d = *(static_cast<double*>(p_value));
+        std::ostringstream ostr;
+        ostr << d;
+        ret = ostr.str();
+      }
+      break;
+    case STRING:
+      ret = *(static_cast<std::string*>(p_value));
+      break;
+  }
+  return ret;
+}
+
+MapValue::MapValue(const MapValue& v)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (!v.has_value) throw IllegalOperation();
+  has_value = true;
+  type = v.type;
+  switch (v.type)
+  {
+    case NUMERIC:
+      p_value = new double(*(static_cast<double*>(v.p_value)));
+      break;
+    case STRING:
+      p_value = new std::string(*(static_cast<std::string*>(v.p_value)));
+      break;
+  }
+}
+
+MapValue& MapValue::operator=(const MapValue& v)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (&v != this)
+  {
+    if (!v.has_value) throw IllegalOperation();
+    clear();
+    has_value = true;
+    type = v.type;
+    switch (v.type)
+    {
+      case NUMERIC:
+        p_value = new double(*(static_cast<double*>(v.p_value)));
+        break;
+      case STRING:
+        p_value = new std::string(*(static_cast<std::string*>(v.p_value)));
+        break;
+    }
+  }
+  return *this;
+}
+
+MapValue::~MapValue()
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  clear();
+}
+
+void MapValue::clear()
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (!has_value) return;
+  switch (type)
+  {
+    case NUMERIC:
+      delete static_cast<double*>(p_value);
+      break;
+    case STRING:
+      delete static_cast<std::string*>(p_value);
+      break;
+  }
+}
+
+MapValue::Type MapValue::getType() const
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  return type;
+}
+
+bool MapValue::hasValue() const
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  return has_value;
+}
+
+std::ostream& operator<<(std::ostream &os, const MapValue& v)
+{
+  //std::cout << __PRETTY_FUNCTION__ << std::endl;
+  if (!v.has_value) return os;
+  switch (v.type)
+  {
+    case MapValue::NUMERIC:
+      os << *(static_cast<double*>(v.p_value));
+      break;
+    case MapValue::STRING:
+      os << *(static_cast<std::string*>(v.p_value));
+      break;
+  }
+  return os;
+}

Added: glemon/trunk/map_value.h
==============================================================================
--- (empty file)
+++ glemon/trunk/map_value.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,43 @@
+#ifndef MAP_VALUE_H
+#define MAP_VALUE_H
+
+#include <exception>
+#include <functional>
+#include <iosfwd>
+
+class MapValue
+{
+  public:
+    friend std::ostream& operator<<(std::ostream &os, const MapValue& v);
+    class IllegalOperation : public std::exception
+    {
+      virtual const char* what() const throw()
+      {
+        return "Illegal operation.";
+      }
+    };
+    typedef enum
+    {
+      NUMERIC = 1 << 0,
+      STRING  = 1 << 1
+    } Type;
+  private:
+    bool has_value;
+    void* p_value;
+    MapValue::Type type;
+    void clear();
+  public:
+    MapValue();
+    MapValue(double);
+    MapValue(std::string);
+    MapValue(const char* str);
+    MapValue(const MapValue& v);
+    MapValue& operator=(const MapValue& v);
+    ~MapValue();
+    operator std::string() const;
+    operator double() const;
+    Type getType() const;
+    bool hasValue() const;
+};
+
+#endif

Added: glemon/trunk/map_value_map.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/map_value_map.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,32 @@
+#include "map_value_map.h"
+#include "mapstorage.h"
+
+MapValueEdgeMap::MapValueEdgeMap(const std::string& _mapName, MapStorage* _pMapStorage) :
+  mapName(_mapName),
+  pMapStorage(_pMapStorage)
+{
+}
+
+MapValueEdgeMap::Value MapValueEdgeMap::operator[](Key k) const {
+  return pMapStorage->get(mapName, k);
+}
+
+void MapValueEdgeMap::set(Key k, Value v)
+{
+  pMapStorage->set(mapName, k, v);
+}
+
+MapValueNodeMap::MapValueNodeMap(const std::string& _mapName, MapStorage* _pMapStorage) :
+  mapName(_mapName),
+  pMapStorage(_pMapStorage)
+{
+}
+
+MapValueNodeMap::Value MapValueNodeMap::operator[](Key k) const {
+  return pMapStorage->get(mapName, k);
+}
+
+void MapValueNodeMap::set(Key k, Value v)
+{
+  pMapStorage->set(mapName, k, v);
+}

Added: glemon/trunk/map_value_map.h
==============================================================================
--- (empty file)
+++ glemon/trunk/map_value_map.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,36 @@
+#ifndef MAP_VALUE_MAP_H
+#define MAP_VALUE_MAP_H
+
+#include "map_value.h"
+#include <string>
+#include "all_include.h"
+
+class MapStorage;
+
+class MapValueEdgeMap
+{
+  private:
+    std::string mapName;
+    MapStorage* pMapStorage;
+  public:
+    typedef MapValue Value;
+    typedef Graph::Edge Key;
+    MapValueEdgeMap(const std::string&, MapStorage*);
+    Value operator[](Key k) const;
+    void set(Key k, Value v);
+};
+
+class MapValueNodeMap
+{
+  private:
+    std::string mapName;
+    MapStorage* pMapStorage;
+  public:
+    typedef MapValue Value;
+    typedef Graph::Node Key;
+    MapValueNodeMap(const std::string&, MapStorage*);
+    Value operator[](Key k) const;
+    void set(Key k, Value v);
+};
+
+#endif

Modified: glemon/trunk/map_win.cc
==============================================================================
--- glemon/trunk/map_win.cc	(original)
+++ glemon/trunk/map_win.cc	Wed Jan  2 22:03:09 2008
@@ -31,7 +31,12 @@
   return true;
 }
 
-MapWin::MapWin(const std::string& title, std::vector<std::string> eml, std::vector<std::string> nml, NoteBookTab & mw):mytab(mw)
+MapWin::MapWin(const std::string& title,
+    std::vector<std::string> n_eml,
+    std::vector<std::string> s_eml,
+    std::vector<std::string> n_nml,
+    std::vector<std::string> s_nml,
+    NoteBookTab & mw):mytab(mw)
 {
   set_title(title);
   set_default_size(200, 50);
@@ -48,7 +53,24 @@
 
   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
   {
-    e_combo_array[i]=new MapSelector(eml, mytab.getActiveEdgeMap(i), edge_property_strings[i], true);
+    switch (i)
+    {
+      case E_WIDTH:
+        e_combo_array[i]=new MapSelector(n_eml, s_eml,
+            mytab.getActiveEdgeMap(i), edge_property_strings[i],
+            true, true, NUM);
+        break;
+      case E_COLOR:
+        e_combo_array[i]=new MapSelector(n_eml, s_eml,
+            mytab.getActiveEdgeMap(i), edge_property_strings[i],
+            true, true, NUM);
+        break;
+      case E_TEXT:
+        e_combo_array[i]=new MapSelector(n_eml, s_eml,
+            mytab.getActiveEdgeMap(i), edge_property_strings[i],
+            true, true, ALL);
+        break;
+    }
 
     (*table).attach((*(e_combo_array[i])),0,1,i,i+1,Gtk::SHRINK,Gtk::SHRINK,10,3);
 
@@ -68,7 +90,24 @@
 
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
   {
-    n_combo_array[i]=new MapSelector(nml, mytab.getActiveNodeMap(i), node_property_strings[i], false);
+    switch (i)
+    {
+      case N_RADIUS:
+        n_combo_array[i]=new MapSelector(n_nml, s_nml,
+            mytab.getActiveNodeMap(i), node_property_strings[i],
+            false, true, NUM);
+        break;
+      case N_COLOR:
+        n_combo_array[i]=new MapSelector(n_nml, s_nml,
+            mytab.getActiveNodeMap(i), node_property_strings[i],
+            false, true, NUM);
+        break;
+      case N_TEXT:
+        n_combo_array[i]=new MapSelector(n_nml, s_nml,
+            mytab.getActiveNodeMap(i), node_property_strings[i],
+            false, true, ALL);
+        break;
+    }
 
     (*table).attach((*(n_combo_array[i])),0,1,i,i+1,Gtk::SHRINK,Gtk::SHRINK,10,3);
 
@@ -82,6 +121,8 @@
 
   vbox.pack_start(*table);
 
+  update(n_eml, s_eml, n_nml, s_nml);
+
   show_all_children();
 
 }
@@ -101,36 +142,40 @@
   mytab.popupNewMapWin(itisedge);
 }
 
-void MapWin::update(std::vector<std::string> eml, std::vector<std::string> nml)
+void MapWin::update(
+    std::vector<std::string> n_eml,
+    std::vector<std::string> s_eml,
+    std::vector<std::string> n_nml,
+    std::vector<std::string> s_nml)
 {
   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
   {
-    e_combo_array[i]->update_list(eml);
+    e_combo_array[i]->update_list(n_eml, s_eml);
   }
 
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
   {
-    n_combo_array[i]->update_list(nml);
+    n_combo_array[i]->update_list(n_nml, s_nml);
   }
 
   mytab.active_maps_needed();
 }
 
-void MapWin::registerNewEdgeMap(std::string newmapname)
+void MapWin::registerNewEdgeMap(std::string newmapname, MapValue::Type type)
 {
   for(int i=0;i<EDGE_PROPERTY_NUM;i++)
   {
     //filling in combo box with choices
-    e_combo_array[i]->append_text((Glib::ustring)newmapname);
+    e_combo_array[i]->append_text((Glib::ustring)newmapname, type);
   }
 }
 
-void MapWin::registerNewNodeMap(std::string newmapname)
+void MapWin::registerNewNodeMap(std::string newmapname, MapValue::Type type)
 {
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
   {
     //filling in combo box with choices
-    n_combo_array[i]->append_text((Glib::ustring)newmapname);
+    n_combo_array[i]->append_text((Glib::ustring)newmapname, type);
   }
 }
 

Modified: glemon/trunk/map_win.h
==============================================================================
--- glemon/trunk/map_win.h	(original)
+++ glemon/trunk/map_win.h	Wed Jan  2 22:03:09 2008
@@ -25,6 +25,7 @@
 #include <all_include.h>
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include "map_value.h"
 
 ///Graph visualization setup window.
 
@@ -64,10 +65,13 @@
   ///It creates the widgets shown in \ref MapWin and
   ///binds the needed signal to the correct place.
   ///\param title title of window
-  ///\param eml edgemap list
-  ///\param nml nodemap list
   ///\param mw the owner \ref NoteBookTab (\ref mytab)
-  MapWin(const std::string& title, std::vector<std::string> eml, std::vector<std::string> nml, NoteBookTab & mw);
+  MapWin(const std::string& title, 
+      std::vector<std::string> n_eml,
+      std::vector<std::string> s_eml,
+      std::vector<std::string> n_nml,
+      std::vector<std::string> s_nml,
+      NoteBookTab & mw);
 
   ///Deregistrates \ref MapWin in its \ref NoteBookTab (\ref mytab)
   virtual bool on_delete_event(GdkEventAny *);
@@ -106,13 +110,13 @@
 
   ///\param new_name
   ///name of new map
-  void registerNewEdgeMap(std::string new_name);
+  void registerNewEdgeMap(std::string new_name, MapValue::Type type);
 
   ///This function inserts name of the new nodemap in the name list in \ref MapSelector s
 
   ///\param new_name
   ///name of new map
-  void registerNewNodeMap(std::string new_name);
+  void registerNewNodeMap(std::string new_name, MapValue::Type type);
 
   ///Close window if Esc key pressed.
   virtual bool closeIfEscapeIsPressed(GdkEventKey*);
@@ -124,9 +128,11 @@
   ///have changed as well. \ref NoteBookTab knows, whether it
   ///has to call this function or not from the \ref NoteBookTab::mapwinexists
   ///variable.
-  ///\param eml edge map list
-  ///\param nml node map list
-  void update(std::vector<std::string> eml, std::vector<std::string> nml);
+  void update(
+    std::vector<std::string> n_eml,
+    std::vector<std::string> s_eml,
+    std::vector<std::string> n_nml,
+    std::vector<std::string> s_nml);
 
   void changeEntry(bool, int, std::string);
 

Modified: glemon/trunk/mapselector.cc
==============================================================================
--- glemon/trunk/mapselector.cc	(original)
+++ glemon/trunk/mapselector.cc	Wed Jan  2 22:03:09 2008
@@ -18,61 +18,63 @@
 
 #include <mapselector.h>
 
-MapSelector::MapSelector(std::vector<std::string> ml, std::string act, std::string labeltext, bool edge, bool d):def(d),itisedge(edge),set_new_map(false)
+MapSelector::MapSelector(std::vector<std::string> n_ml,
+    std::vector<std::string> s_ml, std::string act,
+    std::string labeltext, bool edge, bool d, MapType type) :
+  def(d),
+  itisedge(edge),
+  set_new_map(false),
+  label(labeltext),
+  map_type(type),
+  newbut(Gtk::Stock::NEW)
 {
-  update_list(ml);
+  update_list(n_ml, s_ml);
 
   if(act=="")
-    {
-      cbt.set_active(0);
-      default_state=true;
-    }
+  {
+    cbt.set_active(0);
+    default_state=true;
+  }
   else
-    {
-      cbt.set_active_text((Glib::ustring)act);
-      default_state=false;
-    }
+  {
+    cbt.set_active_text((Glib::ustring)act);
+    default_state=false;
+  }
 
   //binding signal to the actual entry
   cbt.signal_changed().connect
     (
      sigc::mem_fun((*this), &MapSelector::comboChanged),
      false
-     );
-  
-  label=new Gtk::Label(labeltext);
+    );
 
-  label->set_width_chars(longest_property_string_length);
+  label.set_width_chars(longest_property_string_length);
 
-  defbut=NULL;
   if(def)
-    {
-      defbut=new Gtk::Button();
-      defbut->set_label("Reset");
-      
-      defbut->signal_pressed().connect
-	(
-	 sigc::mem_fun(*this, &MapSelector::reset)
-	 );
-    }
+  {
+    defbut.set_label("Reset");
+    defbut.signal_pressed().connect
+      (
+       sigc::mem_fun(*this, &MapSelector::reset)
+      );
+  }
 
-  newbut=new Gtk::Button(Gtk::Stock::NEW);
 
-  newbut->signal_pressed().connect
+  newbut.signal_pressed().connect
     (
      sigc::mem_fun(*this, &MapSelector::new_but_pressed)
-     );
+    );
 
-  add(*label);
+  add(label);
 
   add(cbt);
 
   if(def)
-    {
-      add(*defbut);
-    }
+  {
+    add(defbut);
+  }
 
-  add(*newbut);
+  add(newbut);
 }
 
 void MapSelector::new_but_pressed()
@@ -81,17 +83,31 @@
   signal_newmapwin.emit(itisedge);
 }
 
-void MapSelector::update_list( std::vector< std::string > ml )
+void MapSelector::update_list(std::vector<std::string> n_ml,
+    std::vector<std::string> s_ml)
 {
   int prev_act=cbt.get_active_row_number();
   cbt.clear();
   cbt_content.clear();
-  std::vector< std::string >::iterator emsi=ml.begin();
-  for(;emsi!=ml.end();emsi++)
+
+  if (map_type & NUM)
+  {
+    std::vector< std::string >::iterator emsi=n_ml.begin();
+    for(;emsi!=n_ml.end();emsi++)
+    {
+      cbt.append_text(*emsi);
+      cbt_content.push_back(*emsi);
+    }
+  }
+  if (map_type & STR)
+  {
+    std::vector< std::string >::iterator emsi=s_ml.begin();
+    for(;emsi!=s_ml.end();emsi++)
     {
       cbt.append_text(*emsi);
       cbt_content.push_back(*emsi);
     }
+  }
   if(def)
     {
       cbt.prepend_text("Default values");
@@ -147,16 +163,19 @@
     }
 }
 
-void MapSelector::append_text(Glib::ustring text)
+void MapSelector::append_text(Glib::ustring text, MapValue::Type type)
 {
-  cbt.append_text(text);
-  cbt_content.push_back(text);
+  if (type & map_type)
+  {
+    cbt.append_text(text);
+    cbt_content.push_back(text);
 
-  if(set_new_map)
+    if(set_new_map)
     {
       set_active_text(text);
       set_new_map=false;
     }
+  }
 }
 
 sigc::signal<void, std::string> MapSelector::signal_cbt_ch()

Modified: glemon/trunk/mapselector.h
==============================================================================
--- glemon/trunk/mapselector.h	(original)
+++ glemon/trunk/mapselector.h	Wed Jan  2 22:03:09 2008
@@ -22,6 +22,7 @@
 #include <all_include.h>
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include "map_value.h"
 
 ///A widget by which node and edgemaps can be selected, deselected and created.
 
@@ -80,7 +81,7 @@
 
   ///By pressing it
   ///\ref NewMapWin wilol pop-up
-  Gtk::Button * newbut;
+  Gtk::Button newbut;
 
   ///Reset button.
 
@@ -88,25 +89,28 @@
   ///set to 'Default' option.
   ///
   ///It is visible only if \ref def is true.
-  Gtk::Button * defbut;
-
-  ///Container in which GUI elements are packed.
-  Gtk::HBox hbox;
+  Gtk::Button defbut;
 
   ///Shows purpose of \ref MapSelector piece.
-  Gtk::Label * label;
+  Gtk::Label label;
+
+  /// Which types of maps (integer, string, ...) to display.
+  MapType map_type;
 
  public:
 
   ///Constructor of \ref MapSelector
 
   ///Creates the layout and binds signal to the correct place.
-  ///\param optionlist list of names to place in \ref cbt
+  ///\param mapstorage Pointer to the \ref MapStorage to get the map list from.
   ///\param act preselected option
   ///\param purpose text of label indicating purpose of \ref MapStorage
   ///\param itisedge do \ref MapSelector contains edgemap names or nodemapnames.
   ///\param def do we need 'Default' option. See \ref def.
-  MapSelector(std::vector<std::string> optionlist, std::string act, std::string purpose, bool itisedge, bool def=true);
+  ///\param type Specifies which types of maps to display.
+  MapSelector(std::vector<std::string> n_ml,
+      std::vector<std::string> s_ml, std::string act, std::string labeltext,
+      bool edge, bool d = true, MapType type = ALL);
 
   ///Returns signal emitted if the user has changed the selection. (\ref signal_cbt)
   sigc::signal<void, std::string> signal_cbt_ch();
@@ -119,7 +123,8 @@
   ///Fills in \ref cbt with names, taking
   ///into account that the previously selected option
   ///has to be set back after the operation.
-  void update_list( std::vector<std::string> );
+  void update_list(std::vector<std::string> n_ml,
+      std::vector<std::string> s_ml);
 
   ///Handles changement in \ref cbt.
 
@@ -168,6 +173,6 @@
   ///from that the option to append is coming. In this case
   ///this function  will set \ref cbt to the new option.
   ///\param new_option new option to append
-  void append_text(Glib::ustring new_option);
+  void append_text(Glib::ustring new_option, MapValue::Type);
 };
 #endif //MAPSELECTOR_H

Modified: glemon/trunk/mapstorage.cc
==============================================================================
--- glemon/trunk/mapstorage.cc	(original)
+++ glemon/trunk/mapstorage.cc	Wed Jan  2 22:03:09 2008
@@ -7,7 +7,7 @@
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
  *
  * Permission to use, modify and distribute this software is granted
- * provided that this copyright notice appears in all copies. For
+ * provided that this copyright notice appears in all cop	ies. For
  * precise terms see the accompanying LICENSE file.
  *
  * This software is provided "AS IS" with no warranty of any kind,
@@ -16,10 +16,15 @@
  *
  */
 
+#include "i18n.h"
 #include <limits>
 #include <cmath>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <algorithm>
 #include <gtkmm.h>
-
+#include "file_import_dialog.h"
 #include <mapstorage.h>
 #include <gui_writer.h>
 #include <gui_reader.h>
@@ -29,23 +34,35 @@
 const double a_d=0.05;
 const double p_d=40000;
 
-MapStorage::MapStorage() : modified(false), file_name(""), arrow_pos_read_ok(false), iterations(i_d), attraction(a_d), propulsation(p_d), background_set(false)
-{
-  nodemap_storage["coordinates_x"] = new Graph::NodeMap<double>(graph);
-  coords.setXMap(*nodemap_storage["coordinates_x"]);
-  nodemap_storage["coordinates_y"] = new Graph::NodeMap<double>(graph);
-  coords.setYMap(*nodemap_storage["coordinates_y"]);
-
-  edgemap_storage["arrow_pos_x"] = new Graph::EdgeMap<double>(graph);
-  arrow_pos.setXMap(*edgemap_storage["arrow_pos_x"]);
-  edgemap_storage["arrow_pos_y"] = new Graph::EdgeMap<double>(graph);
-  arrow_pos.setYMap(*edgemap_storage["arrow_pos_y"]);
-
-  nodemap_storage["label"] = new Graph::NodeMap<double>(graph);
-  edgemap_storage["label"] = new Graph::EdgeMap<double>(graph);
-
-  nodemap_default["label"] = 1.0;
-  edgemap_default["label"] = 1.0;
+MapStorage::MapStorage() :
+  gui_sect_save_dest(LGF_FILE),
+  node_coords_save_dest(SpecMapSaveOpts::GUI_SECT),
+  arrow_coords_save_dest(SpecMapSaveOpts::GUI_SECT),
+  modified(false),
+  file_name(""),
+  max_node_label(0),
+  max_edge_label(0),
+  node_coords_one_map_name("coord"),
+  node_coords_two_maps_1_name("coord_x"),
+  node_coords_two_maps_2_name("coord_y"),
+  arrow_coords_one_map_name("arrow"),
+  arrow_coords_two_maps_1_name("arrow_x"),
+  arrow_coords_two_maps_2_name("arrow_y"),
+  iterations(i_d),
+  attraction(a_d),
+  propulsation(p_d),
+  node_coords_x(graph),
+  node_coords_y(graph),
+  arrow_coords_x(graph),
+  arrow_coords_y(graph),
+  node_label(graph),
+  edge_label(graph),
+  background_set(false)
+{
+  node_coords.setXMap(node_coords_x);
+  node_coords.setYMap(node_coords_y);
+  arrow_coords.setXMap(arrow_coords_x);
+  arrow_coords.setYMap(arrow_coords_y);
 
   active_nodemaps.resize(NODE_PROPERTY_NUM);
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
@@ -62,31 +79,51 @@
 
 MapStorage::~MapStorage()
 {
-  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
-      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
-  {
-    delete it->second;
-  }
-  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
-      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
+  clear();
+}
+
+void MapStorage::createNodeMap(const std::string& name, MapValue::Type type,
+    MapValue def_val)
+{
+  NodeMapStore::const_iterator it = nodemaps.find(name);
+  if (it != nodemaps.end())
+    throw Error("Node map " + name + " already exists.");
+
+  switch (type)
   {
-    delete it->second;
+    case MapValue::NUMERIC:
+      nodemaps[name] = new NumericNodeMapData(graph, def_val);
+      break;
+    case MapValue::STRING:
+      nodemaps[name] = new StringNodeMapData(graph, def_val);
+      break;
   }
+
+  nodemaps[name]->default_value = def_val;
+
+  signal_node_map.emit(name, type);
 }
 
-int MapStorage::addNodeMap(const std::string & name, Graph::NodeMap<double> *nodemap, double default_value)
+void MapStorage::createEdgeMap(const std::string& name, MapValue::Type type,
+    MapValue def_val)
 {
-  if( nodemap_storage.find(name) == nodemap_storage.end() )
-    {
-      nodemap_storage[name]=nodemap;
-      // set the maps default value
-      nodemap_default[name] = default_value;
+  EdgeMapStore::const_iterator it = edgemaps.find(name);
+  if (it != edgemaps.end())
+    throw Error("Edge map " + name + " already exists.");
 
-      //announce changement in maps
-      signal_node_map.emit(name);
-      return 0;
-    }
-  return 1;
+  switch (type)
+  {
+    case MapValue::NUMERIC:
+      edgemaps[name] = new NumericEdgeMapData(graph, def_val);
+      break;
+    case MapValue::STRING:
+      edgemaps[name] = new StringEdgeMapData(graph, def_val);
+      break;
+  }
+
+  edgemaps[name]->default_value = def_val;
+
+  signal_edge_map.emit(name, type);
 }
 
 void MapStorage::changeActiveMap(bool itisedge, int prop, std::string mapname)
@@ -115,7 +152,6 @@
     }
 }
 
-
 std::string MapStorage::getActiveEdgeMap(int prop)
 {
   return active_edgemaps[prop];
@@ -126,32 +162,64 @@
   return active_nodemaps[prop];
 }
 
-std::vector<std::string> MapStorage::getEdgeMapList()
+std::vector<std::string> MapStorage::getEdgeMapList(MapType type)
 {
-  std::vector<std::string> eml;
-  eml.resize(edgemap_storage.size());
-  int i=0;
-  std::map< std::string,Graph::EdgeMap<double> * >::iterator emsi=beginOfEdgeMaps();
-  for(;emsi!=endOfEdgeMaps();emsi++)
+  if (type == ALL)
+  {
+    std::vector<std::string> ret;
+    for (EdgeMapStore::const_iterator it = edgemaps.begin();
+        it != edgemaps.end(); ++it)
     {
-      eml[i]=(emsi->first);
-      i++;
+      ret.push_back(it->first);
+    }
+    return ret;
+  }
+  else
+  {
+    std::vector<std::string> ret;
+    for (EdgeMapStore::const_iterator it = edgemaps.begin();
+        it != edgemaps.end(); ++it)
+    {
+      EdgeMapData* data = getEdgeMapData(it->first);
+      MapValue::Type t = data->type();
+      if ((t == MapValue::NUMERIC && (type & NUM)) ||
+          (t == MapValue::STRING && (type & STR)))
+      {
+        ret.push_back(it->first);
+      }
     }
-  return eml;
+    return ret;
+  }
 }
 
-std::vector<std::string> MapStorage::getNodeMapList()
+std::vector<std::string> MapStorage::getNodeMapList(MapType type)
 {
-  std::vector<std::string> nml;
-  nml.resize(nodemap_storage.size());
-  int i=0;
-  std::map< std::string,Graph::NodeMap<double> * >::iterator nmsi=beginOfNodeMaps();
-  for(;nmsi!=endOfNodeMaps();nmsi++)
+  if (type == ALL)
+  {
+    std::vector<std::string> ret;
+    for (NodeMapStore::const_iterator it = nodemaps.begin();
+        it != nodemaps.end(); ++it)
     {
-      nml[i]=(nmsi->first);
-      i++;
+      ret.push_back(it->first);
     }
-  return nml;
+    return ret;
+  }
+  else
+  {
+    std::vector<std::string> ret;
+    for (NodeMapStore::const_iterator it = nodemaps.begin();
+        it != nodemaps.end(); ++it)
+    {
+      NodeMapData* data = getNodeMapData(it->first);
+      MapValue::Type t = data->type();
+      if ((t == MapValue::NUMERIC && (type & NUM)) ||
+          (t == MapValue::STRING && (type & STR)))
+      {
+        ret.push_back(it->first);
+      }
+    }
+    return ret;
+  }
 }
 
 sigc::signal<void, bool, int> MapStorage::signal_prop_ch()
@@ -159,255 +227,491 @@
   return signal_prop;
 }
 
-int MapStorage::addEdgeMap(const std::string & name, Graph::EdgeMap<double> *edgemap, double default_value)
+int MapStorage::readFromFile(const std::string &filename)
 {
-  if( edgemap_storage.find(name) == edgemap_storage.end() )
-    {
-      edgemap_storage[name]=edgemap;
-      // set the maps default value
-      edgemap_default[name] = default_value;
+  using std::vector;
+  using std::map;
+  using std::string;
+
+  // check whether the .conf file exists
+  bool gui_data_in_conf = g_file_test((filename + ".conf").c_str(),
+      (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
 
-      //announce changement in maps
-      signal_edge_map.emit(name);
-      return 0;
-    }
-  return 1;
-}
-
-double MapStorage::maxOfNodeMap(const std::string & name)
-{
-  double max=0;
-  for (NodeIt j(graph); j!=INVALID; ++j)
+  // check whether the .lgf file contains a gui section
+  bool gui_data_in_lgf = false;
   {
-    if( (*nodemap_storage[name])[j]>max )
+    std::ifstream ifs(filename.c_str());
+    std::string line;
+    while (getline(ifs, line))
     {
-      max=(*nodemap_storage[name])[j];
+      int pos = line.find("@gui");
+      if (pos != std::string::npos)
+      {
+        bool only_whitespace_before = true;
+        for (int i = 0; i < pos; ++i)
+        {
+          if (!std::isspace(line[i]))
+          {
+            only_whitespace_before = false;
+            break;
+          }
+        }
+        if (only_whitespace_before) gui_data_in_lgf = true;
+      }
     }
   }
-  return max;
-}
 
-double MapStorage::maxOfEdgeMap(const std::string & name)
-{
-  double max=0;
-  for (EdgeIt j(graph); j!=INVALID; ++j)
+  bool gui_data_found = gui_data_in_lgf || gui_data_in_conf;
+
+  // ask for user input if both exist
+  bool use_gui_data_in_lgf = false;
+  if (gui_data_in_conf && gui_data_in_lgf)
   {
-    if( (*edgemap_storage[name])[j]>max )
-    {
-      max=(*edgemap_storage[name])[j];
+    Gtk::MessageDialog mdialog(_("<b>Found both ") + filename +
+        _(".conf and a gui section in ") + filename + _(".</b>"), true,
+        Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE);
+	  mdialog.add_button(_("Use the ._conf file"), 1);
+	  mdialog.add_button(_("Use the _gui section"), 2);
+    switch (mdialog.run())
+    {
+      case 1:
+        use_gui_data_in_lgf = false;
+        break;
+      case 2:
+        use_gui_data_in_lgf = true;
+        break;
+      case Gtk::RESPONSE_NONE:
+        return 1;
     }
   }
-  return max;
-}
-
-double MapStorage::minOfNodeMap(const std::string & name)
-{
-  NodeIt j(graph);
-  double min;
-  if(j!=INVALID)
-    {
-      min=(*nodemap_storage[name])[j];
-    }
   else
-    {
-      min=0;
-    }
-  for (; j!=INVALID; ++j)
   {
-    if( (*nodemap_storage[name])[j]<min )
-    {
-      min=(*nodemap_storage[name])[j];
-    }
+    use_gui_data_in_lgf = gui_data_in_lgf;
   }
-  return min;
-}
 
-double MapStorage::minOfEdgeMap(const std::string & name)
-{
-  EdgeIt j(graph);
-  double min;
-  if(j!=INVALID)
+  if (gui_data_found)
+  {
+    GUISectData gui_data;
+    if (use_gui_data_in_lgf)
     {
-      min=(*edgemap_storage[name])[j];
+      // read the gui section from the .lgf file
+      try
+      {
+        LemonReader lreader(filename);
+        GuiReader gui_reader(lreader, this, gui_data);
+        lreader.run();
+        gui_sect_save_dest = LGF_FILE;
+      }
+      catch (Exception& error)
+      {
+        clear();
+        return 1;
+      }
     }
-  else
+    else
     {
-      min=0;
+      // read the gui section from the .conf file
+      try
+      {
+        LemonReader lreader(filename + ".conf");
+        GuiReader gui_reader(lreader, this, gui_data);
+        lreader.run();
+        gui_sect_save_dest = CONF_FILE;
+      }
+      catch (Exception& error)
+      {
+        clear();
+        return 1;
+      }
     }
-  for (EdgeIt j(graph); j!=INVALID; ++j)
-  {
-    if( (*edgemap_storage[name])[j]<min )
+
+    // read the graph and maps form the .lgf file
+    try
     {
-      min=(*edgemap_storage[name])[j];
-    }
-  }
-  return min;
-}
+      std::string node_coord_xmap_name, node_coord_ymap_name;
+      std::string arrow_coord_xmap_name, arrow_coord_ymap_name;
 
-int MapStorage::readFromFile(const std::string &filename)
-{
-  bool read_x = false;
-  bool read_y = false;
-  bool read_edge_id = false;
-
-  try {
-    LemonReader lreader(filename);
-    ContentReader content(lreader);
-    lreader.run();
+      if (gui_data.node_coords_save_dest ==
+          MapStorage::SpecMapSaveOpts::NESET_SECT)
+      {
+        switch (gui_data.node_coords_save_map_num)
+        {
+          case SpecMapSaveOpts::ONE_MAP:
+            node_coord_xmap_name = gui_data.node_coords_one_map_name + ":x";
+            node_coord_ymap_name = gui_data.node_coords_one_map_name + ":y";
+            node_coords_one_map_name = gui_data.node_coords_one_map_name;
+            break;
+          case SpecMapSaveOpts::TWO_MAPS:
+            node_coord_xmap_name = gui_data.node_coords_two_maps_1_name;
+            node_coord_ymap_name = gui_data.node_coords_two_maps_2_name;
+            node_coords_two_maps_1_name = gui_data.node_coords_two_maps_1_name;
+            node_coords_two_maps_2_name = gui_data.node_coords_two_maps_2_name;
+            break;
+        }
+        node_coords_save_dest = gui_data.node_coords_save_dest;
+        node_coords_save_map_num = gui_data.node_coords_save_map_num;
+      }
 
-    if (content.nodeSetNum() < 1)
-    {
-      Gtk::MessageDialog mdialog("No nodeset found in file.");
-      mdialog.run();
-      clear();
-      return 1;
+      if (gui_data.arrow_coords_save_dest ==
+          MapStorage::SpecMapSaveOpts::NESET_SECT)
+      {
+        switch (gui_data.arrow_coords_save_map_num)
+        {
+          case SpecMapSaveOpts::ONE_MAP:
+            arrow_coord_xmap_name = gui_data.arrow_coords_one_map_name + ":x";
+            arrow_coord_ymap_name = gui_data.arrow_coords_one_map_name + ":y";
+            arrow_coords_one_map_name = gui_data.arrow_coords_one_map_name;
+            break;
+          case SpecMapSaveOpts::TWO_MAPS:
+            arrow_coord_xmap_name = gui_data.arrow_coords_two_maps_1_name;
+            arrow_coord_ymap_name = gui_data.arrow_coords_two_maps_2_name;
+            arrow_coords_two_maps_1_name =
+              gui_data.arrow_coords_two_maps_1_name;
+            arrow_coords_two_maps_2_name =
+              gui_data.arrow_coords_two_maps_2_name;
+            break;
+        }
+        arrow_coords_save_dest = gui_data.arrow_coords_save_dest;
+        arrow_coords_save_map_num = gui_data.arrow_coords_save_map_num;
+      }
+      readLGF(filename, true,
+          gui_data.main_node_map_names, gui_data.main_edge_map_names,
+          gui_data.node_map_types, gui_data.edge_map_types,
+          node_coord_xmap_name, node_coord_ymap_name,
+          arrow_coord_xmap_name, arrow_coord_ymap_name);
     }
-
-    if (content.edgeSetNum() < 1)
+    catch (Exception& error)
     {
-      Gtk::MessageDialog mdialog("No edgeset found in file.");
-      mdialog.run();
       clear();
       return 1;
     }
 
-    const std::vector<std::string>& nodeMapNames = content.nodeSetMaps(0);
-    const std::vector<std::string>& edgeMapNames = content.edgeSetMaps(0);
-
-    GraphReader<Graph> greader(filename, graph);
-    for (std::vector<std::string>::const_iterator it = nodeMapNames.begin();
-        it != nodeMapNames.end(); ++it)
+    // add the maps from the gui section
+    for (vector<string>::const_iterator
+        it = gui_data.gui_node_map_names.begin();
+        it != gui_data.gui_node_map_names.end(); ++it)
     {
-      if (*it == "coordinates_x")
+      string map_name = *it;
+      switch (gui_data.node_map_types[map_name])
       {
-        read_x = true;
-        //std::cout << "read X nodemap" << std::endl;
+        case MapValue::NUMERIC:
+          {
+            createNodeMap(map_name, MapValue::NUMERIC, double());
+            NumericNodeMap& dmap = getNumericNodeMap(map_name);
+            map<int, double>& smap = *gui_data.numeric_node_maps[map_name];
+            for (NodeIt n(graph); n != INVALID; ++n)
+            {
+              dmap[n] = smap[node_label[n]];
+            }
+            break;
+          }
+        case MapValue::STRING:
+          {
+            createNodeMap(map_name, MapValue::STRING, string());
+            StringNodeMap& dmap = getStringNodeMap(map_name);
+            map<int, string>& smap = *gui_data.string_node_maps[map_name];
+            for (NodeIt n(graph); n != INVALID; ++n)
+            {
+              dmap[n] = smap[node_label[n]];
+            }
+            break;
+          }
       }
-      else if (*it == "coordinates_y")
+      getNodeMapData(map_name)->save_dest = GUI_SECT;
+    }
+    for (vector<string>::const_iterator
+        it = gui_data.gui_edge_map_names.begin();
+        it != gui_data.gui_edge_map_names.end(); ++it)
+    {
+      string map_name = *it;
+      switch (gui_data.edge_map_types[map_name])
       {
-        read_y = true;
-        //std::cout << "read Y nodemap" << std::endl;
+        case MapValue::NUMERIC:
+          {
+            createEdgeMap(map_name, MapValue::NUMERIC, double());
+            NumericEdgeMap& dmap = getNumericEdgeMap(map_name);
+            map<int, double>& smap = *gui_data.numeric_edge_maps[map_name];
+            for (EdgeIt e(graph); e != INVALID; ++e)
+            {
+              dmap[e] = smap[edge_label[e]];
+            }
+            break;
+          }
+        case MapValue::STRING:
+          {
+            createEdgeMap(map_name, MapValue::STRING, string());
+            StringEdgeMap& dmap = getStringEdgeMap(map_name);
+            map<int, string>& smap = *gui_data.string_edge_maps[map_name];
+            for (EdgeIt e(graph); e != INVALID; ++e)
+            {
+              dmap[e] = smap[edge_label[e]];
+            }
+            break;
+          }
       }
-      else if (*it == "label")
+      getEdgeMapData(map_name)->save_dest = GUI_SECT;
+    }
+
+    // restore the node coordinate maps
+    if (gui_data.node_coords_save_dest ==
+        MapStorage::SpecMapSaveOpts::GUI_SECT)
+    {
+      for (NodeIt n(graph); n != INVALID; ++n)
       {
-        //std::cout << "read id nodemap" << std::endl;
+        node_coords.set(n, gui_data.node_coord_map[node_label[n]]);
       }
-      else
+      node_coords_save_dest = gui_data.node_coords_save_dest;
+    }
+    // restore the arrow coordinate maps
+    if (gui_data.arrow_coords_save_dest ==
+        MapStorage::SpecMapSaveOpts::GUI_SECT)
+    {
+      for (EdgeIt e(graph); e != INVALID; ++e)
       {
-        nodemap_storage[*it] = new Graph::NodeMap<double>(graph);
-        //std::cout << "read " << *it << " nodemap" << std::endl;
+        arrow_coords.set(e, gui_data.arrow_coord_map[edge_label[e]]);
       }
-      greader.readNodeMap(*it, *nodemap_storage[*it]);
+      arrow_coords_save_dest = gui_data.arrow_coords_save_dest;
     }
-    for (std::vector<std::string>::const_iterator it = edgeMapNames.begin();
-        it != edgeMapNames.end(); ++it)
+  }
+  else
+  {
+    // there is no gui section neither in the .lgf file nor in the .conf file
     {
-      if (*it == "label")
+      LemonReader lreader(filename);
+      ContentReader content(lreader);
+      try
       {
-        //std::cout << "read id edgemap" << std::endl;
-        read_edge_id = true;
+        lreader.run();
       }
-      else
+      catch (Exception& error)
       {
-        edgemap_storage[*it] = new Graph::EdgeMap<double>(graph);
-        //std::cout << "read " << *it << " edgemap" << std::endl;
+        Gtk::MessageDialog mdialog(error.what());
+        mdialog.run();
+        clear();
+        return 1;
       }
-      greader.readEdgeMap(*it, *edgemap_storage[*it]);
-    }
-    GuiReader gui_reader(greader, this);
-    greader.run();
-  } catch (Exception& error) {
-    Gtk::MessageDialog mdialog(error.what());
-    mdialog.run();
-    clear();
-    return 1;
-  }
 
-  if (!read_edge_id)
-  {
-    edgemap_storage["label"] = new Graph::EdgeMap<double>(graph);
-    int i = 1;
-    for (EdgeIt e(graph); e != INVALID; ++e)
-    {
-      (*edgemap_storage["label"])[e] = i++;
-    }
-  }
+      if (content.nodeSetNum() < 1)
+      {
+        Gtk::MessageDialog mdialog("No nodeset found in file.");
+        mdialog.run();
+        clear();
+        return 1;
+      }
 
-  if (!read_x || !read_y)
-  {
-    int node_num = 0;
-    for (NodeIt n(graph); n != INVALID; ++n)
-    {
-      node_num++;
-    }
-    const double pi = 3.142;
-    double step = 2 * pi / (double) node_num;
-    int i = 0;
-    for (NodeIt n(graph); n != INVALID; ++n)
-    {
-      nodemap_storage["coordinates_x"]->set(n, 250.0 * std::cos(i * step));
-      nodemap_storage["coordinates_y"]->set(n, 250.0 * std::sin(i * step));
-      i++;
-    }
-  }
+      if (content.edgeSetNum() < 1)
+      {
+        Gtk::MessageDialog mdialog("No edgeset found in file.");
+        mdialog.run();
+        clear();
+        return 1;
+      }
 
-  if (!arrow_pos_read_ok)
-  {
-    arrow_pos_read_ok = false;
-    for (EdgeIt e(graph); e != INVALID; ++e)
-    {
-      if (graph.source(e) == graph.target(e))
+      std::vector<std::string> nodeMapNames = content.nodeSetMaps(0);
+      std::vector<std::string> edgeMapNames = content.edgeSetMaps(0);
+      
+      bool read_edge_label = true;
+      if (std::find(edgeMapNames.begin(), edgeMapNames.end(), "label") ==
+          edgeMapNames.end())
       {
-        arrow_pos.set(e, coords[graph.source(e)] + XY(0.0, 80.0));
+        read_edge_label = false;
+      }
+
+      nodeMapNames.erase(
+          std::remove(nodeMapNames.begin(), nodeMapNames.end(), "label"),
+          nodeMapNames.end());
+
+      edgeMapNames.erase(
+          std::remove(edgeMapNames.begin(), edgeMapNames.end(), "label"),
+          edgeMapNames.end());
+
+      FileImportDialog::ImportData data(nodeMapNames, edgeMapNames);
+      FileImportDialog fidialog(&data);
+      int response = fidialog.run();
+      if (response == Gtk::RESPONSE_OK)
+      {
+        try
+        {
+          std::string node_coord_xmap_name, node_coord_ymap_name;
+          std::string arrow_coord_xmap_name, arrow_coord_ymap_name;
+          bool gen_node_coords = false;
+          bool gen_arrow_coords = false;
+
+          switch (data.node_coord_load_from)
+          {
+            case FileImportDialog::ImportData::ONE_MAP:
+              node_coord_xmap_name = data.node_coord_one_map_name + ":x";
+              node_coord_ymap_name = data.node_coord_one_map_name + ":y";
+              node_coords_one_map_name = data.node_coord_one_map_name;
+
+              node_coords_save_dest = SpecMapSaveOpts::NESET_SECT;
+              node_coords_save_map_num = SpecMapSaveOpts::ONE_MAP;
+              break;
+            case FileImportDialog::ImportData::TWO_MAPS:
+              node_coord_xmap_name = data.node_coord_two_maps_1_name;
+              node_coord_ymap_name = data.node_coord_two_maps_2_name;
+              node_coords_two_maps_1_name = data.node_coord_two_maps_1_name;
+              node_coords_two_maps_2_name = data.node_coord_two_maps_2_name;
+
+              node_coords_save_dest = SpecMapSaveOpts::NESET_SECT;
+              node_coords_save_map_num = SpecMapSaveOpts::TWO_MAPS;
+              break;
+            case FileImportDialog::ImportData::DONT_READ:
+              node_coord_xmap_name = "";
+              node_coord_ymap_name = "";
+
+              node_coords_save_dest = SpecMapSaveOpts::GUI_SECT;
+              gen_node_coords = true;
+              break;
+          }
+
+          switch (data.arrow_coord_load_from)
+          {
+            case FileImportDialog::ImportData::ONE_MAP:
+              arrow_coord_xmap_name = data.arrow_coord_one_map_name + ":x";
+              arrow_coord_ymap_name = data.arrow_coord_one_map_name + ":y";
+              arrow_coords_one_map_name = data.arrow_coord_one_map_name;
+
+              arrow_coords_save_dest = SpecMapSaveOpts::NESET_SECT;
+              arrow_coords_save_map_num = SpecMapSaveOpts::ONE_MAP;
+              break;
+            case FileImportDialog::ImportData::TWO_MAPS:
+              arrow_coord_xmap_name = data.arrow_coord_two_maps_1_name;
+              arrow_coord_ymap_name = data.arrow_coord_two_maps_2_name;
+              arrow_coords_two_maps_1_name = data.arrow_coord_two_maps_1_name;
+              arrow_coords_two_maps_2_name = data.arrow_coord_two_maps_2_name;
+
+              arrow_coords_save_dest = SpecMapSaveOpts::NESET_SECT;
+              arrow_coords_save_map_num = SpecMapSaveOpts::TWO_MAPS;
+              break;
+            case FileImportDialog::ImportData::DONT_READ:
+              arrow_coord_xmap_name = "";
+              arrow_coord_ymap_name = "";
+
+              arrow_coords_save_dest = SpecMapSaveOpts::GUI_SECT;
+              gen_arrow_coords = true;
+              break;
+          }
+
+          // read edge and node maps
+          std::vector<std::string> node_map_names;
+          std::vector<std::string> edge_map_names;
+          std::map<std::string, MapValue::Type> node_map_types;
+          std::map<std::string, MapValue::Type> edge_map_types;
+          for (std::vector<std::string>::const_iterator it =
+              data.numeric_node_map_names.begin();
+              it != data.numeric_node_map_names.end(); ++it)
+          {
+            node_map_names.push_back(*it);
+            node_map_types[*it] = MapValue::NUMERIC;
+          }
+          for (std::vector<std::string>::const_iterator it =
+              data.string_node_map_names.begin();
+              it != data.string_node_map_names.end(); ++it)
+          {
+            node_map_names.push_back(*it);
+            node_map_types[*it] = MapValue::STRING;
+          }
+          for (std::vector<std::string>::const_iterator it =
+              data.numeric_edge_map_names.begin();
+              it != data.numeric_edge_map_names.end(); ++it)
+          {
+            edge_map_names.push_back(*it);
+            edge_map_types[*it] = MapValue::NUMERIC;
+          }
+          for (std::vector<std::string>::const_iterator it =
+              data.string_edge_map_names.begin();
+              it != data.string_edge_map_names.end(); ++it)
+          {
+            edge_map_names.push_back(*it);
+            edge_map_types[*it] = MapValue::STRING;
+          }
+
+          readLGF(filename, read_edge_label,
+              node_map_names, edge_map_names,
+              node_map_types, edge_map_types,
+              node_coord_xmap_name, node_coord_ymap_name,
+              arrow_coord_xmap_name, arrow_coord_ymap_name);
+
+          // generate edge labels
+          if (!read_edge_label)
+          {
+            int l = 0;
+            for (EdgeIt e(graph); e != INVALID; ++e)
+            {
+              edge_label[e] = l++;
+            }
+          }
+
+          if (gen_node_coords)
+          {
+            // generate node coordinates
+            int node_num = 0;
+            for (NodeIt n(graph); n != INVALID; ++n) { node_num++; }
+            const double pi = 3.142;
+            double step = 2 * pi / (double) node_num;
+            int i = 0;
+            for (NodeIt n(graph); n != INVALID; ++n)
+            {
+              setNodeCoords(n,
+                  XY(250.0 * std::cos(i * step),
+                    250.0 * std::sin(i * step)));
+              i++;
+            }
+          }
+          if (gen_arrow_coords)
+          {
+            // generate arrow coordinates
+            for (EdgeIt e(graph); e != INVALID; ++e)
+            {
+              if (graph.source(e) == graph.target(e))
+              {
+                setArrowCoords(e,
+                    getNodeCoords(graph.source(e)) + XY(0.0, 80.0));
+              }
+              else
+              {
+                setArrowCoords(e,
+                    (getNodeCoords(graph.source(e)) +
+                     getNodeCoords(graph.target(e))) / 2.0);
+              }
+            }
+          }
+        }
+        catch (Exception& error)
+        {
+          clear();
+          return 1;
+        }
       }
       else
       {
-        arrow_pos.set(e, (coords[graph.source(e)] + coords[graph.target(e)]) / 2.0);
+        clear();
+        return 1;
       }
     }
   }
 
-  // fill in the default values for the maps
-  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
-      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
+  // set max_node_label
   {
-    if ((it->first != "label") &&
-        (it->first != "coordiantes_x") &&
-        (it->first != "coordinates_y"))
-    {
-      nodemap_default[it->first] = 0.0;
-    }
-    else if (it->first == "label")
+    max_node_label = std::numeric_limits<int>::min();
+    for (NodeIt n(graph); n != INVALID; ++n)
     {
-      NodeIt n(graph);
-      double max = (*nodemap_storage["label"])[n];
-      for (; n != INVALID; ++n)
+      if (node_label[n] > max_node_label)
       {
-        if ((*nodemap_storage["label"])[n] > max)
-          max = (*nodemap_storage["label"])[n];
+        max_node_label = node_label[n];
       }
-      nodemap_default["label"] = max + 1.0;
     }
   }
-  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
-      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
+  // set max_edge_label
   {
-    if (it->first != "label")
-    {
-      edgemap_default[it->first] = 0.0;
-    }
-    else
+    max_edge_label = std::numeric_limits<int>::min();
+    for (EdgeIt e(graph); e != INVALID; ++e)
     {
-      double max = std::numeric_limits<double>::min();
-      for (EdgeIt e(graph); e != INVALID; ++e)
+      if (edge_label[e] > max_edge_label)
       {
-        if ((*edgemap_storage["label"])[e] > max)
-          max = (*edgemap_storage["label"])[e];
+        max_edge_label = edge_label[e];
       }
-      if (max > std::numeric_limits<double>::min())
-        edgemap_default["label"] = max + 1.0;
-      else
-        edgemap_default["label"] = 1.0;
     }
   }
 
@@ -416,70 +720,160 @@
 
 void MapStorage::writeToFile(const std::string &filename)
 {
-  GraphWriter<Graph> gwriter(filename, graph);
-
-  for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
-      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
+  // relabel nodes and edges
+  int i = 0;
+  for (NodeIt n(graph); n != INVALID; ++n)
   {
-    gwriter.writeNodeMap(it->first, *(it->second));
+    node_label[n] = i++;
   }
-  for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
-      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
+  max_node_label = i-1;
+  i = 0;
+  for (EdgeIt e(graph); e != INVALID; ++e)
   {
-    if ((it->first != "arrow_pos_x") &&
-        (it->first != "arrow_pos_y"))
+    edge_label[e] = i++;
+  }
+  max_edge_label = i-1;
+
+  // write .lgf file
+  {
+    GraphWriter<Graph> gwriter(filename, graph);
+
+    gwriter.writeNodeMap("label", node_label);
+    gwriter.writeEdgeMap("label", edge_label);
+
+    // write node maps
+    for (NodeMapStore::const_iterator it = nodemaps.begin();
+        it != nodemaps.end(); ++it)
     {
-      gwriter.writeEdgeMap(it->first, *(it->second));
+      if (it->second->save_dest == NESET_SECT)
+      {
+        switch (it->second->type())
+        {
+          case MapValue::NUMERIC:
+            gwriter.writeNodeMap(it->first, getNumericNodeMap(it->first));
+            break;
+          case MapValue::STRING:
+            gwriter.writeNodeMap(it->first, getStringNodeMap(it->first));
+            break;
+        }
+      }
     }
-  }
 
-  GuiWriter gui_writer(gwriter, this);
+    // write edge maps
+    for (EdgeMapStore::const_iterator it = edgemaps.begin();
+        it != edgemaps.end(); ++it)
+    {
+      if (it->second->save_dest == NESET_SECT)
+      {
+        switch (it->second->type())
+        {
+          case MapValue::NUMERIC:
+            gwriter.writeEdgeMap(it->first, getNumericEdgeMap(it->first));
+            break;
+          case MapValue::STRING:
+            gwriter.writeEdgeMap(it->first, getStringEdgeMap(it->first));
+            break;
+        }
+      }
+    }
 
-  gwriter.run();
-}
+    // write node coordinates
+    switch (getNodeCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        switch (getNodeCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            gwriter.writeNodeMap(node_coords_one_map_name + ":x",
+                node_coords_x);
+            gwriter.writeNodeMap(node_coords_one_map_name + ":y",
+                node_coords_y);
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            gwriter.writeNodeMap(node_coords_two_maps_1_name,
+                node_coords_x);
+            gwriter.writeNodeMap(node_coords_two_maps_2_name,
+                node_coords_y);
+            break;
+        }
+        break;
+    }
+
+    // write arrow coordinates
+    switch (getArrowCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        switch (getArrowCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            gwriter.writeEdgeMap(arrow_coords_one_map_name + ":x",
+                arrow_coords_x);
+            gwriter.writeEdgeMap(arrow_coords_one_map_name + ":y",
+                arrow_coords_y);
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            gwriter.writeEdgeMap(arrow_coords_two_maps_1_name,
+                arrow_coords_x);
+            gwriter.writeEdgeMap(arrow_coords_two_maps_2_name,
+                arrow_coords_y);
+            break;
+        }
+        break;
+    }
 
-void MapStorage::clear()
-{
-  for (std::map<std::string, Graph::NodeMap<double>*>::iterator it =
-      nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
-  {
-    if ((it->first != "coordinates_x") &&
-        (it->first != "coordinates_y") &&
-        (it->first != "label"))
+    if (gui_sect_save_dest == LGF_FILE)
     {
-      delete it->second;
-      nodemap_storage.erase(it);
+      GuiWriter gui_writer(gwriter, this);
+      gwriter.run();
     }
-  }
-  for (std::map<std::string, Graph::EdgeMap<double>*>::iterator it =
-      edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
-  {
-    if ((it->first != "label") &&
-        (it->first != "arrow_pos_x") &&
-        (it->first != "arrow_pos_y"))
+    else
     {
-      delete it->second;
-      edgemap_storage.erase(it);
+      gwriter.run();
     }
   }
-  for (std::map<std::string, double>::iterator it =
-      nodemap_default.begin(); it != nodemap_default.end(); ++it)
+
+  // write .conf file
+  if (gui_sect_save_dest == CONF_FILE)
   {
-    if (it->first != "label")
-      nodemap_default.erase(it);
+    LemonWriter lwriter(filename + ".conf");
+    GuiWriter gui_writer(lwriter, this);
+    lwriter.run();
   }
-  for (std::map<std::string, double>::iterator it =
-      edgemap_default.begin(); it != edgemap_default.end(); ++it)
+}
+
+void MapStorage::clear()
+{
+  for (NodeMapStore::iterator it = nodemaps.begin(); it != nodemaps.end(); ++it)
   {
-    if (it->first != "label")
-      edgemap_default.erase(it);
+    delete it->second;
+    nodemaps.erase(it);
+  }
+  for (EdgeMapStore::iterator it = edgemaps.begin(); it != edgemaps.end(); ++it)
+  {
+    delete it->second;
+    edgemaps.erase(it);
   }
   graph.clear();
   file_name = "";
   modified = false;
+  max_node_label = 0;
+  max_edge_label = 0;
+  background_set = false;
+
+  gui_sect_save_dest = LGF_FILE;
+  node_coords_save_dest = SpecMapSaveOpts::GUI_SECT;
+  arrow_coords_save_dest = SpecMapSaveOpts::GUI_SECT;
+  node_coords_one_map_name = "coord";
+  node_coords_two_maps_1_name = "coord_x";
+  node_coords_two_maps_2_name = "coord_y";
+  arrow_coords_one_map_name = "arrow";
+  arrow_coords_two_maps_1_name = "arrow_x";
+  arrow_coords_two_maps_2_name = "arrow_y";
 
-  arrow_pos_read_ok = false;
-  
   for(int i=0;i<NODE_PROPERTY_NUM;i++)
     {
       changeActiveMap(false, i, "");
@@ -499,33 +893,28 @@
   signal_design_win.emit(attraction, propulsation, iterations);
 }
 
-void MapStorage::ArrowPosReadOK()
-{
-  arrow_pos_read_ok = true;
-}
-
 void MapStorage::mapChanged(bool itisedge, std::string mapname)
 {
   if(itisedge)
+  {
+    for(int i=0;i<EDGE_PROPERTY_NUM;i++)
     {
-      for(int i=0;i<EDGE_PROPERTY_NUM;i++)
-	{
-	  if(active_edgemaps[i]==mapname)
-	    {
-	      signal_prop.emit(itisedge, i);
-	    }
-	}
+      if(active_edgemaps[i]==mapname)
+      {
+        signal_prop.emit(itisedge, i);
+      }
     }
+  }
   else
+  {
+    for(int i=0;i<NODE_PROPERTY_NUM;i++)
     {
-      for(int i=0;i<NODE_PROPERTY_NUM;i++)
-	{
-	  if(active_nodemaps[i]==mapname)
-	    {
-	      signal_prop.emit(itisedge, i);
-	    }
-	}
+      if(active_nodemaps[i]==mapname)
+      {
+        signal_prop.emit(itisedge, i);
+      }
     }
+  }
 }
 
 void MapStorage::get_design_data(double & attraction_p, double & propulsation_p, int & iterations_p)
@@ -555,6 +944,479 @@
   signal_design_win.emit(attraction, propulsation, iterations);
 }
 
+XY MapStorage::getNodeCoords(Node n) const
+{
+  return node_coords[n];
+}
+
+void MapStorage::setNodeCoords(Node n, XY c)
+{
+  node_coords.set(n, c);
+}
+
+XY MapStorage::getArrowCoords(Edge e) const
+{
+  return arrow_coords[e];
+}
+
+void MapStorage::setArrowCoords(Edge e, XY c)
+{
+  arrow_coords.set(e, c);
+}
+
+MapValue MapStorage::get(const std::string& name, Node node) const
+{
+  NodeMapData* data = getNodeMapData(name);
+  return data->get(node);
+}
+
+void MapStorage::set(const std::string& name, Node node, MapValue val)
+{
+  NodeMapData* data = getNodeMapData(name);
+  data->set(node, val);
+}
+
+MapValue MapStorage::get(const std::string& name, Edge edge) const
+{
+  EdgeMapData* data = getEdgeMapData(name);
+  return data->get(edge);
+}
+
+void MapStorage::set(const std::string& name, Edge edge, MapValue val)
+{
+  EdgeMapData* data = getEdgeMapData(name);
+  data->set(edge, val);
+}
+
+const std::string& MapStorage::getFileName() const
+{
+  return file_name;
+}
+
+void MapStorage::setFileName(const std::string& fn)
+{
+  file_name = fn;
+}
+
+bool MapStorage::getModified() const
+{
+  return modified;
+}
+
+void MapStorage::setModified(bool m)
+{
+  modified = m;
+}
+
+Node MapStorage::addNode(XY coords)
+{
+  Node node = graph.addNode();
+
+  setNodeCoords(node, coords);
+
+  max_node_label++;
+
+  node_label[node] = max_node_label;
+
+  std::vector<std::string> node_maps = getNodeMapList();
+  for (std::vector<std::string>::const_iterator it = node_maps.begin();
+      it != node_maps.end(); ++it)
+  {
+    NodeMapData* data = getNodeMapData(*it);
+    set(*it, node, data->default_value);
+  }
+
+  return node;
+}
+
+Edge MapStorage::addEdge(Node from, Node to)
+{
+  Edge edge = graph.addEdge(from, to);
+
+  if (from == to)
+  {
+    setArrowCoords(edge, getNodeCoords(from) + XY(0.0, 80.0));
+  }
+  else
+  {
+    setArrowCoords(edge, (getNodeCoords(from) + getNodeCoords(to)) / 2.0);
+  }
+
+  max_edge_label++;
+
+  edge_label[edge] = max_edge_label;
+
+  std::vector<std::string> edge_maps = getEdgeMapList();
+  for (std::vector<std::string>::const_iterator it = edge_maps.begin();
+      it != edge_maps.end(); ++it)
+  {
+    EdgeMapData* data = getEdgeMapData(*it);
+    set(*it, edge, data->default_value);
+  }
+  return edge;
+}
+
+MapStorage::NumericNodeMap& MapStorage::getNumericNodeMap(const std::string& name)
+{
+  NodeMapData* data = getNodeMapData(name);
+  if (data->type() != MapValue::NUMERIC)
+    throw Error("Numeric node map " + name + " does not exists.");
+  return static_cast<NumericNodeMapData*>(data)->map;
+}
+
+MapStorage::StringNodeMap& MapStorage::getStringNodeMap(const std::string& name)
+{
+  NodeMapData* data = getNodeMapData(name);
+  if (data->type() != MapValue::STRING)
+    throw Error("String node map " + name + " does not exists.");
+  return static_cast<StringNodeMapData*>(data)->map;
+}
+
+MapStorage::NumericEdgeMap& MapStorage::getNumericEdgeMap(const std::string& name)
+{
+  EdgeMapData* data = getEdgeMapData(name);
+  if (data->type() != MapValue::NUMERIC)
+    throw Error("Numeric edge map " + name + " does not exists.");
+  return static_cast<NumericEdgeMapData*>(data)->map;
+}
+
+MapStorage::StringEdgeMap& MapStorage::getStringEdgeMap(const std::string& name)
+{
+  EdgeMapData* data = getEdgeMapData(name);
+  if (data->type() != MapValue::STRING)
+    throw Error("String edge map " + name + " does not exists.");
+  return static_cast<StringEdgeMapData*>(data)->map;
+}
+
+MapValueEdgeMap MapStorage::getEdgeMap(const std::string& name)
+{
+  return MapValueEdgeMap(name, this);
+}
+
+MapValueNodeMap MapStorage::getNodeMap(const std::string& name)
+{
+  return MapValueNodeMap(name, this);
+}
+
+int MapStorage::getLabel(Node n) const
+{
+  return node_label[n];
+}
+
+int MapStorage::getLabel(Edge e) const
+{
+  return edge_label[e];
+}
+
+MapStorage::GuiSectSaveDest MapStorage::getGUIDataSaveLocation()
+{
+  return gui_sect_save_dest;
+}
+
+void MapStorage::setGUIDataSaveLocation(MapStorage::GuiSectSaveDest dest)
+{
+  gui_sect_save_dest = dest;
+}
+
+MapStorage::MapSaveDest MapStorage::getNodeMapSaveDest(std::string name) const
+{
+  NodeMapData *data = getNodeMapData(name);
+  return data->save_dest;
+}
+
+MapStorage::MapSaveDest MapStorage::getEdgeMapSaveDest(std::string name) const
+{
+  EdgeMapData *data = getEdgeMapData(name);
+  return data->save_dest;
+}
+
+void MapStorage::setNodeMapSaveDest(std::string name, MapStorage::MapSaveDest dest)
+{
+  NodeMapData *data = getNodeMapData(name);
+  data->save_dest = dest;
+}
+
+void MapStorage::setEdgeMapSaveDest(std::string name, MapStorage::MapSaveDest dest)
+{
+  EdgeMapData *data = getEdgeMapData(name);
+  data->save_dest = dest;
+}
+
+MapStorage::EdgeMapData* MapStorage::getEdgeMapData(std::string name) const
+{
+  EdgeMapStore::const_iterator it = edgemaps.find(name);
+  if (it != edgemaps.end())
+    return it->second;
+  else
+    throw Error("Edge map " + name + " does not exists.");
+}
+
+MapStorage::NodeMapData* MapStorage::getNodeMapData(std::string name) const
+{
+  NodeMapStore::const_iterator it = nodemaps.find(name);
+  if (it != nodemaps.end())
+    return it->second;
+  else
+    throw Error("Node map " + name + " does not exists.");
+}
+
+MapValue::Type MapStorage::getNodeMapElementType(std::string name) const
+{
+  NodeMapData *data = getNodeMapData(name);
+  return data->type();
+}
+
+MapValue::Type MapStorage::getEdgeMapElementType(std::string name) const
+{
+  EdgeMapData *data = getEdgeMapData(name);
+  return data->type();
+}
+
+const MapStorage::NodeLabelMap& MapStorage::getNodeLabelMap()
+{
+  return node_label;
+}
+
+const MapStorage::EdgeLabelMap& MapStorage::getEdgeLabelMap()
+{
+  return edge_label;
+}
+
+const Graph& MapStorage::getGraph()
+{
+  return graph;
+}
+
+bool MapStorage::nodeMapExists(std::string name)
+{
+  NodeMapStore::const_iterator it = nodemaps.find(name);
+  if (it == nodemaps.end())
+    return false;
+  else
+    return true;
+}
+
+bool MapStorage::edgeMapExists(std::string name)
+{
+  EdgeMapStore::const_iterator it = edgemaps.find(name);
+  if (it == edgemaps.end())
+    return false;
+  else
+    return true;
+}
+
+std::vector<std::string> MapStorage::getEdgeMaps(MapType type)
+{
+  std::vector<std::string> maps;
+  for (EdgeMapStore::const_iterator it = edgemaps.begin(); it != edgemaps.end(); ++it)
+  {
+    if (it->second->type() & type)
+    {
+      maps.push_back(it->first);
+    }
+  }
+  return maps;
+}
+
+std::vector<std::string> MapStorage::getNodeMaps(MapType type)
+{
+  std::vector<std::string> maps;
+  for (NodeMapStore::const_iterator it = nodemaps.begin(); it != nodemaps.end(); ++it)
+  {
+    if (it->second->type() & type)
+    {
+      maps.push_back(it->first);
+    }
+  }
+  return maps;
+}
+
+MapStorage::NodeCoordMap& MapStorage::getNodeCoordMap()
+{
+  return node_coords;
+}
+
+MapStorage::ArrowCoordMap& MapStorage::getArrowCoordMap()
+{
+  return arrow_coords;
+}
+
+MapStorage::SpecMapSaveOpts::Dest MapStorage::getNodeCoordsSaveDest()
+{
+  return node_coords_save_dest;
+}
+
+MapStorage::SpecMapSaveOpts::Dest MapStorage::getArrowCoordsSaveDest()
+{
+  return arrow_coords_save_dest;
+}
+
+void MapStorage::setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::Dest dest)
+{
+  node_coords_save_dest = dest;
+}
+
+void MapStorage::setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::Dest dest)
+{
+  arrow_coords_save_dest = dest;
+}
+
+MapStorage::SpecMapSaveOpts::MapNum MapStorage::getNodeCoordsSaveMapNum()
+{
+  return node_coords_save_map_num;
+}
+
+MapStorage::SpecMapSaveOpts::MapNum MapStorage::getArrowCoordsSaveMapNum()
+{
+  return arrow_coords_save_map_num;
+}
+
+void MapStorage::setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::MapNum num)
+{
+  node_coords_save_map_num = num;
+}
+
+void MapStorage::setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::MapNum num)
+{
+  arrow_coords_save_map_num = num;
+}
+
+const std::string& MapStorage::getNodeCoordsOneMapName()
+{
+  return node_coords_one_map_name;
+}
+const std::string& MapStorage::getNodeCoordsTwoMaps1Name()
+{
+  return node_coords_two_maps_1_name;
+}
+const std::string& MapStorage::getNodeCoordsTwoMaps2Name()
+{
+  return node_coords_two_maps_2_name;
+}
+
+void MapStorage::setNodeCoordsOneMapName(const std::string& name)
+{
+  node_coords_one_map_name = name;
+}
+void MapStorage::setNodeCoordsTwoMaps1Name(const std::string& name)
+{
+  node_coords_two_maps_1_name = name;
+}
+void MapStorage::setNodeCoordsTwoMaps2Name(const std::string& name)
+{
+  node_coords_two_maps_2_name = name;
+}
+
+const std::string& MapStorage::getArrowCoordsOneMapName()
+{
+  return arrow_coords_one_map_name;
+}
+const std::string& MapStorage::getArrowCoordsTwoMaps1Name()
+{
+  return arrow_coords_two_maps_1_name;
+}
+const std::string& MapStorage::getArrowCoordsTwoMaps2Name()
+{
+  return arrow_coords_two_maps_2_name;
+}
+
+void MapStorage::setArrowCoordsOneMapName(const std::string& name)
+{
+  arrow_coords_one_map_name = name;
+}
+void MapStorage::setArrowCoordsTwoMaps1Name(const std::string& name)
+{
+  arrow_coords_two_maps_1_name = name;
+}
+void MapStorage::setArrowCoordsTwoMaps2Name(const std::string& name)
+{
+  arrow_coords_two_maps_2_name = name;
+}
+
+void MapStorage::readLGF(
+    const std::string& filename,
+    bool read_edge_label,
+    const std::vector<std::string>& node_map_names,
+    const std::vector<std::string>& edge_map_names,
+    const std::map<std::string, MapValue::Type>& node_map_types,
+    const std::map<std::string, MapValue::Type>& edge_map_types,
+    const std::string& node_coord_xmap_name,
+    const std::string& node_coord_ymap_name,
+    const std::string& arrow_coord_xmap_name,
+    const std::string& arrow_coord_ymap_name)
+{
+  using std::vector;
+  using std::map;
+  using std::string;
+
+  GraphReader<Graph> greader(filename, graph);
+
+  // read the label maps
+  greader.readNodeMap("label", node_label);
+  if (read_edge_label)
+    greader.readEdgeMap("label", edge_label);
+
+  // read the node maps
+  for (vector<string>::const_iterator
+      it = node_map_names.begin();
+      it != node_map_names.end(); ++it)
+  {
+    switch (node_map_types.find(*it)->second)
+    {
+      case MapValue::NUMERIC:
+        {
+          createNodeMap(*it, MapValue::NUMERIC, double());
+          greader.readNodeMap(*it, getNumericNodeMap(*it));
+          break;
+        }
+      case MapValue::STRING:
+        {
+          createNodeMap(*it, MapValue::STRING, string());
+          greader.readNodeMap(*it, getStringNodeMap(*it));
+          break;
+        }
+    }
+    getNodeMapData(*it)->save_dest = NESET_SECT;
+  }
+
+  // read the edge maps
+  for (vector<string>::const_iterator
+      it = edge_map_names.begin();
+      it != edge_map_names.end(); ++it)
+  {
+    switch (edge_map_types.find(*it)->second)
+    {
+      case MapValue::NUMERIC:
+        {
+          createEdgeMap(*it, MapValue::NUMERIC, double());
+          greader.readEdgeMap(*it, getNumericEdgeMap(*it));
+          break;
+        }
+      case MapValue::STRING:
+        {
+          createEdgeMap(*it, MapValue::STRING, string());
+          greader.readEdgeMap(*it, getStringEdgeMap(*it));
+          break;
+        }
+    }
+    getEdgeMapData(*it)->save_dest = NESET_SECT;
+  }
+
+  // read the node coordinate maps
+  if (node_coord_xmap_name != "")
+    greader.readNodeMap(node_coord_xmap_name, node_coords_x);
+  if (node_coord_ymap_name != "")
+    greader.readNodeMap(node_coord_ymap_name, node_coords_y);
+
+  // read the arrow coordinate maps
+  if (arrow_coord_xmap_name != "")
+    greader.readEdgeMap(arrow_coord_xmap_name, arrow_coords_x);
+  if (arrow_coord_ymap_name != "")
+    greader.readEdgeMap(arrow_coord_ymap_name, arrow_coords_y);
+
+  greader.run();
+}
+
 void MapStorage::setBackground(const std::string& file_name)
 {
   if (file_name == background_file_name) return;
@@ -610,13 +1472,13 @@
     {
       if(active_nodemaps[N_RADIUS]!="")
 	{
-	  _nodeSizes=*(nodemap_storage[active_nodemaps[N_RADIUS]]);
+	  _nodeSizes=getNumericNodeMap(active_nodemaps[N_RADIUS]);
 	}
       if(active_nodemaps[N_COLOR]!="")
 	{
 	  for(NodeIt ni(graph);ni!=INVALID;++ni)
 	    {
-	      _nodeColors[ni]=(int)((*(nodemap_storage[active_nodemaps[N_COLOR]]))[ni]);
+	      _nodeColors[ni]=(int)get(active_nodemaps[N_COLOR], ni);
 	    }
 	}
       if(active_nodemaps[N_TEXT]!="")
@@ -624,7 +1486,7 @@
 	  for(NodeIt ni(graph);ni!=INVALID;++ni)
 	    {
 	      std::ostringstream o;
-	      o << ((*(nodemap_storage[active_nodemaps[N_TEXT]]))[ni]);
+	      o << get(active_nodemaps[N_TEXT], ni);
 	      _nodeTextMap[ni]=o.str();	      
 	    }
 	}
@@ -633,21 +1495,33 @@
     {
       if(active_edgemaps[E_WIDTH]!="")
 	{
-	  _edgeWidths=*(edgemap_storage[active_edgemaps[E_WIDTH]]);
+	  _edgeWidths=getNumericEdgeMap(active_edgemaps[E_WIDTH]);
 	}
       if(active_edgemaps[E_COLOR]!="")
 	{
 	  for(EdgeIt ei(graph);ei!=INVALID;++ei)
 	    {
-	      _edgeColors[ei]=(int)((*(edgemap_storage[active_edgemaps[E_COLOR]]))[ei]);
+	      _edgeColors[ei]=(int)get(active_edgemaps[E_COLOR], ei);
 	    }
 	}
     }
   if(shapemap!="Default values")
     {
-      if((minOfNodeMap(shapemap)>=0)&&(maxOfNodeMap(shapemap)<=4))
+      double min = std::numeric_limits<double>::max();
+      double max = std::numeric_limits<double>::min();
+      for (NodeIt n(graph); n != INVALID; ++n)
+      {
+        double v = static_cast<double>(get(shapemap, n));
+        if (v < min) min = v;
+        if (v > max) max = v;
+      }
+      if((min>=0)&&(max<=4))
 	{
-	  _shapes=*(nodemap_storage[shapemap]);
+          NumericNodeMap& map = static_cast<NumericNodeMapData*>(getNodeMapData(shapemap))->map;
+          for (NodeIt n(graph); n != INVALID; ++n)
+          {
+            _shapes[n] = static_cast<int>(map[n]);
+          }
 	}
     }
 
@@ -659,7 +1533,7 @@
     copyright("(C) 2006 LEMON Project").
     absoluteNodeSizes().absoluteEdgeWidths().
     nodeScale(2).nodeSizes(_nodeSizes).
-    coords(coords).
+    coords(node_coords).
     nodeShapes(_shapes).
     nodeColors(composeMap(paletteW,_nodeColors)).
     edgeColors(composeMap(palette,_edgeColors)).

Modified: glemon/trunk/mapstorage.h
==============================================================================
--- glemon/trunk/mapstorage.h	(original)
+++ glemon/trunk/mapstorage.h	Wed Jan  2 22:03:09 2008
@@ -19,9 +19,16 @@
 #ifndef MAPSTORAGE_H
 #define MAPSTORAGE_H
 
-#include <all_include.h>
-#include <xymap.h>
+class Mapstorage;
+
+#include <vector>
+#include <map>
+#include <string>
+#include "all_include.h"
+#include "xymap.h"
 #include <libgnomecanvasmm.h>
+#include "map_value.h"
+#include "map_value_map.h"
 
 ///class MapStorage handles NodeMaps and EdgeMaps.
 
@@ -41,17 +48,218 @@
   bool background_set;
   double background_scaling;
 public:
+  class Error : public std::exception
+  {
+    private:
+      std::string message;
+    public:
+      Error(const std::string& msg) : message(msg) {}
+      virtual const char* what() const throw()
+      {
+        return message.c_str();
+      }
+      ~Error() throw() {}
+  };
+
   void setBackground(const std::string& file_name);
   const std::string& getBackgroundFilename();
   bool isBackgroundSet();
   double getBackgroundScaling();
   void setBackgroundScaling(double scaling);
+
+  enum MapSaveDest { GUI_SECT, NESET_SECT, DONT_SAVE };
+  enum GuiSectSaveDest { LGF_FILE, CONF_FILE };
+  struct SpecMapSaveOpts
+  {
+    enum Dest { GUI_SECT, NESET_SECT };
+    enum MapNum { ONE_MAP, TWO_MAPS };
+  };
+
+  typedef Graph::NodeMap<double> NumericNodeMap;
+  typedef Graph::NodeMap<std::string> StringNodeMap;
+  typedef Graph::EdgeMap<double> NumericEdgeMap;
+  typedef Graph::EdgeMap<std::string> StringEdgeMap;
+  typedef Graph::NodeMap<int> NodeLabelMap;
+  typedef Graph::EdgeMap<int> EdgeLabelMap;
+  typedef XYMap<Graph::NodeMap<double> > NodeCoordMap;
+  typedef XYMap<Graph::EdgeMap<double> > ArrowCoordMap;
+
+  struct EdgeMapData
+  {
+    /// where to save the map
+    MapSaveDest save_dest;
+    /// read-only or read-write
+    bool writeable;
+    /// default value
+    MapValue default_value;
+    virtual MapValue::Type type() = 0;
+    virtual MapValue get(Edge e) = 0;
+    virtual void set(Edge e, MapValue v) = 0;
+    EdgeMapData(MapValue def_val) :
+      save_dest(GUI_SECT),
+      writeable(true),
+      default_value(def_val)
+    {}
+  };
+
+  struct NumericEdgeMapData : public EdgeMapData
+  {
+    NumericEdgeMap map;
+    MapValue::Type type() { return MapValue::NUMERIC; }
+    MapValue get(Edge e) { return MapValue(map[e]); }
+    void set(Edge e, MapValue v) { map.set(e, static_cast<double>(v)); }
+    NumericEdgeMapData(Graph& g, double def_val) :
+      EdgeMapData(MapValue(def_val)),
+      map(g, def_val)
+    {}
+  };
+
+  struct StringEdgeMapData : public EdgeMapData
+  {
+    StringEdgeMap map;
+    MapValue::Type type() { return MapValue::STRING; }
+    MapValue get(Edge e) { return MapValue(map[e]); }
+    void set(Edge e, MapValue v) { map.set(e, static_cast<std::string>(v)); }
+    StringEdgeMapData(Graph& g, std::string def_val) :
+      EdgeMapData(MapValue(def_val)),
+      map(g, def_val)
+    {}
+  };
+
+  struct NodeMapData
+  {
+    /// where to save the map
+    MapSaveDest save_dest;
+    /// read-only or read-write
+    bool writeable;
+    /// default value
+    MapValue default_value;
+    virtual MapValue::Type type() = 0;
+    virtual MapValue get(Node e) = 0;
+    virtual void set(Node e, MapValue v) = 0;
+    NodeMapData(MapValue def_val) :
+      save_dest(GUI_SECT),
+      writeable(true),
+      default_value(def_val)
+    {}
+  };
+
+  struct NumericNodeMapData : public NodeMapData
+  {
+    NumericNodeMap map;
+    MapValue::Type type() { return MapValue::NUMERIC; }
+    MapValue get(Node e) { return MapValue(map[e]); }
+    void set(Node e, MapValue v) { map.set(e, static_cast<double>(v)); }
+    NumericNodeMapData(Graph& g, double def_val) :
+      NodeMapData(MapValue(def_val)),
+      map(g, def_val)
+    {}
+  };
+
+  struct StringNodeMapData : public NodeMapData
+  {
+    StringNodeMap map;
+    MapValue::Type type() { return MapValue::STRING; }
+    MapValue get(Node e) { return MapValue(map[e]); }
+    void set(Node e, MapValue v) { map.set(e, static_cast<std::string>(v)); }
+    StringNodeMapData(Graph& g, std::string def_val) :
+      NodeMapData(MapValue(def_val)),
+      map(g, def_val)
+    {}
+  };
+
+  typedef std::map<std::string, NodeMapData*> NodeMapStore;
+  typedef std::map<std::string, EdgeMapData*> EdgeMapStore;
+
+  struct GUISectData
+  {
+    std::vector<std::string> main_node_map_names;
+    std::vector<std::string> main_edge_map_names;
+
+    std::vector<std::string> gui_node_map_names;
+    std::vector<std::string> gui_edge_map_names;
+
+    std::map<std::string, MapValue::Type> node_map_types;
+    std::map<std::string, MapValue::Type> edge_map_types;
+
+    std::map<std::string, std::map<int, double>* > numeric_node_maps;
+    std::map<std::string, std::map<int, std::string>* > string_node_maps;
+
+    std::map<std::string, std::map<int, double>* > numeric_edge_maps;
+    std::map<std::string, std::map<int, std::string>* > string_edge_maps;
+
+    std::map<int, XY> node_coord_map;
+    std::map<int, XY> arrow_coord_map;
+
+    SpecMapSaveOpts::Dest node_coords_save_dest;
+    SpecMapSaveOpts::MapNum node_coords_save_map_num;
+    std::string node_coords_one_map_name;
+    std::string node_coords_two_maps_1_name;
+    std::string node_coords_two_maps_2_name;
+
+    SpecMapSaveOpts::Dest arrow_coords_save_dest;
+    SpecMapSaveOpts::MapNum arrow_coords_save_map_num;
+    std::string arrow_coords_one_map_name;
+    std::string arrow_coords_two_maps_1_name;
+    std::string arrow_coords_two_maps_2_name;
+
+    ~GUISectData()
+    {
+      using std::map;
+      using std::vector;
+      using std::pair;
+      using std::string;
+
+      for (map<string, map<int, double>* >::iterator it =
+          numeric_node_maps.begin(); it != numeric_node_maps.end(); ++it)
+      {
+        delete it->second;
+      }
+      for (map<string, map<int, string>* >::iterator it =
+          string_node_maps.begin(); it != string_node_maps.end(); ++it)
+      {
+        delete it->second;
+      }
+      for (map<string, map<int, double>* >::iterator it =
+          numeric_edge_maps.begin(); it != numeric_edge_maps.end(); ++it)
+      {
+        delete it->second;
+      }
+      for (map<string, map<int, string>* >::iterator it =
+          string_edge_maps.begin(); it != string_edge_maps.end(); ++it)
+      {
+        delete it->second;
+      }
+    }
+  };
+public:
   ///The graph for which the datas are stored.
   Graph graph;
+  const Graph& getGraph();
+
+private:
+  GuiSectSaveDest gui_sect_save_dest;
+
+  SpecMapSaveOpts::Dest node_coords_save_dest;
+  SpecMapSaveOpts::MapNum node_coords_save_map_num;
+  SpecMapSaveOpts::Dest arrow_coords_save_dest;
+  SpecMapSaveOpts::MapNum arrow_coords_save_map_num;
+
+  NodeMapStore nodemaps;
+  EdgeMapStore edgemaps;
+
+  NodeLabelMap node_label;
+  EdgeLabelMap edge_label;
+
   /// the coordinates of the nodes
-  XYMap<Graph::NodeMap<double> > coords;
+  NodeCoordMap node_coords;
+  Graph::NodeMap<double> node_coords_x;
+  Graph::NodeMap<double> node_coords_y;
+
   /// the coordinates of the arrows on the edges
-  XYMap<Graph::EdgeMap<double> > arrow_pos;
+  ArrowCoordMap arrow_coords;
+  Graph::EdgeMap<double> arrow_coords_x;
+  Graph::EdgeMap<double> arrow_coords_y;
 
   ///The content of the object has changed, update is needed.
   bool modified;
@@ -59,12 +267,21 @@
   ///Name of file loaded in object.
   std::string file_name;
 
-  ///Stores double type NodeMaps
-  std::map< std::string,Graph::NodeMap<double> * > nodemap_storage;
+  // the largest node label
+  int max_node_label;
 
-  ///Stores double type EdgeMaps
-  std::map< std::string,Graph::EdgeMap<double> * > edgemap_storage;
+  // the largest edge label
+  int max_edge_label;
 
+  std::string node_coords_one_map_name;
+  std::string node_coords_two_maps_1_name;
+  std::string node_coords_two_maps_2_name;
+
+  std::string arrow_coords_one_map_name;
+  std::string arrow_coords_two_maps_1_name;
+  std::string arrow_coords_two_maps_2_name;
+
+public:
   ///Stores the default values for the different visualization node attributes
   std::vector<Graph::NodeMap<double> > default_nodemaps;
 
@@ -77,14 +294,6 @@
   /// Stores the active maps for the different visualization edge attributes
   std::vector< std::string > active_edgemaps;
 
-  /// Default values for the maps
-  std::map< std::string, double > nodemap_default;
-
-  /// Default values for the maps
-  std::map< std::string, double > edgemap_default;
-
-  bool arrow_pos_read_ok;
-
 protected:
 
   /// Signal emitted on any change made on map values
@@ -98,13 +307,13 @@
 
   /// std::string is the
   ///name of the new map
-  sigc::signal<void, std::string> signal_node_map;
+  sigc::signal<void, std::string, MapValue::Type> signal_node_map;
 
   /// Signal emitted in the case of edgemap addition
 
   /// std::string is the
   ///name of the new map
-  sigc::signal<void, std::string> signal_edge_map;
+  sigc::signal<void, std::string, MapValue::Type> signal_edge_map;
 
   /// Signal emitted, when entry in \ref MapWin should be changed.
   sigc::signal<void, bool, int, std::string> signal_map_win;
@@ -164,19 +373,19 @@
   std::string getActiveNodeMap(int prop);
 
   /// Returns the names of the edgemaps stored here.
-  std::vector<std::string> getEdgeMapList();
+  std::vector<std::string> getEdgeMapList(MapType type = ALL);
 
   /// Returns the names of the nodemaps stored here.
-  std::vector<std::string> getNodeMapList();
+  std::vector<std::string> getNodeMapList(MapType type = ALL);
 
   ///returns \ref signal_prop to be able to connect functions to it
   sigc::signal<void, bool, int> signal_prop_ch();
 
   ///returns \ref signal_node_map to be able to connect functions to it
-  sigc::signal<void, std::string> signal_node_map_ch(){return signal_node_map;};
+  sigc::signal<void, std::string, MapValue::Type> signal_node_map_ch(){return signal_node_map;};
 
   ///returns \ref signal_edge_map to be able to connect functions to it
-  sigc::signal<void, std::string> signal_edge_map_ch(){return signal_edge_map;};
+  sigc::signal<void, std::string, MapValue::Type> signal_edge_map_ch(){return signal_edge_map;};
 
   ///returns \ref signal_map_win to be able to connect functions to it
   sigc::signal<void, bool, int, std::string> signal_map_win_ch(){return signal_map_win;};
@@ -184,87 +393,17 @@
   ///returns \ref signal_design_win to be able to connect functions to it
   sigc::signal<void, double, double, int> signal_design_win_ch(){return signal_design_win;};
 
+  void createNodeMap(const std::string& name, MapValue::Type type,
+    MapValue def_val);
+  void createEdgeMap(const std::string& name, MapValue::Type type,
+    MapValue def_val);
+
   ///returns \ref signal_background to be able to connect functions to it
   sigc::signal<void> signal_background_ch(){return signal_background;};
 
 
   ///Adds given map to storage.
 
-  ///A name and the map itself has to be provided.
-  ///\param mapname is the name of map
-  ///\param nodemap is the pointer of the given nodemap
-  ///\param def the default value of the map. If not given, it will be 0.
-  ///If new edge is added to graph the value of it in the map will be this.
-  ///\todo map should be given by reference!
-  ///\todo why is default value stored?
-  int addNodeMap(const std::string & mapname,Graph::NodeMap<double> * nodemap, double def=0.0);
-
-  ///Adds given map to storage. A name and the map itself has to be provided.
-
-  ///A name and the map itself has to be provided.
-  ///\param mapname is the name of map
-  ///\param edgemap is the pointer of the given edgemap
-  ///\param def the default value of the map. If not given, it will be 0.
-  ///If new edge is added to graph the value of it in the map will be this.
-  ///\todo map should be given by reference!
-  int addEdgeMap(const std::string & mapname,Graph::EdgeMap<double> * edgemap, double def=0.0);
-
-  ///Returns how much nodemaps is stored in \ref MapStorage
-  int numOfNodeMaps() {return nodemap_storage.size();};
-
-  ///Returns how much edgemaps is stored in \ref MapStorage
-  int numOfEdgeMaps() {return edgemap_storage.size();};
-
-  ///Returns the maximum value of the given NodeMap.
-
-  ///NodeMap has to be given by its name.
-  ///\param name the name of map of which maximum is searched
-  double maxOfNodeMap(const std::string & name);
-
-  ///Returns the maximum value of the given EdgeMap.
-
-  ///EdgeMap has to be given by its name.
-  ///\param name the name of map of which maximum is searched
-  double maxOfEdgeMap(const std::string & name);
-
-  ///Returns the minimum value of the given NodeMap.
-
-  ///NodeMap has to be given by its name.
-  ///\param name the name of map of which minimum is searched
-  double minOfNodeMap(const std::string & name);
-
-  ///Returns the minimum value of the given EdgeMap.
-
-  ///EdgeMap has to be given by its name.
-  ///\param name the name of map of which minimum is searched
-  double minOfEdgeMap(const std::string & name);
-
-  ///Returns iterator pointing to the first NodeMap in storage.
-
-  ///To be able to iterate through each maps this function
-  ///returns an iterator pointing to the first nodemap in
-  ///the storage.
-  std::map< std::string,Graph::NodeMap<double> * >::iterator beginOfNodeMaps(){return nodemap_storage.begin();};
-
-  ///Returns iterator pointing to the first EdgeMap in storage.
-
-  ///To be able to iterate through each maps this function
-  ///returns an iterator pointing to the first edgemap in
-  ///the storage.
-  std::map< std::string,Graph::EdgeMap<double> * >::iterator beginOfEdgeMaps(){return edgemap_storage.begin();};
-
-  ///Returns iterator pointing after the last NodeMap in storage.
-
-  ///To be able to iterate through each maps this function
-  ///returns an iterator pointing to the last nodemap in the storage.
-  std::map< std::string,Graph::NodeMap<double> * >::iterator endOfNodeMaps(){return nodemap_storage.end();};
-
-  ///Returns iterator pointing after the last EdgeMap in storage.
-
-  ///To be able to iterate through each maps this function
-  ///returns an iterator pointing to the last edgemap in the storage.
-  std::map< std::string,Graph::EdgeMap<double> * >::iterator endOfEdgeMaps(){return edgemap_storage.end();};
-
   ///Emits \ref signal_prop if mapvalues have changed, and MapStorage gets to know it.
 
   ///If values in a map have changed, this function checks, whether it is displayed.
@@ -285,8 +424,6 @@
   ///Deletes all datastructures stored here.
   void clear();
 
-  void ArrowPosReadOK();
-
   void get_design_data(double &, double &, int &);
   void set_attraction(double);
   void set_propulsation(double);
@@ -294,6 +431,99 @@
 
   void redesign_data_changed();
 
+  XY getNodeCoords(Node n) const;
+  void setNodeCoords(Node n, XY c);
+  XY getArrowCoords(Edge e) const;
+  void setArrowCoords(Edge e, XY c);
+
+  MapValue get(const std::string& name, Node node) const;
+  void set(const std::string& name, Node node, MapValue val);
+  MapValue get(const std::string& name, Edge edge) const;
+  void set(const std::string& name, Edge edge, MapValue val);
+
+  const std::string& getFileName() const;
+  void setFileName(const std::string& fn);
+
+  bool getModified() const;
+  void setModified(bool m = true);
+
+  Node addNode(XY);
+  Edge addEdge(Node, Node);
+
+  NumericNodeMap& getNumericNodeMap(const std::string& name);
+  StringNodeMap& getStringNodeMap(const std::string& name);
+  NumericEdgeMap& getNumericEdgeMap(const std::string& name);
+  StringEdgeMap& getStringEdgeMap(const std::string& name);
+
+  MapValueEdgeMap getEdgeMap(const std::string& name);
+  MapValueNodeMap getNodeMap(const std::string& name);
+
+  int getLabel(Node) const;
+  int getLabel(Edge) const;
+
+  GuiSectSaveDest getGUIDataSaveLocation();
+  void setGUIDataSaveLocation(GuiSectSaveDest dest);
+
+  MapSaveDest getNodeMapSaveDest(std::string name) const;
+  MapSaveDest getEdgeMapSaveDest(std::string name) const;
+  void setNodeMapSaveDest(std::string name, MapSaveDest dest);
+  void setEdgeMapSaveDest(std::string name, MapSaveDest dest);
+
+  SpecMapSaveOpts::Dest getNodeCoordsSaveDest();
+  SpecMapSaveOpts::Dest getArrowCoordsSaveDest();
+  void setNodeCoordsSaveDest(SpecMapSaveOpts::Dest dest);
+  void setArrowCoordsSaveDest(SpecMapSaveOpts::Dest dest);
+
+  SpecMapSaveOpts::MapNum getNodeCoordsSaveMapNum();
+  SpecMapSaveOpts::MapNum getArrowCoordsSaveMapNum();
+  void setNodeCoordsSaveMapNum(SpecMapSaveOpts::MapNum num);
+  void setArrowCoordsSaveMapNum(SpecMapSaveOpts::MapNum num);
+
+  MapValue::Type getNodeMapElementType(std::string name) const;
+  MapValue::Type getEdgeMapElementType(std::string name) const;
+
+  const NodeLabelMap& getNodeLabelMap();
+  const EdgeLabelMap& getEdgeLabelMap();
+
+  bool nodeMapExists(std::string name);
+  bool edgeMapExists(std::string name);
+
+  std::vector<std::string> getEdgeMaps(MapType type = ALL);
+  std::vector<std::string> getNodeMaps(MapType type = ALL);
+
+  NodeCoordMap& getNodeCoordMap();
+  ArrowCoordMap& getArrowCoordMap();
+
+  const std::string& getNodeCoordsOneMapName();
+  const std::string& getNodeCoordsTwoMaps1Name();
+  const std::string& getNodeCoordsTwoMaps2Name();
+  void setNodeCoordsOneMapName(const std::string& name);
+  void setNodeCoordsTwoMaps1Name(const std::string& name);
+  void setNodeCoordsTwoMaps2Name(const std::string& name);
+
+  const std::string& getArrowCoordsOneMapName();
+  const std::string& getArrowCoordsTwoMaps1Name();
+  const std::string& getArrowCoordsTwoMaps2Name();
+  void setArrowCoordsOneMapName(const std::string& name);
+  void setArrowCoordsTwoMaps1Name(const std::string& name);
+  void setArrowCoordsTwoMaps2Name(const std::string& name);
+
+private:
+  EdgeMapData* getEdgeMapData(std::string name) const;
+  NodeMapData* getNodeMapData(std::string name) const;
+  void readLGF(
+      const std::string& filename,
+      bool read_edge_label,
+      const std::vector<std::string>& node_map_names,
+      const std::vector<std::string>& edge_map_names,
+      const std::map<std::string, MapValue::Type>& node_map_types,
+      const std::map<std::string, MapValue::Type>& edge_map_types,
+      const std::string& node_coord_xmap_name,
+      const std::string& node_coord_ymap_name,
+      const std::string& arrow_coord_xmap_name,
+      const std::string& arrow_coord_ymap_name);
+
+public:
   void exportGraphToEPS(std::vector<bool>, std::string, std::string);
 };
 

Modified: glemon/trunk/nbtab.cc
==============================================================================
--- glemon/trunk/nbtab.cc	(original)
+++ glemon/trunk/nbtab.cc	Wed Jan  2 22:03:09 2008
@@ -30,6 +30,7 @@
   mapstorage=new MapStorage();
 
   Gtk::ScrolledWindow *pScrolledWindow = manage(new Gtk::ScrolledWindow);
+  pScrolledWindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
   gd_canvas=new GraphDisplayerCanvas(*this);
   pScrolledWindow->add(*gd_canvas);
   add(*pScrolledWindow);
@@ -46,19 +47,23 @@
 void NoteBookTab::readFile(const std::string &file)
 {
   mapstorage->readFromFile(file);
-  mapstorage->file_name = file;
-  mapstorage->modified = false;
+  mapstorage->setFileName(file);
+  mapstorage->setModified(false);
   gd_canvas->drawGraph();
   if(mapwinexists)
     {
-      mapwin->update(mapstorage->getEdgeMapList(), mapstorage->getNodeMapList());
+      mapwin->update(
+          mapstorage->getEdgeMapList(NUM),
+          mapstorage->getEdgeMapList(STR),
+          mapstorage->getNodeMapList(NUM),
+          mapstorage->getNodeMapList(STR));
     }
   title_changed(Glib::filename_display_basename(file));
 }
 
 void NoteBookTab::newFile()
 {
-  if (mapstorage->modified)
+  if (mapstorage->getModified())
   {
     Gtk::MessageDialog mdialog("<b>Save changes before closing?</b>", true,
         Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
@@ -80,14 +85,18 @@
   mapstorage->clear();
   if(mapwinexists)
     {
-      mapwin->update(mapstorage->getEdgeMapList(), mapstorage->getNodeMapList());
+      mapwin->update(
+          mapstorage->getEdgeMapList(NUM),
+          mapstorage->getEdgeMapList(STR),
+          mapstorage->getNodeMapList(NUM),
+          mapstorage->getNodeMapList(STR));
     }
   title_changed("unsaved file");
 }
 
 void NoteBookTab::openFile()
 {
-  if (mapstorage->modified)
+  if (mapstorage->getModified())
   {
     Gtk::MessageDialog mdialog("<b>Save changes before closing?</b>", true, 
         Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
@@ -115,12 +124,16 @@
     Glib::ustring filename = fcdialog.get_filename();
     if (!mapstorage->readFromFile(filename))
     {
-      mapstorage->file_name = filename;
-      mapstorage->modified = false;
+      mapstorage->setFileName(filename);
+      mapstorage->setModified(false);
       gd_canvas->drawGraph();
       if(mapwinexists)
 	{
-	  mapwin->update(mapstorage->getEdgeMapList(), mapstorage->getNodeMapList());
+          mapwin->update(
+              mapstorage->getEdgeMapList(NUM),
+              mapstorage->getEdgeMapList(STR),
+              mapstorage->getNodeMapList(NUM),
+              mapstorage->getNodeMapList(STR));
 	}
       title_changed(Glib::filename_display_basename(filename));
     }
@@ -129,14 +142,14 @@
 
 void NoteBookTab::saveFile()
 {
-  if (mapstorage->file_name == "") {
+  if (mapstorage->getFileName() == "") {
     saveFileAs();
   }
   else
   {
-    mapstorage->writeToFile(mapstorage->file_name);
-    mapstorage->modified = false;
-    title_changed(Glib::filename_display_basename(mapstorage->file_name));
+    mapstorage->writeToFile(mapstorage->getFileName());
+    mapstorage->setModified(false);
+    title_changed(Glib::filename_display_basename(mapstorage->getFileName()));
   }
 }
 
@@ -148,16 +161,16 @@
   if (fcdialog.run() == Gtk::RESPONSE_ACCEPT)
   {
     Glib::ustring filename = fcdialog.get_filename();
-    mapstorage->file_name = filename;
+    mapstorage->setFileName(filename);
     mapstorage->writeToFile(filename);
-    mapstorage->modified = false;
+    mapstorage->setModified(false);
     title_changed(Glib::filename_display_basename(filename));
   }
 }
 
 void NoteBookTab::close()
 {
-  if (mapstorage->modified)
+  if (mapstorage->getModified())
   {
     Gtk::MessageDialog mdialog("<b>Save changes before closing?</b>", true,
         Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE);
@@ -179,7 +192,11 @@
   mapstorage->clear();
   if(mapwinexists)
     {
-      mapwin->update(mapstorage->getEdgeMapList(), mapstorage->getNodeMapList());
+      mapwin->update(
+          mapstorage->getEdgeMapList(NUM),
+          mapstorage->getEdgeMapList(STR),
+          mapstorage->getNodeMapList(NUM),
+          mapstorage->getNodeMapList(STR));
     }
   title_changed("unsaved file");
 }
@@ -209,23 +226,23 @@
   return mapstorage->getActiveNodeMap(prop);
 }
 
-void NoteBookTab::registerNewEdgeMap(std::string mapname)
+void NoteBookTab::registerNewEdgeMap(std::string mapname, MapValue::Type type)
 {
   if(mapwinexists)
     {
-      mapwin->registerNewEdgeMap(mapname);
+      mapwin->registerNewEdgeMap(mapname, type);
     }
 }
 
-void NoteBookTab::registerNewNodeMap(std::string mapname)
+void NoteBookTab::registerNewNodeMap(std::string mapname, MapValue::Type type)
 {
   if(mapwinexists)
     {
-      mapwin->registerNewNodeMap(mapname);
+      mapwin->registerNewNodeMap(mapname, type);
     }
   if(epswinexists)
     {
-      epswin->registerNewNodeMap(mapname);
+      epswin->registerNewNodeMap(mapname, type);
     }
 }
 
@@ -233,7 +250,12 @@
 {
   if(!mapwinexists)
     {
-      mapwin=new MapWin("Map Setup - "+name, mapstorage->getEdgeMapList(), mapstorage->getNodeMapList(), *this);
+      mapwin=new MapWin("Map Setup - "+name,
+          mapstorage->getEdgeMapList(NUM),
+          mapstorage->getEdgeMapList(STR),
+          mapstorage->getNodeMapList(NUM),
+          mapstorage->getNodeMapList(STR),
+          *this);
       mapst2mapwin=mapstorage->signal_map_win_ch().connect(sigc::mem_fun(*mapwin, &MapWin::changeEntry));
       mapwin->show();
       mapwinexists=true;
@@ -244,7 +266,7 @@
 {
   if(!epswinexists)
     {
-      epswin=new EpsWin("Export to EPS - "+name, mapstorage->getNodeMapList());
+      epswin=new EpsWin("Export to EPS - "+name, mapstorage->getNodeMapList(NUM), mapstorage->getNodeMapList(STR));
       epswin->show();
       epswinexists=true;
       epswin->signal_eps_details_ch().connect(sigc::mem_fun(*this, &NoteBookTab::exportGraphToEPS));
@@ -263,9 +285,9 @@
       mapstorage->get_design_data(attraction, propulsation, iterations);
       designwin=new DesignWin("Design Setup - "+name, attraction, propulsation, iterations);
 
-      designwin->signal_attraction().connect(sigc::mem_fun(mapstorage, &MapStorage::set_attraction));
-      designwin->signal_propulsation().connect(sigc::mem_fun(mapstorage, &MapStorage::set_propulsation));
-      designwin->signal_iteration().connect(sigc::mem_fun(mapstorage, &MapStorage::set_iteration));
+      designwin->signal_attraction().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_attraction));
+      designwin->signal_propulsation().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_propulsation));
+      designwin->signal_iteration().connect(sigc::mem_fun(*mapstorage, &MapStorage::set_iteration));
       designwin->close_run().connect(sigc::mem_fun(*gd_canvas, &GraphDisplayerCanvas::reDesignGraph));
 
       designwin->signal_delete_event().connect(sigc::mem_fun(*this, &NoteBookTab::closeDesignWin));

Modified: glemon/trunk/nbtab.h
==============================================================================
--- glemon/trunk/nbtab.h	(original)
+++ glemon/trunk/nbtab.h	Wed Jan  2 22:03:09 2008
@@ -27,6 +27,7 @@
 
 #include <libgnomecanvasmm.h>
 #include <libgnomecanvasmm/polygon.h>
+#include "map_value.h"
 
 ///One tab in the Notebook that is placed in the main window (\ref MainWin).
 
@@ -172,7 +173,7 @@
   ///a function with the same name and same parameterin \ref MapWin.
   ///This call-forwarder function is needed, because \ref Mapstorage does not know \ref MapWin
   ///\param mapname name of new map
-  void registerNewEdgeMap(std::string mapname);
+  void registerNewEdgeMap(std::string mapname, MapValue::Type type);
 
   ///Registers recently created nodemap in \ref MapWin.
 
@@ -181,7 +182,7 @@
   ///a function with the same name and same parameter in \ref MapWin.
   ///This call-forwarder function is needed, because \ref Mapstorage does not know \ref MapWin
   ///\param mapname name of new map
-  void registerNewNodeMap(std::string mapname);
+  void registerNewNodeMap(std::string mapname, MapValue::Type type);
 
   ///Pops up and registrates the \ref MapWin of \ref NoteBookTab.
   

Modified: glemon/trunk/new_map_win.cc
==============================================================================
--- glemon/trunk/new_map_win.cc	(original)
+++ glemon/trunk/new_map_win.cc	Wed Jan  2 22:03:09 2008
@@ -29,7 +29,7 @@
   return true;
 }
 
-NewMapWin::NewMapWin(const std::string& title, NoteBookTab & mw, bool itisedge, bool edgenode):Gtk::Dialog(title, true, true),mytab(mw),node("Create NodeMap"),edge("Create EdgeMap")
+NewMapWin::NewMapWin(const std::string& title, NoteBookTab & mw, bool itisedge, bool edgenode, MapType type):Gtk::Dialog(title, true, true),mytab(mw),node("Create NodeMap"),edge("Create EdgeMap"),map_type(type)
 {
   set_default_size(200, 50);
 
@@ -38,7 +38,7 @@
   Gtk::VBox * vbox=get_vbox();
 
   //entries
-  table=new Gtk::Table(3, 2, false);
+  table=new Gtk::Table(5, 2, false);
 
   label=new Gtk::Label;
   label->set_text("Name of new map:");
@@ -47,33 +47,45 @@
   (*table).attach(*label,0,1,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
   (*table).attach(name,1,2,0,1,Gtk::SHRINK,Gtk::SHRINK,10,3);
 
+  lblType.set_label("Element type:");
+  if (map_type & NUM)
+    cbType.append_text("Numeric");
+  if (map_type & STR)
+    cbType.append_text("String");
+  cbType.set_active(0);
+
+  (*table).attach(lblType,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
+  (*table).attach(cbType, 1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
+
   label=new Gtk::Label;
   label->set_text("Default value in the map:");
   default_value.set_text("0");
 
-  (*table).attach(*label,0,1,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
-  (*table).attach(default_value,1,2,1,2,Gtk::SHRINK,Gtk::SHRINK,10,3);
+  (*table).attach(*label,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
+  (*table).attach(default_value,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
 
   //node vs. edge map selector
   Gtk::RadioButton::Group group = node.get_group();
   edge.set_group(group);
-  
+
   if(edgenode)
+  {
+    (*table).attach(node,0,1,3,4,Gtk::SHRINK,Gtk::SHRINK,10,3);
+    (*table).attach(edge,1,2,3,4,Gtk::SHRINK,Gtk::SHRINK,10,3);
+  }
+  else
+  {
+    if(itisedge)
     {
-      (*table).attach(node,0,1,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
-      (*table).attach(edge,1,2,2,3,Gtk::SHRINK,Gtk::SHRINK,10,3);
+      edge.set_active();
     }
-  else
+    else
     {
-      if(itisedge)
-	{
-	  edge.set_active();
-	}
-      else
-	{
-	  node.set_active();
-	}
+      node.set_active();
     }
+  }
+
+  (*table).attach(lblErrorMsg,0,2,4,5,Gtk::SHRINK,Gtk::SHRINK,10,3);
 
   vbox->pack_start(*table);
 
@@ -84,214 +96,242 @@
 
 }
 
-void NewMapWin::on_response(int response_id)
+void NewMapWin::setErrorMsg(const Glib::ustring& msg)
 {
-  if(response_id==Gtk::RESPONSE_OK)
+  lblErrorMsg.set_markup("<i><small>" + msg + "</small></i>");
+}
+
+std::vector<double>* NewMapWin::evaluate_expr(const std::string polishform, bool itisedge)
+{
+  MapStorage& ms = *mytab.mapstorage;
+
+  std::vector<double>* ret = new std::vector<double>;
+  std::stack<double> polishstack;
+
+  if (itisedge)
+  {
+    for(EdgeIt k(ms.graph); k!=INVALID; ++k)
+    {
+      for(int i=0;i<(int)polishform.size();i++)
+      {
+        double op1=0, op2=0;
+        bool operation=true;
+        switch(polishform[i])
+        {
+          case '+':
+          case '-':
+          case '/':
+          case '*':
+            op1=polishstack.top();
+            polishstack.pop();
+            op2=polishstack.top();
+            polishstack.pop();
+            break;
+          default:
+            //substitute variable
+            std::vector<std::string> maps = ms.getEdgeMapList(NUM);
+            bool itisvar=(std::find(maps.begin(), maps.end(), ch2var[ polishform[i] ]) != maps.end());
+            if(itisvar)
+            {
+              polishstack.push(ms.get(ch2var[ polishform[i] ], k));
+            }
+            else
+            {
+              polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
+            }
+            operation=false;
+            break;
+        }
+        if(operation)
+        {
+          double res;
+          switch(polishform[i])
+          {
+            case '+':
+              res=op1+op2;
+              break;
+            case '-':
+              res=op2-op1;
+              break;
+            case '/':
+              res=op2/op1;
+              break;
+            case '*':
+              res=op1*op2;
+              break;
+            default:
+              std::cout << "How could we get here?" << std::endl;
+              break;
+          }
+          polishstack.push(res);
+        }
+      }//foreach letter in polishform
+      ret->push_back(polishstack.top());
+    }//foreach edge
+  }
+  else
+  {
+    for(NodeIt k(ms.graph); k!=INVALID; ++k)
     {
-      double def_val=0;
+      for(int i=0;i<(int)polishform.size();i++)
+      {
+        double op1=0, op2=0;
+        bool operation=true;
+        switch(polishform[i])
+        {
+          case '+':
+          case '-':
+          case '/':
+          case '*':
+            op1=polishstack.top();
+            polishstack.pop();
+            op2=polishstack.top();
+            polishstack.pop();
+            break;
+          default:
+            //substitute variable
+            std::vector<std::string> maps = ms.getNodeMapList(NUM);
+            bool itisvar=(std::find(maps.begin(), maps.end(), ch2var[ polishform[i] ]) != maps.end());
+            if(itisvar)
+            {
+              polishstack.push(ms.get(ch2var[ polishform[i] ], k));
+            }
+            else
+            {
+              polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
+            }
+            operation=false;
+            break;
+        }
+        if(operation)
+        {
+          double res;
+          switch(polishform[i])
+          {
+            case '+':
+              res=op1+op2;
+              break;
+            case '-':
+              res=op2-op1;
+              break;
+            case '/':
+              res=op2/op1;
+              break;
+            case '*':
+              res=op1*op2;
+              break;
+            default:
+              std::cout << "How could we get here?" << std::endl;
+              break;
+          }
+          polishstack.push(res);
+        }
+      }//foreach letter in polishform
+      ret->push_back(polishstack.top());
+    }//foreach edge
+  }
+  return ret;
+}
 
-      //get and formulate text
-      std::string def_val_str=default_value.get_text();
+void NewMapWin::on_response(int response_id)
+{
+  MapStorage& ms = *mytab.mapstorage;
 
-      bool only_nums=true;
-      for(int i=0;i<(int)def_val_str.size() && only_nums;i++)
-	{
-	  if( def_val_str[i]<'0' || def_val_str[i]>'9' )
-	    {
-	      only_nums=false;
-	    }
-	}
-      std::string polishform;
-
-      if(only_nums)
-	{
-	  def_val=atof(def_val_str.c_str());
-	}
+  if(response_id==Gtk::RESPONSE_OK)
+  {
+    std::string map_name = name.get_text();
+    std::string def_val = default_value.get_text();
+
+    if (map_name.empty())
+    {
+      setErrorMsg("No map name given.");
+      return;
+    }
+
+    // check whether the map already exists
+    if (edge.get_active())
+    {
+      if (ms.edgeMapExists(map_name))
+      {
+        setErrorMsg("Map '" + map_name + "' already exists.");
+        return;
+      }
+    }
+    else
+    {
+      if (ms.nodeMapExists(map_name))
+      {
+        setErrorMsg("Map '" + map_name + "' already exists.");
+        return;
+      }
+    }
+
+    Glib::ustring text = cbType.get_active_text();
+    if (text == "Numeric")
+    {
+      double d;
+      char *endptr;
+      d = strtod(def_val.c_str(), &endptr);
+      if (def_val.c_str() + def_val.length() == endptr)
+      {
+        // the full string was a number
+        if (edge.get_active())
+          ms.createEdgeMap(map_name, MapValue::NUMERIC,
+              MapValue(d));
+        else
+          ms.createNodeMap(map_name, MapValue::NUMERIC,
+              MapValue(d));
+      }
+      else
+      {
+        // let't try to evaluate the string as an arithmetic expression
+        std::string polishform =
+          string2Polishform(def_val, edge.get_active());
+        if (polishform.empty())
+          return;
+        std::vector<double>* values =
+          evaluate_expr(polishform, edge.get_active());
+        if (edge.get_active())
+        {
+          ms.createEdgeMap(map_name, MapValue::NUMERIC,
+              MapValue(0.0));
+          std::vector<double>::const_iterator vit = values->begin();
+          for (EdgeIt it(ms.graph); it != INVALID; ++it)
+          {
+            ms.set(map_name, it, MapValue(*vit));
+            ++vit;
+          }
+        }
+        else
+        {
+          ms.createNodeMap(map_name, MapValue::NUMERIC,
+              MapValue(0.0));
+          std::vector<double>::const_iterator vit = values->begin();
+          for (NodeIt it(ms.graph); it != INVALID; ++it)
+          {
+            ms.set(map_name, it, MapValue(*vit));
+            ++vit;
+          }
+        }
+        delete values;
+      }
+    }
+    else if (text == "String")
+    {
+      if (edge.get_active())
+        ms.createEdgeMap(map_name, MapValue::STRING,
+            MapValue(def_val));
       else
-	{
-	  polishform=string2Polishform(def_val_str,edge.get_active());
-	}
-
-      //get name of text
-      std::string mapname=name.get_text();
-      
-      if(!mapname.empty()&&(!polishform.empty()||only_nums))
-	{
-	  int abortion=0;
-	  if(edge.get_active())
-	    {
-	      //create the new map
-	      Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mytab.mapstorage->graph, def_val);
-	      
-	      if(!only_nums)
-		{
-		  std::stack<double> polishstack;
-		  
-		  for(EdgeIt k(mytab.mapstorage->graph); k!=INVALID; ++k)
-		    {
-		      for(int i=0;i<(int)polishform.size();i++)
-			{
-			  double op1=0, op2=0;
-			  bool operation=true;
-			  switch(polishform[i])
-			    {
-			    case '+':
-			    case '-':
-			    case '/':
-			    case '*':
-			      op1=polishstack.top();
-			      polishstack.pop();
-			      op2=polishstack.top();
-			      polishstack.pop();
-			      break;
-			    default:
-			      //substitute variable
-			      std::map< std::string,Graph::EdgeMap<double> * > ems=mytab.mapstorage->edgemap_storage;
-			      bool itisvar=(ems.find(ch2var[ polishform[i] ])!=ems.end());
-			      if(itisvar)
-				{
-				  polishstack.push( (*(mytab.mapstorage->edgemap_storage[ ch2var[ polishform[i] ] ]))[k]);
-				}
-			      else
-				{
-				  polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
-				}
-			      operation=false;
-			      break;
-			    }
-			  if(operation)
-			    {
-			      double res;
-			      switch(polishform[i])
-				{
-				case '+':
-				  res=op1+op2;
-				  break;
-				case '-':
-				  res=op2-op1;
-				  break;
-				case '/':
-				  res=op2/op1;
-				  break;
-				case '*':
-				  res=op1*op2;
-				  break;
-				default:
-				  std::cout << "How could we get here?" << std::endl;
-				  break;
-				}
-			      polishstack.push(res);
-			    }
-			}//foreach letter in polishform
-		      (*emptr)[k]=polishstack.top(); 
-		    }//foreach edge
-		}//!only_nums
-
-	      //if addition was not successful addEdgeMap returns one.
-	      //cause can be that there is already a map named like the new one
-	      if(mytab.mapstorage->addEdgeMap(mapname, emptr, def_val))
-		{
-		  abortion=1;
-		}
-
-	      //add it to the list of the displayable maps
-	      //furthermore it is done by signals
-	      //mytab.registerNewEdgeMap(mapname);
-
-	      //display it
-	      //gdc.changeEdgeText(mapname);
-	    }
-	  else //!edge.get_active()
-	    {
-	      //create the new map
-	      Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mytab.mapstorage->graph, def_val);
-
-	      if(!only_nums)
-		{
-		  std::stack<double> polishstack;
-  
-		  for(NodeIt k(mytab.mapstorage->graph); k!=INVALID; ++k)
-		    {
-		      for(int i=0;i<(int)polishform.size();i++)
-			{
-			  double op1=0, op2=0;
-			  bool operation=true;
-			  switch(polishform[i])
-			    {
-			    case '+':
-			    case '-':
-			    case '/':
-			    case '*':
-			      op1=polishstack.top();
-			      polishstack.pop();
-			      op2=polishstack.top();
-			      polishstack.pop();
-			      break;
-			    default:
-			      std::map< std::string,Graph::NodeMap<double> * > nms=mytab.mapstorage->nodemap_storage;
-			      bool itisvar=(nms.find(ch2var[ polishform[i] ])!=nms.end());
-			      if(itisvar)
-				{
-				  polishstack.push( (*(mytab.mapstorage->nodemap_storage[ ch2var[ polishform[i] ] ]))[k]);
-				}
-			      else
-				{
-				  polishstack.push(atof(ch2var[ polishform[i] ].c_str()));
-				}
-			      operation=false;
-			      break;
-			    }
-			  if(operation)
-			    {
-			      double res;
-			      switch(polishform[i])
-				{
-				case '+':
-				  res=op1+op2;
-				  break;
-				case '-':
-				  res=op2-op1;
-				  break;
-				case '/':
-				  res=op2/op1;
-				  break;
-				case '*':
-				  res=op1*op2;
-				  break;
-				default:
-				  std::cout << "How could we get here?" << std::endl;
-				  break;
-				}
-			      polishstack.push(res);
-			    }
-			}
-		      (*emptr)[k]=polishstack.top(); 
-		    }
-		}
-	      //if addition was not successful addNodeMap returns one.
-	      //cause can be that there is already a map named like the new one
-	      if(mytab.mapstorage->addNodeMap(mapname,emptr, def_val))
-		{
-		  abortion=1;
-		}
-
-	      //add it to the list of the displayable maps
-	      //furthermore it is done by signals
-	      //mytab.registerNewNodeMap(mapname);
-
-	      //display it
-	      //gdc.changeNodeText(mapname);
-	    }
-	  if(!abortion)
-	    {
-	      name.set_text("");
-	      default_value.set_text("0");
-	      edge.show();
-	      node.show();
-	      hide();
-	    }
-	}
+        ms.createNodeMap(map_name, MapValue::STRING,
+            MapValue(def_val));
     }
+
+    name.set_text("");
+    default_value.set_text("0");
+    edge.show();
+    node.show();
+    hide();
+  }
 }
 
 
@@ -308,128 +348,128 @@
   char index='a';
 
   for(int i=0;(valid_entry&&(i<(int)rawcommand.size()));i++)
+  {
+    switch(rawcommand[i])
     {
-      switch(rawcommand[i])
-	{
-	case '+':
-	case '-':
-	case '*':
-	case '/':
-	case ')':
-	case '(':
- 	  if(!variable.empty())
-	    {
-	      valid_entry=validVariable(variable, itisedge);
-	      ch2var[index]=variable;
-	      command+=index;
-	      index++;
-	      variable.erase(0,variable.size());	  
-	    }
-	  command+=rawcommand[i];
-	  break;
-	default:
-	  variable+=rawcommand[i];
-	  break;
-	}
+      case '+':
+      case '-':
+      case '*':
+      case '/':
+      case ')':
+      case '(':
+        if(!variable.empty())
+        {
+          valid_entry=validVariable(variable, itisedge);
+          ch2var[index]=variable;
+          command+=index;
+          index++;
+          variable.erase(0,variable.size());	  
+        }
+        command+=rawcommand[i];
+        break;
+      default:
+        variable+=rawcommand[i];
+        break;
     }
+  }
 
   if(!variable.empty()&&valid_entry)
-    {
-      valid_entry=validVariable(variable, itisedge);
-      ch2var[index]=variable;
-      command+=index;
-      index++;
-      variable.erase(0,variable.size());	  
-    }
+  {
+    valid_entry=validVariable(variable, itisedge);
+    ch2var[index]=variable;
+    command+=index;
+    index++;
+    variable.erase(0,variable.size());	  
+  }
 
   if(valid_entry)
-    {
-      unsigned int pr=10000;
-      bool prevmult=false;
-      unsigned int prev_change=pr;
-      unsigned int prev_br=pr;
-      int counter=0;
-      std::string comm_nobr="";
-      std::vector<unsigned int> p;
-      p.resize(counter+1);
-      
-      //limits
-      //6 brackets embedded
-      //100 operation in a row from the same priority
-      
-      for(int i=0;i<(int)command.size();i++)
-	{
-	  bool put_in_string=true;
-	  switch(command[i])
-	    {
-	    case '(':
-	      pr=prev_br+10000;
-	      prev_br=pr;
-	      prevmult=false;
-	      put_in_string=false;
-	      break;
-	    case ')':
-	      pr=prev_br-10000;
-	      prev_br=pr;
-	      prevmult=false;
-	      put_in_string=false;
-	      break;
-	    case '+':
-	    case '-':
-	      if(prevmult)
-		{
-		  pr=prev_change;
-		}
-	      p[counter]=pr;
-	      pr-=100;
-
-	      prevmult=false;
-	      break;
-	    case '/':
-	    case '*':
-	      if(!prevmult)
-		{
-		  prev_change=pr;
-		  pr+=200;
-		  pr-=1;
-		}
-	      p[counter]=pr;
-	      pr-=1;
-	      prevmult=true;
-	      break;
-	    default:
-	      p[counter]=65000;
-	      break;
-	    }
-	  if(put_in_string)
-	    {
-	      counter++;
-	      p.resize(counter+1);
-	      comm_nobr=comm_nobr+command[i];
-	    }
-	}
+  {
+    unsigned int pr=10000;
+    bool prevmult=false;
+    unsigned int prev_change=pr;
+    unsigned int prev_br=pr;
+    int counter=0;
+    std::string comm_nobr="";
+    std::vector<unsigned int> p;
+    p.resize(counter+1);
+
+    //limits
+    //6 brackets embedded
+    //100 operation in a row from the same priority
+
+    for(int i=0;i<(int)command.size();i++)
+    {
+      bool put_in_string=true;
+      switch(command[i])
+      {
+        case '(':
+          pr=prev_br+10000;
+          prev_br=pr;
+          prevmult=false;
+          put_in_string=false;
+          break;
+        case ')':
+          pr=prev_br-10000;
+          prev_br=pr;
+          prevmult=false;
+          put_in_string=false;
+          break;
+        case '+':
+        case '-':
+          if(prevmult)
+          {
+            pr=prev_change;
+          }
+          p[counter]=pr;
+          pr-=100;
+
+          prevmult=false;
+          break;
+        case '/':
+        case '*':
+          if(!prevmult)
+          {
+            prev_change=pr;
+            pr+=200;
+            pr-=1;
+          }
+          p[counter]=pr;
+          pr-=1;
+          prevmult=true;
+          break;
+        default:
+          p[counter]=65000;
+          break;
+      }
+      if(put_in_string)
+      {
+        counter++;
+        p.resize(counter+1);
+        comm_nobr=comm_nobr+command[i];
+      }
+    }
 
-      tree_node * root=weightedString2Tree(comm_nobr, p, 0);
+    tree_node * root=weightedString2Tree(comm_nobr, p, 0);
 
-      std::string polishform=postOrder(root);
+    std::string polishform=postOrder(root);
 
-      deleteTree(root);
+    deleteTree(root);
 
-      return polishform;
-    }
+    return polishform;
+  }
   return "";
 }
 
 void NewMapWin::deleteTree(NewMapWin::tree_node * node)
 {
   if(node->left_child!=NULL)
-    {
-      deleteTree(node->left_child);
-    }
+  {
+    deleteTree(node->left_child);
+  }
   if(node->right_child!=NULL)
-    {
-      deleteTree(node->right_child);
-    }
+  {
+    deleteTree(node->right_child);
+  }
   delete node;
 }
 
@@ -438,25 +478,25 @@
   unsigned int min=p[offset];
   int minplace=0;
   for(int i=0;i<(int)to_tree.size();i++)
+  {
+    if(min>p[offset+i])
     {
-      if(min>p[offset+i])
-	{
-	  min=p[offset+i];
-	  minplace=i;
-	}
+      min=p[offset+i];
+      minplace=i;
     }
+  }
   tree_node * act_node=new tree_node;
   act_node->ch=to_tree[minplace];
   if(to_tree.size()>=3)
-    {
-      act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
-      act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
-    }
+  {
+    act_node->left_child=weightedString2Tree(to_tree.substr(0,minplace), p, offset);
+    act_node->right_child=weightedString2Tree(to_tree.substr(minplace+1,to_tree.size()-minplace-1), p, offset+minplace+1);
+  }
   else
-    {
-      act_node->left_child=NULL;
-      act_node->right_child=NULL;
-    }
+  {
+    act_node->left_child=NULL;
+    act_node->right_child=NULL;
+  }
   return act_node;
 }
 
@@ -464,56 +504,62 @@
 {
   std::string subtree_to_string;
   if(subtree->left_child)
-    {
-      subtree_to_string=postOrder(subtree->left_child);
-    }
+  {
+    subtree_to_string=postOrder(subtree->left_child);
+  }
   if(subtree->right_child)
-    {
-      subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
-    }
+  {
+    subtree_to_string=subtree_to_string+postOrder(subtree->right_child);
+  }
   subtree_to_string=subtree_to_string+subtree->ch;
   return subtree_to_string;
 }
 
 bool NewMapWin::validVariable(std::string variable, bool itisedge)
 {
+  MapStorage& ms = *mytab.mapstorage;
+
   bool cancel;
   //is it mapname?
   if(itisedge)
-    {
-      cancel=(mytab.mapstorage->edgemap_storage.find(variable)==mytab.mapstorage->edgemap_storage.end());
-    }
+  {
+    std::vector<std::string> edge_maps =
+      ms.getEdgeMapList(NUM);
+    cancel=(std::find(edge_maps.begin(), edge_maps.end(), variable)==edge_maps.end());
+  }
   else
-    {
-      cancel=(mytab.mapstorage->nodemap_storage.find(variable)==mytab.mapstorage->nodemap_storage.end());
-    }
+  {
+    std::vector<std::string> node_maps =
+      ms.getNodeMapList(NUM);
+    cancel=(std::find(node_maps.begin(), node_maps.end(), variable)==node_maps.end());
+  }
   //maybe it is number
   int point_num=0;
   if(cancel)
-    {
-      cancel=false;
-      for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
-	{
-	  if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
-	    {
-	      cancel=true;
-	    }
-	  else
-	    {
-	      if(variable[j]=='.')
-		{
-		  point_num++;
-		  if(point_num>1)
-		    {
-		      cancel=true;
-		    }
-		}
-	    }
-	}
+  {
+    cancel=false;
+    for(int j=0;(!cancel)&&(j<(int)variable.size());j++)
+    {
+      if(((variable[j]<'0')||(variable[j]>'9'))&&(variable[j]!='.'))
+      {
+        cancel=true;
+      }
+      else
+      {
+        if(variable[j]=='.')
+        {
+          point_num++;
+          if(point_num>1)
+          {
+            cancel=true;
+          }
+        }
+      }
     }
+  }
   if(cancel)
-    {
-      return false;
-    }
+  {
+    return false;
+  }
   return true;
 }

Modified: glemon/trunk/new_map_win.h
==============================================================================
--- glemon/trunk/new_map_win.h	(original)
+++ glemon/trunk/new_map_win.h	Wed Jan  2 22:03:09 2008
@@ -35,6 +35,15 @@
   ///The \ref NoteBookTab in which the new map has to be placed.
   NoteBookTab & mytab;
 
+  MapType map_type;
+  Gtk::Label lblType;
+  Gtk::ComboBoxText cbType;
+
+  Gtk::Label lblErrorMsg;
+  void setErrorMsg(const Glib::ustring& msg);
+
+  std::vector<double>* evaluate_expr(const std::string polishform, bool itisedge);
+
 public:
 
   ///Struct to be able to evaluate expressions.
@@ -59,7 +68,7 @@
 
   ///It creates the widgets shown in
   ///NewMapWin.
-  NewMapWin(const std::string& title, NoteBookTab &, bool itisedge=true, bool edgenode=true);
+  NewMapWin(const std::string& title, NoteBookTab &, bool itisedge=true, bool edgenode=true, MapType type = ALL);
 
   ///Callback function for OK button. It creates the map.
   

Added: glemon/trunk/save_details_dialog.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/save_details_dialog.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,16 @@
+#include "save_details_dialog.h"
+#include <gtkmm/stock.h>
+
+SaveDetailsDialog::SaveDetailsDialog(MapStorage *ms) :
+  Gtk::Dialog("Save Details", true),
+  SaveDetails(ms)
+{
+  set_size_request(400, -1);
+
+  Gtk::VBox* pVBox = get_vbox();
+  pVBox->pack_start(SaveDetails, Gtk::PACK_SHRINK);
+
+  add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
+
+  show_all_children();
+}

Added: glemon/trunk/save_details_dialog.h
==============================================================================
--- (empty file)
+++ glemon/trunk/save_details_dialog.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,15 @@
+#ifndef SAVE_DETAILS_DIALOG
+#define SAVE_DETAILS_DIALOG
+
+#include <gtkmm/dialog.h>
+#include "save_details_widget.h"
+
+class SaveDetailsDialog : public Gtk::Dialog
+{
+  private:
+    SaveDetailsWidget SaveDetails;
+  public:
+    SaveDetailsDialog(MapStorage*);
+};
+
+#endif

Added: glemon/trunk/save_details_widget.cc
==============================================================================
--- (empty file)
+++ glemon/trunk/save_details_widget.cc	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,616 @@
+#include "save_details_widget.h"
+#include "mapstorage.h"
+
+SaveDetailsWidget::SaveDetailsWidget(MapStorage* ms) :
+  pMapStorage(ms)
+{
+  Gtk::Notebook* nb = Gtk::manage(new Gtk::Notebook);
+  pack_start(*nb, Gtk::PACK_EXPAND_WIDGET);
+
+  nb->set_tab_pos(Gtk::POS_TOP);
+
+  Gtk::VBox* vbNodeMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbNodeMaps->set_border_width(12);
+
+  Gtk::VBox* vbEdgeMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbEdgeMaps->set_border_width(12);
+
+  Gtk::VBox* vbSpecMaps = Gtk::manage(new Gtk::VBox(false, 18));
+  vbSpecMaps->set_border_width(12);
+
+  Gtk::VBox* vbGuiSect = Gtk::manage(new Gtk::VBox(false, 18));
+  vbGuiSect->set_border_width(12);
+
+  nb->append_page(*vbSpecMaps, "Special Maps");
+  nb->append_page(*vbNodeMaps, "Node Maps");
+  nb->append_page(*vbEdgeMaps, "Edge Maps");
+  nb->append_page(*vbGuiSect, "GUI Section");
+
+  // child widgets of vbSpecMaps
+
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* lblNodeCoordMap =
+      Gtk::manage(new Gtk::Label("<b>Node Coordinates</b>"));
+    lblNodeCoordMap->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    lblNodeCoordMap->set_use_markup();
+    box1->pack_start(*lblNodeCoordMap, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox);
+    box2->pack_start(*box3, Gtk::PACK_SHRINK);
+
+    rbNodeCoordGuiSection.set_label("Save to GUI section");
+    rbNodeCoordNodesetSection.set_label("Save to Nodeset section");
+    Gtk::RadioButtonGroup group = rbNodeCoordGuiSection.get_group();
+    rbNodeCoordNodesetSection.set_group(group);
+
+    box3->pack_start(rbNodeCoordGuiSection, Gtk::PACK_SHRINK);
+    box3->pack_start(rbNodeCoordNodesetSection, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box4 = Gtk::manage(new Gtk::HBox);
+    box3->pack_start(*box4, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill2 = Gtk::manage(new Gtk::Label("    "));
+    box4->pack_start(*fill2, Gtk::PACK_SHRINK);
+
+    Gtk::Table* table1 = Gtk::manage(new Gtk::Table(3, 2));
+    box4->pack_start(*table1, Gtk::PACK_SHRINK);
+
+    rbNodeCoordOneMap.set_label("As one map");
+    rbNodeCoordTwoMaps.set_label("As two maps");
+    group = rbNodeCoordOneMap.get_group();
+    rbNodeCoordTwoMaps.set_group(group);
+
+    table1->attach(rbNodeCoordOneMap, 0, 1, 0, 1);
+    table1->attach(rbNodeCoordTwoMaps, 0, 1, 1, 2);
+    table1->attach(entNodeCoordsOneMap, 1, 2, 0, 1);
+    table1->attach(entNodeCoordsTwoMaps1, 1, 2, 1, 2);
+    table1->attach(entNodeCoordsTwoMaps2, 1, 2, 2, 3);
+
+    switch (pMapStorage->getNodeCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        rbNodeCoordGuiSection.set_active();
+        rbNodeCoordOneMap.set_sensitive(false);
+        rbNodeCoordTwoMaps.set_sensitive(false);
+        entNodeCoordsOneMap.set_sensitive(false);
+        entNodeCoordsTwoMaps1.set_sensitive(false);
+        entNodeCoordsTwoMaps2.set_sensitive(false);
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        rbNodeCoordNodesetSection.set_active();
+        rbNodeCoordOneMap.set_sensitive(true);
+        rbNodeCoordTwoMaps.set_sensitive(true);
+        switch (pMapStorage->getNodeCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            rbNodeCoordOneMap.set_active();
+            entNodeCoordsOneMap.set_sensitive(true);
+            entNodeCoordsTwoMaps1.set_sensitive(false);
+            entNodeCoordsTwoMaps2.set_sensitive(false);
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            rbNodeCoordTwoMaps.set_active();
+            entNodeCoordsOneMap.set_sensitive(false);
+            entNodeCoordsTwoMaps1.set_sensitive(true);
+            entNodeCoordsTwoMaps2.set_sensitive(true);
+            break;
+        }
+        break;
+    }
+
+    entNodeCoordsOneMap.set_text(pMapStorage->getNodeCoordsOneMapName());
+    entNodeCoordsTwoMaps1.set_text(pMapStorage->getNodeCoordsTwoMaps1Name());
+    entNodeCoordsTwoMaps2.set_text(pMapStorage->getNodeCoordsTwoMaps2Name());
+
+    entNodeCoordsOneMap.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsOneMapName));
+    entNodeCoordsTwoMaps1.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsTwoMaps1Name));
+    entNodeCoordsTwoMaps2.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordsTwoMaps2Name));
+
+    rbNodeCoordGuiSection.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordSaveDestChanged));
+    rbNodeCoordNodesetSection.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordSaveDestChanged));
+    rbNodeCoordOneMap.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordMapNumChanged));
+    rbNodeCoordTwoMaps.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeCoordMapNumChanged));
+  }
+
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbSpecMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* lblArrowCoordMap =
+      Gtk::manage(new Gtk::Label("<b>Arrow Coordinates</b>"));
+    lblArrowCoordMap->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    lblArrowCoordMap->set_use_markup();
+    box1->pack_start(*lblArrowCoordMap, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox);
+    box2->pack_start(*box3, Gtk::PACK_SHRINK);
+
+    rbArrowCoordGuiSection.set_label("Save to GUI section");
+    rbArrowCoordEdgesetSection.set_label("Save to Edgeset section");
+    Gtk::RadioButtonGroup group = rbArrowCoordGuiSection.get_group();
+    rbArrowCoordEdgesetSection.set_group(group);
+
+    box3->pack_start(rbArrowCoordGuiSection, Gtk::PACK_SHRINK);
+    box3->pack_start(rbArrowCoordEdgesetSection, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box4 = Gtk::manage(new Gtk::HBox);
+    box3->pack_start(*box4, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill2 = Gtk::manage(new Gtk::Label("    "));
+    box4->pack_start(*fill2, Gtk::PACK_SHRINK);
+
+    Gtk::Table* table1 = Gtk::manage(new Gtk::Table(3, 2));
+    box4->pack_start(*table1, Gtk::PACK_SHRINK);
+
+    rbArrowCoordOneMap.set_label("As one map");
+    rbArrowCoordTwoMaps.set_label("As two maps");
+    group = rbArrowCoordOneMap.get_group();
+    rbArrowCoordTwoMaps.set_group(group);
+
+    table1->attach(rbArrowCoordOneMap, 0, 1, 0, 1);
+    table1->attach(rbArrowCoordTwoMaps, 0, 1, 1, 2);
+    table1->attach(entArrowCoordsOneMap, 1, 2, 0, 1);
+    table1->attach(entArrowCoordsTwoMaps1, 1, 2, 1, 2);
+    table1->attach(entArrowCoordsTwoMaps2, 1, 2, 2, 3);
+
+    switch (pMapStorage->getArrowCoordsSaveDest())
+    {
+      case MapStorage::SpecMapSaveOpts::GUI_SECT:
+        rbArrowCoordGuiSection.set_active();
+        rbArrowCoordOneMap.set_sensitive(false);
+        rbArrowCoordTwoMaps.set_sensitive(false);
+        entArrowCoordsOneMap.set_sensitive(false);
+        entArrowCoordsTwoMaps1.set_sensitive(false);
+        entArrowCoordsTwoMaps2.set_sensitive(false);
+        break;
+      case MapStorage::SpecMapSaveOpts::NESET_SECT:
+        rbArrowCoordEdgesetSection.set_active();
+        rbArrowCoordOneMap.set_sensitive(true);
+        rbArrowCoordTwoMaps.set_sensitive(true);
+        switch (pMapStorage->getArrowCoordsSaveMapNum())
+        {
+          case MapStorage::SpecMapSaveOpts::ONE_MAP:
+            rbArrowCoordOneMap.set_active();
+            entArrowCoordsOneMap.set_sensitive(true);
+            entArrowCoordsTwoMaps1.set_sensitive(false);
+            entArrowCoordsTwoMaps2.set_sensitive(false);
+            break;
+          case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+            rbArrowCoordTwoMaps.set_active();
+            entArrowCoordsOneMap.set_sensitive(false);
+            entArrowCoordsTwoMaps1.set_sensitive(true);
+            entArrowCoordsTwoMaps2.set_sensitive(true);
+            break;
+        }
+        break;
+    }
+
+    entArrowCoordsOneMap.set_text(pMapStorage->getArrowCoordsOneMapName());
+    entArrowCoordsTwoMaps1.set_text(pMapStorage->getArrowCoordsTwoMaps1Name());
+    entArrowCoordsTwoMaps2.set_text(pMapStorage->getArrowCoordsTwoMaps2Name());
+
+    entArrowCoordsOneMap.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsOneMapName));
+    entArrowCoordsTwoMaps1.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsTwoMaps1Name));
+    entArrowCoordsTwoMaps2.signal_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordsTwoMaps2Name));
+
+    rbArrowCoordGuiSection.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordSaveDestChanged));
+    rbArrowCoordEdgesetSection.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordSaveDestChanged));
+    rbArrowCoordOneMap.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordMapNumChanged));
+    rbArrowCoordTwoMaps.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onArrowCoordMapNumChanged));
+  }
+
+  // child widgets of vbGuiSect
+
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbGuiSect->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* lblGuiSectionSave =
+      Gtk::manage(new Gtk::Label("<b>Save Destination</b>"));
+    lblGuiSectionSave->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    lblGuiSectionSave->set_use_markup();
+    box1->pack_start(*lblGuiSectionSave, Gtk::PACK_SHRINK);
+
+    rbLgfFile.set_label("Lgf file");
+    rbConfFile.set_label("Conf file");
+
+    Gtk::RadioButtonGroup group = rbLgfFile.get_group();
+    rbConfFile.set_group(group);
+
+    switch (pMapStorage->getGUIDataSaveLocation())
+    {
+      case MapStorage::LGF_FILE:
+        rbLgfFile.set_active();
+        break;
+      case MapStorage::CONF_FILE:
+        rbConfFile.set_active();
+        break;
+    }
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::VBox* box3 = Gtk::manage(new Gtk::VBox);
+    box2->pack_start(*box3, Gtk::PACK_SHRINK);
+
+    box3->pack_start(rbLgfFile, Gtk::PACK_SHRINK);
+    box3->pack_start(rbConfFile, Gtk::PACK_SHRINK);
+
+    rbLgfFile.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onGuiSectSaveDestChanged));
+    rbConfFile.signal_toggled().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onGuiSectSaveDestChanged));
+  }
+
+  // child widgets of vbNodeMaps
+
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbNodeMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* label1 =
+      Gtk::manage(new Gtk::Label("<b>Save Destination</b>"));
+    label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    label1->set_use_markup();
+    box1->pack_start(*label1, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);
+    box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
+
+    Gtk::ScrolledWindow* swNodeMaps = Gtk::manage(new Gtk::ScrolledWindow);
+    frame->add(*swNodeMaps);
+
+    swNodeMaps->add(twNodeMaps);
+
+    refNodeMapStore = Gtk::ListStore::create(NodeMapColumns);
+
+    std::vector<std::string> node_maps = pMapStorage->getNodeMapList();
+    for (std::vector<std::string>::const_iterator it = node_maps.begin();
+        it != node_maps.end(); ++it)
+    {
+      Gtk::TreeModel::Row row = *(refNodeMapStore->append());
+      row[NodeMapColumns.colName] = *it;
+      switch (pMapStorage->getNodeMapSaveDest(*it))
+      {
+        case MapStorage::GUI_SECT:
+          row[NodeMapColumns.colSaveToMainSect] = false;
+          row[NodeMapColumns.colSaveToGuiSect] = true;
+          break;
+        case MapStorage::NESET_SECT:
+          row[NodeMapColumns.colSaveToMainSect] = true;
+          row[NodeMapColumns.colSaveToGuiSect] = false;
+          break;
+        case MapStorage::DONT_SAVE:
+          row[NodeMapColumns.colSaveToMainSect] = false;
+          row[NodeMapColumns.colSaveToGuiSect] = false;
+          break;
+      }
+    }
+
+    twNodeMaps.set_model(refNodeMapStore);
+    twNodeMaps.append_column("Name", NodeMapColumns.colName);
+    twNodeMaps.append_column_editable("Nodeset section",
+        NodeMapColumns.colSaveToMainSect);
+    twNodeMaps.append_column_editable("GUI section",
+        NodeMapColumns.colSaveToGuiSect);
+
+    swNodeMaps->set_size_request(-1, 200);
+    swNodeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+
+    refNodeMapStore->signal_row_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onNodeMapRowChanged));
+  }
+
+  // child widgets of vbEdgeMaps
+
+  {
+    Gtk::VBox* box1 = Gtk::manage(new Gtk::VBox(false, 6));
+    vbEdgeMaps->pack_start(*box1, Gtk::PACK_SHRINK);
+
+    Gtk::Label* label1 =
+      Gtk::manage(new Gtk::Label("<b>Save Destination</b>"));
+    label1->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+    label1->set_use_markup();
+    box1->pack_start(*label1, Gtk::PACK_SHRINK);
+
+    Gtk::HBox* box2 = Gtk::manage(new Gtk::HBox);
+    box1->pack_start(*box2, Gtk::PACK_SHRINK);
+
+    Gtk::Label* fill1 = Gtk::manage(new Gtk::Label("    "));
+    box2->pack_start(*fill1, Gtk::PACK_SHRINK);
+
+    Gtk::Frame* frame = Gtk::manage(new Gtk::Frame);
+    box2->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET);
+
+    Gtk::ScrolledWindow* swEdgeMaps = Gtk::manage(new Gtk::ScrolledWindow);
+    frame->add(*swEdgeMaps);
+
+    swEdgeMaps->add(twEdgeMaps);
+
+    refEdgeMapStore = Gtk::ListStore::create(EdgeMapColumns);
+
+    std::vector<std::string> edge_maps = pMapStorage->getEdgeMapList();
+    for (std::vector<std::string>::const_iterator it = edge_maps.begin();
+        it != edge_maps.end(); ++it)
+    {
+      Gtk::TreeModel::Row row = *(refEdgeMapStore->append());
+      row[EdgeMapColumns.colName] = *it;
+      switch (pMapStorage->getEdgeMapSaveDest(*it))
+      {
+        case MapStorage::GUI_SECT:
+          row[EdgeMapColumns.colSaveToMainSect] = false;
+          row[EdgeMapColumns.colSaveToGuiSect] = true;
+          break;
+        case MapStorage::NESET_SECT:
+          row[EdgeMapColumns.colSaveToMainSect] = true;
+          row[EdgeMapColumns.colSaveToGuiSect] = false;
+          break;
+        case MapStorage::DONT_SAVE:
+          row[EdgeMapColumns.colSaveToMainSect] = false;
+          row[EdgeMapColumns.colSaveToGuiSect] = false;
+          break;
+      }
+    }
+
+    twEdgeMaps.set_model(refEdgeMapStore);
+    twEdgeMaps.append_column("Name", EdgeMapColumns.colName);
+    twEdgeMaps.append_column_editable("Edgeset section",
+        EdgeMapColumns.colSaveToMainSect);
+    twEdgeMaps.append_column_editable("GUI section",
+        EdgeMapColumns.colSaveToGuiSect);
+
+    swEdgeMaps->set_size_request(-1, 200);
+    swEdgeMaps->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+
+    refEdgeMapStore->signal_row_changed().connect(
+        sigc::mem_fun(*this, &SaveDetailsWidget::onEdgeMapRowChanged));
+  }
+
+  show_all_children();
+}
+
+void SaveDetailsWidget::onGuiSectSaveDestChanged()
+{
+  if (rbLgfFile.get_active())
+  {
+    pMapStorage->setGUIDataSaveLocation(MapStorage::LGF_FILE);
+  }
+  else if (rbConfFile.get_active())
+  {
+    pMapStorage->setGUIDataSaveLocation(MapStorage::CONF_FILE);
+  }
+}
+
+void SaveDetailsWidget::onEdgeMapRowChanged(const Gtk::TreeModel::Path& path,
+    const Gtk::TreeModel::iterator& iter)
+{
+  Gtk::TreeModel::Row row = *iter;
+  Glib::ustring map_name = row[EdgeMapColumns.colName];
+  if (row[EdgeMapColumns.colSaveToMainSect] &&
+      row[EdgeMapColumns.colSaveToGuiSect])
+  {
+    if (pMapStorage->getEdgeMapSaveDest(map_name) == MapStorage::NESET_SECT)
+    {
+      pMapStorage->setEdgeMapSaveDest(map_name, MapStorage::GUI_SECT);
+      row[EdgeMapColumns.colSaveToMainSect] = false;
+    }
+    else
+    {
+      pMapStorage->setEdgeMapSaveDest(map_name, MapStorage::NESET_SECT);
+      row[EdgeMapColumns.colSaveToGuiSect] = false;
+    }
+  }
+  else if (row[EdgeMapColumns.colSaveToMainSect])
+  {
+    pMapStorage->setEdgeMapSaveDest(map_name, MapStorage::NESET_SECT);
+  }
+  else if (row[EdgeMapColumns.colSaveToGuiSect])
+  {
+    pMapStorage->setEdgeMapSaveDest(map_name, MapStorage::GUI_SECT);
+  }
+  else
+  {
+    pMapStorage->setEdgeMapSaveDest(map_name, MapStorage::DONT_SAVE);
+  }
+}
+
+void SaveDetailsWidget::onNodeMapRowChanged(const Gtk::TreeModel::Path& path,
+    const Gtk::TreeModel::iterator& iter)
+{
+  Gtk::TreeModel::Row row = *iter;
+  Glib::ustring map_name = row[NodeMapColumns.colName];
+  if (row[NodeMapColumns.colSaveToMainSect] &&
+      row[NodeMapColumns.colSaveToGuiSect])
+  {
+    if (pMapStorage->getNodeMapSaveDest(map_name) == MapStorage::NESET_SECT)
+    {
+      pMapStorage->setNodeMapSaveDest(map_name, MapStorage::GUI_SECT);
+      row[NodeMapColumns.colSaveToMainSect] = false;
+    }
+    else
+    {
+      pMapStorage->setNodeMapSaveDest(map_name, MapStorage::NESET_SECT);
+      row[NodeMapColumns.colSaveToGuiSect] = false;
+    }
+  }
+  else if (row[NodeMapColumns.colSaveToMainSect])
+  {
+    pMapStorage->setNodeMapSaveDest(map_name, MapStorage::NESET_SECT);
+  }
+  else if (row[NodeMapColumns.colSaveToGuiSect])
+  {
+    pMapStorage->setNodeMapSaveDest(map_name, MapStorage::GUI_SECT);
+  }
+  else
+  {
+    pMapStorage->setNodeMapSaveDest(map_name, MapStorage::DONT_SAVE);
+  }
+}
+
+void SaveDetailsWidget::onNodeCoordSaveDestChanged()
+{
+  if (rbNodeCoordGuiSection.get_active())
+  {
+    pMapStorage->setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::GUI_SECT);
+    rbNodeCoordOneMap.set_sensitive(false);
+    rbNodeCoordTwoMaps.set_sensitive(false);
+    entNodeCoordsOneMap.set_sensitive(false);
+    entNodeCoordsTwoMaps1.set_sensitive(false);
+    entNodeCoordsTwoMaps2.set_sensitive(false);
+  }
+  else if (rbNodeCoordNodesetSection.get_active())
+  {
+    pMapStorage->setNodeCoordsSaveDest(MapStorage::SpecMapSaveOpts::NESET_SECT);
+    rbNodeCoordOneMap.set_sensitive(true);
+    rbNodeCoordTwoMaps.set_sensitive(true);
+    switch (pMapStorage->getNodeCoordsSaveMapNum())
+    {
+      case MapStorage::SpecMapSaveOpts::ONE_MAP:
+        entNodeCoordsOneMap.set_sensitive(true);
+        entNodeCoordsTwoMaps1.set_sensitive(false);
+        entNodeCoordsTwoMaps2.set_sensitive(false);
+        break;
+      case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+        entNodeCoordsOneMap.set_sensitive(false);
+        entNodeCoordsTwoMaps1.set_sensitive(true);
+        entNodeCoordsTwoMaps2.set_sensitive(true);
+        break;
+    }
+  }
+}
+
+void SaveDetailsWidget::onNodeCoordMapNumChanged()
+{
+  if (rbNodeCoordOneMap.get_active())
+  {
+    pMapStorage->setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::ONE_MAP);
+    entNodeCoordsOneMap.set_sensitive(true);
+    entNodeCoordsTwoMaps1.set_sensitive(false);
+    entNodeCoordsTwoMaps2.set_sensitive(false);
+  }
+  else if (rbNodeCoordTwoMaps.get_active())
+  {
+    pMapStorage->setNodeCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::TWO_MAPS);
+    entNodeCoordsOneMap.set_sensitive(false);
+    entNodeCoordsTwoMaps1.set_sensitive(true);
+    entNodeCoordsTwoMaps2.set_sensitive(true);
+  }
+}
+
+void SaveDetailsWidget::onNodeCoordsOneMapName()
+{
+  pMapStorage->setNodeCoordsOneMapName(entNodeCoordsOneMap.get_text());
+}
+void SaveDetailsWidget::onNodeCoordsTwoMaps1Name()
+{
+  pMapStorage->setNodeCoordsTwoMaps1Name(entNodeCoordsTwoMaps1.get_text());
+}
+void SaveDetailsWidget::onNodeCoordsTwoMaps2Name()
+{
+  pMapStorage->setNodeCoordsTwoMaps2Name(entNodeCoordsTwoMaps2.get_text());
+}
+
+void SaveDetailsWidget::onArrowCoordSaveDestChanged()
+{
+  if (rbArrowCoordGuiSection.get_active())
+  {
+    pMapStorage->setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::GUI_SECT);
+    rbArrowCoordOneMap.set_sensitive(false);
+    rbArrowCoordTwoMaps.set_sensitive(false);
+    entArrowCoordsOneMap.set_sensitive(false);
+    entArrowCoordsTwoMaps1.set_sensitive(false);
+    entArrowCoordsTwoMaps2.set_sensitive(false);
+  }
+  else if (rbArrowCoordEdgesetSection.get_active())
+  {
+    pMapStorage->setArrowCoordsSaveDest(MapStorage::SpecMapSaveOpts::NESET_SECT);
+    rbArrowCoordOneMap.set_sensitive(true);
+    rbArrowCoordTwoMaps.set_sensitive(true);
+    switch (pMapStorage->getArrowCoordsSaveMapNum())
+    {
+      case MapStorage::SpecMapSaveOpts::ONE_MAP:
+        entArrowCoordsOneMap.set_sensitive(true);
+        entArrowCoordsTwoMaps1.set_sensitive(false);
+        entArrowCoordsTwoMaps2.set_sensitive(false);
+        break;
+      case MapStorage::SpecMapSaveOpts::TWO_MAPS:
+        entArrowCoordsOneMap.set_sensitive(false);
+        entArrowCoordsTwoMaps1.set_sensitive(true);
+        entArrowCoordsTwoMaps2.set_sensitive(true);
+        break;
+    }
+  }
+}
+
+void SaveDetailsWidget::onArrowCoordMapNumChanged()
+{
+  if (rbArrowCoordOneMap.get_active())
+  {
+    pMapStorage->setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::ONE_MAP);
+    entArrowCoordsOneMap.set_sensitive(true);
+    entArrowCoordsTwoMaps1.set_sensitive(false);
+    entArrowCoordsTwoMaps2.set_sensitive(false);
+  }
+  else if (rbArrowCoordTwoMaps.get_active())
+  {
+    pMapStorage->setArrowCoordsSaveMapNum(MapStorage::SpecMapSaveOpts::TWO_MAPS);
+    entArrowCoordsOneMap.set_sensitive(false);
+    entArrowCoordsTwoMaps1.set_sensitive(true);
+    entArrowCoordsTwoMaps2.set_sensitive(true);
+  }
+}
+
+void SaveDetailsWidget::onArrowCoordsOneMapName()
+{
+  pMapStorage->setArrowCoordsOneMapName(entArrowCoordsOneMap.get_text());
+}
+void SaveDetailsWidget::onArrowCoordsTwoMaps1Name()
+{
+  pMapStorage->setArrowCoordsTwoMaps1Name(entArrowCoordsTwoMaps1.get_text());
+}
+void SaveDetailsWidget::onArrowCoordsTwoMaps2Name()
+{
+  pMapStorage->setArrowCoordsTwoMaps2Name(entArrowCoordsTwoMaps2.get_text());
+}
+
+SaveDetailsWidget::~SaveDetailsWidget()
+{
+}

Added: glemon/trunk/save_details_widget.h
==============================================================================
--- (empty file)
+++ glemon/trunk/save_details_widget.h	Wed Jan  2 22:03:09 2008
@@ -0,0 +1,86 @@
+#ifndef SAVE_DETAILS_WIDGET
+#define SAVE_DETAILS_WIDGET
+
+#include <gtkmm/box.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/treemodel.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/scrolledwindow.h>
+
+class MapStorage;
+
+class SaveDetailsWidget : public Gtk::VBox
+{
+  public:
+    struct MapModelColumns : public Gtk::TreeModel::ColumnRecord
+    {
+      MapModelColumns()
+      {
+        add(colName);
+        add(colSaveToMainSect);
+        add(colSaveToGuiSect);
+      }
+      Gtk::TreeModelColumn<Glib::ustring> colName;
+      Gtk::TreeModelColumn<bool> colSaveToMainSect;
+      Gtk::TreeModelColumn<bool> colSaveToGuiSect;
+    };
+  private:
+    Gtk::RadioButton rbLgfFile;
+    Gtk::RadioButton rbConfFile;
+
+    Gtk::TreeView twNodeMaps;
+    Gtk::TreeView twEdgeMaps;
+
+    MapModelColumns NodeMapColumns;
+    MapModelColumns EdgeMapColumns;
+
+    Glib::RefPtr<Gtk::ListStore> refNodeMapStore;
+    Glib::RefPtr<Gtk::ListStore> refEdgeMapStore;
+
+    Gtk::RadioButton rbNodeCoordGuiSection;
+    Gtk::RadioButton rbNodeCoordNodesetSection;
+    Gtk::RadioButton rbNodeCoordOneMap;
+    Gtk::RadioButton rbNodeCoordTwoMaps;
+    Gtk::Entry entNodeCoordsOneMap;
+    Gtk::Entry entNodeCoordsTwoMaps1;
+    Gtk::Entry entNodeCoordsTwoMaps2;
+
+    Gtk::RadioButton rbArrowCoordGuiSection;
+    Gtk::RadioButton rbArrowCoordEdgesetSection;
+    Gtk::RadioButton rbArrowCoordOneMap;
+    Gtk::RadioButton rbArrowCoordTwoMaps;
+    Gtk::Entry entArrowCoordsOneMap;
+    Gtk::Entry entArrowCoordsTwoMaps1;
+    Gtk::Entry entArrowCoordsTwoMaps2;
+
+    MapStorage* pMapStorage;
+
+    void onGuiSectSaveDestChanged();
+
+    void onNodeCoordSaveDestChanged();
+    void onNodeCoordMapNumChanged();
+
+    void onNodeCoordsOneMapName();
+    void onNodeCoordsTwoMaps1Name();
+    void onNodeCoordsTwoMaps2Name();
+
+    void onArrowCoordSaveDestChanged();
+    void onArrowCoordMapNumChanged();
+
+    void onArrowCoordsOneMapName();
+    void onArrowCoordsTwoMaps1Name();
+    void onArrowCoordsTwoMaps2Name();
+
+    void onEdgeMapRowChanged(const Gtk::TreeModel::Path& path,
+        const Gtk::TreeModel::iterator& iter);
+    void onNodeMapRowChanged(const Gtk::TreeModel::Path& path,
+        const Gtk::TreeModel::iterator& iter);
+  public:
+    SaveDetailsWidget(MapStorage* ms);
+    ~SaveDetailsWidget();
+};
+
+#endif

Modified: glemon/trunk/xml.h
==============================================================================
--- glemon/trunk/xml.h	(original)
+++ glemon/trunk/xml.h	Wed Jan  2 22:03:09 2008
@@ -16,6 +16,9 @@
  *
  */
 
+#ifndef GLEMON_XML_H
+#define GLEMON_XML_H
+
 #include <iostream>
 #include <string>
 #include <vector>
@@ -442,3 +445,4 @@
   
 }
 
+#endif



More information about the Lemon-commits mailing list