from gi.repository import Gtk, Gdk, GdkPixbuf

(TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF) = range(2)

DRAG_ACTION = Gdk.DragAction.COPY

class DragDropWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Drag and Drop Demo")

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        hbox = Gtk.Box(spacing=12)
        vbox.pack_start(hbox, True, True, 0)

        self.listview = DragSource()
        self.drop_area = DropArea()

        hbox.pack_start(self.listview, True, True, 0)
        hbox.pack_start(self.drop_area, True, True, 0)

#        self.add_text_targets() # Works fine
        self.add_text_targets_manually() # Does not work

    def add_text_targets(self):
        self.drop_area.drag_dest_add_text_targets()
        self.listview.drag_source_add_text_targets()

    def add_text_targets_manually(self):
        entries = [Gtk.TargetEntry.new("UTF8_STRING", 0, 0),
            Gtk.TargetEntry.new("TEXT", 0, 0),
            Gtk.TargetEntry.new("COMPOUND_TEXT", 0, 0),
            Gtk.TargetEntry.new("text/plain;charset=utf-8", 0, 0),
            Gtk.TargetEntry.new("text/uri-list", 0, 0),]
        target_list = Gtk.TargetList.new(entries)

        self.drop_area.drag_dest_set_target_list(target_list)
        self.listview.drag_source_set_target_list(target_list)

class DragSource(Gtk.TreeView):

    def __init__(self):
        Gtk.TreeView.__init__(self)

        model = Gtk.ListStore(str)
        
        model.append(["Item 1",])
        model.append(["Item 2",])
        model.append(["Item 3",])

        renderer = Gtk.CellRendererText()
        col = Gtk.TreeViewColumn("Text", renderer, text=0)
        self.append_column(col)

        self.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], DRAG_ACTION)
        self.connect("drag-data-get", self.on_drag_data_get)

        self.set_model(model)

    def on_drag_data_get(self, widget, drag_context, data, info, time):
        selection = self.get_selection()
        model, tree_iter = selection.get_selected()

        text = model.get_value(tree_iter, 0)
        data.set_text(text, -1)

class DropArea(Gtk.Label):

    def __init__(self):
        Gtk.Label.__init__(self, "Drop something on me!")
        self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)

        self.connect("drag-data-received", self.on_drag_data_received)

    def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
        if info == TARGET_ENTRY_TEXT:
            text = data.get_text()
            print "Received text: %s" % text

        elif info == TARGET_ENTRY_PIXBUF:
            pixbuf = data.get_pixbuf()
            width = pixbuf.get_width()
            height = pixbuf.get_height()

            print "Received pixbuf with width %spx and height %spx" % (width, height)

win = DragDropWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

