Re: DND with a TreeModelFilter



On Thu, 2010-07-15 at 16:04 +0200, Murray Cumming wrote: 
> Yes, that seems to happen even with the normal ListStore model, ignoring
> TreeModelFilter, and ignoring your custom model. It doesn't happen if I
> comment out your 
>   context->drag_finish(false, false, time);
> line. Did you see that code somewhere else?

Yeah, I got it from the gtkmm tutorial.
http://library.gnome.org/devel/gtkmm-tutorial/unstable/sec-dragcontext.html.en states:

  More importantly, you should call the drag_finish() method from your
  drag_data_received signal handler to indicate whether the drop was
  successful.

and the ensuing example
(http://library.gnome.org/devel/gtkmm-tutorial/unstable/sec-dnd-example.html.en) contains the actual line of code I used.

> Note that, at least with a simple ListStore or TreeStore model, you need
> to call the base class's method to actually have the default
> auto-reordering behaviour, like so:
>   Gtk::TreeView::on_drag_data_received(context, x, y, selection_data,
> info, time);

If I comment out the drag_finish() call and add what you suggest above,
calling the base class on_drag_data_received() method, I don't
experience the freeze-up, but:

* The Gtk-WARNING appears again.
* None of the overridden methods in my model are called, still.

> But even when using the TreeModelFilter, or your custom TreeModel, I
> then don't see the 
>   "You must override the default 'drag_data_received'" 
> warning that you mentioned. Could you please create a test case that
> shows that problem, without the hang (cursor grab)?

I didn't see the warning using my previously attached test case either.
I'm attaching my ever so slightly modified test that does produce the
warning for me.

> Also, what version of GTK+ are you using?

GTK+: 2.18.9
gtkmm: 2.18.2

/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);
        Gtk::TreeView::on_drag_data_received(
            context, x, y, selection_data, info, 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]