Index: glom/libglom/data_structure/layout/layoutitem_placeholder.cc
===================================================================
--- glom/libglom/data_structure/layout/layoutitem_placeholder.cc	(Revision 0)
+++ glom/libglom/data_structure/layout/layoutitem_placeholder.cc	(Revision 0)
@@ -0,0 +1,67 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * glom
+ * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
+ * 
+ * glom is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * glom is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with glom.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#include "layoutitem_placeholder.h"
+#include <glibmm/i18n.h>
+
+namespace Glom
+{
+	
+LayoutItem_Placeholder::LayoutItem_Placeholder()
+{
+	
+}
+
+LayoutItem_Placeholder::~LayoutItem_Placeholder()
+{
+	
+}
+	
+LayoutItem_Placeholder::LayoutItem_Placeholder(const LayoutItem_Placeholder& src) :
+	LayoutItem(src)
+{
+	
+}
+	
+LayoutItem* LayoutItem_Placeholder::clone() const
+{
+	return new LayoutItem_Placeholder(*this);
+}
+	
+bool LayoutItem_Placeholder::operator==(const LayoutItem_Placeholder* src) const
+{
+	return LayoutItem::operator==(*src);	
+}
+
+Glib::ustring LayoutItem_Placeholder::get_part_type_name() const
+{
+	return _("Placeholder");
+}
+
+Glib::ustring LayoutItem_Placeholder::get_report_part_id() const
+{
+	return "placeholder";
+}
+
+}
Index: glom/libglom/data_structure/layout/layoutitem_placeholder.h
===================================================================
--- glom/libglom/data_structure/layout/layoutitem_placeholder.h	(Revision 0)
+++ glom/libglom/data_structure/layout/layoutitem_placeholder.h	(Revision 0)
@@ -0,0 +1,58 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * glom
+ * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
+ * 
+ * glom is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * glom is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with glom.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _LAYOUTITEM_PLACEHOLDER_H_
+#define _LAYOUTITEM_PLACEHOLDER_H_
+
+#include "layoutitem.h"
+
+namespace Glom
+{
+
+class LayoutItem_Placeholder: public LayoutItem 
+{
+public:
+	LayoutItem_Placeholder();
+	~LayoutItem_Placeholder();
+	
+	LayoutItem_Placeholder(const LayoutItem_Placeholder& src);
+	
+	/** Create a new copied instance.
+	* This allows us to deep-copy a list of LayoutItems.
+	*/
+	virtual LayoutItem* clone() const;
+	
+	virtual Glib::ustring get_part_type_name() const;
+	virtual Glib::ustring get_report_part_id() const;
+	
+	bool operator==(const LayoutItem_Placeholder* src) const;
+protected:
+
+private:
+
+};
+
+}
+
+#endif // _LAYOUTITEM_PLACEHOLDER_H_
Index: glom/libglom/data_structure/layout/Makefile.am
===================================================================
--- glom/libglom/data_structure/layout/Makefile.am	(Revision 1147)
+++ glom/libglom/data_structure/layout/Makefile.am	(Arbeitskopie)
@@ -13,5 +13,7 @@
                               layoutitem_image.h layoutitem_image.cc \
                               usesrelationship.h usesrelationship.cc \
                               fieldformatting.h fieldformatting.cc \
-                              custom_title.h custom_title.cc
+                              custom_title.h custom_title.cc \
+                              layoutitem_placeholder.h \
+                              layoutitem_placeholder.cc
 
Index: glom/utility_widgets/flowtablewithfields.h
===================================================================
--- glom/utility_widgets/flowtablewithfields.h	(Revision 1147)
+++ glom/utility_widgets/flowtablewithfields.h	(Arbeitskopie)
@@ -28,6 +28,7 @@
 #include <glom/libglom/data_structure/layout/layoutitem_portal.h>
 #include <glom/libglom/data_structure/layout/layoutitem_button.h>
 #include <glom/libglom/data_structure/layout/layoutitem_text.h>
+#include <glom/libglom/data_structure/layout/layoutitem_placeholder.h>
 #include <glom/libglom/data_structure/field.h>
 #include <glom/libglom/document/document_glom.h>
 #include "../mode_data/box_data_list_related.h"
@@ -65,7 +66,7 @@
 
   virtual void add_layout_item(const sharedptr<LayoutItem>& item);
   virtual void add_layout_group(const sharedptr<LayoutGroup>& group);
-
+	
   virtual void set_field_editable(const sharedptr<const LayoutItem_Field>& field, bool editable = true);
 
   virtual Gnome::Gda::Value get_field_value(const sharedptr<const LayoutItem_Field>& field) const;
@@ -184,6 +185,7 @@
   void add_button_at_position(const sharedptr<LayoutItem_Button>& layoutitem_button, const Glib::ustring& table_name, const type_list_layoutwidgets::iterator& add_before);
   void add_textobject_at_position(const sharedptr<LayoutItem_Text>& layoutitem_text, const Glib::ustring& table_name, const type_list_layoutwidgets::iterator& add_before);
   void add_imageobject_at_position(const sharedptr<LayoutItem_Image>& layoutitem_image, const Glib::ustring& table_name, const type_list_layoutwidgets::iterator& add_before);
+  void add_placeholder_at_position(const sharedptr<LayoutItem_Placeholder>& layoutitem_image, const Glib::ustring& table_name, const type_list_layoutwidgets::iterator& add_before);
 
   void add_layoutwidgetbase(LayoutWidgetBase* layout_widget);
   void add_layoutwidgetbase(LayoutWidgetBase* layout_widget, const type_list_layoutwidgets::iterator& add_before);
@@ -192,8 +194,17 @@
   void add_layout_notebook_at_position(const sharedptr<LayoutItem_Notebook>& notebook, const type_list_layoutwidgets::iterator& add_before);
   void add_layout_related_at_position(const sharedptr<LayoutItem_Portal>& portal, const type_list_layoutwidgets::iterator& add_before);
 
+  virtual void on_dnd_add_layout_item(LayoutWidgetBase* above);
+  virtual void on_dnd_add_layout_group(LayoutWidgetBase* above); 
+	virtual void on_dnd_add_placeholder(LayoutWidgetBase* above);
+	virtual void on_dnd_remove_placeholder();
+  
+  sharedptr<LayoutItem_Portal> get_layout_item_from_relation();
+  
   Box_Data_List_Related* create_related(const sharedptr<LayoutItem_Portal>& portal, bool show_title = true);
 
+  Gtk::Alignment* m_placeholder;
+  
   Glib::ustring m_table_name;
 
   type_signal_field_edited m_signal_field_edited;
Index: glom/utility_widgets/dragbutton.cc
===================================================================
--- glom/utility_widgets/dragbutton.cc	(Revision 0)
+++ glom/utility_widgets/dragbutton.cc	(Revision 0)
@@ -0,0 +1,46 @@
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#include "dragbutton.h"
+
+namespace Glom
+{
+  
+DragButton::DragButton(const Glib::ustring& label, const Glib::ustring& id)
+{
+  m_id = id;
+  set_label(label);
+  std::list<Gtk::TargetEntry> targetentries;
+  targetentries.push_back(Gtk::TargetEntry(get_target()));
+  drag_source_set(targetentries);
+}
+
+DragButton::~DragButton()
+{
+
+}
+
+void DragButton::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, 
+                                  Gtk::SelectionData& selection_data, guint, guint)
+{
+  selection_data.set(get_target(), m_id);
+}
+
+} // namespace Glom
Index: glom/utility_widgets/dragbutton.h
===================================================================
--- glom/utility_widgets/dragbutton.h	(Revision 0)
+++ glom/utility_widgets/dragbutton.h	(Revision 0)
@@ -0,0 +1,94 @@
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#include <gtkmm/button.h>
+#include <string>
+
+#ifndef DRAGBUTTON_H
+#define DRAGBUTTON_H
+
+namespace Glom
+{
+  
+class DragButton : public Gtk::Button
+{
+  public:
+    DragButton(const Glib::ustring& label, const Glib::ustring& id);  
+    ~DragButton();
+
+  
+    static gchar* get_target() {return "flowtable";};
+  protected:
+    virtual void on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, 
+                                  Gtk::SelectionData& selection_data, guint, guint);
+  
+  private:
+    Glib::ustring m_id;
+};
+
+}
+#endif // DRAGBUTTON_H
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#include <gtkmm/button.h>
+#include <string>
+
+#ifndef DRAGBUTTON_H
+#define DRAGBUTTON_H
+
+namespace Glom
+{
+  
+class DragButton : public Gtk::Button
+{
+  public:
+    DragButton(Glib::ustring label);  
+    ~DragButton();
+
+  
+    static gchar* get_target() {return "flowtable";};
+  protected:
+    virtual void on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, 
+                                  Gtk::SelectionData& selection_data, guint, guint);
+  
+  private:
+    Glib::ustring m_label;
+};
+
+}
+#endif // DRAGBUTTON_H
Index: glom/utility_widgets/test_flowtable.cc
===================================================================
--- glom/utility_widgets/test_flowtable.cc	(Revision 1147)
+++ glom/utility_widgets/test_flowtable.cc	(Arbeitskopie)
@@ -19,9 +19,23 @@
  */
  
 #include <gtkmm.h>
-#include "flowtable.h"
+#include "flowtablewithfields.h"
 
 
+#include "dragwindow.h"
+
+void on_drag_data_get_label(const Glib::RefPtr<Gdk::DragContext>&, Gtk::SelectionData& selection_data, guint, guint)
+{
+  selection_data.set(selection_data.get_target(), 8, (const guchar*)"label", 5);
+}
+
+void on_drag_data_get_entry(const Glib::RefPtr<Gdk::DragContext>&, Gtk::SelectionData& selection_data, guint, guint)
+{
+  selection_data.set(selection_data.get_target(), 8, (const guchar*)"entry", 5);
+}
+
+#include "dragwindow.h"
+
 int
 main(int argc, char* argv[])
 {
@@ -31,38 +45,8 @@
   //Gtk::VBox flowtable;
   Glom::FlowTable flowtable;
   flowtable.set_columns_count(2);
+  flowtable.set_padding(5);
 
-  Gtk::Entry button1; //"one");
-  button1.show();
-  button1.set_text("debug");
-
-  Glom::FlowTable inner_table;
-  inner_table.set_padding(20);
-  inner_table.set_design_mode();
-  inner_table.set_columns_count(1);
-  inner_table.show();
-  flowtable.add(inner_table);
-
-  Gtk::Entry button2; button2.set_text("two");
-  inner_table.add(button1, button2);
-  button2.show();
-  button2.set_size_request(40, 40);
-
-  Gtk::Entry button3; button3.set_text("three");
-  button3.show();
-
-  Gtk::Entry button4; button4.set_text("four");
-  inner_table.add(button3, button4);
-  button4.show();
-  button4.set_size_request(20, 30);
-
-  Gtk::Entry button5; button5.set_text("five");
-  button5.show();
-
-  Gtk::Entry button6; button6.set_text("six");
-  inner_table.add(button5, button6);
-  button6.show();
-
   Gtk::Entry button7; button7.set_text("seven");;
   button7.show();
   //button7.set_size_request(100, 100);
@@ -70,7 +54,7 @@
   Gtk::Entry button8; button8.set_text("eight");
   flowtable.add(button7, button8);
   button8.show();
-  button8.set_size_request(100, 300);
+  //button8.set_size_request(100, 100);
 
   Gtk::Entry button9; button9.set_text("nine");;
   button9.show();
@@ -80,6 +64,11 @@
   flowtable.add(button9, button10);
   button10.show();
 
+  Gtk::Entry button11; button11.set_text("eleven");
+  Gtk::Entry button12; button11.set_text("eleven");
+  flowtable.add(button11, button12);
+  button11.show(); button12.show();
+  
   window.add(flowtable);
   flowtable.set_design_mode();
   flowtable.show();
@@ -87,6 +76,9 @@
 
   flowtable.set_padding(20);
 
+  Glom::DragWindow drag_window;
+  drag_window.show();
+  
   Gtk::Main::run(window);
 
 
Index: glom/utility_widgets/flowtable.cc
===================================================================
--- glom/utility_widgets/flowtable.cc	(Revision 1147)
+++ glom/utility_widgets/flowtable.cc	(Arbeitskopie)
@@ -19,25 +19,40 @@
  */
  
 #include "flowtable.h"
+#include "dragbutton.h"
+#include "entryglom.h"
+#include "labelglom.h"
+#include "buttonglom.h"
+#include "imageglom.h"
+#include "layoutwidgetbase.h"
 #include "gtk/gtkwidget.h"
 #include "gdk/gdktypes.h"
+#include <iostream>
+#include <gdkmm/window.h>
 
 namespace Glom
 {
 
 FlowTable::FlowTableItem::FlowTableItem()
-: m_expand_first_full(false),
+: m_first(NULL),
+  m_second(NULL),
+  m_expand_first_full(false),
   m_expand_second(false)
 {
 }
 
 FlowTable::FlowTable()
-: m_columns_count(1),
+: m_dnd_in_progress(false),
+  m_columns_count(1),
   m_padding(0),
   m_design_mode(false)
 {
   set_flags(Gtk::NO_WINDOW);
   set_redraw_on_allocate(false);
+  std::list<Gtk::TargetEntry> drag_targets;
+  Gtk::TargetEntry drag_target(DragButton::get_target());
+  drag_targets.push_back(drag_target);
+  drag_dest_set(drag_targets);
 }
 
 FlowTable::~FlowTable()
@@ -58,7 +73,6 @@
   item.m_second = &second;
   item.m_expand_second = expand_second; //Expand to fill the width for all of the second item.
   m_children.push_back(item);
-
   gtk_widget_set_parent(first.gobj(), GTK_WIDGET(gobj()));
   gtk_widget_set_parent(second.gobj(), GTK_WIDGET(gobj()));
 }
@@ -74,6 +88,14 @@
   gtk_widget_set_parent(first.gobj(), GTK_WIDGET(gobj()));
 }
 
+/*
+ * {{{ Unrelevant for DND
+ */
+
+/*
+ * {{{ Unrelevant for DND
+ */
+
 void FlowTable::set_columns_count(guint value)
 {
   //Silently correct an invalid value:
@@ -707,22 +729,12 @@
 {
   if(m_design_mode)
   {
-    m_refGdkWindow = get_window();
+    //m_refGdkWindow = get_window();
     if(m_refGdkWindow)
     {
       m_refGC = Gdk::GC::create(m_refGdkWindow);
       m_refGC->set_line_attributes(1 /* width */, Gdk::LINE_ON_OFF_DASH, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER);
 
-      //Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
-      //Gdk::Color color_blue("blue");
-      //Gdk::Color color_red("red");
-      //colormap->alloc_color(color_blue);
-      //colormap->alloc_color(color_red);
-
-      //m_refGdkWindow->set_background( color_red );
-      //m_refGdkWindow->clear();
-      //m_refGC->set_foreground( color_blue );
-
       for(type_vecLines::iterator iter = m_lines_horizontal.begin(); iter != m_lines_horizontal.end(); ++iter)
       {
         //TODO: Add draw_line(point, point) to gdkmm:
@@ -733,12 +745,141 @@
       {
         m_refGdkWindow->draw_line(m_refGC, iter->first.get_x(), iter->first.get_y(), iter->second.get_x(), iter->second.get_y());
       }
+      // Draw preview
+      /*if (m_dnd_in_progress)
+      {
+        m_refGdkWindow->draw_rectangle(m_refGC, false, 
+                                       m_preview_rect.get_x(),
+                                       m_preview_rect.get_y(),
+                                       m_preview_rect.get_width(),
+                                       m_preview_rect.get_height());
+      }*/
     }
   }
-
   return Gtk::Container::on_expose_event(event);
 }
 
+/*
+ * }}}
+ */
+
+void FlowTable::dnd_show_preview(int drag_x, int drag_y)
+{
+  m_preview_rect.set_x(drag_x);
+  m_preview_rect.set_y(drag_y);
+  m_preview_rect.set_width(100);
+  m_preview_rect.set_height(20);
+}
+
+bool FlowTable::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time)
+{
+  dnd_show_preview(x, y);
+#ifndef TEST
+	FlowTableItem* item = dnd_get_item(x, y);
+	LayoutWidgetBase* above = dnd_find_datawidget (item);
+	// above might be 0 here...
+  g_message ("Adding placeholder");
+	on_dnd_add_placeholder (above);
+#endif
+  change_dnd_status(true);
+  return true;
+
+}
+
+void FlowTable::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& drag_context, int drag_x, int drag_y, const Gtk::SelectionData& selection_data, guint, guint time)
+{
+  FlowTableItem* item = dnd_get_item(drag_x, drag_y);
+	Glib::ustring type = selection_data.get_data_as_string();
+	LayoutWidgetBase* above = dnd_find_datawidget (item);
+#ifndef TEST
+	if (type == "LayoutItem")
+  {
+    on_dnd_add_layout_item(above);
+  }
+  else if (type == "LayoutGroup")
+  {
+    on_dnd_add_layout_group(above);
+  }
+  else
+    std::cerr << "Unknown drop type: " << type << std::endl;
+#endif
+  change_dnd_status(false);
+}
+
+void FlowTable::on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& drag_context, guint time)
+{
+#ifndef TEST
+  on_dnd_remove_placeholder();
+  g_message ("Removing placeholder");
+#endif
+  change_dnd_status(false);
+}
+
+// Calculate the nearest FlowTableItem below the current drag position
+FlowTable::FlowTableItem*
+FlowTable::dnd_get_item(int drag_x, int drag_y)
+{
+  for (std::vector<FlowTableItem>::iterator cur_item = m_children.begin(); cur_item != m_children.end(); 
+       cur_item++)
+  {
+    int x, y;
+    cur_item->m_first->get_window()->get_position(x, y);
+    if (drag_y > y)
+    {
+      std::cout << "Found Widget"  << std::endl;
+      return &(*cur_item);
+    }
+  }
+  return 0;
+}
+
+void FlowTable::change_dnd_status(bool active)
+{
+  m_dnd_in_progress = active;
+  queue_draw();
+}
+
+LayoutWidgetBase* FlowTable::dnd_find_datawidget(FlowTableItem* item)
+{
+#ifndef TEST
+  // Test if we have a datawidget below which we want to add
+	LayoutWidgetBase* above = 0;
+  if (item)
+  {
+    if (item->m_second)
+    {
+      above = dynamic_cast<LayoutWidgetBase*>(item->m_second);
+      std::cout << "above LayoutWidget: " << (above != 0) << std::endl;
+    }
+    else if (item->m_first)
+    {
+      // LayoutGroup
+      Gtk::Frame* frame = dynamic_cast<Gtk::Frame*>(item->m_first);
+      if (frame)
+      {
+        std::cout << "Frame:" << dynamic_cast<Gtk::Label*>(frame->get_label_widget())->get_text() 
+          << std::endl;
+        Gtk::Alignment* alignment = dynamic_cast<Gtk::Alignment*>(frame->get_child());
+        if (alignment)
+        {
+          std::cout << "Alignment" << std::endl;
+          Gtk::EventBox* eventbox = dynamic_cast<Gtk::EventBox*>(alignment->get_child());
+          if (eventbox)
+          {
+            above = dynamic_cast<LayoutWidgetBase*>(eventbox->get_child());
+            std::cout << "Eventbox!" << std::endl;
+          }
+        }
+        std::cout << "above LayoutGroup: " << (above != 0) << std::endl;
+      }
+    }
+  }
+	return above;
+#else
+	return 0;
+#endif
+}
+
 } //namespace Glom
 
 
Index: glom/utility_widgets/flowtable.h
===================================================================
--- glom/utility_widgets/flowtable.h	(Revision 1147)
+++ glom/utility_widgets/flowtable.h	(Arbeitskopie)
@@ -22,6 +22,7 @@
 #define GLOM_UTILITYWIDGETS_FLOWTABLE_H
 
 #include <gtkmm.h>
+#include "layoutwidgetbase.h"
 
 namespace Glom
 {
@@ -36,7 +37,7 @@
 
   virtual void add(Gtk::Widget& first, Gtk::Widget& second, bool expand_second = false);
   virtual void add(Gtk::Widget& first, bool expand = false); //override
-
+  
   virtual void remove(Gtk::Widget& first); //override
 
   void set_columns_count(guint value);
@@ -69,6 +70,17 @@
   virtual void on_unrealize();
   virtual bool on_expose_event(GdkEventExpose* event);
 
+  //DND stuff:
+  virtual bool on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time);
+  virtual void on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& drag_context, guint time);
+  virtual void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& drag_context, int, int, const Gtk::SelectionData& selection_data, guint, guint time);
+#ifndef TEST 
+  virtual void on_dnd_add_layout_item(LayoutWidgetBase* above) = 0;
+  virtual void on_dnd_add_layout_group(LayoutWidgetBase* above) = 0;
+	virtual void on_dnd_add_placeholder(LayoutWidgetBase* above) = 0;
+  virtual void on_dnd_remove_placeholder() = 0;
+#endif
+
   int get_column_height(guint start_widget, guint widget_count, int& total_width) const;
 
   /** 
@@ -96,7 +108,19 @@
   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().
-
+  
+  FlowTableItem* dnd_get_item(int x, int y);
+  void dnd_show_preview(int drag_x, int drag_x);
+  void change_dnd_status(bool active = true);
+	LayoutWidgetBase* dnd_find_datawidget(FlowTableItem* item);
+	
+  bool m_dnd_in_progress;
+  
+  enum
+  {
+    BELOW = -1
+  };
+  
   bool child_is_visible(const Gtk::Widget* widget) const;
 
   Gtk::Allocation assign_child(Gtk::Widget* widget, int x, int y);
@@ -116,6 +140,9 @@
   //For drawing:
   Glib::RefPtr<Gdk::Window> m_refGdkWindow;
   Glib::RefPtr<Gdk::GC> m_refGC;
+  
+  // For preview rectacle
+  Gdk::Rectangle m_preview_rect;
 };
 
 } //namespace Glom
Index: glom/utility_widgets/flowtablewithfields.cc
===================================================================
--- glom/utility_widgets/flowtablewithfields.cc	(Revision 1147)
+++ glom/utility_widgets/flowtablewithfields.cc	(Arbeitskopie)
@@ -24,16 +24,18 @@
 #include "notebookglom.h"
 #include "imageglom.h"
 #include "labelglom.h"
+#include "../application.h"
 #include <gtkmm/checkbutton.h>
 #include <glom/libglom/data_structure/glomconversions.h>
 #include "../mode_data/box_data_list_related.h"
 #include "../mode_data/dialog_choose_relationship.h"
 #include <bakery/App/App_Gtk.h> //For util_bold_message().
 #include <glibmm/i18n.h>
+#include <glom/libglom/data_structure/layout/layoutitem_placeholder.h>
 
 namespace Glom
 {
-
+  
 FlowTableWithFields::Info::Info()
 : m_first(0),
   m_second(0),
@@ -42,7 +44,8 @@
 }
 
 FlowTableWithFields::FlowTableWithFields(const Glib::ustring& table_name)
-: m_table_name(table_name)
+: m_placeholder(0),
+  m_table_name(table_name)
 {
 }
 
@@ -133,6 +136,13 @@
               sharedptr<LayoutItem_Image> layout_imageobject = sharedptr<LayoutItem_Image>::cast_dynamic(item);
               if(layout_imageobject)
                 add_imageobject_at_position(layout_imageobject, m_table_name, add_before);
+            	else
+            	{
+            	  sharedptr<LayoutItem_Placeholder> layout_placeholder = 
+            	    sharedptr<LayoutItem_Placeholder>::cast_dynamic(item);
+                if (layout_placeholder)
+                  add_placeholder_at_position(layout_placeholder, m_table_name, add_before);
+              }
             }
           }
         }
@@ -179,9 +189,13 @@
     flow_table->set_table(m_table_name);
 
     flow_table->set_columns_count(group->m_columns_count);
-    flow_table->set_padding(6);
     flow_table->show();
-    alignment->add(*flow_table);
+    
+    Gtk::EventBox* event_box = Gtk::manage( new Gtk::EventBox() );
+    event_box->add(*flow_table);
+    event_box->show();
+    
+    alignment->add(*event_box);
 
     LayoutGroup::type_map_items items = group->get_items(); 
     for(LayoutGroup::type_map_items::const_iterator iter = items.begin(); iter != items.end(); ++iter)
@@ -192,7 +206,7 @@
         flow_table->add_layout_item(item);
       }
     }
-
+    
     add(*frame, true /* expand */);
 
     m_sub_flow_tables.push_back(flow_table);
@@ -506,6 +520,28 @@
   }
 }
 
+void FlowTableWithFields::add_placeholder_at_position(const sharedptr<LayoutItem_Placeholder>& layoutitem_text, const Glib::ustring& /* table_name */, const type_list_layoutwidgets::iterator& add_before)
+{
+  //Add the widget:
+  m_placeholder = Gtk::manage(new Gtk::Alignment());
+  m_placeholder->set(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+  m_placeholder->show();
+
+  LabelGlom* label = Gtk::manage(new LabelGlom("", 0.0 /* xalign */, 0.5 /* yalign */)); //The alignment here seems to be necessary as well (or instead of) the parent Gtk::Alignment.
+  // FIXME: Theming?
+  Glib::ustring markup = "<span background=\"#00FF00\">";
+  markup += ("New Field"); 
+  markup += "</span>";
+  label->set_markup (markup);
+  label->show();
+  m_placeholder->add(*label);
+
+  // We don't want to modify the database...
+  //add_layoutwidgetbase(label, add_before);
+
+  add(*m_placeholder, true /* expand */);
+}
+
 void FlowTableWithFields::add_imageobject_at_position(const sharedptr<LayoutItem_Image>& layoutitem_image, const Glib::ustring& /* table_name */, const type_list_layoutwidgets::iterator& add_before)
 {
   //Add the widget:
@@ -938,39 +974,7 @@
   }
   else if(item_type == LayoutWidgetBase::TYPE_PORTAL)
   {
-    try
-    {
-      Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(GLOM_GLADEDIR "glom.glade", "dialog_choose_relationship");
-
-      Dialog_ChooseRelationship* dialog = 0;
-      refXml->get_widget_derived("dialog_choose_relationship", dialog);
-
-      if(dialog)
-      {
-        Document_Glom* pDocument = static_cast<Document_Glom*>(get_document());
-        dialog->set_document(pDocument, m_table_name);
-        //TODO: dialog->set_transient_for(*get_app_window());
-        const int response = dialog->run();
-        dialog->hide();
-        if(response == Gtk::RESPONSE_OK)
-        {
-          //Get the chosen relationship:
-          sharedptr<Relationship> relationship  = dialog->get_relationship_chosen();
-          if(relationship)
-          {
-            sharedptr<LayoutItem_Portal> layout_item = sharedptr<LayoutItem_Portal>::create();
-            layout_item->set_relationship(relationship);
-            layout_item_new = layout_item;
-          }
-        }
-
-        delete dialog;
-      }
-    }
-    catch(const Gnome::Glade::XmlError& ex)
-    {
-      std::cerr << ex.what() << std::endl;
-    }
+    layout_item_new = get_layout_item_from_relation();
   }
   else if(item_type == LayoutWidgetBase::TYPE_BUTTON)
   {
@@ -979,7 +983,7 @@
     layout_item->set_title(_("New Button"));
     layout_item_new = layout_item;
   }
-  else if(item_type == LayoutWidgetBase::TYPE_BUTTON)
+  else if(item_type == LayoutWidgetBase::TYPE_TEXT)
   {
     sharedptr<LayoutItem_Text> layout_item = sharedptr<LayoutItem_Text>::create();
     layout_item->set_name(_("text"));
@@ -1067,4 +1071,128 @@
   signal_requested_related_details().emit(table_name, primary_key_value);
 }
 
+void FlowTableWithFields::on_dnd_add_layout_item(LayoutWidgetBase* above)
+{
+  type_list_layoutwidgets::iterator cur_widget;
+  if (above)
+  {
+    for (cur_widget = m_list_layoutwidgets.begin(); cur_widget != m_list_layoutwidgets.end();
+         cur_widget++)
+    {
+      if (*cur_widget == above)
+      {
+        break;
+      }
+    }
+  }
+  else
+  {
+    cur_widget = m_list_layoutwidgets.end();
+  }
+  Gtk::Container* pWindow = get_toplevel();
+  App_Glom* pApp = dynamic_cast<App_Glom*>(pWindow);
+  sharedptr<LayoutItem_Field> layout_item_field = DataWidget::offer_field_list(m_table_name,
+                                                                               sharedptr<LayoutItem_Field>(),
+                                                                               get_document(),
+                                                                               pApp);
+  if(layout_item_field)
+    add_layout_item_at_position(layout_item_field, cur_widget);
+}
+
+void FlowTableWithFields::on_dnd_add_layout_group(LayoutWidgetBase* above)
+{
+  type_list_layoutwidgets::iterator cur_widget;
+  if (above)
+  {
+    for (cur_widget = m_list_layoutwidgets.begin(); cur_widget != m_list_layoutwidgets.end();
+         cur_widget++)
+    {
+      if (*cur_widget == above)
+      {
+        break;
+      }
+    }
+  }
+  else
+  {
+    cur_widget = m_list_layoutwidgets.end();
+  }
+  sharedptr<LayoutGroup> group(new LayoutGroup());
+  group->set_title("test");
+  add_layout_group_at_position(group, cur_widget);
+}
+
+void FlowTableWithFields::on_dnd_add_placeholder(LayoutWidgetBase* above)
+{
+	type_list_layoutwidgets::iterator cur_widget;
+	if (m_placeholder)
+	{
+	  // Only one placeholder at a time
+	  on_dnd_remove_placeholder();
+	}
+	
+  if (above)
+  {
+    for (cur_widget = m_list_layoutwidgets.begin(); cur_widget != m_list_layoutwidgets.end();
+         cur_widget++)
+    {	
+			if (*cur_widget == above)
+      {
+        break;
+      }
+    }
+  }
+  else
+  {
+    cur_widget = m_list_layoutwidgets.end();
+  }
+  sharedptr<LayoutItem_Placeholder> placeholder_field(new LayoutItem_Placeholder);
+	add_layout_item_at_position (placeholder_field, cur_widget);
+}
+
+void FlowTableWithFields::on_dnd_remove_placeholder()
+{
+  if (m_placeholder)
+  {
+    remove (*m_placeholder);
+  }
+}
+
+sharedptr<LayoutItem_Portal> FlowTableWithFields::get_layout_item_from_relation()
+{
+  sharedptr<LayoutItem_Portal> layout_item(0);
+  try
+  {
+    Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(GLOM_GLADEDIR "glom.glade", "dialog_choose_relationship");
+
+    Dialog_ChooseRelationship* dialog = 0;
+    refXml->get_widget_derived("dialog_choose_relationship", dialog);
+
+    if(dialog)
+    {
+      Document_Glom* pDocument = static_cast<Document_Glom*>(get_document());
+      dialog->set_document(pDocument, m_table_name);
+      //TODO: dialog->set_transient_for(*get_app_window());
+      const int response = dialog->run();
+      dialog->hide();
+      if(response == Gtk::RESPONSE_OK)
+      {
+        //Get the chosen relationship:
+        sharedptr<Relationship> relationship  = dialog->get_relationship_chosen();
+        if(relationship)
+        {
+          layout_item = sharedptr<LayoutItem_Portal>::create();
+          layout_item->set_relationship(relationship);
+        }
+      }
+      delete dialog;
+    }
+  }
+  catch(const Gnome::Glade::XmlError& ex)
+  {
+    std::cerr << ex.what() << std::endl;
+  }
+  return layout_item;
+}
+
 } //namespace Glom
Index: glom/utility_widgets/dragwindow.cc
===================================================================
--- glom/utility_widgets/dragwindow.cc	(Revision 0)
+++ glom/utility_widgets/dragwindow.cc	(Revision 0)
@@ -0,0 +1,48 @@
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "dragwindow.h"
+#include "dragbutton.h"
+#include <glibmm/i18n.h>
+
+namespace Glom
+{
+
+DragWindow::DragWindow()
+{
+  set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+  set_title(_("Drag window"));  
+  
+  DragButton* drag_item = Gtk::manage(new DragButton(_("Drag LayoutItem"), "LayoutItem"));
+  DragButton* drag_group = Gtk::manage(new DragButton(_("Drag LayoutGroup"), "LayoutGroup"));  
+  
+  m_box.pack_start(*drag_item);
+  m_box.pack_start(*drag_group);
+                                       
+  add (m_box);
+  show_all_children();
+}
+
+DragWindow::~DragWindow()
+{
+  
+}
+
+} // namespace Glom
Index: glom/utility_widgets/dragwindow.h
===================================================================
--- glom/utility_widgets/dragwindow.h	(Revision 0)
+++ glom/utility_widgets/dragwindow.h	(Revision 0)
@@ -0,0 +1,84 @@
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DRAGWINDOW_H_
+#define _DRAGWINDOW_H_
+
+#include <gtkmm/window.h>
+#include <gtkmm/box.h>
+
+namespace Glom
+{
+
+class DragWindow: public Gtk::Window 
+{
+  public:
+    DragWindow();
+    ~DragWindow();
+  
+  private:
+    Gtk::HBox m_box;
+};
+
+}
+
+#endif // _DRAGWINDOW_H_
+/* Glom
+ *
+ * Copyright (C) 2007 Johannes Schmid <johannes.schmid@openismus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DRAGWINDOW_H_
+#define _DRAGWINDOW_H_
+
+#include <gtkmm/window.h>
+#include <gtkmm/box.h>
+
+namespace Glom
+{
+
+class DragWindow: public Gtk::Window 
+{
+  public:
+    DragWindow();
+    ~DragWindow();
+  
+  private:
+    Gtk::HBox m_box;
+};
+
+}
+
+#endif // _DRAGWINDOW_H_
Index: glom/utility_widgets/datawidget.cc
===================================================================
--- glom/utility_widgets/datawidget.cc	(Revision 1147)
+++ glom/utility_widgets/datawidget.cc	(Arbeitskopie)
@@ -528,6 +528,11 @@
 
 sharedptr<LayoutItem_Field> DataWidget::offer_field_list(const Glib::ustring& table_name, const sharedptr<const LayoutItem_Field>& start_field)
 {
+  return offer_field_list(table_name, start_field, get_document(), get_application());
+}
+
+sharedptr<LayoutItem_Field> DataWidget::offer_field_list(const Glib::ustring& table_name, const sharedptr<const LayoutItem_Field>& start_field, Document_Glom* document, App_Glom* app)
+{
   sharedptr<LayoutItem_Field> result;
 
   try
@@ -539,8 +544,8 @@
 
     if(dialog)
     {
-      dialog->set_document(get_document(), table_name, start_field);
-      dialog->set_transient_for(*get_application());
+      dialog->set_document(document, table_name, start_field);
+      dialog->set_transient_for(*app);
       int response = dialog->run();
       dialog->hide();
       if(response == Gtk::RESPONSE_OK)
Index: glom/utility_widgets/datawidget.h
===================================================================
--- glom/utility_widgets/datawidget.h	(Revision 1147)
+++ glom/utility_widgets/datawidget.h	(Arbeitskopie)
@@ -60,6 +60,7 @@
   virtual void set_editable(bool editable = true);
   virtual void set_viewable(bool viewable = true);
 
+  static sharedptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name, const sharedptr<const LayoutItem_Field>& start_field, Document_Glom* document, App_Glom* app);
   sharedptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name);
   sharedptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name, const sharedptr<const LayoutItem_Field>& start_field);
 #ifndef ENABLE_CLIENT_ONLY
Index: glom/utility_widgets/Makefile.am
===================================================================
--- glom/utility_widgets/Makefile.am	(Revision 1147)
+++ glom/utility_widgets/Makefile.am	(Arbeitskopie)
@@ -33,15 +33,32 @@
                                labelglom.h labelglom.cc \
                                dialog_choose_id.cc dialog_choose_id.h \
                                dialog_choose_date.cc dialog_choose_date.h \
-                               filechooserdialog.cc filechooserdialog.h
+                               filechooserdialog.cc filechooserdialog.h \
+                               dragbutton.cc dragbutton.h \
+                               dragwindow.cc dragwindow.h \
+                               floweventbox.h floweventbox.cc 
 
 libutility_widgets_a_LIBADD = adddel/libutility_widgets_adddel.a \
                               db_adddel/libutility_widgets_db_adddel.a
 
 
+
 noinst_PROGRAMS = test
+test_SOURCES = test_flowtable.cc \
+  flowtable.cc \
+  dragbutton.cc \
+  dragwindow.cc 
+test_LDADD = $(GLOM_LIBS)
+test_CXXFLAGS = -DTEST
 
-test_SOURCES = test_flowtable.cc flowtable.cc flowtable.h
 
-test_LDADD =  $(GLOM_LIBS)
 
+
+
+
+
+
+
+
+
+
Index: glom/frame_glom.cc
===================================================================
--- glom/frame_glom.cc	(Revision 1147)
+++ glom/frame_glom.cc	(Arbeitskopie)
@@ -37,6 +37,7 @@
 #ifndef ENABLE_CLIENT_ONLY
 #include <glom/mode_design/dialog_add_related_table.h>
 #include <glom/mode_design/script_library/dialog_script_library.h>
+#include <glom/utility_widgets/dragwindow.h>
 #endif // !ENABLE_CLIENT_ONLY
 
 #ifndef ENABLE_CLIENT_ONLY
@@ -1062,7 +1063,7 @@
 
   if(m_pLabel_userlevel)
     m_pLabel_userlevel->set_text(user_level_name);
-
+  
   show_table_title(); 
 }
 
@@ -1249,6 +1250,12 @@
 
 }
 
+void Frame_Glom::on_menu_developer_fields_interactive()
+{
+  DragWindow* dragwin = new DragWindow;
+  dragwin->show();
+}
+
 void Frame_Glom::do_menu_developer_fields(Gtk::Window& parent)
 {
   //Check that there is a table to show:
Index: glom/application.cc
===================================================================
--- glom/application.cc	(Revision 1147)
+++ glom/application.cc	(Arbeitskopie)
@@ -333,6 +333,11 @@
   m_listDeveloperActions.push_back(action);  
   m_refActionGroup_Others->add(action, sigc::mem_fun(*m_pFrame, &Frame_Glom::on_menu_developer_fields) );
 
+  action = Gtk::Action::create("GlomAction_Menu_Developer_Fields_Interactive", _("_Fields Interactive"));
+  m_listDeveloperActions.push_back(action);  
+  m_refActionGroup_Others->add(action, sigc::mem_fun(*m_pFrame, &Frame_Glom::on_menu_developer_fields_interactive) );
+	
+	
   action = Gtk::Action::create("GlomAction_Menu_Developer_RelationshipsOverview", _("_Relationships Overview"));
   m_listDeveloperActions.push_back(action);
   m_refActionGroup_Others->add(action, sigc::mem_fun(*m_pFrame, &Frame_Glom::on_menu_developer_relationships_overview) );
@@ -401,6 +406,7 @@
     "      <menu action='Glom_Menu_Developer'>"
     "        <menuitem action='GlomAction_Menu_Developer_Database_Preferences' />"
     "        <menuitem action='GlomAction_Menu_Developer_Fields' />"
+    "        <menuitem action='GlomAction_Menu_Developer_Fields_Interactive' />"		
     "        <menuitem action='GlomAction_Menu_Developer_Relationships' />"
     "        <menuitem action='GlomAction_Menu_Developer_RelationshipsOverview' />"
     "        <menuitem action='GlomAction_Menu_Developer_Layout' />"
Index: glom/frame_glom.h
===================================================================
--- glom/frame_glom.h	(Revision 1147)
+++ glom/frame_glom.h	(Arbeitskopie)
@@ -97,6 +97,7 @@
   void on_menu_developer_database_preferences();
 
   void on_menu_developer_fields();
+  void on_menu_developer_fields_interactive();
   void do_menu_developer_fields(Gtk::Window& parent);
 
   void on_menu_developer_relationships_overview();
