Reputation: 2231
Is there a good way of pasting items after or below an item in a Gtk TreeView. Is it even possible to do that with one function? I made this self-contained example, but I am not sure what best-practices for this behavior should be. Is there maybe a way to deselect the TreeView and then paste at the end if nothing is selected?
from gi.repository import Gtk, Gdk
import json
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="TreeView Drag and Drop")
self.connect("delete-event", Gtk.main_quit)
self.set_border_width(10)
self.set_default_size(400, 300)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.add(vbox)
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
button = Gtk.Button("Cut")
button.connect("clicked", self.on_cut_clicked)
hbox.pack_start(button, True, True, 0)
button = Gtk.Button(stock=Gtk.STOCK_COPY)
button.connect("clicked", self.on_copy_clicked)
hbox.pack_start(button, True, True, 0)
button = Gtk.Button(stock=Gtk.STOCK_PASTE)
button.connect("clicked", self.on_paste_clicked)
hbox.pack_start(button, True, True, 0)
vbox.add(hbox)
self.store = Gtk.TreeStore(bool, str)
self.view = Gtk.TreeView(model=self.store)
vbox.add(self.view)
renderer_toggle = Gtk.CellRendererToggle()
column_toggle = Gtk.TreeViewColumn("", renderer_toggle, active=0)
renderer_toggle.connect("toggled", self.on_toggled)
self.view.append_column(column_toggle)
renderer_name = Gtk.CellRendererText()
column_name = Gtk.TreeViewColumn("Name", renderer_name, text=1)
self.view.append_column(column_name)
self.add_test_data()
def add_test_data(self):
parent = self.store.append(None, [True, "Item 1"])
self.store.append(parent, [True, "Item 2"])
self.store.append(None, [True, "Item 3"])
self.store.append(None, [True, "Item 4"])
def on_toggled(self, cellrenderer, path):
self.store[path][0] = not self.store[path][0]
def on_cut_clicked(self, button):
"""Ignores children of selection"""
self.on_copy_clicked(None)
selection = self.view.get_selection()
model, row_list = selection.get_selected_rows()
itr = model.get_iter(row_list[0])
model.remove(itr)
def on_copy_clicked(self, button):
"""Ignores children of selection"""
selection = self.view.get_selection()
model, row_list = selection.get_selected_rows()
if len(row_list) == 0:
return
liste = []
liste.append("TreeViewRow")
for row in row_list:
path = model[row]
liste.append([path[0], path[1]])
data = json.dumps(liste)
self.clipboard.set_text(data, -1)
def on_paste_clicked(self, button):
"""Ignores children of selection"""
text = self.clipboard.wait_for_text()
try:
parse = json.loads(text)
json_str = True
except:
print("Not JSON")
json_str = False
if text != None and json_str == True:
if parse[0] == "TreeViewRow":
selection = self.view.get_selection()
model, row_list = selection.get_selected_rows()
itr = model.get_iter(row_list[0])
self.store.append(itr, parse[1])
else:
print("Could not paste.")
win = MainWindow()
win.show_all()
Gtk.main()
Upvotes: 0
Views: 132
Reputation: 5440
Is there a good way of pasting items after or below an item in a Gtk TreeView. Is it even possible to do that with one function?
Not with a single function. Also, it doesn't work well if you have multiple selection enabled, because then you normally don't want to insert after the first of multiple selected rows.
Is there maybe a way to deselect the TreeView and then paste at the end if nothing is selected?
'Behaviour' of a program isn't really a question of best practices, but of how you want a program to behave. To accept several different 'styles', the functions are subdivided in several steps. I think the intuitive steps would be:
self.view.get_selection()
selection.get_selected()
insert_after
If get_selected
returns itr == None
, then you can just use append(None...)
, so the new row will be appended at the very end.
Upvotes: 1