Add optional column on tree view

issue10989
review374321002
This commit is contained in:
Cédric Krier committed 2022-02-03 23:13:27 +01:00
1 parent a52aee3397
commit 3cae98b262
5 files changed
+75 -17

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Manage optional column
* Default CSV encoding to UTF8 with BOM
* Display the number of selected records
* Humanize the count result
+17
View File
@@ -143,3 +143,20 @@ def populate(menu, model, record, title='', field=None, context=None):
action_menu.append(email_item)
email_item.connect('activate', email, toolbar)
menu.show_all()
def popup(menu, widget):
def menu_position(menu, x, y, user_data):
widget_allocation = widget.get_allocation()
x, y = widget.get_window().get_root_coords(
widget_allocation.x, widget_allocation.y)
return (x, y + widget_allocation.height, False)
menu.show_all()
if hasattr(menu, 'popup_at_widget'):
menu.popup_at_widget(
widget, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST,
Gtk.get_current_event())
else:
menu.popup(
None, None, menu_position, None, 0,
Gtk.get_current_event_time())
+2 -15
View File
@@ -17,6 +17,7 @@ from tryton.action import Action
from tryton.common import (
RPCException, RPCExecute, message, sur, sur_3b, timezoned_date)
from tryton.common.common import selection as selection_
from tryton.common.popup_menu import popup
from tryton.common.underline import set_underline
from tryton.gui import Main
from tryton.gui.window import Window
@@ -587,21 +588,7 @@ class Form(TabContent):
if not widget.props.active:
menu.popdown()
return
def menu_position(menu, x, y, user_data):
widget_allocation = widget.get_allocation()
x, y = widget.get_window().get_root_coords(
widget_allocation.x, widget_allocation.y)
return (x, y + widget_allocation.height, False)
menu.show_all()
if hasattr(menu, 'popup_at_widget'):
menu.popup_at_widget(
widget, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST,
Gtk.get_current_event())
else:
menu.popup(
None, None, menu_position, None, 0,
Gtk.get_current_event_time())
popup(menu, widget)
def record_message(self, position, size, max_size, record_id):
name = str(position) if position else '_'
@@ -37,6 +37,7 @@ class Screen:
# Width of tree columns per model
# It is shared with all connection but it is the price for speed.
tree_column_width = collections.defaultdict(lambda: {})
tree_column_optional = {}
def __init__(self, model_name, **attributes):
context = attributes.get('context', {})
+54 -2
View File
@@ -14,7 +14,7 @@ from tryton.common import (
RPCException, RPCExecute, Tooltips, domain_inversion, node_attributes,
simplify, unique_value)
from tryton.common.cellrendererbutton import CellRendererButton
from tryton.common.popup_menu import populate
from tryton.common.popup_menu import populate, popup
from tryton.config import CONFIG
from tryton.gui.window import Window
from tryton.pyson import PYSONDecoder
@@ -334,6 +334,9 @@ class TreeXMLViewParser(XMLViewParser):
self.view.treeview.append_column(column)
if 'optional' in attributes:
self.view.optionals.append(column)
if 'sum' in attributes:
text = attributes['sum'] + _(':')
label, sum_ = Gtk.Label(label=text), Gtk.Label()
@@ -435,6 +438,7 @@ class ViewTree(View):
def __init__(self, view_id, screen, xml, children_field):
self.children_field = children_field
self.optionals = []
self.sum_widgets = []
self.sum_box = Gtk.HBox()
self.treeview = None
@@ -485,6 +489,23 @@ class ViewTree(View):
self.display()
if self.optionals:
if self.draggable:
column = self.treeview.get_columns()[0]
else:
column = Gtk.TreeViewColumn()
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.name = None
column._type = 'optional'
self.treeview.insert_column(column, 0)
image = Gtk.Image()
image.set_from_pixbuf(common.IconFactory.get_pixbuf('tryton-menu'))
image.show()
column.set_widget(image)
column.set_fixed_width(25)
column.set_clickable(True)
column.connect('clicked', self.optional_menu)
# Add last column if necessary after display for updated visible
for column in self.treeview.get_columns():
if column.get_expand() and column.get_visible():
@@ -496,6 +517,30 @@ class ViewTree(View):
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
self.treeview.append_column(column)
def optional_menu(self, column):
def toggle(menuitem, column):
column.set_visible(menuitem.get_active())
self.save_optional()
widget = column.get_widget()
menu = Gtk.Menu()
for optional in self.optionals:
menuitem = Gtk.CheckMenuItem(label=optional.get_title())
menuitem.set_active(optional.get_visible())
menuitem.connect('toggled', toggle, optional)
menu.add(menuitem)
popup(menu, widget)
def save_optional(self):
fields = {c.name: not c.get_visible() for c in self.optionals}
try:
RPCExecute(
'model', 'ir.ui.view_tree_optional', 'set_optional',
self.view_id, fields)
except RPCException:
pass
self.screen.tree_column_optional[self.view_id] = fields
def get_column_widget(self, column):
'Return the widget of the column'
idx = [c for c in self.treeview.get_columns()
@@ -1066,13 +1111,20 @@ class ViewTree(View):
domain.append(tab_domain)
domain = simplify(domain)
decoder = PYSONDecoder(self.screen.context)
tree_column_optional = self.screen.tree_column_optional.get(
self.view_id, {})
for column in self.treeview.get_columns():
name = column.name
if not name:
continue
widget = self.get_column_widget(column)
widget.set_editable()
if decoder.decode(widget.attrs.get('tree_invisible', '0')):
if column.name in tree_column_optional:
optional = tree_column_optional[column.name]
else:
optional = bool(int(widget.attrs.get('optional', '0')))
invisible = decoder.decode(widget.attrs.get('tree_invisible', '0'))
if invisible or optional:
column.set_visible(False)
elif name == self.screen.exclude_field:
column.set_visible(False)