=== modified file 'configure.in'
--- old/configure.in	2007-02-06 22:16:15 +0000
+++ new/configure.in	2007-01-18 15:09:47 +0000
@@ -49,7 +49,7 @@
 
 # Checks for libraries
 # We need libgnome only for gnome_help_display().:
-PKG_CHECK_MODULES(GLOM, bakery-2.4 >= 2.3.18 gtkmm-2.4 >= 2.6.1 gthread-2.0 gnome-vfsmm-2.6 >= 2.11.1 libgnomecanvasmm-2.6 >= 2.10.0 libxslt >= 1.1.10 pygda-1.2 pygtk-2.0 >= 2.6.0 libgnome-2.0 >= 2.6.0 iso-codes libgdamm-2.0 >= 1.3.7 libgtksourceviewmm-1.0)
+PKG_CHECK_MODULES(GLOM, bakery-2.4 >= 2.3.18 gtkmm-2.4 >= 2.6.1 gthread-2.0 gnome-vfsmm-2.6 >= 2.11.1 libgnomecanvasmm-2.6 >= 2.10.0 libxslt >= 1.1.10 pygda-1.2 pygtk-2.0 >= 2.6.0 libgnome-2.0 >= 2.6.0 iso-codes libgdamm-2.0 >= 1.3.7 goocanvas libgtksourceviewmm-1.0)
 
 GLOM_LIBS+=" --no-undefined"
 AC_SUBST(GLOM_CFLAGS)

=== modified file 'glom/application.cc'
--- old/glom/application.cc	2007-02-06 22:16:49 +0000
+++ new/glom/application.cc	2007-02-06 21:36:50 +0000
@@ -371,6 +371,7 @@
     "        <menuitem action='GlomAction_Menu_Developer_Database_Preferences' />"
     "        <menuitem action='GlomAction_Menu_Developer_Fields' />"
     "        <menuitem action='GlomAction_Menu_Developer_Relationships' />"
+    "        <menuitem action='GlomAction_Menu_Developer_RelationshipsOverview' />"
     "        <menuitem action='GlomAction_Menu_Developer_Layout' />"
     "        <menuitem action='GlomAction_Menu_Developer_Users' />"
     "        <menuitem action='GlomAction_Menu_Developer_Reports' />"

=== modified file 'glom/libglom/document/document_glom.cc'
--- old/glom/libglom/document/document_glom.cc	2007-02-06 22:16:49 +0000
+++ new/glom/libglom/document/document_glom.cc	2007-02-06 21:59:01 +0000
@@ -115,6 +115,8 @@
 #define GLOM_ATTRIBUTE_SEQUENCE "sequence"
 #define GLOM_ATTRIBUTE_HIDDEN "hidden"
 #define GLOM_ATTRIBUTE_DEFAULT "default"
+#define GLOM_ATTRIBUTE_OVERVIEW_X "overview_x"
+#define GLOM_ATTRIBUTE_OVERVIEW_Y "overview_y"
 #define GLOM_ATTRIBUTE_FIELD "field"
 #define GLOM_ATTRIBUTE_EDITABLE "editable"
 #define GLOM_DEPRECATED_ATTRIBUTE_EXAMPLE_ROWS "example_rows"
@@ -1013,6 +1015,38 @@
   return result;
 }
 
+void Document_Glom::set_node_attribute_value_as_float(xmlpp::Element* node, const Glib::ustring& strAttributeName, float value)
+{
+    if(value == std::numeric_limits<float>::infinity() && !node->get_attribute(strAttributeName))
+    return; //Use the non-existance of an attribute to mean "invalid"/infinity, to save space.
+  
+  //Get text representation of float:
+  std::stringstream thestream;
+  thestream.imbue( std::locale::classic() ); //The C locale.
+  thestream << value;
+  const Glib::ustring sequence_string = thestream.str();
+
+  set_node_attribute_value(node, strAttributeName, sequence_string);
+}
+
+float Document_Glom::get_node_attribute_value_as_float(const xmlpp::Element* node, const Glib::ustring& strAttributeName)
+{
+  float result = std::numeric_limits<float>::infinity();
+  const Glib::ustring value_string = get_node_attribute_value(node, strAttributeName);
+
+  //Get number for string:
+  if(!value_string.empty())
+  {
+    //Visible fields, with sequence:
+    std::stringstream thestream;
+    thestream.imbue( std::locale::classic() ); //The C locale.
+    thestream.str(value_string);
+    thestream >> result;
+  }
+
+  return result;
+}
+
 void Document_Glom::set_node_attribute_value_as_value(xmlpp::Element* node, const Glib::ustring& strAttributeName, const Gnome::Gda::Value& value,  Field::glom_field_type field_type)
 {
   NumericFormat format_ignored; //Because we use ISO format.
@@ -1093,6 +1127,38 @@
   }
 }
 
+bool Document_Glom::get_table_overview_position ( const Glib::ustring &table_name,
+                                                  float &x, float &y ) const
+{
+  type_tables::const_iterator it = m_tables.find(table_name);
+  if(it != m_tables.end())
+  {
+    if ( it->second.m_overviewx == std::numeric_limits<float>::infinity() ||
+         it->second.m_overviewy == std::numeric_limits<float>::infinity() )
+    {
+      return false;
+    }
+    x = it->second.m_overviewx;
+    y = it->second.m_overviewy;
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+    
+void Document_Glom::set_table_overview_position ( const Glib::ustring &table_name,
+                                                  float x, float y )
+{
+  type_tables::iterator it = m_tables.find(table_name);
+  if(it != m_tables.end())
+  {
+    it->second.m_overviewx = x;
+    it->second.m_overviewy = y;
+  }
+}
+    
 void Document_Glom::set_tables(const type_listTableInfo& tables)
 {
   //TODO: Avoid adding information about tables that we don't know about - that should be done explicitly.
@@ -1976,6 +2042,9 @@
           doctableinfo.m_info = table_info;
 
           doctableinfo.m_example_rows = get_child_text_node(nodeTable, GLOM_NODE_EXAMPLE_ROWS);
+          doctableinfo.m_overviewx = get_node_attribute_value_as_float(nodeTable, GLOM_ATTRIBUTE_OVERVIEW_X);
+          doctableinfo.m_overviewy = get_node_attribute_value_as_float(nodeTable, GLOM_ATTRIBUTE_OVERVIEW_Y);
+
           if(doctableinfo.m_example_rows.empty()) //Try the deprecated attribute instead
             doctableinfo.m_example_rows = get_node_attribute_value(nodeTable, GLOM_DEPRECATED_ATTRIBUTE_EXAMPLE_ROWS);
 
@@ -2620,6 +2689,9 @@
         set_node_attribute_value_as_bool(nodeTable, GLOM_ATTRIBUTE_HIDDEN, doctableinfo.m_info->m_hidden);
         set_node_attribute_value_as_bool(nodeTable, GLOM_ATTRIBUTE_DEFAULT, doctableinfo.m_info->m_default);
 
+        set_node_attribute_value_as_float(nodeTable, GLOM_ATTRIBUTE_OVERVIEW_X, doctableinfo.m_overviewx);
+        set_node_attribute_value_as_float(nodeTable, GLOM_ATTRIBUTE_OVERVIEW_Y, doctableinfo.m_overviewy);
+        
         if(m_is_example) //The example data is useless to non-example files (and is big):
           set_child_text_node(nodeTable, GLOM_NODE_EXAMPLE_ROWS, doctableinfo.m_example_rows);
         //else

=== modified file 'glom/libglom/document/document_glom.h'
--- old/glom/libglom/document/document_glom.h	2007-02-06 22:16:49 +0000
+++ new/glom/libglom/document/document_glom.h	2007-02-06 21:56:06 +0000
@@ -261,6 +261,27 @@
   void set_layout_current(const Glib::ustring& table_name, const Glib::ustring& layout_name);
   Glib::ustring get_layout_current(const Glib::ustring& table_name) const;
 
+  // Used by Relationship Overview dialog to preserve table locations accross instantiations:
+    
+    /**
+     * Retrieve the x and y coordinates for the given table position.
+     * 
+     * @param table_name The name of the table to query.
+     * @param x The x coordinate of the table position.
+     * @param y The y coordinate of the table position.
+     * @return false if the table does not have any 
+     */
+    bool get_table_overview_position ( const Glib::ustring &table_name, float &x, float &y ) const;
+    
+    /**
+     * Set the position of a table in the relationship overview dialog.
+     * 
+     * @param table_name The name of the table to modify.
+     * @param x The x coordinate of the table position.
+     * @param y The y coordinate of the table position.
+     */
+    void set_table_overview_position ( const Glib::ustring &table_name, float x, float y );
+    
   enum userLevelReason
   {
     USER_LEVEL_REASON_UNKNOWN,
@@ -333,6 +354,8 @@
   static guint get_node_attribute_value_as_decimal(const xmlpp::Element* node, const Glib::ustring& strAttributeName);
   static double get_node_attribute_value_as_decimal_double(const xmlpp::Element* node, const Glib::ustring& strAttributeName);
 
+  static float get_node_attribute_value_as_float(const xmlpp::Element* node, const Glib::ustring& strAttributeName);
+  static void set_node_attribute_value_as_float( xmlpp::Element* node, const Glib::ustring& strAttributeName, float value );
   static void set_node_attribute_value_as_value(xmlpp::Element* node, const Glib::ustring& strAttributeName, const Gnome::Gda::Value& value, Field::glom_field_type field_type);
   static Gnome::Gda::Value get_node_attribute_value_as_value(const xmlpp::Element* node, const Glib::ustring& strAttributeName, Field::glom_field_type field_type);
 
@@ -358,6 +381,8 @@
   {
   public:
     DocumentTableInfo()
+        : m_overviewx ( std::numeric_limits<float>::infinity () ),
+          m_overviewy ( std::numeric_limits<float>::infinity () )
     {
       m_info = sharedptr<TableInfo>(new TableInfo()); //Avoid a null sharedptr.
     }
@@ -380,6 +405,8 @@
     type_map_layout_primarykeys m_map_current_record; //The record last viewed in each layout.
 
     Glib::ustring m_layout_current;
+    
+    float m_overviewx, m_overviewy;
   };
 
   DocumentTableInfo& get_table_info_with_add(const Glib::ustring& table_name);

=== modified file 'glom/relationships_overview/dialog_relationships_overview.cc'
--- old/glom/relationships_overview/dialog_relationships_overview.cc	2007-02-06 22:16:49 +0000
+++ new/glom/relationships_overview/dialog_relationships_overview.cc	2006-12-03 13:47:39 +0000
@@ -24,32 +24,318 @@
 #include <bakery/App/App_Gtk.h> //For util_bold_message().
 #include <glibmm/i18n.h>
 #include <sstream> //For stringstream
-
-namespace Glom
-{
-
-Dialog_RelationshipsOverview::Dialog_RelationshipsOverview(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade)
-: Gtk::Dialog(cobject),
-  m_scrolledwindow_canvas(0)
-{
-  refGlade->get_widget("scrolledwindow_canvas", m_scrolledwindow_canvas);
-  m_scrolledwindow_canvas->add(m_canvas);
-  m_canvas.show();
-  add_view(&m_canvas);
-  
-  show_all_children();
-}
-
-Dialog_RelationshipsOverview::~Dialog_RelationshipsOverview()
-{
-  remove_view(&m_canvas);
-}
-
+#include <algorithm>
+
+namespace Glom {
+    static gboolean on_button_press ( GooCanvasItemView *view,
+                                      GooCanvasItemView *target,
+                                      GdkEventButton *event,
+                                      gpointer data ) {
+        return static_cast<Dialog_RelationshipsOverview*>(data)->on_button_press_canvas(view,target,event);
+    }
+    
+    static gboolean on_motion_notify (GooCanvasItemView *view,
+                                      GooCanvasItemView *target,
+                                      GdkEventMotion *event,
+                                      gpointer data) {
+        return static_cast<Dialog_RelationshipsOverview*>(data)->on_motion_canvas ( view, target, event );
+    }
+        
+    static gboolean on_button_release (GooCanvasItemView *view,
+                                       GooCanvasItemView *target,
+                                       GdkEventButton *event,
+                                       gpointer data) {
+        return static_cast<Dialog_RelationshipsOverview*>(data)->on_button_release_canvas (view, target, event);
+    }
+    
+    static void on_item_view_created_c ( GooCanvasView *view, GooCanvasItemView *item_view,
+                                         GooCanvasItem *item, gpointer data ) {
+        static_cast<Dialog_RelationshipsOverview*>(data)->on_item_view_created ( view, item_view, item );
+    }
+    
+    gboolean Dialog_RelationshipsOverview::on_button_release_canvas (GooCanvasItemView *view,
+                                                                     GooCanvasItemView *target,
+                                                                     GdkEventButton *event ) {
+        GooCanvasView *canvas_view = goo_canvas_item_view_get_canvas_view (view);
+        goo_canvas_view_pointer_ungrab (canvas_view, view, event->time);
+        this->m_dragging = FALSE;
+        
+        return TRUE;
+    }
+    
+    gboolean Dialog_RelationshipsOverview::on_button_press_canvas (GooCanvasItemView *view,
+                                                                   GooCanvasItemView *target,
+                                                                   GdkEventButton *event ) {
+        GooCanvasView *canvas_view;
+        GdkCursor *fleur;
+        GooCanvasItem *item;
+        
+        switch (event->button) {
+        case 1:
+            item = goo_canvas_item_view_get_item (view);
+            while ( item != NULL && !goo_canvas_item_is_container(item) )
+                item = goo_canvas_item_get_parent ( item );
+            goo_canvas_item_raise ( item, NULL );
+            
+            this->m_drag_x = event->x;
+            this->m_drag_y = event->y;
+            
+            fleur = gdk_cursor_new (GDK_FLEUR);
+            canvas_view = goo_canvas_item_view_get_canvas_view (view);
+            goo_canvas_view_pointer_grab (canvas_view, view,
+                                          static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
+                                          fleur,
+                                          event->time );
+            gdk_cursor_unref (fleur);
+            this->m_dragging = TRUE;
+            break;
+            
+        default:
+            break;
+        }
+        
+        return TRUE;
+    }
+
+    gboolean Dialog_RelationshipsOverview::on_motion_canvas (GooCanvasItemView *view,
+                                                             GooCanvasItemView *target,
+                                                             GdkEventMotion *event ) {
+        if ( view != NULL ) {
+            GooCanvasItem *item = goo_canvas_item_view_get_item (view);
+            while ( item != NULL && !goo_canvas_item_is_container(item) )
+                item = goo_canvas_item_get_parent ( item );
+            
+            if ( item != NULL && this->m_dragging && (event->state & GDK_BUTTON1_MASK)) {
+                double new_x = event->x;
+                double new_y = event->y;
+
+                TableView * tv = m_tables[item];
+                goo_canvas_item_translate (item, new_x - this->m_drag_x, new_y - this->m_drag_y);
+                tv->x1 += new_x - this->m_drag_x;
+                tv->y1 += new_y - this->m_drag_y;
+                tv->x2 += new_x - this->m_drag_x;
+                tv->y2 += new_y - this->m_drag_y;
+                
+                m_document->set_table_overview_position ( tv->tableName, tv->x1, tv->y1 );
+                m_modified = true;
+                updateRelationships ( tv );
+                for ( std::vector<TableView*>::iterator it = tv->updateOnMove.begin();
+                      it != tv->updateOnMove.end(); ++it )
+                    updateRelationships ( *it );
+            }
+        }
+        return TRUE;
+    }
+
+    void Dialog_RelationshipsOverview::on_item_view_created ( GooCanvasView *view,
+                                                              GooCanvasItemView *view_item,
+                                                              GooCanvasItem *item ) {
+        if ( goo_canvas_item_is_container(item) ) {
+            g_signal_connect ( view_item, "motion_notify_event",
+                               G_CALLBACK(on_motion_notify), static_cast<gpointer>(this) );
+            g_signal_connect ( view_item, "button_press_event",
+                               (GtkSignalFunc) on_button_press, this);
+            g_signal_connect ( view_item, "button_release_event",
+                               (GtkSignalFunc) on_button_release, this);
+        }
+    }
+    
+    void Dialog_RelationshipsOverview::on_response ( int id ) {
+        if ( m_modified && m_document )
+            m_document->set_modified ();
+        hide ();
+    }
+
+    Dialog_RelationshipsOverview::Dialog_RelationshipsOverview(BaseObjectType* cobject,
+                                                               const Glib::RefPtr<Gnome::Glade::Xml>& refGlade)
+        : Gtk::Dialog(cobject),
+          m_dragging(false),
+          m_scrolledwindow_canvas(0),
+          m_modified(false),
+          m_document(0) {
+        
+        refGlade->get_widget("scrolledwindow_canvas", m_scrolledwindow_canvas);
+        //this->signal_cancelled.connect(sigc::mem_fun(*this, &Dialog_RelationshipsOverview::on_cancel));
+        m_model = goo_canvas_model_simple_new ();
+        GtkWidget *canvas_temp = goo_canvas_view_new ();
+        goo_canvas_view_set_model ( GOO_CANVAS_VIEW (canvas_temp), GOO_CANVAS_MODEL(m_model) );
+        g_signal_connect ( canvas_temp, "item-view-created",
+                           G_CALLBACK(on_item_view_created_c), static_cast<gpointer>(this) );
+        
+        m_canvas = Glib::wrap ( canvas_temp );
+        m_scrolledwindow_canvas->add(*m_canvas);
+        m_canvas->show ();
+    }
+
+    void Dialog_RelationshipsOverview::updateModel () {
+        TableView *tv, *tv_to;
+        GooCanvasItem *root, *table_group, *table_rect, *table_text; //, *item;
+        root = goo_canvas_model_get_root_item ( GOO_CANVAS_MODEL(m_model) );
+        while ( goo_canvas_item_get_n_children(root) > 0 )
+            goo_canvas_item_remove_child ( root, 0 );
+        
+        for ( TableIterator it = m_tables.begin(); it != m_tables.end(); it++ )
+            delete it->second;
+        m_tables.clear ();
+        m_tableNames.clear ();
+        
+        m_document = dynamic_cast<Document_Glom*>(get_document());
+        if ( m_document ) {
+            Document_Glom::type_listTableInfo tables = m_document->get_tables();
+            int sizex, sizey, table_height, max_table_height = 0;
+            std::string title;
+            sizex = sizey = 10;
+            const int table_width = 200;
+            const int field_height = 20;
+            Document_Glom::type_vecFields::size_type i, j;
+            for ( Document_Glom::type_listTableInfo::iterator it = tables.begin(); it != tables.end(); ++it ) {
+                Document_Glom::type_vecFields fields = m_document->get_table_fields ( (*it)->get_name() );
+                table_group = goo_canvas_group_new ( root );
+                tv = new TableView ();
+                tv->tableName = (*it)->get_name();
+                tv->group = table_group;
+                m_tables[table_group] = tv;
+                m_tableNames[(*it)->get_name()] = tv;
+                
+                table_height = field_height * (fields.size() + 1);
+                title = "<b>";
+                title += (*it)->get_title_or_name().c_str();
+                title += "</b>";
+                if ( !m_document->get_table_overview_position ( tv->tableName, tv->x1, tv->y1 ) )
+                {
+                    tv->x1 = sizex;
+                    tv->y1 = sizey;
+                    m_document->set_table_overview_position ( tv->tableName, tv->x1, tv->y1 );
+                    m_modified = true;
+                }
+                tv->x2 = tv->x1 + table_width;
+                tv->y2 = tv->y1 + table_height;
+                
+                table_rect = goo_canvas_rect_new ( table_group, tv->x1, tv->y1, table_width, table_height,
+                                                   "line-width", 2.0, "radius-x", 4.0,
+                                                   "radius-y", 4.0, "stroke-color", "black",
+                                                   "fill-color", "white", NULL );
+                
+                table_text = goo_canvas_text_new ( table_group, title.c_str(),
+                                                   tv->x1 + 5, tv->y1 + 5, table_width - 10,
+                                                   GTK_ANCHOR_NORTH_WEST, "font", "sans 10",
+                                                   "use-markup", true, NULL );
+                goo_canvas_polyline_new_line ( table_group, tv->x1, tv->y1 + field_height, tv->x1 + table_width,
+                                               tv->y1 + field_height, "stroke-color", "black",
+                                               "line-width", 1.0, NULL );
+                int y = field_height;
+                
+                for ( Document_Glom::type_vecFields::iterator it = fields.begin(); it != fields.end(); ++it ) {
+                    if ( (*it)->get_primary_key() ) {
+                        title = "<u>";
+                        title += (*it)->get_title_or_name().c_str();
+                        title += "</u>";
+                        goo_canvas_text_new ( table_group, title.c_str(),
+                                              tv->x1 + 5, tv->y1 + 5 + y, table_width - 10,
+                                              GTK_ANCHOR_NORTH_WEST, "font", "sans 10",
+                                                           "use-markup", true, NULL );
+                    } else {
+                        goo_canvas_text_new ( table_group, (*it)->get_title_or_name().c_str(),
+                                                           tv->x1 + 5, tv->y1 + 5 + y, table_width - 10,
+                                                           GTK_ANCHOR_NORTH_WEST, "font", "sans 10", NULL );
+                    }
+                    y += field_height;
+                }
+                sizex += table_width + 10;
+                max_table_height = table_height > max_table_height ? table_height : max_table_height;
+            }
+            
+            for ( Document_Glom::type_listTableInfo::iterator it = tables.begin(); it != tables.end(); ++it ) {
+                Document_Glom::type_vecRelationships relationships = m_document->get_relationships ( (*it)->get_name() );
+                Document_Glom::type_vecFields fields = m_document->get_table_fields ( (*it)->get_name() );
+                Document_Glom::type_vecFields to_fields;
+                
+                tv = m_tableNames[(*it)->get_name()];
+                for ( Document_Glom::type_vecRelationships::iterator rit = relationships.begin();
+                      rit != relationships.end(); rit++ ) {
+                    if ( m_document->get_field((*rit)->get_to_table(), (*rit)->get_to_field())->get_primary_key() ) {
+                        for ( i = 0; i < fields.size() && fields[i]->get_name() != (*rit)->get_from_field();
+                              ++i ) {}
+                        
+                        tv_to = m_tableNames[(*rit)->get_to_table()];
+                        to_fields = m_document->get_table_fields((*rit)->get_to_table());
+                        
+                        for ( j = 0; j < to_fields.size() && to_fields[j]->get_name() != (*rit)->get_to_field();
+                              ++j ) {}
+                        
+                        /*
+                        std::cout << (*rit)->get_from_table() << "::" << (*rit)->get_from_field() << "[" << i
+                                  << "] -> " << (*rit)->get_to_table() << "::" << (*rit)->get_to_field()
+                                  << "[" << j << "]" << std::endl;
+                        */
+                        
+                        tv->relationships[std::make_pair(tv_to, j)] = i;
+                        if ( std::find(tv_to->updateOnMove.begin(), tv_to->updateOnMove.end(), tv) == tv_to->updateOnMove.end() )
+                            tv_to->updateOnMove.push_back ( tv );
+                    }
+                }
+                updateRelationships ( tv );
+            }
+            
+            goo_canvas_view_set_bounds ( GOO_CANVAS_VIEW(m_canvas->gobj()), 0, 0, sizex, max_table_height );
+        }
+    }
+
+    void Dialog_RelationshipsOverview::updateRelationships ( TableView *table_from ) {
+        //std::cout << "updateRelationships: " << item << std::endl;
+        
+        TableView *table_to;
+        double x_from, y_from, x_to, y_to;
+        const int field_height = 20;
+        
+        GooCanvasItem *root = goo_canvas_model_get_root_item(GOO_CANVAS_MODEL(m_model));
+        for ( std::vector<GooCanvasItem*>::iterator it = table_from->lines.begin();
+              it != table_from->lines.end(); ++it ) {
+            goo_canvas_item_remove_child ( root, goo_canvas_item_find_child(root, *it) );
+        }
+        table_from->lines.clear();
+        
+        for ( RelationshipIterator it = table_from->relationships.begin();
+              it != table_from->relationships.end(); ++it ) {
+            
+            table_to = it->first.first;
+            if ( table_to->x1 - table_from->x1 > 0 ) {
+                if ( table_to->x1 - table_from->x2 < 0 ) {
+                    x_from = table_from->x2;
+                    x_to = table_to->x2;
+                } else {
+                    x_from = table_from->x2;
+                    x_to = table_to->x1;
+                }
+            } else {
+                if ( table_from->x1 - table_to->x2 < 0 ) {
+                    x_from = table_from->x1;
+                    x_to = table_to->x1;
+                } else {
+                    x_from = table_from->x1;
+                    x_to = table_to->x2;
+                }
+            }
+            
+            y_from = table_from->y1 + (1.5 + it->second) * field_height;
+            y_to = table_to->y1 + (1.5 + it->first.second) * field_height;
+            
+            table_from->lines.push_back ( goo_canvas_polyline_new_line ( root,
+                                                                         x_from, y_from, x_to, y_to,
+                                                                         "line-width", 1.0,
+                                                                         "stroke-color", "black",
+                                                                         "start-arrow", FALSE,
+                                                                         "end-arrow", TRUE,
+                                                                         "arrow-width", 10.0,
+                                                                         "arrow-length", 10.0, NULL ) );
+        }
+    }
+    
+    Dialog_RelationshipsOverview::~Dialog_RelationshipsOverview() {
+        //remove_view(&canvas);
+        //g_object_unref ( canvas );
+        delete m_canvas;
+        g_object_unref ( m_model );
+    }
+    
 } //namespace Glom
-
-
-
-
-
-
-

=== modified file 'glom/relationships_overview/dialog_relationships_overview.h'
--- old/glom/relationships_overview/dialog_relationships_overview.h	2007-02-06 22:16:49 +0000
+++ new/glom/relationships_overview/dialog_relationships_overview.h	2006-12-03 13:36:47 +0000
@@ -23,27 +23,69 @@
 
 #include <glom/libglom/document/document_glom.h>
 #include <gtkmm/dialog.h>
+#include <gtkmm/widget.h>
 #include <libglademm.h>
+#include <goocanvas.h>
+#include <map>
+#include <vector>
+
 #include "relationships_canvas.h"
 
-namespace Glom
-{
+namespace Glom {
 
-class Dialog_RelationshipsOverview 
-  : public Gtk::Dialog,
-    public Base_DB //Give it access to the document, and to the database utilities
-{
+class Dialog_RelationshipsOverview  : public Gtk::Dialog,
+                                      public View_Composite_Glom {
 public:
-  Dialog_RelationshipsOverview(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
-  virtual ~Dialog_RelationshipsOverview();
-
+    Dialog_RelationshipsOverview(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
+    void updateModel ();
+    virtual ~Dialog_RelationshipsOverview();
+    gboolean on_button_press_canvas ( GooCanvasItemView *view, GooCanvasItemView *target,
+                                      GdkEventButton *event );
+    gboolean on_button_release_canvas ( GooCanvasItemView *view, GooCanvasItemView *target,
+                                        GdkEventButton *event );
+    gboolean on_motion_canvas ( GooCanvasItemView *view, GooCanvasItemView *target, GdkEventMotion *event );
+    void on_item_view_created ( GooCanvasView *view, GooCanvasItemView *item, GooCanvasItem *item );
+    //Glib::SignalProxy1< void,const Glib::RefPtr<Dialog_RelationshipsOverview>& > signal_canvas_motion ();
+    //Glib::SignalProxy3 < gboolean, GooCanvasItemView *,
+    //GooCanvasItemView *, GdkEventMotion * > signal_canvas_motion ();
+    
 protected:
+    void on_response ( int id );
+    
+    gboolean m_modified;
+    gboolean m_dragging;
+    gdouble m_drag_x, m_drag_y;
+    Gtk::ScrolledWindow *m_scrolledwindow_canvas;
+    Gtk::Widget *m_canvas;
+    GooCanvasModelSimple *m_model;
+    Document_Glom *m_document;
+    
+    class TableView {
+    public:
+        Glib::ustring tableName;
+        
+        GooCanvasItem *group;
+        GooCanvasBounds bounds;
+        
+        std::vector<GooCanvasItem*> lines;
+        
+        // pair<Foreign table, foreign field number> -> local field number
+        std::map<std::pair<TableView*, int>, int> relationships;
+        std::vector<TableView*> updateOnMove;
+        
+        float x1, y1, x2, y2;
+    };
+    std::map<GooCanvasItem*, TableView*> m_tables;
+    std::map<Glib::ustring, TableView*> m_tableNames;
+    typedef std::map<GooCanvasItem*, TableView*>::iterator TableIterator;
+    typedef std::map< std::pair<TableView*, int>, int >::iterator RelationshipIterator;
+    
+    void updateRelationships ( TableView * );
+    
 
-  Gtk::ScrolledWindow* m_scrolledwindow_canvas;
-  RelationshipsCanvas m_canvas;
   //Gnome::Canvas::Group m_canvas_group;
 };
 
-} //namespace Glom
+}; //namespace Glom
 
 #endif //GLOM_DIALOG_RELATIONSHIPS_OVERVIEW


