[glom/spread-table] Details: FlowTable: Initial use of GtkSpreadTable instead of custom code.



commit 5f520998d0c307f73e2e35a8818e57bc99335fa0
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Oct 8 11:59:48 2010 +0200

    Details: FlowTable: Initial use of GtkSpreadTable instead of custom code.
    
      * glom/utility_widgets/flowtable.[h|cc]: Derive from GtkSpreadTable,
      removing API and implementation that is then provided by that base class.
    * glom/utility_widgets/flowtable_dnd.[h|cc]: Remove FlowTable_DND (and its
      use for now. We will need to reimplement it somehow with GtkSpreadTable,
      hopefully in a simpler way.
    
      * glom/mode_data/box_data_details.cc
      * glom/mode_data/flowtablewithfieldse.[h|cc]:
      * glom/utility_widgets/test_flowtable.cc: Adapted.

 ChangeLog                              |   14 +
 Makefile_glom.am                       |    2 -
 glom/mode_data/box_data_details.cc     |   10 +-
 glom/mode_data/flowtablewithfields.cc  |  287 +------------
 glom/mode_data/flowtablewithfields.h   |   29 +--
 glom/utility_widgets/flowtable.cc      |  753 +-------------------------------
 glom/utility_widgets/flowtable.h       |   68 +---
 glom/utility_widgets/flowtable_dnd.cc  |  518 ----------------------
 glom/utility_widgets/flowtable_dnd.h   |   88 ----
 glom/utility_widgets/test_flowtable.cc |   17 +-
 10 files changed, 60 insertions(+), 1726 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c43ce9c..fa4aa78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-10-08  Murray Cumming  <murrayc murrayc com>
+
+	Details: FlowTable: Initial use of GtkSpreadTable instead of custom code.
+
+  * glom/utility_widgets/flowtable.[h|cc]: Derive from GtkSpreadTable,
+  removing API and implementation that is then provided by that base class.
+	* glom/utility_widgets/flowtable_dnd.[h|cc]: Remove FlowTable_DND (and its
+  use for now. We will need to reimplement it somehow with GtkSpreadTable,
+  hopefully in a simpler way.
+
+  * glom/mode_data/box_data_details.cc
+  * glom/mode_data/flowtablewithfieldse.[h|cc]:
+  * glom/utility_widgets/test_flowtable.cc: Adapted.
+
 2010-10-07  Murray Cumming  <murrayc murrayc com>
 
 	Choices: Do not offer editing formatting features when choosign extra fields.
diff --git a/Makefile_glom.am b/Makefile_glom.am
index d1a71bd..d85d7ab 100644
--- a/Makefile_glom.am
+++ b/Makefile_glom.am
@@ -332,8 +332,6 @@ glom_source_files +=							\
 	glom/mode_design/translation/window_translations.h				\
 	glom/utility_widgets/filechooserdialog_saveextras.cc		\
 	glom/utility_widgets/filechooserdialog_saveextras.h		\
-	glom/utility_widgets/flowtable_dnd.cc				\
-	glom/utility_widgets/flowtable_dnd.h				\
 	glom/utility_widgets/layouttoolbar.cc				\
 	glom/utility_widgets/layouttoolbar.h				\
 	glom/utility_widgets/layouttoolbarbutton.cc			\
diff --git a/glom/mode_data/box_data_details.cc b/glom/mode_data/box_data_details.cc
index c688f66..9908277 100644
--- a/glom/mode_data/box_data_details.cc
+++ b/glom/mode_data/box_data_details.cc
@@ -58,14 +58,14 @@ Box_Data_Details::Box_Data_Details(bool bWithNavButtons /* = true */)
 
   add_view(&m_FlowTable); //Allow this to access the document too.
 
-  m_FlowTable.set_columns_count(1); //Sub-groups will have multiple columns (by default, there is one sub-group, with 2 columns).
+  m_FlowTable.set_lines(1); //Sub-groups will have multiple columns (by default, there is one sub-group, with 2 columns).
 
   #ifndef GLOM_ENABLE_MAEMO
-  m_FlowTable.set_column_padding(Utils::DEFAULT_SPACING_SMALL); //The default anyway.
-  m_FlowTable.set_row_padding(Utils::DEFAULT_SPACING_SMALL); //The default anyway.
+  m_FlowTable.set_horizontal_spacing(Utils::DEFAULT_SPACING_SMALL); //The default anyway.
+  m_FlowTable.set_vertical_spacing(Utils::DEFAULT_SPACING_SMALL); //The default anyway.
   #else
-  m_FlowTable.set_row_padding(0); //The hildon buttons and entries have their own default padding.
-  m_FlowTable.set_column_padding(HILDON_MARGIN_DOUBLE); //As per the UI specs.
+  m_FlowTable.set_vertical_spacing(0); //The hildon buttons and entries have their own default padding.
+  m_FlowTable.set_horizontal_spacing(HILDON_MARGIN_DOUBLE); //As per the UI specs.
   #endif
 
   //m_strHint = _("When you change the data in a field the database is updated immediately.\n Click [New] to add a new record.\n Leave automatic ID fields empty - they will be filled for you.");
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index 203fbc0..3e2619c 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -203,11 +203,11 @@ void FlowTableWithFields::add_layout_group_at_position(const sharedptr<LayoutGro
     add_view(flow_table); //Allow these sub-flowtables to access the document too.
     flow_table->set_table(m_table_name);
 
-    flow_table->set_columns_count(group->get_columns_count());
+    flow_table->set_lines(group->get_columns_count());
 
     //Use the parent table's padding:
-    flow_table->set_column_padding(get_column_padding());
-    flow_table->set_row_padding(get_row_padding());
+    flow_table->set_horizontal_spacing(get_horizontal_spacing());
+    flow_table->set_vertical_spacing(get_vertical_spacing());
     flow_table->show();
 
     Gtk::EventBox* event_box = Gtk::manage( new Gtk::EventBox() ); //TODO_Leak: Valgrind says this is possibly leaked.
@@ -393,9 +393,9 @@ void FlowTableWithFields::add_layout_notebook_at_position(const sharedptr<Layout
         add_view(flow_table); //Allow these sub-flowtables to access the document too.
         flow_table->set_table(m_table_name);
 
-        flow_table->set_columns_count(group->get_columns_count());
-        flow_table->set_column_padding(get_column_padding());
-        flow_table->set_row_padding(get_row_padding());
+        flow_table->set_lines(group->get_columns_count());
+        flow_table->set_horizontal_spacing(get_horizontal_spacing());
+        flow_table->set_vertical_spacing(get_vertical_spacing());
         flow_table->show();
 
         // Put the new flowtable in an event box to catch events
@@ -482,8 +482,8 @@ void FlowTableWithFields::add_group(const Glib::ustring& group_name, const Glib:
 
     FlowTableWithFields* flow_table = Gtk::manage( new FlowTableWithFields() );
 
-    flow_table->set_columns_count(1);
-    flow_table->set_column_padding(get_column_padding());
+    flow_table->set_line(1);
+    flow_table->set_horizontal_spacing(get_column_padding());
     flow_table->set_row_padding(get_row_padding());
     flow_table->show();
     alignment->add(*flow_table);
@@ -1131,7 +1131,7 @@ void FlowTableWithFields::on_flowtable_entry_open_details_requested(const shared
 void FlowTableWithFields::set_design_mode(bool value)
 {
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-  FlowTableDnd::set_design_mode(value);
+  FlowTable::set_design_mode(value);
 #else
   FlowTable::set_design_mode(value);
 #endif
@@ -1325,6 +1325,7 @@ void FlowTableWithFields::apply_size_groups_to_labels(const type_vec_sizegroups&
     //Only align labels in the first column, because items in separate columns
     //couldn't be aligned vertically anyway, and this would cause extra space.
     //TODO: Use a different SizeGroup for items in 2nd columns?
+    /* TODO:
     guint column = 0;
     const bool column_allocated = get_column_for_first_widget(*label_parent, column);
     if(!column_allocated)
@@ -1338,6 +1339,7 @@ void FlowTableWithFields::apply_size_groups_to_labels(const type_vec_sizegroups&
       size_group->add_widget(*label);
       info.m_first_in_sizegroup = size_group; //Remember it so we can remove it later.
     }
+    */
   }
 }
 
@@ -1365,14 +1367,14 @@ void FlowTableWithFields::align_child_group_labels()
 
 guint FlowTableWithFields::get_sub_flowtables_max_columns() const
 {
-  guint result = get_columns_count();
+  guint result = get_lines();
 
   for(type_sub_flow_tables::const_iterator iter = m_sub_flow_tables.begin(); iter != m_sub_flow_tables.end(); ++iter)
   {
     const FlowTableWithFields* subtable = *iter;
     if(subtable)
     {
-      const guint count = subtable->get_columns_count();
+      const guint count = subtable->get_lines();
       if(count > result)
           result = count;
     }
@@ -1381,253 +1383,8 @@ guint FlowTableWithFields::get_sub_flowtables_max_columns() const
   return result;
 }
 
-
-void FlowTableWithFields::on_size_allocate(Gtk::Allocation& allocation)
-{
-  FlowTable::on_size_allocate(allocation);
-
-  sharedptr<const LayoutGroup> group = get_layout_group();
-  Glib::ustring group_name;
-  if(group)
-     group_name = group->get_name();
-
-  //The widgets have now been allocated their sizes and columns,
-  //so this should be able to work:
-  if(m_columns_allocated_changed)
-  {
-    apply_size_groups_to_labels(m_vec_size_groups);
-
-    //Prevent unnecessary repeated (endless?) size allocation requested:
-    m_columns_allocated_changed = false;
-  }
-}
-
 #ifndef GLOM_ENABLE_CLIENT_ONLY
 
-void FlowTableWithFields::on_dnd_add_layout_item_by_type(int item_type_num, Gtk::Widget* above_widget)
-{
-  LayoutWidgetBase::enumType item_type = static_cast<LayoutWidgetBase::enumType>(item_type_num);
-  LayoutWidgetBase* above = dynamic_cast<LayoutWidgetBase*>(above_widget);
-  if(!above)
-    return;
-
-  switch(item_type)
-  {
-    case LayoutWidgetBase::TYPE_FIELD:
-      on_dnd_add_layout_item_field(above);
-      break;
-    case LayoutWidgetBase::TYPE_BUTTON:
-      on_dnd_add_layout_item_button(above);
-      break;
-    case LayoutWidgetBase::TYPE_TEXT:
-      on_dnd_add_layout_item_text(above);
-      break;
-    case LayoutWidgetBase::TYPE_IMAGE:
-      on_dnd_add_layout_item_image(above);
-      break;
-    case LayoutWidgetBase::TYPE_GROUP:
-      on_dnd_add_layout_group(above);
-      break;
-    case LayoutWidgetBase::TYPE_NOTEBOOK:
-      on_dnd_add_layout_notebook(above);
-      break;
-    case LayoutWidgetBase::TYPE_PORTAL:
-      on_dnd_add_layout_portal(above);
-      break;
-    default:
-      std::cerr << G_STRFUNC << ": Unknown drop type: " << item_type << std::endl;
-   }
-}
-
-void FlowTableWithFields::on_dnd_add_layout_item_field(LayoutWidgetBase* above)
-{
-  //Ask the user to choose the layout item
-  sharedptr<LayoutItem_Field> layout_item_field =
-    DataWidget::offer_field_list(m_table_name, sharedptr<LayoutItem_Field>(),
-      get_document(), Application::get_application());
-  if(!layout_item_field)
-  {
-    realize();
-    return;
-  }
-
-  sharedptr<LayoutItem> item = sharedptr<LayoutItem>::cast_dynamic(layout_item_field);
-  dnd_add_to_layout_group(item, above);
-
-  //Tell the parent to tell the document to save the layout
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_notebook (LayoutWidgetBase* above)
-{
-  sharedptr<LayoutItem_Notebook> notebook(new LayoutItem_Notebook);
-  sharedptr<LayoutItem> item = sharedptr<LayoutItem>::cast_dynamic(notebook);
-  notebook->set_name(_("Notebook"));
-  // Add a group to the notebook
-  sharedptr<LayoutGroup> group(new LayoutGroup ());
-  group->set_title(_("New Group"));
-  group->set_name(_("Group"));
-  notebook->m_list_items.push_back(group);
-
-  dnd_add_to_layout_group(item, above);
-
-  //Tell the parent to tell the document to save the layout
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_portal (LayoutWidgetBase* above)
-{
-  sharedptr<LayoutItem_Portal> portal = get_portal_relationship();
-
-  if(portal)
-  {
-    sharedptr<LayoutItem> item = sharedptr<LayoutItem>::cast_dynamic(portal);
-    dnd_add_to_layout_group(item, above);
-
-    //Tell the parent to tell the document to save the layout
-    signal_layout_changed().emit();
-  }
-}
-
-void FlowTableWithFields::on_dnd_add_layout_group(LayoutWidgetBase* above)
-{
-  sharedptr<LayoutGroup> group(new LayoutGroup());
-  group->set_title(_("New Group"));
-  group->set_name(_("Group"));
-
-  sharedptr<LayoutItem> item = sharedptr<LayoutItem>::cast_dynamic(group);
-  dnd_add_to_layout_group (item, above);
-
-  //Tell the parent to tell the document to save the layout
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_item_button(LayoutWidgetBase* above)
-{
-  // create the button
-  sharedptr<LayoutItem_Button> layout_item_button = sharedptr<LayoutItem_Button>::create();
-  layout_item_button->set_title(_("New Button")); //Give the button a default title, so it is big enough, and so people see that they should change it.
-  layout_item_button->set_name("new_button");
-
-  dnd_add_to_layout_group(layout_item_button, above);
-  //Tell the parent to tell the document to save the layout:
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_item_text(LayoutWidgetBase* above)
-{
-  // create the text label
-  sharedptr<LayoutItem_Text> textobject = sharedptr<LayoutItem_Text>::create();
-  textobject->set_name(_("text"));
-  textobject->set_text(_("New Text"));
-  sharedptr<LayoutItem> layout_item = sharedptr<LayoutItem>::cast_dynamic(textobject);
-
-  dnd_add_to_layout_group(layout_item, above);
-  //Tell the parent to tell the document to save the layout
-
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_item_image(LayoutWidgetBase* above)
-{
-  // create the text label
-  sharedptr<LayoutItem_Image> image_object = sharedptr<LayoutItem_Image>::create();
-  sharedptr<LayoutItem> layout_item = sharedptr<LayoutItem>::cast_dynamic(image_object);
-
-  dnd_add_to_layout_group(layout_item, above);
-  //Tell the parent to tell the document to save the layout
-
-  signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item)
-{
-  dnd_add_to_layout_group(item, above);
-
-  // Don't do this here - it's done in the drag_end handler
-  // signal_layout_changed().emit();
-}
-
-void FlowTableWithFields::on_dnd_add_placeholder(Gtk::Widget* above_widget)
-{
-  LayoutWidgetBase* above = dynamic_cast<LayoutWidgetBase*>(above_widget);
-  if(!above)
-    return;
-
-  if(m_placeholder)
-  {
-    if(dynamic_cast<Glom::PlaceholderGlom*>(above))
-      return;
-
-    on_dnd_remove_placeholder();
-  }
-  type_list_layoutwidgets::iterator cur_widget = std::find (m_list_layoutwidgets.begin(),
-                                                            m_list_layoutwidgets.end(),
-                                                            above);
-  sharedptr<LayoutItem_Placeholder> placeholder_field(new LayoutItem_Placeholder);
-  sharedptr<LayoutItem> item = sharedptr<LayoutItem>::cast_dynamic(placeholder_field);
-  add_layout_item_at_position(placeholder_field, cur_widget);
-
-  dnd_add_to_layout_group(item, above, true /* ignore error*/);
-}
-
-void FlowTableWithFields::on_dnd_remove_placeholder()
-{
-  if(m_placeholder)
-  {
-    //Get the layout group that the "above" widget's layout item is in
-    sharedptr<LayoutGroup> layout_group = get_layout_group();
-    if(layout_group)
-    {
-      LayoutGroup::type_list_items items = layout_group->get_items();
-      for (LayoutGroup::type_list_items::iterator item = items.begin();
-           item != items.end(); ++item)
-      {
-        sharedptr<LayoutItem_Placeholder> placeholder =
-          sharedptr<LayoutItem_Placeholder>::cast_dynamic(*item);
-
-        if(placeholder)
-        {
-          layout_group->remove_item(*item);
-        }
-      }
-    }
-
-    remove(*m_placeholder);
-  }
-
-  m_placeholder = 0;
-}
-
-void FlowTableWithFields::dnd_notify_failed_drop()
-{
-  // TODO: Avoid this error message, maybe by adding a group.
-  // TODO: At least avoid losing the dragged item.
-  Gtk::MessageDialog dialog(_("You cannot drop anything here. Try to add a group first"),
-                      false, Gtk::MESSAGE_ERROR);
-  dialog.run();
-}
-
-bool FlowTableWithFields::dnd_add_to_layout_group(const sharedptr<LayoutItem>& item,  LayoutWidgetBase* layoutwidget, bool ignore_error)
-{
-  //Get the layout group that the "above" widget's layout item is in:
-  sharedptr<LayoutGroup> layout_group = get_layout_group();
-  if(!layout_group)
-  {
-    if(!ignore_error)
-      dnd_notify_failed_drop();
-
-    return false;
-  }
-
-  if(layoutwidget && layoutwidget->get_layout_item())
-    layout_group->add_item(item, layoutwidget->get_layout_item());
-  else
-    layout_group->add_item(item);
-
-  return true;
-}
-
 void FlowTableWithFields::on_menu_properties_activate()
 {
   Dialog_FlowTable* dialog = 0;
@@ -1723,24 +1480,6 @@ sharedptr<LayoutItem_Portal> FlowTableWithFields::get_portal_relationship()
   return sharedptr<LayoutItem_Portal>();
 }
 
-void FlowTableWithFields::set_child_widget_dnd_in_progress(Gtk::Widget* child, bool in_progress)
-{
-  //To be reimplemented by derived classes.
-  LayoutWidgetBase* base = dynamic_cast<LayoutWidgetBase*>(child);
-  if(!child)
-    return;
-
-  base->set_dnd_in_progress(in_progress);
-}
-
-bool FlowTableWithFields::get_child_widget_dnd_in_progress(Gtk::Widget* child) const
-{
-  LayoutWidgetBase* base = dynamic_cast<LayoutWidgetBase*>(child);
-  if(!base)
-    return false;
-  else
-    return base->get_dnd_in_progress();
-}
 
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
diff --git a/glom/mode_data/flowtablewithfields.h b/glom/mode_data/flowtablewithfields.h
index 7e0273a..99014ef 100644
--- a/glom/mode_data/flowtablewithfields.h
+++ b/glom/mode_data/flowtablewithfields.h
@@ -23,11 +23,7 @@
 
 #include "config.h" // For GLOM_ENABLE_CLIENT_ONLY
 
-#ifdef GLOM_ENABLE_CLIENT_ONLY
 #include <glom/utility_widgets/flowtable.h>
-#else
-#include <glom/utility_widgets/flowtable_dnd.h>
-#endif
 #include <libglom/data_structure/layout/layoutgroup.h>
 #include <libglom/data_structure/layout/layoutitem_field.h>
 #include <libglom/data_structure/layout/layoutitem_notebook.h>
@@ -54,11 +50,9 @@ class DataWidget;
 
 class FlowTableWithFields
   :
-#ifdef GLOM_ENABLE_CLIENT_ONLY
     public FlowTable,
+#ifndef GLOM_ENABLE_CLIENT_ONLY
     public LayoutWidgetUtils,
-#else
-    public FlowTableDnd,
 #endif
     public View_Composite_Glom
 {
@@ -243,31 +237,10 @@ private:
   void add_layout_notebook_at_position(const sharedptr<LayoutItem_Notebook>& notebook, const type_list_layoutwidgets::iterator& add_before);
   void add_layout_portal_at_position(const sharedptr<LayoutItem_Portal>& portal, const type_list_layoutwidgets::iterator& add_before);
 
-  virtual void on_size_allocate(Gtk::Allocation& allocation);
-
 #ifndef GLOM_ENABLE_CLIENT_ONLY
 
-  virtual void on_dnd_add_layout_item_by_type(int item_type_num, Gtk::Widget* above);
-  virtual void on_dnd_add_placeholder(Gtk::Widget* above);
-  virtual void on_dnd_remove_placeholder();
-  virtual void set_child_widget_dnd_in_progress(Gtk::Widget* child, bool in_progress);
-  virtual bool get_child_widget_dnd_in_progress(Gtk::Widget* child) const;
-
-
-  void on_dnd_add_layout_item_field(LayoutWidgetBase* above);
-  void on_dnd_add_layout_group(LayoutWidgetBase* above);
-  void on_dnd_add_layout_item_button(LayoutWidgetBase* above);
-  void on_dnd_add_layout_item_text(LayoutWidgetBase* above);
-  void on_dnd_add_layout_item_image(LayoutWidgetBase* above);
-  void on_dnd_add_layout_notebook(LayoutWidgetBase* above);
-  void on_dnd_add_layout_portal(LayoutWidgetBase* above);
-  void on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item);
-
   sharedptr<LayoutItem_Portal> get_portal_relationship();
 
-  void dnd_notify_failed_drop();
-  bool dnd_add_to_layout_group(const sharedptr<LayoutItem>& item, LayoutWidgetBase* layoutwidget, bool ignore_error = false);
-
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
   Box_Data_List_Related* create_related(const sharedptr<LayoutItem_Portal>& portal, bool show_title = true);
diff --git a/glom/utility_widgets/flowtable.cc b/glom/utility_widgets/flowtable.cc
index 18a9b5c..d5ab5b2 100644
--- a/glom/utility_widgets/flowtable.cc
+++ b/glom/utility_widgets/flowtable.cc
@@ -27,31 +27,11 @@
 namespace Glom
 {
 
-static void container_forall_callback(GtkWidget* widget_gobj, void* data)
-{
-  try
-  {
-    FlowTable::ForallSlot& slot = *static_cast<FlowTable::ForallSlot*>(data);
-    Gtk::Widget *const widget = Glib::wrap(widget_gobj);
-
-    g_return_if_fail(widget != 0);
-
-    slot(*widget);
-  }
-  catch(...)
-  {
-    Glib::exception_handlers_invoke();
-  }
-}
-
-
 FlowTable::FlowTableItem::FlowTableItem(Gtk::Widget* first, FlowTable* /* flowtable */)
 : m_first(first),
   m_second(0),
   m_expand_first_full(false),
-  m_expand_second(false),
-  m_has_allocated_column(false),
-  m_allocated_column(0)
+  m_expand_second(false)
 {
 
 }
@@ -60,9 +40,7 @@ FlowTable::FlowTableItem::FlowTableItem(Gtk::Widget* first, Gtk::Widget* second,
 : m_first(first),
   m_second(second),
   m_expand_first_full(false),
-  m_expand_second(false),
-  m_has_allocated_column(false),
-  m_allocated_column(0)
+  m_expand_second(false)
 {
 
 }
@@ -70,45 +48,12 @@ FlowTable::FlowTableItem::FlowTableItem(Gtk::Widget* first, Gtk::Widget* second,
 
 FlowTable::FlowTable()
 :
-  m_columns_allocated_changed(false),
-  m_columns_count(1),
-  m_column_padding(Utils::DEFAULT_SPACING_SMALL), //A sane default.
-  m_row_padding(Utils::DEFAULT_SPACING_SMALL), //A sane default.
   m_design_mode(false)
 {
-  set_has_window(false);
-  set_redraw_on_allocate(false);
 }
 
 FlowTable::~FlowTable()
 {
-  //Delete managed children.
-  //(For some reason this is not always happening via Gtk::Container:
-  /* Actualy, don't do this because we would then be double-deleting what the
-   * Container base class already deleted. We'll have to really find out if/why some
-   * things are not being deleted. murrayc.
-  bool one_deleted = true;
-  while(!m_children.empty() && one_deleted)
-  {
-    one_deleted = false;
-
-    type_vecChildren::iterator iter = m_children.begin();
-    FlowTableItem& item = *iter;
-
-    //Delete the widgets:
-    if(item.m_first || item.m_second)
-    {
-      if(item.m_first && item.m_first->is_managed_())
-        delete item.m_first;
-
-      if(item.m_second && item.m_second->is_managed_())
-        delete item.m_second;
-
-      m_children.erase(iter);
-      one_deleted = true; //Make sure that we loop again.
-    }
-  }
-  */
 }
 
 void FlowTable::set_design_mode(bool value)
@@ -122,18 +67,28 @@ void FlowTable::add(Gtk::Widget& first, Gtk::Widget& second, bool expand_second)
 {
   FlowTableItem item(&first, &second, this);
 
+  Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox(false, get_horizontal_spacing()));
+
   item.m_expand_second = expand_second; //Expand to fill the width for all of the second item.
   m_children.push_back(item);
-  item.m_first->set_parent(*this);
-  item.m_second->set_parent(*this);
+
+  hbox->pack_start(first, Gtk::PACK_SHRINK);
+  hbox->pack_start(second, expand_second ? Gtk::PACK_EXPAND_WIDGET : Gtk::PACK_SHRINK);
+  hbox->show();
+
+  hbox->set_halign(Gtk::ALIGN_FILL);
+  append_child(*hbox);
 }
 
 void FlowTable::add(Gtk::Widget& first, bool expand)
 {
   FlowTableItem item(&first, this);
+
   item.m_expand_first_full = expand; //Expand to fill the width for first and second.
   m_children.push_back(item);
-  item.m_first->set_parent(*this);
+
+  first.set_halign(Gtk::ALIGN_FILL);
+  append_child(first); //TODO: expand
 }
 
 void FlowTable::insert_before(Gtk::Widget& first, Gtk::Widget& before, bool expand)
@@ -150,8 +105,11 @@ void FlowTable::insert_before(Gtk::Widget& first, Gtk::Widget& second, Gtk::Widg
   insert_before(item, before);
 }
 
-void FlowTable::insert_before(FlowTableItem& item, Gtk::Widget& before)
+void FlowTable::insert_before(FlowTableItem& /* item */, Gtk::Widget& /* before */)
 {
+  std::cerr << G_STRFUNC << ": Not implemented" << std::endl;
+  //TODO:
+  /*
   bool found = false;
   std::vector<FlowTableItem>::iterator pos;
   for(pos = m_children.begin(); pos != m_children.end(); ++pos)
@@ -199,607 +157,7 @@ void FlowTable::insert_before(FlowTableItem& item, Gtk::Widget& before)
     m_children.push_back(item);
   else
     m_children.insert(pos, item);
-}
-
-void FlowTable::set_columns_count(guint value)
-{
-  //Silently correct an invalid value:
-  if(value == 0)
-    value = 1;
-
-  m_columns_count = value;
-}
-
-guint FlowTable::get_columns_count() const
-{
-  return m_columns_count;
-}
-
-void FlowTable::get_item_requested_width(const FlowTableItem& item, int& first, int& second) const
-{
-  //Initialize output paramters:
-  first = 0;
-  second = 0;
-
-  Gtk::Widget* first_widget = item.m_first;
-  Gtk::Widget* second_widget = item.m_second;
-
-  if(child_is_visible(first_widget) || child_is_visible(second_widget))
-  {
-    if(child_is_visible(first_widget))
-    {
-      //Discover how much space this child needs:
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      first_widget->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-      first = child_requisition_request_natural.width;
-    }
-
-    if(child_is_visible(second_widget))
-    {
-      //Discover how much space this child needs:
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      second_widget->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-      second = child_requisition_request_min.width;
-    }
-  }
-}
-
-int FlowTable::get_item_requested_height(const FlowTableItem& item) const
-{
-  int result = 0;
-
-  Gtk::Widget* first = item.m_first;
-  Gtk::Widget* second = item.m_second;
-  int max_child_height = 0;
-  if(child_is_visible(first) || child_is_visible(second))
-  {
-    //Look at both widgets and see which one has most height:
-    if(child_is_visible(first))
-    {
-      // Ask the child how much space it needs:
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      first->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-
-      max_child_height = child_requisition_request_min.height;
-    }
-
-    if(child_is_visible(second))
-    {
-      // Ask the child how much space it needs:
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      second->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-
-      max_child_height = MAX(max_child_height, child_requisition_request_min.height);
-    }
-
-    //Use the largest height (they are next to each other, horizontally):
-    result += max_child_height;
-  }
-
-  return result;
-}
-
-int FlowTable::get_column_height(guint start_widget, guint widget_count, int& total_width) const
-{
-  //init_db_details output parameter:
-  total_width = 0;
-
-  //Just add the heights together:
-  int column_height = 0;
-  int column_width_first = 0;
-  int column_width_second = 0;
-  int column_width_singles = 0;
-  guint i = 0;
-  for(i = start_widget; i < (start_widget+widget_count);  ++i)
-  {
-    const FlowTableItem& item = m_children[i];
-    const int item_height = get_item_requested_height(item);
-
-    int item_width_first = 0;
-    int item_width_second = 0;
-    get_item_requested_width(item, item_width_first, item_width_second);
-
-    column_height += item_height;
-
-    //Add the padding if it's not the first widget, and if one is visible:
-    if( (i != start_widget) && item_height)
-    {
-      column_height += m_row_padding;
-    }
-
-    if(item_height) //If one was visible.
-    {
-      if(child_is_visible(item.m_second))
-      {
-        column_width_first = MAX(column_width_first, item_width_first);
-        column_width_second = MAX(column_width_second, item_width_second);
-      }
-      else
-      {
-        //If there is only a first widget and no second one, then that first widget should take up the whole width,
-        //instead of increasing the width for the first sub-column:
-        column_width_singles = MAX(column_width_singles, item_width_first);
-      }
-    }
-
-  }
-
-   total_width = column_width_first +  column_width_second;
-
-   //See whether the single items need even more space:
-   total_width = MAX(total_width, column_width_singles);
-
-   if( (column_width_first > 0) && (column_width_second > 0) ) //Add padding if necessary.
-     total_width += m_column_padding;
-
-  return column_height;
-}
-
-int FlowTable::get_minimum_column_height(guint start_widget, guint columns_count, int& total_width) const
-{
-  //init_db_details output parameter:
-  total_width = 0;
-
-  //Discover how best (least column height) to arrange these widgets in these columns, keeping them in sequence,
-  //and then say how high the columns must best.
-
-  if(columns_count == 1)
-  {
-    //Just add the heights together:
-    const guint widgets_count = m_children.size() - start_widget;
-    int column_height = get_column_height(start_widget, widgets_count, total_width);
-
-    return column_height;
-  }
-  else
-  {
-    //Try each combination of widgets in the first column, combined with the the other combinations in the following columns:
-    int minimum_column_height = 0;
-    int width_for_minimum_column_height = 0;
-    bool at_least_one_combination_checked = false;
-
-    const guint count_items_remaining = m_children.size() - start_widget;
-
-    for(guint first_column_widgets_count = 1;  first_column_widgets_count <= count_items_remaining; ++first_column_widgets_count)
-    {
-      int first_column_width = 0;
-      int first_column_height = get_column_height(start_widget, first_column_widgets_count, first_column_width);
-      int minimum_column_height_sofar = first_column_height;
-
-      int others_column_width = 0;
-      const guint others_column_start_widget =  start_widget + first_column_widgets_count;
-      //Call this function recursively to get the minimum column height in the other columns, when these widgets are in the first column:
-      int minimum_column_height_nextcolumns = 0;
-      if( others_column_start_widget  < m_children.size())
-      {
-        minimum_column_height_nextcolumns = get_minimum_column_height(others_column_start_widget, columns_count - 1, others_column_width);
-        others_column_width += m_column_padding; //Add the padding between the previous column and this one.
-
-        minimum_column_height_sofar = MAX(first_column_height, minimum_column_height_nextcolumns);
-      }
-
-      //See whether this is better than the last one:
-      if(at_least_one_combination_checked)
-      {
-        if(minimum_column_height_sofar < minimum_column_height)
-        {
-          minimum_column_height = minimum_column_height_sofar;
-          width_for_minimum_column_height = first_column_width + others_column_width;
-        }
-      }
-      else
-      {
-        minimum_column_height = minimum_column_height_sofar;
-        width_for_minimum_column_height = first_column_width + others_column_width;
-
-        at_least_one_combination_checked = true;
-      }
-    }
-
-    total_width = width_for_minimum_column_height;
-
-    return minimum_column_height;
-  }
-}
-
-void FlowTable::on_size_request(Gtk::Requisition* requisition)
-{
-  // Set a minimum size so people are able to drag items into the
-  // table
-  const int MIN_HEIGHT = (m_design_mode ? 50 : 0);
-  const int MIN_WIDTH = (m_design_mode ? 100 : 0);
-
-  //Initialize the output parameter:
-  *requisition = Gtk::Requisition();
-
-  //Discover the total amount of minimum space needed by this container widget, by examining its child widgets,
-  //by examing every possible sequential arrangement of the widgets in this fixed number of columsn:
-  int total_width = 0;
-  const int column_height = get_minimum_column_height(0, m_columns_count, total_width); //This calls itself recursively.
-
-  requisition->height = (column_height > MIN_HEIGHT ? column_height : MIN_HEIGHT);
-  requisition->width = (total_width > MIN_WIDTH ? total_width : MIN_WIDTH);
-}
-
-//Give it whatever height/width it wants, at this location:
-Gtk::Allocation FlowTable::assign_child(Gtk::Widget* widget, int x, int y, int width, int height)
-{
-  //Assign sign space to the child:
-  Gtk::Allocation child_allocation;
-
-  child_allocation.set_x(x);
-  child_allocation.set_y(y);
-
-  child_allocation.set_width(width);
-  child_allocation.set_height(height);
-
-  //g_warning("  assigning: x=%d, y=%d, width=%d, height=%d", x, y, child_requisition_request.width, child_requisition_request.height);
-  //g_warning("    far x=%d, far y=%d", x+child_requisition_request.width , y+child_requisition_request.height);
-
-  widget->size_allocate(child_allocation);
-
-  return child_allocation; //Return this so we can cache it.
-}
-
-//Give it whatever height/width it wants, at this location:
-Gtk::Allocation FlowTable::assign_child(Gtk::Widget* widget, int x, int y)
-{
-  //Discover how much space this child needs:;
-  //TODO: Which one should we use?
-  Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-  widget->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-
-  //Give it as much space as it wants:
-  return assign_child(widget, x, y, child_requisition_request_min.width, child_requisition_request_min.height);
-}
-
-void FlowTable::get_item_max_width_requested(guint start, guint height, guint& first_max_width, guint& second_max_width, guint& singles_max_width, bool& is_last_column) const
-{
-  //Initialize output parameters:
-  first_max_width = 0;
-  second_max_width = 0;
-  singles_max_width = 0;
-  is_last_column = false;
-
-  if(m_children.empty())
-    return;
-
-  guint height_so_far = 0;
-  bool first_item_added = false;
-  guint i = start;
-  while( (height_so_far < height) && (i < m_children.size()))
-  {
-    const FlowTableItem& item = m_children[i];
-    Gtk::Widget* first = item.m_first;
-    Gtk::Widget* second = item.m_second;
-
-    guint height_item = 0;
-
-    guint padding_above = 0;
-    //Add padding above the item, if it is after another one.
-    if( first_item_added && (child_is_visible(first) || child_is_visible(second)) )
-       padding_above += m_row_padding;
-
-    guint item_first_width = 0;
-    guint singles_width = 0;
-    if(child_is_visible(first))
-    {
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      first->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-
-      if(child_is_visible(second))
-      {
-        //There are 2 widgets so put one in each sub-column, lined up with the widgets in the other rows:
-        item_first_width = child_requisition_request_min.width;
-      }
-      else
-      {
-        //There is only one widget, so let it take up the whole space and not affect the widths of the sub-columns:
-        singles_width = child_requisition_request_min.width;
-      }
-
-      height_item = MAX(height_item, (guint)child_requisition_request_min.height);
-      first_item_added = true;
-    }
-
-    guint item_second_width = 0;
-    if(child_is_visible(second))
-    {
-      //TODO: Which one should we use?
-      Gtk::Requisition child_requisition_request_min, child_requisition_request_natural;
-      second->get_preferred_size(child_requisition_request_min, child_requisition_request_natural);
-
-      item_second_width = child_requisition_request_min.width;
-      //g_warning("item_second_width=%d", item_second_width);
-      height_item = MAX(height_item, (guint)child_requisition_request_min.height);
-      first_item_added = true;
-    }
-
-    if(height_item)
-      height_item += padding_above;
-
-    height_so_far += height_item;
-    if(height_so_far <= height) //Don't remember the width details if the widgets are too high for the end of this column:
-    {
-      first_max_width = MAX(first_max_width, item_first_width);
-      second_max_width = MAX(second_max_width, item_second_width);
-      //g_warning("max item_second_width=%d", second_max_width);
-      singles_max_width = MAX(singles_max_width, singles_width);
-    }
-
-    ++i;
-  }
-
-  //Tell the caller if this was the last column,
-  //so that it can decide to use all available space.
-  if(i == m_children.size())
-    is_last_column = true;
-
-  //g_warning("i=%d", i);
-  //g_warning("get_item_max_width_requested(guint start=%d, guint height=%d, guint& first_max_width=%d, guint& second_max_width=%d",  start, height, first_max_width, second_max_width);
-}
-
-void FlowTable::on_size_allocate(Gtk::Allocation& allocation)
-{
-  //Do something with the space that we have actually been given:
-  //(We will not be given heights or widths less than we have requested, though we might get more)
-
-  set_allocation(allocation);
-
-  //This will be used in on_draw():
-  m_lines_horizontal.clear();
-  m_lines_vertical.clear();
-
-  //Discover the widths of the different parts of the first column:
-  guint first_max_width = 0;
-  guint second_max_width = 0;
-  guint singles_max_width = 0;
-  bool is_last_column = false;
-  get_item_max_width_requested(0, allocation.get_height(), first_max_width, second_max_width, singles_max_width, is_last_column);  //TODO: Give the 2nd part of the column a bit more if the total needed is less than the allocation given.
-
-  //Calculate where the columns should start on the x axis.
-  int column_x_start = allocation.get_x();
-
-  int column_x_start_second = column_x_start + first_max_width;
-  if(first_max_width > 0) //Add padding between first and second sub sets of items, if there is a first set.
-    column_x_start_second += m_column_padding;
-
-  //Used for drawing horizontal lines:
-  guint column_max_width = MAX(first_max_width + m_column_padding + second_max_width, singles_max_width);
-  //Use the whole remaining width if there is no column after this:
-  if(is_last_column)
-  {
-    column_max_width = allocation.get_width() - (column_x_start - allocation.get_x());
-  }
-
-  int column_child_y_start = allocation.get_y();
-
-  guint column_number = 0; //Just for remembering it for later.
-  guint count = m_children.size();
-  for(guint i = 0; i < count; ++i)
-  {
-    FlowTableItem& item = m_children[i];
-
-    const int item_height = get_item_requested_height(item);
-
-    //Start a new column if necessary:
-    int bottom = allocation.get_y() + allocation.get_height();
-    if( (column_child_y_start + item_height) > bottom)
-    {
-      //start a new column:
-      column_child_y_start = allocation.get_y();
-      ++column_number;
-      const int column_x_start_plus_singles = column_x_start + singles_max_width;
-      column_x_start = column_x_start_second + second_max_width;
-      column_x_start = MAX(column_x_start, column_x_start_plus_singles); //Maybe the single items take up even more width.
-      column_x_start += m_column_padding;
-
-      //Draw vertical line to separate the columns, in the middle of the padding:
-      const int line_x = column_x_start - (m_column_padding / 2);
-      const int line_height = allocation.get_height();
-      m_lines_vertical.push_back( type_line( Gdk::Point(line_x, allocation.get_y()), Gdk::Point(line_x, allocation.get_y() + line_height) ) );
-
-      {
-        //Discover the widths of the different parts of this column:
-        first_max_width = 0;
-        second_max_width= 0;
-        singles_max_width = 0;
-        bool is_last_column = false;
-
-        get_item_max_width_requested(i, allocation.get_height(), first_max_width, second_max_width, singles_max_width, is_last_column);
-
-        column_x_start_second = column_x_start + first_max_width;
-        if(first_max_width > 0) //Add padding between first and second sub sets of items, if there is a first set.
-          column_x_start_second += m_column_padding;
-
-        //Used for drawing horizontal lines:
-        column_max_width = MAX(first_max_width + m_column_padding + second_max_width, singles_max_width);
-
-        //Use the whole remaining width if there is no column after this:
-        if(is_last_column)
-        {
-          column_max_width = allocation.get_width() - (column_x_start - allocation.get_x());
-        }
-      }
-    }
-
-    bool something_added = false;
-
-    Gtk::Widget* first = item.m_first;
-    Gtk::Widget* second = item.m_second;
-    if(child_is_visible(second))
-    {
-      //Place the 2 items so that they line up with the 2 items in other rows:
-      if(child_is_visible(first))
-      {
-        //Assign space to the child:
-
-        //Make all the left edges line up, and give the full first-item width, even if that's more width than it requested,
-        //so that it can align itself in the available space.
-        item.m_first_allocation = assign_child(first, column_x_start, column_child_y_start, first_max_width, item_height);
-        something_added = true;
-      }
-
-      if(true) //Unecessary check: child_is_visible(second))
-      {
-        //Assign space to the child:
-
-        //Make all the left edges line up:
-
-        if(!(item.m_expand_second))
-          item.m_second_allocation = assign_child(second, column_x_start_second, column_child_y_start);
-        else
-        {
-          const int second_width_available = column_max_width - first_max_width - m_column_padding;
-          item.m_second_allocation = assign_child(second, column_x_start_second, column_child_y_start, second_width_available, item_height);
-        }
-
-        something_added = true;
-      }
-    }
-    else if(child_is_visible(first))
-    {
-      //There is only one item - so let it take up the whole width of the column, if requested:
-
-      //Assign space to the child:
-      if(!(item.m_expand_first_full))
-        item.m_first_allocation = assign_child(first, column_x_start, column_child_y_start);
-      else
-      {
-        item.m_first_allocation = assign_child(first, column_x_start, column_child_y_start, column_max_width, item_height);
-      }
-
-      something_added = true;
-    }
-
-    if(something_added)
-    {
-      //Let later code know where the widgets are, and whether the layout has
-      //changed since m_columns_allocated_changed was last set to false.
-      if(!item.m_has_allocated_column || (item.m_allocated_column != column_number))
-      {
-        item.m_allocated_column = column_number;
-        item.m_has_allocated_column = true;
-        m_columns_allocated_changed = true;
-      }
-
-      //Start the next child below this child, plus the padding
-      column_child_y_start += item_height;
-      column_child_y_start += m_row_padding; //Ignored if this is the last item - we will just start a new column when we find that column_child_y_start is too much.
-
-      //Add horizontal line in the middle of the padding:
-      const guint line_y = column_child_y_start - (m_row_padding / 2);
-      const guint line_width = column_max_width;
-      m_lines_horizontal.push_back( type_line( Gdk::Point(column_x_start, line_y), Gdk::Point(column_x_start + line_width, line_y) ) );
-    }
-  }
-}
-
-GType FlowTable::child_type_vfunc() const
-{
-  //TODO: What is this for?
-  if(!m_children.empty())
-    return GTK_TYPE_WIDGET;
-  else
-    return G_TYPE_NONE;
-}
-
-
-void FlowTable::on_add(Gtk::Widget* child)
-{
-  FlowTableItem item(child, 0);
-  m_children.push_back(item);
-
-  gtk_widget_set_parent(GTK_WIDGET(item.m_first->gobj()), GTK_WIDGET(gobj()));
-
-  //This is protected, but should be public: child.set_parent(*this);
-
-}
-
-
-
-void FlowTable::on_remove(Gtk::Widget* child)
-{
-  if(child)
-  {
-    const bool visible = child_is_visible(child);
-
-  //g_warning("FlowTable::on_remove");
-    for(type_vecChildren::iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
-    {
-      FlowTableItem& item = *iter;
-
-      if(item.m_first == child)
-      {
-            //g_warning("FlowTable::on_remove unparenting first");
-        gtk_widget_unparent(GTK_WIDGET(item.m_first->gobj())); //This is protected, but should be public: child.unparent();
-        item.m_first = 0;
-
-       if(visible)
-          queue_resize();
-      }
-
-      if(item.m_second == child)
-      {
-        //g_warning("FlowTable::on_remove unparenting second");
-        gtk_widget_unparent(GTK_WIDGET(item.m_second->gobj())); //This is protected, but should be public: child.unparent();
-        item.m_second = 0;
-
-        if(visible)
-          queue_resize();
-      }
-    }
-  }
-
- //g_warning("FlowTable::on_remove end");
-}
-
-
-void FlowTable::forall_vfunc(gboolean /* include_internals */, GtkCallback callback, gpointer callback_data)
-{
-  for(type_vecChildren::const_iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
-  {
-    const FlowTableItem& item = *iter;
-
-    Gtk::Widget* first = item.m_first;
-    if(first)
-      callback(first->gobj(), callback_data);
-
-    Gtk::Widget* second = item.m_second;
-    if(second)
-      callback(second->gobj(), callback_data);
-  }
-}
-
-void FlowTable::forall(const ForallSlot& slot)
-{
-  ForallSlot slot_copy(slot);
-  gtk_container_forall(gobj(), &container_forall_callback, &slot_copy);
-}
-
-void FlowTable::set_column_padding(guint padding)
-{
-  m_column_padding = padding;
-}
-
-guint FlowTable::get_column_padding() const
-{
-  return m_column_padding;
-}
-
-void FlowTable::set_row_padding(guint padding)
-{
-  m_row_padding = padding;
-}
-
-guint FlowTable::get_row_padding() const
-{
-  return m_row_padding;
+  */
 }
 
 bool FlowTable::child_is_visible(const Gtk::Widget* widget) const
@@ -861,76 +219,5 @@ void FlowTable::remove_all()
   m_children.clear();
 }
 
-void FlowTable::on_realize()
-{
-  Gtk::Container::on_realize();
-
-  if(!m_refGdkWindow)
-  {
-    m_refGdkWindow = get_window();
-  }
-}
-
-void FlowTable::on_unrealize()
-{
-  m_refGdkWindow.reset();
-
-  Gtk::Container::on_unrealize();
-}
-
-bool FlowTable::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
-{
-  if(m_design_mode)
-  {
-    m_refGdkWindow = get_window();
-    if(m_refGdkWindow)
-    {
-      Cairo::RefPtr<Cairo::Context> cr = m_refGdkWindow->create_cairo_context();
-      cr->set_line_width(1);
-      cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
-      cr->set_line_join(Cairo::LINE_JOIN_MITER);
-      std::vector<double> dashes;
-      dashes.push_back(10);
-      cr->set_dash(dashes, 0);
-
-      for(type_vecLines::iterator iter = m_lines_horizontal.begin(); iter != m_lines_horizontal.end(); ++iter)
-      {
-        cr->move_to(iter->first.get_x(), iter->first.get_y());
-        cr->line_to(iter->second.get_x(), iter->second.get_y());
-        cr->stroke();
-      }
-
-      for(type_vecLines::iterator iter = m_lines_vertical.begin(); iter != m_lines_vertical.end(); ++iter)
-      {
-        cr->move_to(iter->first.get_x(), iter->first.get_y());
-        cr->line_to(iter->second.get_x(), iter->second.get_y());
-        cr->stroke();
-      }
-    }
-  }
-
-  return Gtk::Container::on_draw(cr);
-}
-
-bool FlowTable::get_column_for_first_widget(const Gtk::Widget& first, guint& column)
-{
-  //Initialize output parameter:
-  column = 0;
-
-  for(type_vecChildren::const_iterator iter = m_children.begin(); iter != m_children.end(); ++iter)
-  {
-    const FlowTableItem& item = *iter;
-
-    if((&first == item.m_first) && item.m_has_allocated_column)
-    {
-       column = item.m_allocated_column;
-       return true;
-    }
-  }
-
-  return false;
-}
-
-
 
 } //namespace Glom
diff --git a/glom/utility_widgets/flowtable.h b/glom/utility_widgets/flowtable.h
index be7de54..550c618 100644
--- a/glom/utility_widgets/flowtable.h
+++ b/glom/utility_widgets/flowtable.h
@@ -27,7 +27,7 @@
 namespace Glom
 {
 
-class FlowTable : public Gtk::Container
+class FlowTable : public Gtk::SpreadTable
 {
 public:
   FlowTable();
@@ -42,71 +42,18 @@ public:
 
   virtual void remove(Gtk::Widget& first); //override
 
-  void set_columns_count(guint value);
-
-  guint get_columns_count() const;
-
-  /** Sets the padding to put between the columns of widgets.
-   */
-  void set_column_padding(guint padding);
-
-  /** Gets the padding between the columns of widgets.
-   */
-  guint get_column_padding() const;
-
-  /** Sets the padding to put between the rows of widgets.
-   */
-  void set_row_padding(guint padding);
-
-  /** Gets the padding between the rows of widgets.
-   */
-  guint get_row_padding() const;
-
   /** Show extra UI that is useful in RAD tools:
    */
   virtual void set_design_mode(bool value = true);
 
   void remove_all();
 
-  // Implement forall which is not implemented in gtkmm:
-  typedef sigc::slot<void, Widget&> ForallSlot;
-  void forall(const ForallSlot& slot);
-
-  /** Get the column in which the specified "first" widget is placed.
-   * result false if the widget is not one of the "first" widgets, or
-   * if has not yet been placed in a column, because the size has not yet been requested.
-   */
-  bool get_column_for_first_widget(const Gtk::Widget& first, guint& column);
-
 private:
 
   //Overrides:
 
-  //Handle child widgets:
-  virtual void on_size_request(Gtk::Requisition* requisition);
-  virtual GType child_type_vfunc() const;
-  virtual void on_add(Gtk::Widget* child);
-  virtual void forall_vfunc(gboolean include_internals, GtkCallback callback, gpointer callback_data);
-  virtual void on_remove(Gtk::Widget* child);
-
-
 protected:
 
-  virtual void on_size_allocate(Gtk::Allocation& allocation);
-
-  //Do extra drawing:
-  //Virtual method overrides:
-  void on_realize();
-  void on_unrealize();
-  bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
-
-  int get_column_height(guint start_widget, guint widget_count, int& total_width) const;
-
-  /**
-   * @result The height when the children are arranged optimally (so that the height is minimum).
-   */
-  int get_minimum_column_height(guint start_widget, guint columns_count, int& total_width) const;
-
   class FlowTableItem
   {
   public:
@@ -137,31 +84,18 @@ private:
 
   int get_item_requested_height(const FlowTableItem& item) const;
   void get_item_requested_width(const FlowTableItem& item, int& first, int& second) const;
-  void get_item_max_width_requested(guint start, guint height, guint& first_max_width, guint& second_max_width, guint& singles_max_width, bool& is_last_column) const; //TODO: maybe combine this with code in get_minimum_column_height().
 
   bool child_is_visible(const Gtk::Widget* widget) const;
 
-  Gtk::Allocation assign_child(Gtk::Widget* widget, int x, int y);
-  Gtk::Allocation assign_child(Gtk::Widget* widget, int x, int y, int width, int height);
 
 protected:
   typedef std::vector<FlowTableItem> type_vecChildren;
   type_vecChildren m_children;
 
-  //Reset this and check it later to see if the layout of items has changed.
-  bool m_columns_allocated_changed;
 
 private:
-  guint m_columns_count;
-  guint m_column_padding, m_row_padding;
   bool m_design_mode;
 
-  //Lines to draw in on_expose_event:
-  typedef std::pair<Gdk::Point, Gdk::Point> type_line;
-  typedef std::vector<type_line> type_vecLines;
-  type_vecLines m_lines_vertical;
-  type_vecLines m_lines_horizontal;
-
   //For drawing:
   Glib::RefPtr<Gdk::Window> m_refGdkWindow;
 };
diff --git a/glom/utility_widgets/test_flowtable.cc b/glom/utility_widgets/test_flowtable.cc
index 78f7dba..4cc1fc6 100644
--- a/glom/utility_widgets/test_flowtable.cc
+++ b/glom/utility_widgets/test_flowtable.cc
@@ -17,7 +17,7 @@
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
- 
+
 #include <gtkmm.h>
 #include "flowtable.h"
 
@@ -44,9 +44,9 @@ main(int argc, char* argv[])
   Gtk::Window window;
   //Gtk::VBox flowtable;
   Glom::FlowTable flowtable;
-  flowtable.set_columns_count(3);
-  flowtable.set_column_padding(100);
-  flowtable.set_row_padding(0);
+  flowtable.set_lines(2);
+  flowtable.set_horizontal_spacing(6);
+  flowtable.set_vertical_spacing(6);
 
   Gtk::Entry button7; button7.set_text("seven");
   button7.show();
@@ -69,20 +69,15 @@ main(int argc, char* argv[])
   Gtk::Entry button12; button11.set_text("eleven");
   flowtable.add(button11, button12);
   button11.show(); button12.show();
-  
+
   window.add(flowtable);
   flowtable.set_design_mode();
   flowtable.show();
 
 //  Glom::DragWindow drag_window;
 //  drag_window.show();
-  
+
   Gtk::Main::run(window);
 
   return 0;
 }
-
-
-
-
-



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]