GTK Drag-and-drop Validation X11 Cursor lock up within drag_get_data.



Hi,

I have been unable to get drag and drop validation working in pygtk. I
am out of ideas and would like a second opinion.

My goal is to only allow files which contain .jpg to be dropped.

Specifically, whenever I call widget.drag_get_data within the
drag-motion callback The X11 cursor locks up. Making debugging tedious
and aggravating since I have to kill X11 and re launch everything.

Here is my source code, I think the issue lies specifically in the
drag_motion_cb and drag_data_received_cb methods. I have left the
commented out sections I have tried before.

Using Google code search searching for drag_get_data doesn't show
anyone else doing advanced validation. So I'm guessing others failed
as well.

I am out of ideas and will end up just using simple DnD in my linux
port (without proper validation) if I cannot figure this out.

Thanks in advance.

=============

import pygtk
pygtk.require('2.0')
import gobject
import gtk

TARGET_TEXT_URI_LIST = 0

drop_targets = [
  ("text/uri-list", 0, TARGET_TEXT_URI_LIST)
]


class TestApp(gobject.GObject):
  builder = gtk.Builder()
  window = None
  button = None

  def __init__(self):
    gobject.GObject.__init__(self)

    assert self.builder != None
    self.builder.add_from_file("MainWindow.glade");
    self.window = self.builder.get_object("window1")
    self.button = self.builder.get_object("button1")

    self.window.connect("destroy", gtk.main_quit)

    self.button.drag_dest_set(gtk.DEST_DEFAULT_ALL, drop_targets,
gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_LINK|gtk.gdk.ACTION_MOVE)

    self.button.connect("drag-data-received", self.drag_data_received_cb)
    self.button.connect("drag-drop", self.drag_drop_cb)
    self.button.connect("drag-motion", self.drag_motion_cb)
    self.button.connect("drag-leave", self.drag_leave_cb)

    self.window.show_all()

  drop_data_ready = False
  drop_occurred = False
  drop_highlight = False
  drop_data = None

  def drag_data_received_cb(self,widget,context,x,y,data,info,timestamp):
    print "drag_data_received_cb"

    # Check to see if we have the drop data yet.
    if False == self.drop_data_ready:
      # If this is data we expected or can handle, then process it.
      if TARGET_TEXT_URI_LIST == info and data.get_format() == 8 and
data.get_length() > 0:
        self.drop_data = data.get_uris()
        self.drop_data_ready = True
      context.drag_status(gtk.gdk.ACTION_COPY, timestamp)

    # Actual drop handling code.
    if True == self.drop_occurred:
      # Reset state.
      self.drop_occurred = False

      print "RECEIVED DROP",self.drop_data

      # Notify whether we handled the drop or not.
      context.finish(True,False,timestamp)

      # Clean up.
      self.drag_leave_cb(widget, context, timestamp)
    return True

  def drag_drop_cb(self,widget,context,x,y,timestamp):
    target = widget.drag_dest_find_target(context,
widget.drag_dest_get_target_list())

    # Is it something we can handle?

    if target == gtk.gdk.atom_intern("text/uri-list", False):
      # Tell data recieved handler (do_drag_data_received) we can
actually handle the drop.
      self.drop_occurred = True

      widget.drag_get_data(context,target,timestamp)

      # We can handle this data type.
      return True
    else:
      # We cannot handle the drop.
      return False
    pass

  def drag_motion_cb(self,widget,context,x,y,timestamp):



    if not self.drop_data_ready:
      widget.drag_get_data(context,
gtk.gdk.atom_intern("text/uri-list",False), timestamp)
      return False



    """
    target = widget.drag_dest_find_target(context,
widget.drag_dest_get_target_list())
    if target == gtk.gdk.atom_intern("text/uri-list", False):
      if True == self.drop_data_ready:
        pass
      else:


        #widget.drag_get_data(context, target, timestamp)
        pass
      """



    context.drag_status(gtk.gdk.ACTION_COPY, timestamp)
    """

    if target == gtk.gdk.atom_intern("text/uri-list", False):
      if True == self.drop_data_ready:
        if repr(drop_data).find(".jpg") != -1:
          # Tell Gdk we can handle this.
          context.drag_status(gtk.gdk.ACTION_COPY, timestamp)

          # Draw drop highlight (but only once).
          if False == self.drop_highlight:
            widget.drag_highlight()
            self.drop_highlight = True

          # Return here, don't fall through.
          return True
      else:
        # Request drag data from the source.
        widget.drag_get_data(context, target, timestamp)

        # Fall-through to not allowing.
    """

    # not something we can handle
    #context.drag_status(0, timestamp) # Don't allow drop.
    return True


    pass
  def drag_leave_cb(self,widget,context,timestamp):
    # Cleanup drag data.
    if True == self.drop_data_ready:
      self.drop_data = None
      self.drop_data_ready = False

    # Un-draw the highlight.
    if True == self.drop_highlight:
      widget.drag_unhighlight()
      self.drop_highlight = False
    pass



gobject.type_register(TestApp)

def main():
  car = TestApp()
  gtk.main()

if __name__ == '__main__':
  main()



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