merge
This commit is contained in:
commit
91f2cbea41
5 files changed
+98
-44
No files matched your search
@@ -40,6 +40,7 @@ class CharField(object):
|
||||
if self.attrs.get('on_change', False):
|
||||
record.on_change(self.name, self.attrs['on_change'])
|
||||
record.on_change_with(self.name)
|
||||
record.autocomplete_with(self.name)
|
||||
|
||||
def domains_get(self, record):
|
||||
screen_domain = domain_inversion(record.group.domain,
|
||||
|
||||
@@ -35,6 +35,7 @@ class Record(SignalEvent):
|
||||
self.attachment_count = -1
|
||||
self.next = {} # Used in Group list
|
||||
self.value = {}
|
||||
self.autocompletion = {}
|
||||
|
||||
def __getitem__(self, name):
|
||||
if name not in self._loaded and self.id > 0:
|
||||
@@ -233,6 +234,10 @@ class Record(SignalEvent):
|
||||
if not vals:
|
||||
return
|
||||
self.set_default(vals)
|
||||
for fieldname, fieldinfo in self.group.fields.iteritems():
|
||||
if not fieldinfo.attrs.get('autocomplete'):
|
||||
continue
|
||||
self.do_autocomplete(fieldname)
|
||||
|
||||
def rec_name(self):
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
@@ -438,6 +443,43 @@ class Record(SignalEvent):
|
||||
return
|
||||
self.group.fields[fieldname].set_on_change(self, res)
|
||||
|
||||
def autocomplete_with(self, field_name):
|
||||
for fieldname, fieldinfo in self.group.fields.iteritems():
|
||||
autocomplete = fieldinfo.attrs.get('autocomplete', [])
|
||||
if field_name not in autocomplete:
|
||||
continue
|
||||
self.do_autocomplete(fieldname)
|
||||
|
||||
def do_autocomplete(self, fieldname):
|
||||
self.autocompletion[fieldname] = []
|
||||
autocomplete = self.group.fields[fieldname].attrs['autocomplete']
|
||||
args = self._get_on_change_args(autocomplete)
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
ctx.update(self.context_get())
|
||||
args = ('model', self.model_name, 'autocomplete_' + fieldname, args,
|
||||
ctx)
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except Exception, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
if not res:
|
||||
# ensure res is a list
|
||||
res = []
|
||||
self.autocompletion[fieldname] = res
|
||||
|
||||
def cond_default(self, field_name, value):
|
||||
ctx = rpc.CONTEXT.copy()
|
||||
ctx.update(self.context_get())
|
||||
args = ('model', 'ir.default', 'get_default', self.model_name,
|
||||
field_name + '=' + str(value), ctx)
|
||||
try:
|
||||
res = rpc.execute(*args)
|
||||
except Exception, exception:
|
||||
res = common.process_exception(exception, self.window, *args)
|
||||
if not res:
|
||||
return
|
||||
self.set_default(res)
|
||||
|
||||
def get_attachment_count(self, reload=False):
|
||||
if self.id < 0:
|
||||
return 0
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
import gettext
|
||||
|
||||
import gobject
|
||||
import gtk
|
||||
from interface import WidgetInterface
|
||||
from tryton.common import Tooltips
|
||||
|
||||
_ = gettext.gettext
|
||||
|
||||
|
||||
class Char(WidgetInterface):
|
||||
"Char"
|
||||
|
||||
@@ -15,12 +17,25 @@ class Char(WidgetInterface):
|
||||
super(Char, self).__init__(field_name, model_name, window, attrs=attrs)
|
||||
|
||||
self.widget = gtk.HBox()
|
||||
self.entry = gtk.Entry()
|
||||
self.entry.set_property('activates_default', True)
|
||||
self.entry.set_max_length(int(attrs.get('size', 0)))
|
||||
self.entry.set_width_chars(5)
|
||||
self.autocomplete = bool(attrs.get('autocomplete'))
|
||||
if self.autocomplete:
|
||||
self.entry = gtk.ComboBoxEntry()
|
||||
self.entry_store = gtk.ListStore(gobject.TYPE_STRING)
|
||||
self.entry.set_model(self.entry_store)
|
||||
self.entry.set_text_column(0)
|
||||
completion = gtk.EntryCompletion()
|
||||
completion.set_model(self.entry_store)
|
||||
completion.set_text_column(0)
|
||||
self.entry.get_child().set_completion(completion)
|
||||
else:
|
||||
self.entry = gtk.Entry()
|
||||
self.entry.set_property('activates_default', True)
|
||||
self.entry.set_max_length(int(attrs.get('size', 0)))
|
||||
self.entry.set_width_chars(5)
|
||||
|
||||
self.entry.connect('populate-popup', self._populate_popup)
|
||||
self.entry.connect('activate', self.sig_activate)
|
||||
|
||||
self.entry.connect('activate', self.sig_activate)
|
||||
self.entry.connect('focus-in-event', lambda x, y: self._focus_in())
|
||||
self.entry.connect('focus-out-event', lambda x, y: self._focus_out())
|
||||
self.widget.pack_start(self.entry)
|
||||
@@ -32,18 +47,46 @@ class Char(WidgetInterface):
|
||||
return self.entry.grab_focus()
|
||||
|
||||
def set_value(self, record, field):
|
||||
return field.set_client(record, self.entry.get_text() or False)
|
||||
entry = self.entry.get_child() if self.autocomplete else self.entry
|
||||
value = entry.get_text() or False
|
||||
return field.set_client(record, value)
|
||||
|
||||
def display(self, record, field):
|
||||
super(Char, self).display(record, field)
|
||||
if record and self.autocomplete:
|
||||
autocompletion = record.autocompletion.get(self.field_name, [])
|
||||
current = [elem[0] for elem in self.entry_store]
|
||||
if autocompletion != current:
|
||||
self.entry_store.clear()
|
||||
for row in autocompletion:
|
||||
self.entry_store.append((row,))
|
||||
elif self.autocomplete:
|
||||
self.entry_store.clear()
|
||||
if not field:
|
||||
self.entry.set_text('')
|
||||
return False
|
||||
self.entry.set_text(field.get(record) or '')
|
||||
value = ''
|
||||
else:
|
||||
value = field.get(record) or ''
|
||||
self.display_value(value)
|
||||
|
||||
def display_value(self, value):
|
||||
if not self.autocomplete:
|
||||
self.entry.set_text(value)
|
||||
return
|
||||
for idx, row in enumerate(self.entry_store):
|
||||
if row[0] == value:
|
||||
self.entry.set_active(idx)
|
||||
return
|
||||
else:
|
||||
self.entry.get_child().set_text(value)
|
||||
|
||||
def _readonly_set(self, value):
|
||||
sensitivity = {True: gtk.SENSITIVITY_OFF, False: gtk.SENSITIVITY_AUTO}
|
||||
super(Char, self)._readonly_set(value)
|
||||
self.entry.set_editable(not value)
|
||||
if self.autocomplete:
|
||||
self.entry.get_child().set_editable(not value)
|
||||
self.entry.set_button_sensitivity(sensitivity[value])
|
||||
else:
|
||||
self.entry.set_editable(not value)
|
||||
if value:
|
||||
self.widget.set_focus_chain([])
|
||||
else:
|
||||
|
||||
@@ -68,42 +68,9 @@ class Many2One(WidgetInterface):
|
||||
|
||||
self._readonly = False
|
||||
|
||||
self.completion = gtk.EntryCompletion()
|
||||
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
|
||||
if attrs.get('completion', False):
|
||||
try:
|
||||
result = rpc.execute('model', self.attrs['relation'],
|
||||
'search_read', [], 0, None, None, ['rec_name'],
|
||||
rpc.CONTEXT)
|
||||
names = [(x['id'], x['rec_name']) for x in result]
|
||||
except Exception, exception:
|
||||
common.process_exception(exception, self.window)
|
||||
names = []
|
||||
if names:
|
||||
self.load_completion(names)
|
||||
|
||||
def grab_focus(self):
|
||||
return self.wid_text.grab_focus()
|
||||
|
||||
def load_completion(self, names):
|
||||
self.completion.set_match_func(self.match_func, None)
|
||||
self.completion.connect("match-selected", self.on_completion_match)
|
||||
self.wid_text.set_completion(self.completion)
|
||||
self.completion.set_model(self.liststore)
|
||||
self.completion.set_text_column(1)
|
||||
for object_id, name in names:
|
||||
self.liststore.append([object_id, name])
|
||||
|
||||
def match_func(self, completion, key_string, iter, data):
|
||||
model = self.completion.get_model()
|
||||
modelstr = model[iter][1].lower()
|
||||
return modelstr.startswith(key_string)
|
||||
|
||||
def on_completion_match(self, completion, model, iter):
|
||||
self.field.set_client(self.record, int(model[iter][0]))
|
||||
self.display(self.record, self.field)
|
||||
return True
|
||||
|
||||
def _readonly_set(self, value):
|
||||
self._readonly = value
|
||||
self.wid_text.set_editable(not value)
|
||||
|
||||
@@ -543,7 +543,8 @@ class ParserForm(ParserInterface):
|
||||
continue
|
||||
for attr_name in ('relation', 'domain', 'selection',
|
||||
'relation_field', 'string', 'views', 'invisible',
|
||||
'add_remove', 'sort', 'context', 'size', 'filename'):
|
||||
'add_remove', 'sort', 'context', 'size', 'filename',
|
||||
'autocomplete'):
|
||||
if attr_name in fields[name].attrs and \
|
||||
not attr_name in attrs:
|
||||
attrs[attr_name] = fields[name].attrs[attr_name]
|
||||
|
||||
Reference in new issue
Block a user