[tryton-debian-vcs] tryton-client branch upstream updated. upstream/3.0.2-1-gad63d59
Mathias Behrle
tryton-debian-vcs at alioth.debian.org
Wed Apr 16 16:10:54 UTC 2014
The following commit has been merged in the upstream branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/tryton-client.git;a=commitdiff;h=upstream/3.0.2-1-gad63d59
commit ad63d594c6d12fd0145f43c494bc7ca70fe68df2
Author: Mathias Behrle <mathiasb at m9s.biz>
Date: Wed Apr 16 14:48:40 2014 +0200
Adding upstream version 3.0.3.
diff --git a/CHANGELOG b/CHANGELOG
index 85ce572..c47ee1f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+Version 3.0.3 - 2014-04-07
+* Bug fixes (see mercurial logs for details)
+
Version 3.0.2 - 2013-12-04
* Bug fixes (see mercurial logs for details)
diff --git a/COPYRIGHT b/COPYRIGHT
index 8121458..c952d2e 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,8 +1,8 @@
Copyright (C) 2012-2013 Antoine Smolders.
-Copyright (C) 2010-2013 Nicolas Évrard.
-Copyright (C) 2007-2013 Cédric Krier.
+Copyright (C) 2010-2014 Nicolas Évrard.
+Copyright (C) 2007-2014 Cédric Krier.
Copyright (C) 2007-2013 Bertrand Chenal.
-Copyright (C) 2008-2013 B2CK SPRL.
+Copyright (C) 2008-2014 B2CK SPRL.
Copyright (C) 2008-2011 Udo Spallek.
Copyright (C) 2008-2011 virtual things - Preisler & Spallek GbR.
Copyright (C) 2011-2012 Rodrigo Hübner.
diff --git a/PKG-INFO b/PKG-INFO
index 1ffc501..6c6833d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: tryton
-Version: 3.0.2
+Version: 3.0.3
Summary: Tryton client
Home-page: http://www.tryton.org/
Author: Tryton
diff --git a/tryton.egg-info/PKG-INFO b/tryton.egg-info/PKG-INFO
index 1ffc501..6c6833d 100644
--- a/tryton.egg-info/PKG-INFO
+++ b/tryton.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: tryton
-Version: 3.0.2
+Version: 3.0.3
Summary: Tryton client
Home-page: http://www.tryton.org/
Author: Tryton
diff --git a/tryton/common/domain_parser.py b/tryton/common/domain_parser.py
index e17be8d..3fbccd6 100644
--- a/tryton/common/domain_parser.py
+++ b/tryton/common/domain_parser.py
@@ -184,7 +184,7 @@ def convert_value(field, value):
def convert_boolean():
if isinstance(value, basestring):
- return any(test.lower().startswith(value.lower())
+ return any(test.decode('utf-8').lower().startswith(value.lower())
for test in (_('y'), _('yes'), _('true'), _('t'), '1'))
else:
return bool(value)
diff --git a/tryton/common/selection.py b/tryton/common/selection.py
index e7b7947..88fd848 100644
--- a/tryton/common/selection.py
+++ b/tryton/common/selection.py
@@ -24,7 +24,7 @@ class SelectionMixin(object):
if (not isinstance(selection, (list, tuple))
and key not in self._values2selection):
try:
- if key:
+ if self.attrs.get('selection_change_with'):
selection = RPCExecute('model', self.model_name, selection,
dict(key))
else:
diff --git a/tryton/gui/window/view_form/model/field.py b/tryton/gui/window/view_form/model/field.py
index c4a7a2e..e83543f 100644
--- a/tryton/gui/window/view_form/model/field.py
+++ b/tryton/gui/window/view_form/model/field.py
@@ -488,25 +488,29 @@ class O2MField(CharField):
return
record.parent.signal('record-modified')
- def _set_default_value(self, record):
+ def _set_default_value(self, record, fields=None):
if record.value.get(self.name) is not None:
return
from group import Group
parent_name = self.attrs.get('relation_field', '')
- group = Group(self.attrs['relation'], {},
+ fields = fields or {}
+ group = Group(self.attrs['relation'], fields,
parent=record,
parent_name=parent_name,
child_name=self.name,
context=self.context,
parent_datetime_field=self.attrs.get('datetime_field'))
- if record.model_name == self.attrs['relation']:
+ if not fields and record.model_name == self.attrs['relation']:
group.fields = record.group.fields
+ record.value[self.name] = group
+ self._connect_value(group)
+
+ def _connect_value(self, group):
group.signal_connect(group, 'group-changed', self._group_changed)
group.signal_connect(group, 'group-list-changed',
self._group_list_changed)
group.signal_connect(group, 'group-cleared', self._group_cleared)
group.signal_connect(group, 'record-modified', self._record_modified)
- record.value[self.name] = group
def get_client(self, record):
self._set_default_value(record)
@@ -572,44 +576,29 @@ class O2MField(CharField):
return result
def _set_value(self, record, value, default=False):
- from group import Group
-
+ self._set_default_value(record)
+ group = record.value[self.name]
if not value or (len(value) and isinstance(value[0], (int, long))):
mode = 'list ids'
else:
mode = 'list values'
- group = record.value.get(self.name)
- fields = {}
- if group is not None:
- fields = group.fields.copy()
- # Unconnect to prevent infinite loop
- group.signal_unconnect(group)
- group.destroy()
- elif record.model_name == self.attrs['relation']:
- fields = record.group.fields
- if fields:
- fields = dict((fname, field.attrs)
- for fname, field in fields.iteritems())
if mode == 'list values' and len(value):
context = self.context_get(record)
- field_names = set(f for v in value for f in v if f not in fields)
+ field_names = set(f for v in value for f in v
+ if f not in group.fields)
if field_names:
try:
- fields.update(RPCExecute('model', self.attrs['relation'],
- 'fields_get', list(field_names),
- main_iteration=False, context=context))
+ fields = RPCExecute('model', self.attrs['relation'],
+ 'fields_get', list(field_names),
+ main_iteration=False, context=context)
except RPCException:
return
+ group.load_fields(fields)
- parent_name = self.attrs.get('relation_field', '')
- group = Group(self.attrs['relation'], fields,
- parent=record, parent_name=parent_name,
- child_name=self.name,
- context=self.context,
- parent_datetime_field=self.attrs.get('datetime_field'))
- record.value[self.name] = group
if mode == 'list ids':
+ for old_record in group:
+ group.remove(old_record, remove=True, signal=False)
group.load(value)
else:
for vals in value:
@@ -621,30 +610,37 @@ class O2MField(CharField):
new_record.id *= -1 # Don't consider record as unsaved
new_record.set(vals)
group.append(new_record)
- group.signal_connect(group, 'group-changed', self._group_changed)
- group.signal_connect(group, 'group-list-changed',
- self._group_list_changed)
- group.signal_connect(group, 'group-cleared', self._group_cleared)
- group.signal_connect(group, 'record-modified', self._record_modified)
- return group
- def set(self, record, value):
- self._set_value(record, value, default=False)
+ def set(self, record, value, _default=False):
+ group = record.value.get(self.name)
+ fields = {}
+ if group is not None:
+ fields = group.fields.copy()
+ # Unconnect to prevent infinite loop
+ group.signal_unconnect(group)
+ group.destroy()
+ elif record.model_name == self.attrs['relation']:
+ fields = record.group.fields
+ if fields:
+ fields = dict((fname, field.attrs)
+ for fname, field in fields.iteritems())
+
+ record.value[self.name] = None
+ self._set_default_value(record, fields=fields)
+ group = record.value[self.name]
+
+ group.signal_unconnect(group)
+ self._set_value(record, value, default=_default)
+ self._connect_value(group)
def set_client(self, record, value, force_change=False):
pass
def set_default(self, record, value):
- previous_group = record.value.get(self.name)
- group = self._set_value(record, value, default=True)
- if previous_group:
- group.record_deleted.extend(x for x in previous_group if x.id >= 0)
- group.record_deleted.extend(previous_group.record_deleted)
- group.record_removed.extend(previous_group.record_removed)
+ self.set(record, value, _default=True)
record.modified_fields.setdefault(self.name)
def set_on_change(self, record, value):
- self._set_default_value(record)
if isinstance(value, (list, tuple)):
self._set_value(record, value)
record.modified_fields.setdefault(self.name)
@@ -732,36 +728,6 @@ class O2MField(CharField):
class M2MField(O2MField):
- def set(self, record, value):
- from group import Group
- group = record.value.get(self.name)
- fields = {}
- if group is not None:
- fields = group.fields.copy()
- # Unconnect to prevent infinite loop
- group.signal_unconnect(group)
- group.destroy()
- elif record.model_name == self.attrs['relation']:
- fields = record.group.fields
- parent_name = self.attrs.get('relation_field', '')
- group = Group(self.attrs['relation'], {},
- parent=record, parent_name=parent_name,
- child_name=self.name,
- context=self.context,
- parent_datetime_field=self.attrs.get('datetime_field'))
- if record.value.get(self.name):
- group.record_removed.extend(record.value[self.name])
- group.record_deleted.extend(record.value[self.name].record_deleted)
- group.record_removed.extend(record.value[self.name].record_removed)
- record.value[self.name] = group
- group.fields = fields
- group.load(value)
- group.signal_connect(group, 'group-changed', self._group_changed)
- group.signal_connect(group, 'group-list-changed',
- self._group_list_changed)
- group.signal_connect(group, 'group-cleared', self._group_cleared)
- group.signal_connect(group, 'record-modified', self._record_modified)
-
def get_on_change_value(self, record):
return self.get_eval(record)
@@ -779,6 +745,12 @@ class ReferenceField(CharField):
return None
def get(self, record):
+ if record.parent_name == self.name:
+ if record.parent:
+ return '%s,%s' % (record.group.parent.model_name,
+ record.parent.id)
+ else:
+ return None
if (record.value.get(self.name)
and record.value[self.name][0]
and record.value[self.name][1] >= -1):
diff --git a/tryton/gui/window/view_form/model/group.py b/tryton/gui/window/view_form/model/group.py
index 145e9f9..695513f 100644
--- a/tryton/gui/window/view_form/model/group.py
+++ b/tryton/gui/window/view_form/model/group.py
@@ -398,9 +398,6 @@ class Group(SignalEvent, list):
to_add.keys(), main_iteration=False, context=self.context)
except RPCException:
return False
- for name in to_add:
- if name not in values:
- values[name] = False
for record in new:
record.set_default(values, signal=signal)
diff --git a/tryton/gui/window/view_form/view/form_gtk/char.py b/tryton/gui/window/view_form/view/form_gtk/char.py
index 55d9327..50fbad4 100644
--- a/tryton/gui/window/view_form/view/form_gtk/char.py
+++ b/tryton/gui/window/view_form/view/form_gtk/char.py
@@ -49,8 +49,10 @@ class Char(WidgetInterface, TranslateMixin):
def translate_widget(self):
entry = gtk.Entry()
entry.set_property('activates_default', True)
- entry.set_width_chars(int(self.attrs.get('size', -1)))
- entry.set_max_length(int(self.attrs.get('size', 0)))
+ if self.record:
+ field_size = self.record.expr_eval(self.attrs.get('size'))
+ entry.set_width_chars(field_size or -1)
+ entry.set_max_length(field_size or 0)
return entry
@staticmethod
diff --git a/tryton/gui/window/view_form/view/graph_gtk/bar.py b/tryton/gui/window/view_form/view/graph_gtk/bar.py
index 8abebb5..0d99af6 100644
--- a/tryton/gui/window/view_form/view/graph_gtk/bar.py
+++ b/tryton/gui/window/view_form/view/graph_gtk/bar.py
@@ -65,6 +65,9 @@ class Bar(Graph):
def motion(self, widget, event):
super(Bar, self).motion(widget, event)
+ if not getattr(self, 'area', None):
+ return
+
def intersect(bar, event):
x = self.area.w * bar.x + self.area.x
y = self.area.h * bar.y + self.area.y
diff --git a/tryton/gui/window/view_form/view/graph_gtk/line.py b/tryton/gui/window/view_form/view/graph_gtk/line.py
index bd05f53..13868f4 100644
--- a/tryton/gui/window/view_form/view/graph_gtk/line.py
+++ b/tryton/gui/window/view_form/view/graph_gtk/line.py
@@ -154,6 +154,9 @@ class Line(Graph):
cr.restore()
def motion(self, widget, event):
+ if not getattr(self, 'area', None):
+ return
+
nearest = None
for point in self.points:
x = point.x * self.area.w + self.area.x
diff --git a/tryton/gui/window/view_form/view/graph_gtk/pie.py b/tryton/gui/window/view_form/view/graph_gtk/pie.py
index 174ebf5..9018288 100644
--- a/tryton/gui/window/view_form/view/graph_gtk/pie.py
+++ b/tryton/gui/window/view_form/view/graph_gtk/pie.py
@@ -108,6 +108,9 @@ class Pie(Graph):
def motion(self, widget, event):
super(Pie, self).motion(widget, event)
+ if not getattr(self, 'area', None):
+ return
+
d = (event.x - self.centerx) ** 2 + (event.y - self.centery) ** 2
if d > self.radius ** 2:
self.popup.hide()
diff --git a/tryton/gui/window/view_form/view/list.py b/tryton/gui/window/view_form/view/list.py
index d927d70..1b61eaf 100644
--- a/tryton/gui/window/view_form/view/list.py
+++ b/tryton/gui/window/view_form/view/list.py
@@ -588,16 +588,19 @@ class ViewList(ParserView):
def __button_press(self, treeview, event):
if event.button == 3:
- path = treeview.get_path_at_pos(int(event.x), int(event.y))
+ try:
+ path, col, x, y = treeview.get_path_at_pos(
+ int(event.x), int(event.y))
+ except TypeError:
+ # Outside row
+ return False
selection = treeview.get_selection()
if selection.get_mode() == gtk.SELECTION_SINGLE:
model = selection.get_selected()[0]
elif selection.get_mode() == gtk.SELECTION_MULTIPLE:
model = selection.get_selected_rows()[0]
- if (not path) or not path[0]:
- return False
- group = model.group
- record = group[path[0][0]]
+ record = model.get_value(model.get_iter(path), 0)
+ group = record.group
menu = gtk.Menu()
menu.popup(None, None, None, event.button, event.time)
diff --git a/tryton/gui/window/view_form/view/list_gtk/editabletree.py b/tryton/gui/window/view_form/view/list_gtk/editabletree.py
index 319fe6c..50b660c 100644
--- a/tryton/gui/window/view_form/view/list_gtk/editabletree.py
+++ b/tryton/gui/window/view_form/view/list_gtk/editabletree.py
@@ -21,7 +21,7 @@ class TreeView(gtk.TreeView):
def next_column(self, path, column=None, editable=True, _sign=1):
columns = self.get_columns()
if column is None:
- column = columns[-1 * _sign]
+ column = columns[-1 if _sign > 0 else 0]
model = self.get_model()
record = model.get_value(model.get_iter(path), 0)
if _sign < 0:
diff --git a/tryton/gui/window/win_search.py b/tryton/gui/window/win_search.py
index 388b1e0..cc5e1cb 100644
--- a/tryton/gui/window/win_search.py
+++ b/tryton/gui/window/win_search.py
@@ -109,10 +109,8 @@ class WinSearch(NoModal):
if response_id == gtk.RESPONSE_OK:
res = self.screen.sel_ids_get()
elif response_id == gtk.RESPONSE_APPLY:
- if not self.screen.search_filter():
- res = self.screen.sel_ids_get()
- else:
- return
+ self.screen.search_filter(self.screen.screen_container.get_text())
+ return
elif response_id == gtk.RESPONSE_ACCEPT:
screen = Screen(self.model_name, domain=self.domain,
context=self.context, mode=['form'])
diff --git a/tryton/gui/window/wizard.py b/tryton/gui/window/wizard.py
index a910de4..869ec06 100644
--- a/tryton/gui/window/wizard.py
+++ b/tryton/gui/window/wizard.py
@@ -350,9 +350,13 @@ class WizardDialog(Wizard, NoModal):
dialog = self.page
if (hasattr(dialog, 'screen')
and dialog.screen.current_record
- and self.sensible_widget != main.window
- and self.ids):
- dialog.screen.reload(self.ids, written=True)
+ and self.sensible_widget != main.window):
+ if dialog.screen.model_name == self.model:
+ ids = self.ids
+ else:
+ # Wizard run from a children record so reload parent record
+ ids = [dialog.screen.current_record.id]
+ dialog.screen.reload(ids, written=True)
def end(self):
super(WizardDialog, self).end()
diff --git a/tryton/version.py b/tryton/version.py
index b21c548..0158ec3 100644
--- a/tryton/version.py
+++ b/tryton/version.py
@@ -1,6 +1,6 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
PACKAGE = "tryton"
-VERSION = "3.0.2"
+VERSION = "3.0.3"
LICENSE = "GPL-3"
WEBSITE = "http://www.tryton.org/"
--
tryton-client
More information about the tryton-debian-vcs
mailing list