Re: DND with a TreeModelFilter



On Wed, 2010-07-07 at 10:23 +0200, Murray Cumming wrote: 
> On Tue, 2010-07-06 at 02:08 +0200, Staffan Gimåker wrote:
> > I tried deriving a new model from TreeModelFilter, TreeDragDest and
> > TreeDragSource, implementing the virtual functions in the latter two,
> > but that did not work -- the virtual functions were never called and I
> > got the GTK assertion below:
> > 
> > "Gtk-WARNING **:You must override the default 'drag_data_received' 
> > handler on GtkTreeView when using models that don't support the
> > GtkTreeDragDest interface and enabling drag-and-drop.
> [snip]
> 
> > Connecting to the signal_drag_data_received() did not make a
> > difference.
> [snip]
> 
> It's asking you to override on_drag_data_received() (the default signal
> handler), not just connect to signal_drag_data_received(). Of course,
> that's not obvious.
> 
> If that doesn't help, please try to create a simple test case. This
> sounds rather awkward but that might let us help.

I attached a stripped down test case. It consists of a derived TreeModel
that overrides the row_draggable_vfunc() etc. methods and a class
derived from TreeView, overriding on_drag_data_received().

Each of the overridden methods basically just print out the function
name and does little else.

The good news is that the Gtk-WARNING disappears. The bad news is that
none of the overridden methods in my tree model are called. And even
worse, it also hangs my system. Not in a everything freezes way, but it
messes up the input system, the mouse in particular is left totally
unusable. The "hang" can only be cured with a restart or by killing the
application. To be on the safe side I recommend that you test run it by
doing:

  ./dndtest & sleep 15 && killall dndtest

/Staffan
#include <gtkmm.h>
#include <iostream>

class MyModel : public Gtk::TreeModelFilter,
                public Gtk::TreeDragDest,
                public Gtk::TreeDragSource
{
public:
    static Glib::RefPtr<MyModel> create(
        const Glib::RefPtr<Gtk::TreeModel> &child_model)
    {
        return Glib::RefPtr<MyModel>(new MyModel(child_model));
    }

protected:
    MyModel(const Glib::RefPtr<Gtk::TreeModel> &child_model)
        : Gtk::TreeModelFilter(child_model) {}

    virtual bool row_draggable_vfunc(const Gtk::TreeModel::Path &path) const
    {
        std::cout << "row_draggable_vfunc" << std::endl;
        return true;
    }

    virtual bool drag_data_get_vfunc(
        const Gtk::TreeModel::Path &path,
        Gtk::SelectionData &selection_data) const
    {
        std::cout << "drag_data_get_vfunc" << std::endl;
        return true;
    }

    virtual bool drag_data_delete_vfunc(const Gtk::TreeModel::Path &path)
    {
        std::cout << "drag_data_delete_vfunc" << std::endl;
        return true;
    }

    virtual bool row_drop_possible_vfunc(
        const Gtk::TreeModel::Path &dest_path,
        const Gtk::SelectionData &selection_data) const
    {
        std::cout << "row_drop_possible_vfunc" << std::endl;
        return true;
    }

    virtual bool drag_data_received_vfunc(
        const Gtk::TreeModel::Path &dest,
        const Gtk::SelectionData &selection_data)
    {
        std::cout << "drag_data_received_vfunc" << std::endl;
        return true;
    }
};

class MyTreeView : public Gtk::TreeView
{
public:

protected:
    virtual void on_drag_data_received(
        const Glib::RefPtr<Gdk::DragContext> &context,
        int x, int y,
        const Gtk::SelectionData &selection_data,
        guint info, guint time)
    {
        std::cout << "on_drag_data_received" << std::endl;
        context->drag_finish(false, false, time);
    }
};

struct MyCols : public Gtk::TreeModelColumnRecord
{
    MyCols() { add(m_name); }

    Gtk::TreeModelColumn<std::string> m_name;
};

int main(int argc, char *argv[])
{
    Gtk::Main kit(argc, argv);

    Gtk::Window window;

    MyCols cols;
    Glib::RefPtr<Gtk::TreeStore> model = Gtk::TreeStore::create(cols);
    Glib::RefPtr<Gtk::TreeModelFilter> filter =
        Gtk::TreeModelFilter::create(model);
    Glib::RefPtr<MyModel> my_model = MyModel::create(filter);

    for( int i = 0; i < 3; ++i )
    {
        Gtk::TreeModel::Row row = *model->append();
        row[cols.m_name] = "Test";
    }

    MyTreeView view;
    view.set_model(my_model);
    view.set_reorderable(true);
    view.append_column("Name", cols.m_name);
    view.show();
    window.add(view);

    Gtk::Main::run(window);

    return 0;
}

Attachment: signature.asc
Description: This is a digitally signed message part



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