Index: ChangeLog
===================================================================
--- ChangeLog	(Revision 1099)
+++ ChangeLog	(Arbeitskopie)
@@ -1,3 +1,22 @@
+2007-04-30  Johannes Schmid <johannes.schmid@openismus.com>
+
+	* glom/frame_glom.cc:
+	* glom/utility_widgets/Makefile.am:
+	* glom/utility_widgets/dragbutton.cc:
+	* glom/utility_widgets/dragbutton.h:
+	* glom/utility_widgets/dragwindow.cc:
+	* glom/utility_widgets/dragwindow.h:
+	* glom/utility_widgets/flowtable.cc:
+	* glom/utility_widgets/flowtable.h:
+	* glom/utility_widgets/flowtablewithfields.cc:
+	* glom/utility_widgets/flowtablewithfields.h:
+	* glom/utility_widgets/test_flowtable.cc:
+	
+	Dnd test code
+	To test, choose Developer->Fields menu item. A small window with a button to drag
+	from will popup. Try to drag this where you want it in the window, you should be able to choose
+	the type of the field. Anyway, the preview does not yet work like in the test_flowtable test program.
+
 2007-04-23  Armin Burgmeier  <armin@openismus.com>
 
 	* glom/glade.glom: Fixed the dialog so that the recent chooser is
Index: docs/user-guide/es/legal.xml
===================================================================
--- docs/user-guide/es/legal.xml	(Revision 1099)
+++ docs/user-guide/es/legal.xml	(Arbeitskopie)
@@ -1,76 +1,16 @@
-   <legalnotice id="legalnotice">
-         <para>
-           Permission is granted to copy, distribute and/or modify this
-           document under the terms of the GNU Free Documentation
-           License (GFDL), Version 1.1 or any later version published
-           by the Free Software Foundation with no Invariant Sections,
-           no Front-Cover Texts, and no Back-Cover Texts.  You can find
-           a copy of the GFDL at this <ulink type="help"
-           url="ghelp:fdl">link</ulink> or in the file COPYING-DOCS
-           distributed with this manual.
-          </para>
-          <para> This manual is part of a collection of GNOME manuals
-           distributed under the GFDL.  If you want to distribute this
-           manual separately from the collection, you can do so by
-           adding a copy of the license to the manual, as described in
-           section 6 of the license.
-         </para>
+<?xml version="1.0" encoding="utf-8"?>
+<legalnotice id="legalnotice">
+         <para>Se otorga permiso para copiar, distribuir y/o modificar este documento bajo los términos de la Licencia de Documentación Libre de GNU, Versión 1.1 o cualquier otra versión posterior publicada por la Free Software Foundation; sin Secciones Invariantes ni Textos de Cubierta Delantera ni Textos de Cubierta Trasera. Puede encontrar una copia de la licencia GFDL en este <ulink type="help" url="ghelp:fdl">enlace</ulink> o en el archivo COPYING-DOCS distribuido con este manual.</para>
+          <para>Este manual es parte de una colección de manuales de GNOME distribuido bajo la GFDL. Si quiere distribuir este manual por separado de la colección, puede hacerlo añadiendo una copia de la licencia al manual, tal como se describe en la sección 6 de la licencia.</para>
  
-         <para>
-           Many of the names used by companies to distinguish their
-           products and services are claimed as trademarks. Where those
-           names appear in any GNOME documentation, and the members of
-           the GNOME Documentation Project are made aware of those
-           trademarks, then the names are in capital letters or initial
-           capital letters.
-         </para>
+         <para>Muchos de los nombres usados por compañías para distinguir sus productos y servicios son mencionados como marcas comerciales. Donde esos nombres aparezcan en cualquier documentación de GNOME, y los miembros del Proyecto de Documentación de GNOME están al corriente de esas marcas comerciales, entonces los nombres se pondrán en mayúsculas o con la inicial en mayúsculas.</para>
  
-         <para>
-           DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT ARE PROVIDED
-           UNDER  THE TERMS OF THE GNU FREE DOCUMENTATION LICENSE
-           WITH THE FURTHER UNDERSTANDING THAT:
- 
-           <orderedlist>
+         <para>ESTE DOCUMENTO Y LAS VERSIONES MODIFICADAS DEL MISMO SE PROPORCIONAN SEGÚN LAS CONDICIONES ESTABLECIDAS EN LA LICENCIA DE DOCUMENTACIÓN LIBRE DE GNU (GFDL) Y TENIENDO EN CUENTA QUE: <orderedlist>
                  <listitem>
-                   <para>DOCUMENT IS PROVIDED ON AN "AS IS" BASIS,
-                     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR
-                     IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-                     THAT THE DOCUMENT OR MODIFIED VERSION OF THE
-                     DOCUMENT IS FREE OF DEFECTS MERCHANTABLE, FIT FOR
-                     A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
-                     RISK AS TO THE QUALITY, ACCURACY, AND PERFORMANCE
-                     OF THE DOCUMENT OR MODIFIED VERSION OF THE
-                     DOCUMENT IS WITH YOU. SHOULD ANY DOCUMENT OR
-                     MODIFIED VERSION PROVE DEFECTIVE IN ANY RESPECT,
-                     YOU (NOT THE INITIAL WRITER, AUTHOR OR ANY
-                     CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
-                     SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
-                     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
-                     LICENSE. NO USE OF ANY DOCUMENT OR MODIFIED
-                     VERSION OF THE DOCUMENT IS AUTHORIZED HEREUNDER
-                     EXCEPT UNDER THIS DISCLAIMER; AND
-                   </para>
+                   <para>EL DOCUMENTO SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, NI EXPLÍCITA NI IMPLÍCITA INCLUYENDO, SIN LIMITACIÓN, GARANTÍA DE QUE EL DOCUMENTO O VERSIÓN MODIFICADA DE ÉSTE CAREZCA DE DEFECTOS COMERCIALES, SEA ADECUADO A UN FIN CONCRETO O INCUMPLA ALGUNA NORMATIVA. TODO EL RIESGO RELATIVO A LA CALIDAD, PRECISIÓN Y UTILIDAD DEL DOCUMENTO O SU VERSIÓN MODIFICADA RECAE EN USTED. SI CUALQUIER DOCUMENTO O VERSIÓN MODIFICADA DE AQUÉL RESULTARA DEFECTUOSO EN CUALQUIER ASPECTO, USTED (Y NO EL REDACTOR INICIAL, AUTOR O CONTRIBUYENTE) ASUMIRÁ LOS COSTES DE TODA REPARACIÓN, MANTENIMIENTO O CORRECCIÓN NECESARIOS. ESTA RENUNCIA DE GARANTÍA ES UNA PARTE ESENCIAL DE ESTA LICENCIA. NO SE AUTORIZA EL USO DE NINGÚN DOCUMENTO NI VERSIÓN MODIFICADA DE ÉSTE POR EL PRESENTE, SALVO DENTRO DEL CUMPLIMIENTO DE LA RENUNCIA;Y</para>
                  </listitem>
                  <listitem>
-                   <para>UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL
-                        THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE),
-                        CONTRACT, OR OTHERWISE, SHALL THE AUTHOR,
-                        INITIAL WRITER, ANY CONTRIBUTOR, OR ANY
-                        DISTRIBUTOR OF THE DOCUMENT OR MODIFIED VERSION
-                        OF THE DOCUMENT, OR ANY SUPPLIER OF ANY OF SUCH
-                        PARTIES, BE LIABLE TO ANY PERSON FOR ANY
-                        DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
-                        CONSEQUENTIAL DAMAGES OF ANY CHARACTER
-                        INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
-                        OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR
-                        MALFUNCTION, OR ANY AND ALL OTHER DAMAGES OR
-                        LOSSES ARISING OUT OF OR RELATING TO USE OF THE
-                        DOCUMENT AND MODIFIED VERSIONS OF THE DOCUMENT,
-                        EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
-                        THE POSSIBILITY OF SUCH DAMAGES.
-                   </para>
+                   <para>BAJO NINGUNA CIRCUNSTANCIA NI BAJO NINGUNA TEORÍA LEGAL, SEA POR ERROR (INCLUYENDO NEGLIGENCIA), CONTRATO O DE ALGÚN OTRO MODO, EL AUTOR, EL ESCRITOR INICIAL, CUALQUIER CONTRIBUIDOR, O CUALQUIER DISTRIBUIDOR DEL DOCUMENTO O VERSIÓN MODIFICADA DEL DOCUMENTO, O CUALQUIER PROVEEDOR DE CUALQUIERA DE ESAS PARTES, SERÁ RESPONSABLE ANTE NINGUNA PERSONA POR NINGÚN DAÑO DIRECTO, INDIRECTO, ESPECIAL, INCIDENTAL O DERIVADO DE NINGÚN TIPO, INCLUYENDO, SIN LIMITACIÓN DAÑOS POR PÉRDIDA DE MERCANCÍAS, PARO TÉCNICO, FALLO INFORMÁTICO O MAL FUNCIONAMIENTO O CUALQUIER OTRO POSIBLE DAÑO O PÉRDIDAS DERIVADAS O RELACIONADAS CON EL USO DEL DOCUMENTO O SUS VERSIONES MODIFICADAS, AUNQUE DICHA PARTE HAYA SIDO INFORMADA DE LA POSIBILIDAD DE QUE SE PRODUJESEN DICHOS DAÑOS.</para>
                  </listitem>
-           </orderedlist>
-         </para>
+           </orderedlist></para>
    </legalnotice>
- 
\ Kein Zeilenvorschub am Ende der Datei
Index: docs/user-guide/ChangeLog
===================================================================
--- docs/user-guide/ChangeLog	(Revision 1099)
+++ docs/user-guide/ChangeLog	(Arbeitskopie)
@@ -1,3 +1,15 @@
+2007-04-30  Johannes Schmid,,,  <jhs@idefix>
+
+	reviewed by: <delete if not using a buddy>
+
+	* es/legal.xml:
+
+2007-04-30  Johannes Schmid,,,  <jhs@idefix>
+
+	reviewed by: <delete if not using a buddy>
+
+	* es/legal.xml:
+
 2007-04-25  Jorge Gonzalez <jorgegonz@svn.gnome.org>
 
 	* es/es.po: Added spanish translation
Index: glom/utility_widgets/flowtablewithfields.h
===================================================================
--- glom/utility_widgets/flowtablewithfields.h	(Revision 1099)
+++ glom/utility_widgets/flowtablewithfields.h	(Arbeitskopie)
@@ -188,8 +188,11 @@
   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(DataWidget* widget);
+  
   Box_Data_List_Related* create_related(const sharedptr<LayoutItem_Portal>& portal, bool show_title = true);
 
+  
   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(Glib::ustring label)
+{
+  m_label = label;
+  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(selection_data.get_target(), m_label);
+}
+
+} // 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,47 @@
+/* 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 1099)
+++ glom/utility_widgets/test_flowtable.cc	(Arbeitskopie)
@@ -22,6 +22,8 @@
 #include "flowtable.h"
 
 
+#include "dragwindow.h"
+
 int
 main(int argc, char* argv[])
 {
@@ -31,38 +33,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 +42,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 +52,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 +64,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 1099)
+++ 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,11 +73,70 @@
   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()));
+  setup_drag(item);
 }
 
+void FlowTable::insert_above(Gtk::Widget& widget, Gtk::Widget& before, bool expand_second)
+{
+  bool found = false;
+  std::vector<FlowTableItem>::iterator pos;
+  for (pos = m_children.begin(); pos != m_children.end(); pos++)
+  {
+      if (((*pos).m_first && (*pos).m_first->gobj() == before.gobj()) || ((*pos).m_second && (*pos).m_second->gobj() == before.gobj()))
+      {
+        std::cout << "found!" << std::endl;
+        found = true;
+	break;
+      }
+  }
+  if (!found)
+    return;
+  FlowTableItem item;
+  item.m_first = &widget;
+  item.m_second = 0;
+  item.m_expand_second = expand_second;
+  gtk_widget_set_parent(widget.gobj(), GTK_WIDGET(gobj()));
+  if (pos == m_children.end())
+  {
+    m_children.push_back(item);
+  } else {
+    m_children.insert(pos, item);
+  }
+  setup_drag(item);
+}
+
+
+
+void FlowTable::insert_below(Gtk::Widget& widget, Gtk::Widget& after, bool expand_second)
+{
+  bool found = false;
+  std::vector<FlowTableItem>::iterator pos;
+  for (pos = m_children.begin(); pos != m_children.end(); pos++)
+  {
+      if (((*pos).m_first && (*pos).m_first->gobj() == after.gobj()) || ((*pos).m_second && (*pos).m_second->gobj() == after.gobj()))
+      {
+        found = true;
+	    break;
+      }
+  }
+  if (!found)
+    return;
+  FlowTableItem item;
+  item.m_first = &widget;
+  item.m_second = 0;
+  item.m_expand_second = expand_second;
+  gtk_widget_set_parent(widget.gobj(), GTK_WIDGET(gobj()));
+  if (pos == m_children.end())
+  {
+    m_children.push_back(item);
+  } else {
+    m_children.insert(++pos, item);
+  }
+  setup_drag(item);
+}
+
 void FlowTable::add(Gtk::Widget& first, bool expand)
 {
   FlowTableItem item;
@@ -72,8 +146,13 @@
   m_children.push_back(item);
 
   gtk_widget_set_parent(first.gobj(), GTK_WIDGET(gobj()));
+  setup_drag(item);
 }
 
+/*
+ * {{{ Unrelevant for DND
+ */
+
 void FlowTable::set_columns_count(guint value)
 {
   //Silently correct an invalid value:
@@ -707,22 +786,13 @@
 {
   if(m_design_mode)
   {
+    std::cout << "Expose Event!" << std::endl;
     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 +803,166 @@
       {
         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);
 
-  return Gtk::Container::on_expose_event(event);
 }
 
+/*
+ * }}}
+ */
+
+bool FlowTable::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time)
+{
+  m_dnd_in_progress = true;
+  std::cout << "Drag motion" << std::endl;
+  DragPosition pos;
+  dnd_get_item(x, y, pos);
+  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)
+{
+  if (m_dnd_in_progress)
+  {
+    DragPosition pos;
+    FlowTableItem* item = dnd_get_item(drag_x, drag_y, pos);
+#ifndef TEST
+    DataWidget* mywidget = dynamic_cast<DataWidget*>(item->m_second);
+    if (mywidget)
+      on_dnd_add_layout_item(mywidget);
+#endif
+    m_dnd_in_progress = false;
+  }
+}
+
+void FlowTable::on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& drag_context, guint time)
+{
+  if (m_dnd_in_progress)
+  {
+    // Expose event to clear preview rectangle!
+    std::cout << "Drag leave!" << std::endl;
+    get_window()->invalidate_region(get_window()->get_visible_region());
+  }
+}
+
+FlowTable::FlowTableItem*
+FlowTable::dnd_get_item(int drag_x, int drag_y, DragPosition& position)
+{
+  std::vector<FlowTableItem>::iterator pos;
+  int min = -1;
+  FlowTableItem* item = 0;
+  // Calculate the nearest FlowTableItem from the current drag position
+  for (pos = m_children.begin(); pos != m_children.end(); pos++)
+  {
+    bool above;
+    FlowTableItem* current_item = &(*pos);
+    int min1 = dnd_get_distance(current_item, drag_x, drag_y, above);
+    if (min1 == -1)
+      continue;
+    if (min == -1 || min > min1)
+    {
+      min = min1;
+      if (above)
+        position = ABOVE;
+      else
+        position = BELOW;
+      item = current_item;
+    }
+  }
+  if (item)
+  {
+    dnd_set_preview(item, position);
+  }
+  return item;
+}
+
+int FlowTable::dnd_get_distance(FlowTableItem* item, int drag_x, int drag_y, bool& above)
+{
+  int x1;
+  int y1;
+  int x2;
+  int y2;
+  int width;
+  int height;
+  item->m_first->get_window()->get_position(x1, y1);
+  if (item->m_second)
+  {
+    item->m_second->get_window()->get_position(x2, y2);
+    item->m_second->get_window()->get_size(width, height);
+    x2 = x2 + width;
+    y2 = y2 + height;
+  }
+  else
+  {
+    item->m_first->get_window()->get_size(width, height);
+    x2 = x1 + width;
+    y2 = y1 + height;
+  }
+  if (drag_x > x1 && drag_x < x2)
+  {
+    above = ((y1 - drag_y) > 0);
+    return MIN(abs(drag_y - y1), abs(drag_y - y2));
+  }
+  else
+    return -1;
+}
+
+void FlowTable::dnd_set_preview(FlowTableItem* item, DragPosition position)
+{
+  const int gap = m_padding;
+  int x, y;
+  int x2 = 0, y2 = 0;
+  int width, height;
+  int width2 = 0, height2 = 0;
+  item->m_first->get_window()->get_position(x, y);
+  item->m_first->get_window()->get_size(width, height);
+  if (item->m_second)
+  {
+    item->m_second->get_window()->get_position(x2, y2);
+    item->m_second->get_window()->get_size(width2, height2);
+  }
+  m_preview_rect.set_width(width + width2 - gap);
+  m_preview_rect.set_height(height);
+  switch (position)
+  {
+    case ABOVE:
+      m_preview_rect.set_x(x + gap);
+      m_preview_rect.set_y(y - gap);
+      break;
+    case BELOW:
+      m_preview_rect.set_x(x + gap);
+      m_preview_rect.set_y(y + height);
+      break;
+  }
+  std::cout << m_preview_rect.get_x() << " " << m_preview_rect.get_y() << std::endl;
+  
+  // Expose event!
+  get_window()->invalidate_region(get_window()->get_visible_region());
+}
+
+void FlowTable::setup_drag(FlowTableItem& item)
+{
+  if (item.m_first)
+  {
+    item.m_first->signal_drag_motion().connect(
+                                                sigc::mem_fun(this, &FlowTable::on_drag_motion));
+    item.m_first->signal_drag_data_received().connect(
+                                                       sigc::mem_fun(this, &FlowTable::on_drag_data_received));
+    item.m_first->signal_drag_leave().connect(
+                                               sigc::mem_fun(this, &FlowTable::on_drag_leave));
+  }
+}
+
 } //namespace Glom
 
 
Index: glom/utility_widgets/flowtable.h
===================================================================
--- glom/utility_widgets/flowtable.h	(Revision 1099)
+++ glom/utility_widgets/flowtable.h	(Arbeitskopie)
@@ -22,6 +22,7 @@
 #define GLOM_UTILITYWIDGETS_FLOWTABLE_H
 
 #include <gtkmm.h>
+#include "datawidget.h"
 
 namespace Glom
 {
@@ -36,7 +37,10 @@
 
   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 insert_above(Gtk::Widget& widget, Gtk::Widget& before, bool expand_second = false);
+  virtual void insert_below(Gtk::Widget& widget, Gtk::Widget& after, bool expand_second = false);
 
+  
   virtual void remove(Gtk::Widget& first); //override
 
   void set_columns_count(guint value);
@@ -69,6 +73,16 @@
   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(DataWidget* widget) = 0;
+#endif
+  
+  bool m_dnd_in_progress;
+
   int get_column_height(guint start_widget, guint widget_count, int& total_width) const;
 
   /** 
@@ -97,6 +111,17 @@
   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().
 
+  enum DragPosition
+  {
+    ABOVE,
+    BELOW
+  };
+  
+  FlowTableItem* dnd_get_item(int x, int y, DragPosition& position);
+  int dnd_get_distance(FlowTableItem* item, int x, int y, bool& above);
+  void dnd_set_preview(FlowTableItem* item, DragPosition position);
+  void setup_drag(FlowTableItem& item);
+  
   bool child_is_visible(const Gtk::Widget* widget) const;
 
   Gtk::Allocation assign_child(Gtk::Widget* widget, int x, int y);
@@ -116,6 +141,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 1099)
+++ glom/utility_widgets/flowtablewithfields.cc	(Arbeitskopie)
@@ -1058,4 +1058,9 @@
   signal_requested_related_details().emit(table_name, primary_key_value);
 }
 
+void FlowTableWithFields::on_dnd_add_layout_item(DataWidget* widget)
+{
+  on_datawidget_layout_item_added(TYPE_FIELD, widget);
+}
+
 } //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,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 "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_button = Gtk::manage(new DragButton(_("Drag Widget")));
+  
+  m_box.pack_start(*drag_button);
+  
+  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,42 @@
+/* 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/Makefile.am
===================================================================
--- glom/utility_widgets/Makefile.am	(Revision 1099)
+++ glom/utility_widgets/Makefile.am	(Arbeitskopie)
@@ -33,15 +33,29 @@
                                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 
 
 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 1099)
+++ glom/frame_glom.cc	(Arbeitskopie)
@@ -32,6 +32,7 @@
 #include <glom/mode_design/dialog_add_related_table.h>
 #include <glom/mode_design/script_library/dialog_script_library.h>
 #include <glom/dialog_new_self_hosted_connection.h>
+#include <glom/utility_widgets/dragwindow.h>
 
 #define ENABLE_RELATIONSHIPS_OVERVIEW
 #ifdef ENABLE_RELATIONSHIPS_OVERVIEW
@@ -1246,6 +1247,9 @@
     m_pDialog_Fields->set_transient_for(parent);
     m_pDialog_Fields->init_db_details(m_table_name);
     m_pDialog_Fields->show();
+    
+    DragWindow* dragwin = Gtk::manage(new DragWindow);
+    dragwin->show();
   }
 }
 
