[glom] FlowTableDnd: Some refactoring.



commit 7bdbe1b3281149019b3e942049e0de3c2d42e976
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Dec 11 19:38:28 2009 +0100

    FlowTableDnd: Some refactoring.
    
    	* glom/utility_widgets/flowtable_dnd.[h|cc],
    	* glom/mode_data/flowtable_withfields.[h|cc]: Make FlowTableDnd less
    	aware of LayoutItems, though it is still not yet generic enough.
    	* glom/utility_widgets/test_flowtable_dnd.cc:
    	* glom/Makefile_tests.am: Added test_flowtable_dnd.

 ChangeLog                                  |   10 +++
 Makefile_tests.am                          |   32 +++++++--
 glom/mode_data/flowtablewithfields.cc      |   69 +++++++++++++++++-
 glom/mode_data/flowtablewithfields.h       |   23 ++++---
 glom/utility_widgets/flowtable_dnd.cc      |  106 ++++++++++++++++-----------
 glom/utility_widgets/flowtable_dnd.h       |   27 +++-----
 glom/utility_widgets/layoutwidgetutils.cc  |    7 ++
 glom/utility_widgets/layoutwidgetutils.h   |    2 +-
 glom/utility_widgets/placeholder-glom.cc   |    4 +-
 glom/utility_widgets/test_flowtable_dnd.cc |   88 +++++++++++++++++++++++
 10 files changed, 285 insertions(+), 83 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 263263d..d5904c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-12-10  Murray Cumming  <murrayc murrayc com>
 
+	FlowTableDnd: Some refactoring.
+
+	* glom/utility_widgets/flowtable_dnd.[h|cc],
+	* glom/mode_data/flowtable_withfields.[h|cc]: Make FlowTableDnd less 
+	aware of LayoutItems, though it is still not yet generic enough.
+	* glom/utility_widgets/test_flowtable_dnd.cc:
+	* glom/Makefile_tests.am: Added test_flowtable_dnd.
+
+2009-12-10  Murray Cumming  <murrayc murrayc com>
+
 	* examples/example_film_manager.glom: Added silly example data, 
 	fixing bug #600859 (Michael Hasselmann)
 
diff --git a/Makefile_tests.am b/Makefile_tests.am
index f753c3f..e5eafcf 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -20,6 +20,7 @@ check_PROGRAMS =						\
 	glom/libglom/test_document				\
 	glom/libglom/test_sharedptr_layoutitem			\
 	glom/utility_widgets/test_flowtable			\
+	glom/utility_widgets/test_flowtable_dnd			\
 	glom/utility_widgets/egg/toolpalette/testtoolpalette	\
 	glom/test_pyembed					\
 	tests/test_parsing_time			\
@@ -47,7 +48,8 @@ dist_noinst_SCRIPTS = tests/dtd/test_file_validation.sh
 
 #TESTS_ENVIRONMENT=which valgrind && valgrind --tool=memcheck --leak-check=full --leak-resolution=high --trace-children=yes --num-callers=30
 
-tests_ldadd = glom/libglom/libglom-$(GLOM_ABI_VERSION).la $(LIBGLOM_LIBS)
+LIBGLOM_LA = glom/libglom/libglom-$(GLOM_ABI_VERSION).la $(LIBGLOM_LIBS)
+tests_ldadd = $(LIBGLOM_LA)
 
 glom_libglom_test_connectionpool_SOURCES = glom/libglom/test_connectionpool.cc
 glom_libglom_test_document_SOURCES = glom/libglom/test_document.cc
@@ -77,20 +79,38 @@ tests_import_test_signals_SOURCES =	\
 glom_libglom_test_connectionpool_LDADD = $(tests_ldadd)
 glom_libglom_test_document_LDADD = $(tests_ldadd)
 glom_libglom_test_sharedptr_layoutitem_LDADD = $(tests_ldadd)
+
 glom_utility_widgets_test_flowtable_SOURCES =	\
 	glom/utility_widgets/flowtable.cc	\
 	glom/utility_widgets/flowtable.h	\
 	glom/utility_widgets/test_flowtable.cc
-
 glom_utility_widgets_test_flowtable_LDADD = $(GLOM_LIBS)
 
+EGGTOOLPALETTE_LIBS = glom/utility_widgets/egg/toolpalette/libeggtoolpalette.a\
+	glom/utility_widgets/egg/util/libeggutil.a		\
+	$(EGG_LIBS)
+
+# You must remove PlaceholderGlom::get_application() to avoid having to specify 
+# a huge set of .cc files when building this test:
+glom_utility_widgets_test_flowtable_dnd_SOURCES =	\
+	glom/utility_widgets/flowtable.cc	\
+	glom/utility_widgets/flowtable.h	\
+	glom/utility_widgets/flowtable_dnd.cc	\
+	glom/utility_widgets/flowtable_dnd.h	\
+	glom/utility_widgets/layoutwidgetutils.h \
+	glom/utility_widgets/layoutwidgetutils.cc \
+	glom/utility_widgets/layoutwidgetbase.h \
+	glom/utility_widgets/layoutwidgetbase.cc \
+	glom/utility_widgets/placeholder-glom.h \
+	glom/utility_widgets/placeholder-glom.cc \
+	glom/utility_widgets/test_flowtable_dnd.cc
+glom_utility_widgets_test_flowtable_dnd_LDADD = $(LIBGLOM_LA) $(GLOM_LIBS) $(EGGTOOLPALETTE_LIBS)
+
 glom_utility_widgets_egg_toolpalette_testtoolpalette_SOURCES =	\
 	glom/utility_widgets/egg/toolpalette/testtoolpalette.c
-
 glom_utility_widgets_egg_toolpalette_testtoolpalette_LDADD =	\
-	glom/utility_widgets/egg/toolpalette/libeggtoolpalette.a\
-	glom/utility_widgets/egg/util/libeggutil.a		\
-	$(EGG_LIBS)
+	$(EGGTOOLPALETTE_LIBS)
+	
 
 glom_test_pyembed_LDADD = $(LIBGLOM_LIBS) $(PYTHON_LIBS)
 
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index b9fb52a..7e2a8cc 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -662,7 +662,7 @@ void FlowTableWithFields::add_placeholder_at_position(const sharedptr<LayoutItem
   m_placeholder->set(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
   m_placeholder->show();
 
-  PlaceholderGlom* preview = Gtk::manage (new PlaceholderGlom);
+  PlaceholderGlom* preview = Gtk::manage(new PlaceholderGlom);
   preview->show();
 
   m_placeholder->add(*preview);
@@ -1217,6 +1217,42 @@ void FlowTableWithFields::on_flowtable_requested_related_details(const Glib::ust
 }
 
 #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 << "FlowTableWithFields::on_dnd_add_layout_item(): 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
@@ -1301,7 +1337,7 @@ void FlowTableWithFields::on_dnd_add_layout_item_text(LayoutWidgetBase* above)
   textobject->set_text(_("New Text"));
   sharedptr<LayoutItem> layout_item = sharedptr<LayoutItem>::cast_dynamic(textobject);
 
-  dnd_add_to_layout_group (layout_item, above);
+  dnd_add_to_layout_group(layout_item, above);
   //Tell the parent to tell the document to save the layout
 
   signal_layout_changed().emit();
@@ -1313,7 +1349,7 @@ void FlowTableWithFields::on_dnd_add_layout_item_image(LayoutWidgetBase* above)
   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);
+  dnd_add_to_layout_group(layout_item, above);
   //Tell the parent to tell the document to save the layout
 
   signal_layout_changed().emit();
@@ -1327,8 +1363,12 @@ void FlowTableWithFields::on_dnd_add_layout_item(LayoutWidgetBase* above, const
   // signal_layout_changed().emit();
 }
 
-void FlowTableWithFields::on_dnd_add_placeholder(LayoutWidgetBase* above)
+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))
@@ -1342,6 +1382,7 @@ void FlowTableWithFields::on_dnd_add_placeholder(LayoutWidgetBase* 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*/);
 }
 
@@ -1512,6 +1553,26 @@ 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
 
 } //namespace Glom
diff --git a/glom/mode_data/flowtablewithfields.h b/glom/mode_data/flowtablewithfields.h
index 8fd16b1..1b71a1e 100644
--- a/glom/mode_data/flowtablewithfields.h
+++ b/glom/mode_data/flowtablewithfields.h
@@ -215,18 +215,21 @@ private:
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
 
-  virtual void on_dnd_add_placeholder(LayoutWidgetBase* above);
+  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;
     
-  // Methods for the different layout object
-  virtual void on_dnd_add_layout_item_field(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_group(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_item_button(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_item_text(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_item_image(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_notebook(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_portal(LayoutWidgetBase* above);
-  virtual void on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item);
+  
+  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();
 
diff --git a/glom/utility_widgets/flowtable_dnd.cc b/glom/utility_widgets/flowtable_dnd.cc
index 704d270..a21d14a 100644
--- a/glom/utility_widgets/flowtable_dnd.cc
+++ b/glom/utility_widgets/flowtable_dnd.cc
@@ -146,13 +146,39 @@ bool FlowTableDnd::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& /* drag_
   y += get_allocation().get_y();
   
   m_current_dnd_item = dnd_item_at_position(x, y);  
-  LayoutWidgetBase* above = dnd_datawidget_from_item(0);
+  Gtk::Widget* above = dnd_datawidget_from_item(0);
 
   // above might be 0 here...
   on_dnd_add_placeholder(above);
   return false;
 }
 
+void FlowTableDnd::on_dnd_add_layout_item_by_type(int item_type, Gtk::Widget* above)
+{
+  //This is not pure virtual, so we can easily use this base class in unit tests.
+  std::cerr << "FlowTableDnd::on_dnd_add_layout_item_by_type(): Not implemented. Derived classes should implement this." << std::endl;
+}
+
+void FlowTableDnd::on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item)
+{
+  //This is not pure virtual, so we can easily use this base class in unit tests.
+  std::cerr << "FlowTableDnd::on_dnd_add_layout_item(): Not implemented. Derived classes should implement this." << std::endl;
+
+}
+
+void FlowTableDnd::on_dnd_add_placeholder(Gtk::Widget* above)
+{
+  //This is not pure virtual, so we can easily use this base class in unit tests.
+  std::cerr << "FlowTableDnd::on_dnd_add_placeholder(): Not implemented. Derived classes should implement this." << std::endl;
+}
+
+void FlowTableDnd::on_dnd_remove_placeholder()
+{
+  //This is not pure virtual, so we can easily use this base class in unit tests.
+  std::cerr << "FlowTableDnd::on_dnd_remove_placeholder(): Not implemented. Derived classes should implement this." << std::endl;
+}
+
+
 void FlowTableDnd::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 */)
 {
   Gtk::Widget* palette = drag_get_source_widget(drag_context);
@@ -160,42 +186,18 @@ void FlowTableDnd::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& d
     palette = palette->get_parent();
   
   on_dnd_remove_placeholder();
-  LayoutWidgetBase* above = dnd_datawidget_from_item(0);
+  Gtk::Widget* above = dnd_datawidget_from_item(0);
   if(palette)
   {
     GtkWidget* tool_item = egg_tool_palette_get_drag_item(EGG_TOOL_PALETTE(palette->gobj()), selection_data.gobj());
-    LayoutWidgetBase::enumType type = 
-      static_cast<LayoutWidgetBase::enumType>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tool_item), "glom-type")));
-
-    switch(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 << "Unknown drop type: " << type << std::endl;
-    }
+    const int type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tool_item), "glom-type"));
+    on_dnd_add_layout_item_by_type(type, above);
   }
   else
   {
+    //TODO: When is this code path taken?
+    std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): Unexpected code path." << std::endl;
+    /*
     gpointer* data = (gpointer*)selection_data.get_data();
     LayoutWidgetBase* base = (LayoutWidgetBase*)*data;
     if(base)
@@ -217,6 +219,7 @@ void FlowTableDnd::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& d
         base->set_dnd_in_progress(false);
       }
     }
+    */
   }
 }
 
@@ -271,11 +274,11 @@ FlowTableDnd::dnd_item_at_position(int drag_x, int drag_y)
   return 0;
 }
 
-LayoutWidgetBase* FlowTableDnd::dnd_datawidget_from_item(FlowTable::FlowTableItem* item)
+Gtk::Widget* FlowTableDnd::dnd_datawidget_from_item(FlowTable::FlowTableItem* item)
 {
   // Test if we have a datawidget below which we want to add
   LayoutWidgetBase* above = 0;
-  FlowTableItem* used_item;
+  FlowTableItem* used_item = 0;
   if(item)
     used_item = item;
   else
@@ -306,7 +309,8 @@ LayoutWidgetBase* FlowTableDnd::dnd_datawidget_from_item(FlowTable::FlowTableIte
       } 
     }
   }
-  return above;
+
+  return dynamic_cast<Gtk::Widget*>(above);
 }
 
 FlowTable::FlowTableItem* FlowTableDnd::find_current_dnd_item(Gtk::Widget* child, int /* x */, int y)
@@ -373,7 +377,7 @@ bool FlowTableDnd::on_child_drag_motion(const Glib::RefPtr<Gdk::DragContext>& /*
 {
   m_current_dnd_item = find_current_dnd_item(child, x, y);
   
-  LayoutWidgetBase* above = dnd_datawidget_from_item(0);
+  Gtk::Widget* above = dnd_datawidget_from_item(0);
   
   // above might be 0 here...
   on_dnd_add_placeholder(above);
@@ -397,16 +401,27 @@ void FlowTableDnd::on_child_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&
                                           Gtk::Widget* child)
 {
   FlowTableItem* item = find_current_dnd_item(child);
-  LayoutWidgetBase* base = dnd_datawidget_from_item(item);
+  Gtk::Widget* base = dnd_datawidget_from_item(item);
 
   gpointer data = 0;
   if(base)
     data = base;
 
-  selection_data.set("LayoutWidgetBase*", 8, (guint8*)&data, 
+  selection_data.set("Gtk::Widget*", 8, (guint8*)&data, 
                       sizeof(gpointer*));
 }
 
+void FlowTableDnd::set_child_widget_dnd_in_progress(Gtk::Widget* child, bool in_progress)
+{
+  //To be reimplemented by derived classes.
+}
+
+bool FlowTableDnd::get_child_widget_dnd_in_progress(Gtk::Widget* child) const
+{
+  //To be reimplemented by derived classes.
+  return false;
+}
+
 void FlowTableDnd::on_child_drag_begin(const Glib::RefPtr<Gdk::DragContext>& drag_context,
                           Gtk::Widget* child)
 {
@@ -423,8 +438,8 @@ void FlowTableDnd::on_child_drag_begin(const Glib::RefPtr<Gdk::DragContext>& dra
   if(item->m_second)
     item->m_second->hide();
 
-  LayoutWidgetBase* base = dnd_datawidget_from_item(item);
-  base->set_dnd_in_progress(); 
+  Gtk::Widget* base = dnd_datawidget_from_item(item);
+  set_child_widget_dnd_in_progress(base);
 }
 
 void FlowTableDnd::on_child_drag_end(const Glib::RefPtr<Gdk::DragContext>& /* drag_context */,
@@ -434,8 +449,11 @@ void FlowTableDnd::on_child_drag_end(const Glib::RefPtr<Gdk::DragContext>& /* dr
   if(!item)
     return;
 
-  LayoutWidgetBase* base = dnd_datawidget_from_item(item);
-  if(base->get_dnd_in_progress())
+  Gtk::Widget* base = dnd_datawidget_from_item(item);
+  if(!base)
+    return;
+
+  if(get_child_widget_dnd_in_progress(base))
   {
     if(!item)
       return;
@@ -446,9 +464,11 @@ void FlowTableDnd::on_child_drag_end(const Glib::RefPtr<Gdk::DragContext>& /* dr
   }
   else if(!m_internal_drag)
   {
-    sharedptr<LayoutItem> item = base->get_layout_item();
+    LayoutWidgetBase* base_layout = dynamic_cast<LayoutWidgetBase*>(base);
+    sharedptr<LayoutItem> item = base_layout->get_layout_item();
     sharedptr<LayoutGroup> group = sharedptr<LayoutGroup>::cast_dynamic(get_layout_item());
-    group->remove_item(item);
+    if(group)
+      group->remove_item(item);
   }
 
   signal_layout_changed().emit();
diff --git a/glom/utility_widgets/flowtable_dnd.h b/glom/utility_widgets/flowtable_dnd.h
index ebd100c..601b121 100644
--- a/glom/utility_widgets/flowtable_dnd.h
+++ b/glom/utility_widgets/flowtable_dnd.h
@@ -39,6 +39,8 @@ class FlowTableDnd :
 public:
   FlowTableDnd();
   ~FlowTableDnd();
+
+  virtual void set_design_mode(bool value = true);
   
 private:
   virtual bool on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, guint time);
@@ -58,32 +60,23 @@ private:
   void start_dnd(Gtk::Widget& child);
   void stop_dnd(Gtk::Widget& child);
 
-protected:
-  virtual void set_design_mode(bool value = true);
+  //To be implemented by the derived class:
+  virtual void on_dnd_add_layout_item_by_type(int item_type, Gtk::Widget* above);
+  virtual void on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item);
 
-private:
-  // Methods for the different layout object,
-  // to be implemented in the derived class.
-  virtual void on_dnd_add_layout_item_field(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_group(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_item_button(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_item_text(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_item_image(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_notebook(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_portal(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_add_layout_item(LayoutWidgetBase* above, const sharedptr<LayoutItem>& item) = 0;
+  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 = true);
+  virtual bool get_child_widget_dnd_in_progress(Gtk::Widget* child) const;
 
-  virtual void on_dnd_add_placeholder(LayoutWidgetBase* above) = 0;
-  virtual void on_dnd_remove_placeholder() = 0;    
   
   void dnd_remove_placeholder_idle();
   bool dnd_remove_placeholder_real();
   
   FlowTableItem* dnd_item_at_position(int x, int y);
-  LayoutWidgetBase* dnd_datawidget_from_item(FlowTableItem* item);
+  Gtk::Widget* dnd_datawidget_from_item(FlowTableItem* item);
     
-private:
   FlowTableItem* find_current_dnd_item (Gtk::Widget* child, int x = -1, int y = -1);
   FlowTableItem* m_current_dnd_item;
     
diff --git a/glom/utility_widgets/layoutwidgetutils.cc b/glom/utility_widgets/layoutwidgetutils.cc
index 328bd99..a2b7e7a 100644
--- a/glom/utility_widgets/layoutwidgetutils.cc
+++ b/glom/utility_widgets/layoutwidgetutils.cc
@@ -114,6 +114,13 @@ void LayoutWidgetUtils::on_menu_delete_activate()
     signal_layout_changed().emit();
   }
 }
+
+void LayoutWidgetUtils::on_menu_properties_activate()
+{
+  //This is not pure virtual, so we can easily use this base class in unit tests.
+  std::cerr << "LayoutWidgetUtils::on_menu_properties_activate(): Not imlemented. Derived classes should override this." << std::endl;
+}
+
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
 } // namespace Glom
diff --git a/glom/utility_widgets/layoutwidgetutils.h b/glom/utility_widgets/layoutwidgetutils.h
index 87e89af..85042d7 100644
--- a/glom/utility_widgets/layoutwidgetutils.h
+++ b/glom/utility_widgets/layoutwidgetutils.h
@@ -39,7 +39,7 @@ protected:
   void setup_util_menu();
   Gtk::Menu* m_pPopupMenuUtils;
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-  virtual void on_menu_properties_activate() = 0;
+  virtual void on_menu_properties_activate();
 
   // This one is implemented here:
   virtual void on_menu_delete_activate();
diff --git a/glom/utility_widgets/placeholder-glom.cc b/glom/utility_widgets/placeholder-glom.cc
index 3d0656d..9688bb6 100644
--- a/glom/utility_widgets/placeholder-glom.cc
+++ b/glom/utility_widgets/placeholder-glom.cc
@@ -25,7 +25,7 @@
 #include "placeholder-glom.h"
 #include "labelglom.h"
 #include <gtkmm/messagedialog.h>
-#include <glom/application.h>
+//#include <glom/application.h>
 #include <glibmm/i18n.h>
 #include <string.h> // for memset
 
@@ -55,7 +55,7 @@ App_Glom* PlaceholderGlom::get_application()
   Gtk::Container* pWindow = get_toplevel();
   //TODO: This only works when the child widget is already in its parent.
 
-  return dynamic_cast<App_Glom*>(pWindow);
+  return 0; //dynamic_cast<App_Glom*>(pWindow);
 }
 
 void PlaceholderGlom::on_size_request(Gtk::Requisition* requisition)
diff --git a/glom/utility_widgets/test_flowtable_dnd.cc b/glom/utility_widgets/test_flowtable_dnd.cc
new file mode 100644
index 0000000..2c9114c
--- /dev/null
+++ b/glom/utility_widgets/test_flowtable_dnd.cc
@@ -0,0 +1,88 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * 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.h>
+#include "flowtable_dnd.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);
+}
+*/
+
+int
+main(int argc, char* argv[])
+{
+  Gtk::Main mainInstance(argc, argv);
+
+  Gtk::Window window;
+  //Gtk::VBox flowtable;
+  Glom::FlowTableDnd flowtable;
+  flowtable.set_columns_count(3);
+  flowtable.set_column_padding(100);
+  flowtable.set_row_padding(0);
+
+  Gtk::Entry button7; button7.set_text("seven");
+  button7.show();
+  //button7.set_size_request(100, 100);
+
+  Gtk::Entry button8; button8.set_text("eight");
+  flowtable.add(button7, button8);
+  button8.show();
+  //button8.set_size_request(100, 100);
+
+  Gtk::Label button9; button9.set_text("nine"); //TODO: valgrind says that something here is leaked.
+  button9.show();
+  //button7.set_size_request(100, 100);
+
+  Gtk::Entry button10; button10.set_text("ten");
+  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();
+
+//  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]