[glom/gtktoolpallete] Avoid a Dnd Crash, making the problem clearer.



commit 3926bfda4eab30fb15abe705288cc347f134d4d8
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Dec 30 16:44:23 2009 +0100

    Avoid a Dnd Crash, making the problem clearer.

 glom/libglom/connectionpool.cc           |    2 +-
 glom/mode_data/flowtablewithfields.cc    |   20 +++---
 glom/utility_widgets/flowtable_dnd.cc    |   53 ++++++--------
 glom/utility_widgets/layoutwidgetbase.cc |    4 +-
 glom/utility_widgets/placeholder-glom.cc |  117 +-----------------------------
 glom/utility_widgets/placeholder-glom.h  |   10 +---
 6 files changed, 40 insertions(+), 166 deletions(-)
---
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index 949fac9..4548688 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -535,7 +535,7 @@ bool ConnectionPool::startup(const SlotProgress& slot_progress, bool network_sha
 
   //If we crash while running (unlikely, hopefully), then try to cleanup.
   //Comment this out if you want to see the backtrace in a debugger.
-  previous_sig_handler = signal(SIGSEGV, &on_linux_signal);
+  //previous_sig_handler = signal(SIGSEGV, &on_linux_signal);
 
   return true;
 }
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index 9b2e4af..94a2953 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -678,8 +678,12 @@ void FlowTableWithFields::add_textobject_at_position(const sharedptr<LayoutItem_
 
 void FlowTableWithFields::add_placeholder_at_position(const sharedptr<LayoutItem_Placeholder>& /* layoutitem_placeholder */, const Glib::ustring& /* table_name */, const type_list_layoutwidgets::iterator& add_before)
 {
-  //Remove the placeholder, 
-  remove(m_placeholder_alignment);
+  //Remove the placeholder:
+  if(m_placeholder_alignment.get_parent())
+  {
+    std::cerr << "FlowTableWithFields::add_placeholder_at_position(): placeholder already added." << std::endl;
+    return;
+  }
 
   m_list_layoutwidgets.insert(add_before, &m_placeholder);
 
@@ -1431,8 +1435,6 @@ void FlowTableWithFields::on_dnd_add_layout_item(LayoutWidgetBase* above, const
 
 void FlowTableWithFields::on_dnd_add_placeholder(Gtk::Widget* above_widget)
 {
-   std::cout << "DEBUG: FlowTableWithFields::on_dnd_add_placeholder()" << std::endl;
-
   LayoutWidgetBase* above = dynamic_cast<LayoutWidgetBase*>(above_widget);
   if(!above)
     return;
@@ -1452,14 +1454,12 @@ void FlowTableWithFields::on_dnd_add_placeholder(Gtk::Widget* above_widget)
 
 void FlowTableWithFields::on_dnd_remove_placeholder()
 { 
-  std::cout << "DEBUG: FlowTableWithFields::on_dnd_remove_placeholder()" << std::endl;
-
   //Get the layout group that the "above" widget's layout item is in
   sharedptr<LayoutGroup> layout_group = get_layout_group();
   if(layout_group)
   { 
     LayoutGroup::type_list_items items = layout_group->get_items();
-    for (LayoutGroup::type_list_items::iterator item = items.begin();
+    for(LayoutGroup::type_list_items::iterator item = items.begin();
          item != items.end(); ++item)
     {
       sharedptr<LayoutItem_Placeholder> placeholder = 
@@ -1471,10 +1471,8 @@ void FlowTableWithFields::on_dnd_remove_placeholder()
       }  
     }
 
-std::cout << "DEBUG: FlowTableWithFields::on_dnd_remove_placeholder() 1" << std::endl;
-
-    remove(m_placeholder_alignment);
-std::cout << "DEBUG: FlowTableWithFields::on_dnd_remove_placeholder() 2" << std::endl;
+    if(m_placeholder_alignment.get_parent())
+      remove(m_placeholder_alignment);
   }
 }
 
diff --git a/glom/utility_widgets/flowtable_dnd.cc b/glom/utility_widgets/flowtable_dnd.cc
index 9137743..63eebe3 100644
--- a/glom/utility_widgets/flowtable_dnd.cc
+++ b/glom/utility_widgets/flowtable_dnd.cc
@@ -199,14 +199,25 @@ void FlowTableDnd::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& d
   }
   else
   {
-    //If the item was dragged from an FlowTable.
+    //If the item was dragged from a FlowTable.
     std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): !palette" << std::endl;
     
-    gpointer* data = (gpointer*)selection_data.get_data();
+    gpointer* pdata = (gpointer*)selection_data.get_data();
+    if(!pdata)
+      return;
+    std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): typeid: " << typeid(pdata).name() << std::endl;
+
+    gpointer data = *pdata;
     if(!data)
       return;
+    std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): typeid: " << typeid(data).name() << std::endl;
+
+    Gtk::Widget* widget = static_cast<Gtk::Widget*>(data);
+    std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): typeid: " << typeid(widget).name() << std::endl;
+std::cout << "DEBUG: FlowTableDnd::on_drag_data_received(): gobjecttype: " << G_OBJECT_TYPE_NAME(widget->gobj()) << std::endl;
 
-    LayoutWidgetBase* base = static_cast<LayoutWidgetBase*>(*data);
+
+    LayoutWidgetBase* base = dynamic_cast<LayoutWidgetBase*>(widget);
     if(!base)
       return;
 
@@ -231,13 +242,18 @@ void FlowTableDnd::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& d
       base->set_dnd_in_progress(false);
     }
     else
-      std::cerr << "FlowTableDnd::on_drag_data_received(): above was not a LayoutWidgetBase." << std::endl;
+    {
+      std::cerr << "FlowTableDnd::on_drag_data_received(): above was not a LayoutWidgetBase: above = " << above << std::endl;
+    }
   }
+
+  queue_draw();
 }
 
 void FlowTableDnd::on_drag_leave(const Glib::RefPtr<Gdk::DragContext>& /* drag_context */, guint /* time */)
 {
-  dnd_remove_placeholder_idle();
+  on_dnd_remove_placeholder();
+  queue_draw();
 }
 
 // Calculate the nearest FlowTableDndItem below the current drag position
@@ -397,7 +413,8 @@ bool FlowTableDnd::on_child_drag_motion(const Glib::RefPtr<Gdk::DragContext>& /*
 
 void FlowTableDnd::on_child_drag_leave(const Glib::RefPtr<Gdk::DragContext>& /* drag_context */, guint /* time */)
 {
-  dnd_remove_placeholder_idle();
+  on_dnd_remove_placeholder();
+  queue_draw();
 }
 
 void FlowTableDnd::on_child_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& drag_context, int x, int y, 
@@ -502,28 +519,4 @@ void FlowTableDnd::set_design_mode(bool value)
     foreach(sigc::mem_fun(*this, &FlowTableDnd::stop_dnd));
 }
 
-/* This is a hack. The problem is that when you move the mouse down to the last
- item, the item gets the "drag-motion" signal but in the same moment, the placeholder
- is removed and the mouse pointer is no longer over the widget. Thus, it gets
- a "drag-leave" signal and it's impossible to drop an item at the end. Doing 
- the removal of the placeholder in an idle handler fixes it. */
-
-void FlowTableDnd::dnd_remove_placeholder_idle()
-{
-  std::cout << "DEBUG: FlowTableDnd::dnd_remove_placeholder_idle()" << std::endl;
-  static sigc::connection connection;
-  if(connection)
-    connection.disconnect();
-
-  Glib::signal_idle().connect( sigc::mem_fun(*this, &FlowTableDnd::dnd_remove_placeholder_real) );
-}
-
-bool FlowTableDnd::dnd_remove_placeholder_real()
-{
-  std::cout << "DEBUG: FlowTableDnd::dnd_remove_placeholder_real()" << std::endl;
-  on_dnd_remove_placeholder();
-  queue_draw();
-  return false; // remove from idle source
-}
-
 } // namspace Glom
diff --git a/glom/utility_widgets/layoutwidgetbase.cc b/glom/utility_widgets/layoutwidgetbase.cc
index 593a8cb..f2a9dd2 100644
--- a/glom/utility_widgets/layoutwidgetbase.cc
+++ b/glom/utility_widgets/layoutwidgetbase.cc
@@ -26,9 +26,9 @@ namespace Glom
 {
 
 LayoutWidgetBase::LayoutWidgetBase()
-: m_pLayoutItem(0)
+: 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-  , m_drag_in_progress(false)
+  m_drag_in_progress(false)
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 {
 }
diff --git a/glom/utility_widgets/placeholder-glom.cc b/glom/utility_widgets/placeholder-glom.cc
index 2ea1455..9129ea8 100644
--- a/glom/utility_widgets/placeholder-glom.cc
+++ b/glom/utility_widgets/placeholder-glom.cc
@@ -25,25 +25,15 @@
 #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
 
 namespace Glom
 {
 
-PlaceholderGlom::PlaceholderGlom() :
-  Glib::ObjectBase("glom_placeholder"),
-  Gtk::Widget()
+PlaceholderGlom::PlaceholderGlom()
 {
-  set_flags(Gtk::NO_WINDOW);
-#ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
-  signal_realize().connect(sigc::mem_fun(*this, &PlaceholderGlom::on_realize));
-  signal_unrealize().connect(sigc::mem_fun(*this, &PlaceholderGlom::on_unrealize));
-  signal_expose_event().connect(sigc::mem_fun(*this, &PlaceholderGlom::on_expose_event));
-  signal_size_request().connect(sigc::mem_fun(*this, &PlaceholderGlom::on_size_request));
-  signal_size_allocate().connect(sigc::mem_fun(*this, &PlaceholderGlom::on_size_allocate));
-#endif  
 }
 
 PlaceholderGlom::~PlaceholderGlom()
@@ -52,110 +42,11 @@ PlaceholderGlom::~PlaceholderGlom()
 
 App_Glom* PlaceholderGlom::get_application()
 {
-  //Gtk::Container* pWindow = get_toplevel();
+  Gtk::Container* pWindow = get_toplevel();
   //TODO: This only works when the child widget is already in its parent.
 
-  return 0; //dynamic_cast<App_Glom*>(pWindow);
+  return dynamic_cast<App_Glom*>(pWindow);
 }
 
-void PlaceholderGlom::on_size_request(Gtk::Requisition* requisition)
-{
-  //Initialize the output parameter:
-  *requisition = Gtk::Requisition();
-
-  // Take some mimimum size, we later want to cover the whole space available
-  requisition->height = 30;
-  requisition->width = 200;
-}
-
-void PlaceholderGlom::on_size_allocate(Gtk::Allocation& allocation)
-{
-  //Use the offered allocation for this container:
-  set_allocation(allocation);
-
-  if(m_refGdkWindow)
-  {
-    m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(),
-            allocation.get_width(), allocation.get_height() );
-  }
-}
-
-void PlaceholderGlom::on_realize()
-{
-  //Call base class:
-#ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED  
-  Gtk::Widget::on_realize();
-#endif  
-
-  ensure_style();
-
-
-  if(!m_refGdkWindow)
-  {
-    //Create the GdkWindow:
-    GdkWindowAttr attributes;
-    memset(&attributes, 0, sizeof(attributes));
-
-    Gtk::Allocation allocation = get_allocation();
-
-    //Set initial position and size of the Gdk::Window:
-    attributes.x = allocation.get_x();
-    attributes.y = allocation.get_y();
-    attributes.width = allocation.get_width();
-    attributes.height = allocation.get_height();
-
-    attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; 
-    attributes.window_type = GDK_WINDOW_CHILD;
-    attributes.wclass = GDK_INPUT_OUTPUT;
-
-
-    m_refGdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes,
-            GDK_WA_X | GDK_WA_Y);
-    unset_flags(Gtk::NO_WINDOW);
-    set_window(m_refGdkWindow);
-
-    //set colors
-    modify_fg(Gtk::STATE_NORMAL , Gdk::Color("black"));
-
-    //make the widget receive expose events
-    m_refGdkWindow->set_user_data(gobj());
-  }
-}
-
-void PlaceholderGlom::on_unrealize()
-{
-  m_refGdkWindow.reset();
-#ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED  
-  Gtk::Widget::on_unrealize();
-#endif  
-}
-
-bool PlaceholderGlom::on_expose_event(GdkEventExpose* event)
-{
-  if(m_refGdkWindow)
-  {
-    Cairo::RefPtr<Cairo::Context> cr = m_refGdkWindow->create_cairo_context();
-    if(event)
-    {
-      // clip to the area that needs to be re-exposed so we don't draw any
-      // more than we need to.
-      cr->rectangle(event->area.x, event->area.y,
-              event->area.width, event->area.height);
-      cr->clip();
-    }
-
-    // Paint the background:
-    Gdk::Cairo::set_source_color(cr, get_style()->get_bg(Gtk::STATE_NORMAL));
-    cr->paint();
-
-    // Draw the foreground:
-    Gdk::Cairo::set_source_color(cr, get_style()->get_fg(Gtk::STATE_NORMAL));
-    cr->set_line_width(4);
-    cr->rectangle(0, 0,  get_allocation().get_width(), get_allocation().get_height());
-    cr->stroke();
-  }
-
-  return true;
-}
 
 } // namespace Glom
diff --git a/glom/utility_widgets/placeholder-glom.h b/glom/utility_widgets/placeholder-glom.h
index db7362c..abbec29 100644
--- a/glom/utility_widgets/placeholder-glom.h
+++ b/glom/utility_widgets/placeholder-glom.h
@@ -34,7 +34,7 @@ namespace Glom
 {
 
 class PlaceholderGlom: 
-  public Gtk::Widget,
+  public Gtk::Frame,
   public LayoutWidgetBase
 {
 public:
@@ -44,14 +44,6 @@ public:
 
 private:
   virtual App_Glom* get_application();
-  
-  virtual void on_size_request(Gtk::Requisition* requisition);
-  virtual void on_size_allocate(Gtk::Allocation& allocation);
-  virtual void on_realize();
-  virtual void on_unrealize();
-  virtual bool on_expose_event(GdkEventExpose* event);
-
-  Glib::RefPtr<Gdk::Window> m_refGdkWindow;
 };
 
 } // namespace Glom



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