Handle invisible states on list view
This commit is contained in:
1 parent
266443843e
commit
028cef7267
9 files changed
+157
-36
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Handle invisible states on list view
|
||||
* Add user warnings
|
||||
* Add Model in logs
|
||||
* Allow to duplicate many records at once
|
||||
|
||||
@@ -9,6 +9,8 @@ class CellRendererButton(gtk.GenericCellRenderer):
|
||||
__gproperties__ = {
|
||||
"text": (gobject.TYPE_STRING, None, "Text",
|
||||
"Displayed text", gobject.PARAM_READWRITE),
|
||||
'visible': (gobject.TYPE_INT, 'Visible',
|
||||
'Visible', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
}
|
||||
|
||||
__gsignals__ = {
|
||||
@@ -21,6 +23,7 @@ class CellRendererButton(gtk.GenericCellRenderer):
|
||||
self.text = text
|
||||
self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE)
|
||||
self.clicking = False
|
||||
self.visible = True
|
||||
|
||||
def do_set_property(self, pspec, value):
|
||||
setattr(self, pspec.name, value)
|
||||
@@ -30,6 +33,11 @@ class CellRendererButton(gtk.GenericCellRenderer):
|
||||
|
||||
def on_render(self, window, widget, background_area, cell_area,
|
||||
expose_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
# Handle Pixmap window as pygtk failed
|
||||
if type(window) == gtk.gdk.Pixmap:
|
||||
return
|
||||
state = gtk.STATE_NORMAL
|
||||
shadow = gtk.SHADOW_OUT
|
||||
if self.clicking and flags & gtk.CELL_RENDERER_SELECTED:
|
||||
@@ -61,6 +69,8 @@ class CellRendererButton(gtk.GenericCellRenderer):
|
||||
|
||||
def on_start_editing(self, event, widget, path, background_area,
|
||||
cell_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
if (event is None) or ((event.type == gtk.gdk.BUTTON_PRESS) \
|
||||
or (event.type == gtk.gdk.KEY_PRESS \
|
||||
and event.keyval == gtk.keysyms.space)):
|
||||
|
||||
@@ -19,6 +19,8 @@ class CellRendererDate(gtk.GenericCellRenderer):
|
||||
'Background Set', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
'editable': (gobject.TYPE_INT, 'Editable',
|
||||
'Editable', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
'visible': (gobject.TYPE_INT, 'Visible',
|
||||
'Visible', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
}
|
||||
|
||||
def __init__(self, format):
|
||||
@@ -31,9 +33,12 @@ class CellRendererDate(gtk.GenericCellRenderer):
|
||||
self.cmd = ''
|
||||
self.text = self._renderer.get_property('text')
|
||||
self.editable = self._renderer.get_property('editable')
|
||||
self.visible = True
|
||||
|
||||
def do_set_property(self, pspec, value):
|
||||
setattr(self, pspec.name, value)
|
||||
if pspec.name == 'visible':
|
||||
return
|
||||
self._renderer.set_property(pspec.name, value)
|
||||
self.set_property("mode", self._renderer.get_property("mode"))
|
||||
|
||||
@@ -45,6 +50,8 @@ class CellRendererDate(gtk.GenericCellRenderer):
|
||||
|
||||
def on_render(self, window, widget, background_area, cell_area,
|
||||
expose_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
# Handle Pixmap window as pygtk failed
|
||||
if type(window) == gtk.gdk.Pixmap:
|
||||
layout = widget.create_pango_layout(self.text)
|
||||
@@ -60,11 +67,15 @@ class CellRendererDate(gtk.GenericCellRenderer):
|
||||
|
||||
def on_activate(self, event, widget, path, background_area, cell_area,
|
||||
flags):
|
||||
if not self.visible:
|
||||
return
|
||||
return self._renderer.activate(event, widget, path, background_area,
|
||||
cell_area, flags)
|
||||
|
||||
def on_start_editing(self, event, widget, path, background_area,
|
||||
cell_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
editable = DateEntry(self.format, self._date_cb, self._process_cb)
|
||||
|
||||
colormap = editable.get_colormap()
|
||||
|
||||
@@ -21,6 +21,8 @@ class CellRendererText(gtk.GenericCellRenderer):
|
||||
'Editable', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
'xalign': (gobject.TYPE_FLOAT, 'XAlign',
|
||||
'XAlign', 0, 1, 0, gobject.PARAM_READWRITE),
|
||||
'visible': (gobject.TYPE_INT, 'Visible',
|
||||
'Visible', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
@@ -30,9 +32,12 @@ class CellRendererText(gtk.GenericCellRenderer):
|
||||
|
||||
self.text = self._renderer.get_property('text')
|
||||
self.editable = self._renderer.get_property('editable')
|
||||
self.visible = True
|
||||
|
||||
def do_set_property(self, pspec, value):
|
||||
setattr(self, pspec.name, value)
|
||||
if pspec.name == 'visible':
|
||||
return
|
||||
self._renderer.set_property(pspec.name, value)
|
||||
self.set_property("mode", self._renderer.get_property("mode"))
|
||||
|
||||
@@ -44,6 +49,8 @@ class CellRendererText(gtk.GenericCellRenderer):
|
||||
|
||||
def on_render(self, window, widget, background_area, cell_area,
|
||||
expose_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
# Handle Pixmap window as pygtk failed
|
||||
if type(window) == gtk.gdk.Pixmap:
|
||||
layout = widget.create_pango_layout(self.text)
|
||||
@@ -59,11 +66,15 @@ class CellRendererText(gtk.GenericCellRenderer):
|
||||
|
||||
def on_activate(self, event, widget, path, background_area, cell_area,
|
||||
flags):
|
||||
if not self.visible:
|
||||
return
|
||||
return self._renderer.activate(event, widget, path, background_area,
|
||||
cell_area, flags)
|
||||
|
||||
def on_start_editing(self, event, widget, path, background_area,
|
||||
cell_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
if not event:
|
||||
event = gtk.gdk.Event(gtk.keysyms.Tab)
|
||||
editable = self._renderer.start_editing(event, widget, path,
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import gtk
|
||||
import gobject
|
||||
import pango
|
||||
|
||||
|
||||
class CellRendererToggle(gtk.GenericCellRenderer):
|
||||
__gproperties__ = {
|
||||
'activatable': (gobject.TYPE_INT, 'Activatable',
|
||||
'Activatable', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
'visible': (gobject.TYPE_INT, 'Visible',
|
||||
'Visible', 0, 10, 0, gobject.PARAM_READWRITE),
|
||||
}
|
||||
|
||||
__gsignals__ = {
|
||||
'toggled': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
|
||||
(gobject.TYPE_STRING, )),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.__gobject_init__()
|
||||
self._renderer = gtk.CellRendererToggle()
|
||||
self._renderer.connect('toggled', self._sig_toggled)
|
||||
self.set_property("mode", self._renderer.get_property("mode"))
|
||||
|
||||
self.activatable = self._renderer.get_property('activatable')
|
||||
self.visible = True
|
||||
|
||||
def do_set_property(self, pspec, value):
|
||||
setattr(self, pspec.name, value)
|
||||
if pspec.name == 'visible':
|
||||
return
|
||||
self._renderer.set_property(pspec.name, value)
|
||||
self.set_property("mode", self._renderer.get_property("mode"))
|
||||
|
||||
def do_get_property(self, pspec):
|
||||
return getattr(self, pspec.name)
|
||||
|
||||
def on_get_size(self, widget, cell_area):
|
||||
return self._renderer.get_size(widget, cell_area)
|
||||
|
||||
def on_render(self, window, widget, background_area, cell_area,
|
||||
expose_area, flags):
|
||||
if not self.visible:
|
||||
return
|
||||
# Handle Pixmap window as pygtk failed
|
||||
if type(window) == gtk.gdk.Pixmap:
|
||||
return
|
||||
return self._renderer.render(window, widget, background_area,
|
||||
cell_area, expose_area, flags)
|
||||
|
||||
def on_activate(self, event, widget, path, background_area, cell_area,
|
||||
flags):
|
||||
if not self.visible:
|
||||
return
|
||||
return self._renderer.activate(event, widget, path, background_area,
|
||||
cell_area, flags)
|
||||
|
||||
def get_active(self):
|
||||
return self._renderer.get_active()
|
||||
|
||||
def set_active(self, setting):
|
||||
return self._renderer.set_active(setting)
|
||||
|
||||
def _sig_toggled(self, renderer, path):
|
||||
if self.activatable and self.visible:
|
||||
self.emit('toggled', path)
|
||||
|
||||
gobject.type_register(CellRendererToggle)
|
||||
@@ -108,14 +108,14 @@ class CharField(object):
|
||||
def create(self, model):
|
||||
return False
|
||||
|
||||
def state_set(self, model):
|
||||
def state_set(self, model, states=('readonly', 'required', 'invisible')):
|
||||
state_changes = self.attrs.get('states', {})
|
||||
if isinstance(state_changes, basestring):
|
||||
try:
|
||||
state_changes = eval(state_changes)
|
||||
except:
|
||||
return
|
||||
for key in ('readonly', 'required', 'invisible'):
|
||||
for key in states:
|
||||
if key == 'readonly' and self.attrs.get(key, False):
|
||||
continue
|
||||
if key in state_changes:
|
||||
@@ -550,8 +550,8 @@ class O2MField(CharField):
|
||||
self.get_state_attrs(model)['valid'] = res
|
||||
return res
|
||||
|
||||
def state_set(self, model):
|
||||
super(O2MField, self).state_set(model)
|
||||
def state_set(self, model, states=('readonly', 'required', 'invisible')):
|
||||
super(O2MField, self).state_set(model, states=states)
|
||||
if self.get_state_attrs(model).get('readonly', False):
|
||||
model.value[self.name].readonly = True
|
||||
else:
|
||||
|
||||
@@ -11,6 +11,7 @@ import gettext
|
||||
import tryton.common as common
|
||||
from tryton.config import CONFIG
|
||||
from tryton.common.cellrendererbutton import CellRendererButton
|
||||
from tryton.common.cellrenderertoggle import CellRendererToggle
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -561,7 +562,7 @@ class ViewList(ParserView):
|
||||
if not renderers:
|
||||
continue
|
||||
renderer = renderers[0]
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
editable = renderer.get_property('activatable')
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
@@ -595,7 +596,7 @@ class ViewList(ParserView):
|
||||
self.widget_tree.editable = False
|
||||
for col in self.widget_tree.get_columns():
|
||||
for renderer in col.get_cell_renderers():
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
renderer.set_property('activatable', False)
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
|
||||
@@ -3,6 +3,7 @@ import gtk
|
||||
import parser
|
||||
import gettext
|
||||
from tryton.common.cellrendererbutton import CellRendererButton
|
||||
from tryton.common.cellrenderertoggle import CellRendererToggle
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -74,7 +75,7 @@ class EditableTreeView(gtk.TreeView):
|
||||
if not cols[idx].get_cell_renderers():
|
||||
continue
|
||||
renderer = cols[idx].get_cell_renderers()[0]
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
editable = renderer.get_property('activatable')
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
@@ -93,7 +94,7 @@ class EditableTreeView(gtk.TreeView):
|
||||
if not cols[idx].get_cell_renderers():
|
||||
continue
|
||||
renderer = cols[idx].get_cell_renderers()[0]
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
editable = renderer.get_property('activatable')
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
@@ -176,7 +177,7 @@ class EditableTreeView(gtk.TreeView):
|
||||
col = None
|
||||
for column in self.get_columns():
|
||||
renderer = column.get_cell_renderers()[0]
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
editable = renderer.get_property('activatable')
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
|
||||
@@ -23,6 +23,7 @@ import tryton.common as common
|
||||
from tryton.common.cellrendererbutton import CellRendererButton
|
||||
from tryton.common.cellrendererdate import CellRendererDate
|
||||
from tryton.common.cellrenderertext import CellRendererText
|
||||
from tryton.common.cellrenderertoggle import CellRendererToggle
|
||||
from tryton.action import Action
|
||||
from tryton.translate import date_format
|
||||
import mx.DateTime
|
||||
@@ -107,7 +108,7 @@ class ParserTree(ParserInterface):
|
||||
renderer = cell.renderer
|
||||
|
||||
readonly = not (editable and not node_attrs.get('readonly', False))
|
||||
if isinstance(renderer, gtk.CellRendererToggle):
|
||||
if isinstance(renderer, CellRendererToggle):
|
||||
renderer.set_property('activatable', not readonly)
|
||||
elif isinstance(renderer,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
@@ -247,41 +248,61 @@ class Char(object):
|
||||
def setter(self, column, cell, store, iter):
|
||||
model = store.get_value(iter, 0)
|
||||
text = self.get_textual_value(model)
|
||||
cell.set_property('text', text)
|
||||
fg_color = self.get_color(model)
|
||||
cell.set_property('foreground', fg_color)
|
||||
if fg_color == 'black':
|
||||
cell.set_property('foreground-set', False)
|
||||
|
||||
if isinstance(cell, CellRendererToggle):
|
||||
cell.set_active(bool(text))
|
||||
else:
|
||||
cell.set_property('foreground-set', True)
|
||||
cell.set_property('text', text)
|
||||
fg_color = self.get_color(model)
|
||||
cell.set_property('foreground', fg_color)
|
||||
if fg_color == 'black':
|
||||
cell.set_property('foreground-set', False)
|
||||
else:
|
||||
cell.set_property('foreground-set', True)
|
||||
|
||||
if self.attrs['type'] in ('float', 'integer', 'biginteger', 'boolean',
|
||||
'numeric', 'float_time'):
|
||||
align = 1
|
||||
else:
|
||||
align = 0
|
||||
|
||||
states = ('invisible')
|
||||
if hasattr(self.treeview, 'editable') \
|
||||
and self.treeview.editable:
|
||||
states = ('readonly', 'required', 'invisible')
|
||||
|
||||
field = model[self.field_name]
|
||||
field.state_set(model, states=states)
|
||||
invisible = field.get_state_attrs(model).get('invisible', False)
|
||||
cell.set_property('visible', not invisible)
|
||||
|
||||
if hasattr(self.treeview, 'editable') \
|
||||
and self.treeview.editable:
|
||||
field = model[self.field_name]
|
||||
field.state_set(model)
|
||||
bg_color = 'white'
|
||||
if not field.get_state_attrs(model).get('valid', True):
|
||||
bg_color = COLORS.get('invalid', 'white')
|
||||
elif bool(int(field.get_state_attrs(model).get('required', 0))):
|
||||
bg_color = COLORS.get('required', 'white')
|
||||
cell.set_property('background', bg_color)
|
||||
if bg_color == 'white':
|
||||
cell.set_property('background-set', False)
|
||||
else:
|
||||
cell.set_property('background-set', True)
|
||||
cell.set_property('foreground-set', True)
|
||||
readonly = field.get_state_attrs(model).get('readonly', False)
|
||||
if isinstance(cell, gtk.CellRendererToggle):
|
||||
if invisible:
|
||||
readonly = True
|
||||
|
||||
if not isinstance(cell, CellRendererToggle):
|
||||
bg_color = 'white'
|
||||
if not field.get_state_attrs(model).get('valid', True):
|
||||
bg_color = COLORS.get('invalid', 'white')
|
||||
elif bool(int(field.get_state_attrs(model).get('required', 0))):
|
||||
bg_color = COLORS.get('required', 'white')
|
||||
cell.set_property('background', bg_color)
|
||||
if bg_color == 'white':
|
||||
cell.set_property('background-set', False)
|
||||
else:
|
||||
cell.set_property('background-set', True)
|
||||
cell.set_property('foreground-set', True)
|
||||
|
||||
if isinstance(cell, CellRendererToggle):
|
||||
cell.set_property('activatable', not readonly)
|
||||
elif isinstance(cell,
|
||||
(gtk.CellRendererProgress, CellRendererButton)):
|
||||
pass
|
||||
else:
|
||||
cell.set_property('editable', not readonly)
|
||||
|
||||
cell.set_property('xalign', align)
|
||||
|
||||
def get_color(self, model):
|
||||
@@ -314,17 +335,12 @@ class Boolean(Int):
|
||||
|
||||
def __init__(self, *args):
|
||||
super(Boolean, self).__init__(*args)
|
||||
self.renderer = gtk.CellRendererToggle()
|
||||
self.renderer = CellRendererToggle()
|
||||
self.renderer.connect('toggled', self._sig_toggled)
|
||||
|
||||
def get_textual_value(self, model):
|
||||
return model[self.field_name].get_client(model)
|
||||
|
||||
def setter(self, column, cell, store, iter):
|
||||
model = store.get_value(iter, 0)
|
||||
value = self.get_textual_value(model)
|
||||
cell.set_active(bool(value))
|
||||
|
||||
def _sig_toggled(self, renderer, path):
|
||||
store = self.treeview.get_model()
|
||||
model = store.get_value(store.get_iter(path), 0)
|
||||
|
||||
Reference in new issue
Block a user