I am trying to prevent drops to the first line of a treeview. My code is basically working, but I would like for the drag icon to change when I move over the first line to indicate that a drop is not permitted there. I set action
to “0 to indicate that a drop will not be accepted” (as per documentation), but that setting does not affect the icon. Any suggestions?
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
class DragWindow(Gtk.Window):
def __init__(self):
super().__init__()
self.set_default_size(300, 200)
self.connect('destroy', Gtk.main_quit)
hbox = Gtk.Box()
hbox.set_orientation(Gtk.Orientation.HORIZONTAL)
button = Gtk.Button.new_with_label('Label')
hbox.pack_start(button, False, False, 0)
model = Gtk.ListStore.new([str])
treeview = Gtk.TreeView.new_with_model(model)
model.append(('row 1',))
model.append(('row 2',))
label = Gtk.Label.new('drop in this column')
label.show()
renderer = Gtk.CellRendererText()
renderer.set_alignment(0.5, 0.5)
col = Gtk.TreeViewColumn('', renderer, text=0)
col.set_widget(label)
col.set_alignment(0.5)
treeview.append_column(col)
hbox.pack_end(treeview, True, True, 0)
self.add(hbox)
self.show_all()
button.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
[Gtk.TargetEntry.new('button', Gtk.TargetFlags.SAME_APP, 0)],
Gdk.DragAction.COPY)
treeview.enable_model_drag_dest(
[Gtk.TargetEntry.new('button', Gtk.TargetFlags.SAME_APP, 0)],
Gdk.DragAction.COPY)
treeview.connect('drag-data-received', self.on_drag_data_received)
treeview.connect('drag-motion', self.on_drag_motion)
def on_drag_motion(self, treeview, context, x, y, time):
dest_row = treeview.get_dest_row_at_pos(x, y)
if dest_row is not None:
path, position = dest_row
if path == Gtk.TreePath.new_first() \
and position != Gtk.TreeViewDropPosition.AFTER:
print('invalid position')
Gdk.drag_status(context, 0, time)
return False
else:
print('valid position')
Gdk.drag_status(context, Gdk.DragAction.COPY, time)
return True
else:
print('not in treeview')
Gdk.drag_status(context, Gdk.DragAction.COPY, time)
return True
def on_drag_data_received(self, treeview, context, x, y, data, info, time):
selection = treeview.get_selection()
model = treeview.get_model()
new_row = ('data',)
dest_row = treeview.get_dest_row_at_pos(x, y)
if dest_row is not None:
path, position = dest_row
if path == Gtk.TreePath.new_first() \
and position != Gtk.TreeViewDropPosition.AFTER:
return
dest_iter = model.get_iter(path)
if position == Gtk.TreeViewDropPosition.BEFORE:
drop_iter = model.insert_before(dest_iter, new_row)
else:
drop_iter = model.insert_after(dest_iter, new_row)
else:
drop_iter = model.append(new_row)
selection.select_iter(drop_iter)
dragwindow = DragWindow()
Gtk.main()