tryton 7.4.10__py3-none-any.whl → 7.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tryton might be problematic. Click here for more details.
- tryton/__init__.py +1 -1
- tryton/bus.py +113 -69
- tryton/chat.py +179 -0
- tryton/client.py +7 -0
- tryton/common/__init__.py +15 -11
- tryton/common/button.py +1 -1
- tryton/common/cellrendererfloat.py +1 -1
- tryton/common/cellrenderertext.py +2 -2
- tryton/common/common.py +91 -19
- tryton/common/environment.py +2 -2
- tryton/common/number_entry.py +12 -6
- tryton/common/selection.py +1 -1
- tryton/data/locale/bg/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/bg/LC_MESSAGES/tryton.po +26 -16
- tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/ca/LC_MESSAGES/tryton.po +29 -18
- tryton/data/locale/cs/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/cs/LC_MESSAGES/tryton.po +28 -16
- tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/de/LC_MESSAGES/tryton.po +27 -18
- tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/es/LC_MESSAGES/tryton.po +25 -16
- tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/es_419/LC_MESSAGES/tryton.po +26 -16
- tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/et/LC_MESSAGES/tryton.po +28 -18
- tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/fa/LC_MESSAGES/tryton.po +28 -18
- tryton/data/locale/fi/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/fi/LC_MESSAGES/tryton.po +25 -16
- tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/fr/LC_MESSAGES/tryton.po +25 -16
- tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/hu/LC_MESSAGES/tryton.po +28 -18
- tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/id/LC_MESSAGES/tryton.po +23 -16
- tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/it/LC_MESSAGES/tryton.po +29 -18
- tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/lo/LC_MESSAGES/tryton.po +26 -18
- tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/lt/LC_MESSAGES/tryton.po +30 -18
- tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/nl/LC_MESSAGES/tryton.po +25 -16
- tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/pl/LC_MESSAGES/tryton.po +31 -18
- tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/pt/LC_MESSAGES/tryton.po +148 -177
- tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/ro/LC_MESSAGES/tryton.po +32 -19
- tryton/data/locale/ru/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/ru/LC_MESSAGES/tryton.po +28 -16
- tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/sl/LC_MESSAGES/tryton.po +33 -18
- tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/tr/LC_MESSAGES/tryton.po +25 -16
- tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/uk/LC_MESSAGES/tryton.po +31 -18
- tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
- tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po +27 -18
- tryton/data/pixmaps/tryton/tryton-chat.svg +1 -0
- tryton/data/pixmaps/tryton/tryton-note.svg +1 -4
- tryton/gui/window/attachment.py +2 -2
- tryton/gui/window/board.py +1 -1
- tryton/gui/window/form.py +57 -10
- tryton/gui/window/note.py +2 -2
- tryton/gui/window/tabcontent.py +8 -1
- tryton/gui/window/view_board/action.py +1 -1
- tryton/gui/window/view_form/model/field.py +34 -28
- tryton/gui/window/view_form/model/group.py +4 -4
- tryton/gui/window/view_form/model/record.py +19 -4
- tryton/gui/window/view_form/screen/screen.py +24 -4
- tryton/gui/window/view_form/view/calendar_gtk/calendar_.py +1 -1
- tryton/gui/window/view_form/view/calendar_gtk/toolbar.py +1 -1
- tryton/gui/window/view_form/view/form.py +2 -1
- tryton/gui/window/view_form/view/form_gtk/binary.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/calendar_.py +4 -4
- tryton/gui/window/view_form/view/form_gtk/char.py +42 -5
- tryton/gui/window/view_form/view/form_gtk/checkbox.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/dictionary.py +53 -15
- tryton/gui/window/view_form/view/form_gtk/float.py +3 -7
- tryton/gui/window/view_form/view/form_gtk/image.py +4 -4
- tryton/gui/window/view_form/view/form_gtk/integer.py +1 -1
- tryton/gui/window/view_form/view/form_gtk/many2many.py +3 -4
- tryton/gui/window/view_form/view/form_gtk/many2one.py +2 -2
- tryton/gui/window/view_form/view/form_gtk/multiselection.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/one2many.py +11 -8
- tryton/gui/window/view_form/view/form_gtk/progressbar.py +2 -2
- tryton/gui/window/view_form/view/form_gtk/pyson.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/reference.py +4 -4
- tryton/gui/window/view_form/view/form_gtk/richtextbox.py +5 -5
- tryton/gui/window/view_form/view/form_gtk/selection.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/state_widget.py +8 -6
- tryton/gui/window/view_form/view/form_gtk/textbox.py +4 -4
- tryton/gui/window/view_form/view/form_gtk/timedelta.py +3 -3
- tryton/gui/window/view_form/view/form_gtk/url.py +2 -2
- tryton/gui/window/view_form/view/form_gtk/widget.py +1 -1
- tryton/gui/window/view_form/view/graph_gtk/bar.py +7 -7
- tryton/gui/window/view_form/view/graph_gtk/graph.py +2 -2
- tryton/gui/window/view_form/view/graph_gtk/line.py +5 -5
- tryton/gui/window/view_form/view/graph_gtk/pie.py +2 -2
- tryton/gui/window/view_form/view/list.py +107 -52
- tryton/gui/window/view_form/view/list_gtk/editabletree.py +2 -2
- tryton/gui/window/view_form/view/list_gtk/widget.py +22 -20
- tryton/gui/window/view_form/view/screen_container.py +13 -1
- tryton/gui/window/win_csv.py +2 -2
- tryton/gui/window/win_export.py +9 -7
- tryton/gui/window/win_form.py +74 -39
- tryton/gui/window/win_import.py +5 -6
- tryton/gui/window/wizard.py +11 -11
- tryton/jsonrpc.py +2 -2
- tryton/plugins/__init__.py +0 -1
- tryton/pyson.py +18 -18
- tryton/rpc.py +7 -5
- {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/METADATA +5 -5
- {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/RECORD +121 -120
- tryton/gui/window/view_form/view/list_gtk/generictreemodel.py +0 -426
- {tryton-7.4.10.data → tryton-7.6.1.data}/scripts/tryton +0 -0
- {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/WHEEL +0 -0
- {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/licenses/LICENSE +0 -0
- {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,7 @@ class StateMixin(object):
|
|
|
14
14
|
|
|
15
15
|
def __init__(self, *args, **kwargs):
|
|
16
16
|
self.attrs = kwargs.pop('attrs')
|
|
17
|
-
super(
|
|
17
|
+
super().__init__(*args, **kwargs)
|
|
18
18
|
|
|
19
19
|
def state_set(self, record):
|
|
20
20
|
if record:
|
|
@@ -30,7 +30,7 @@ class StateMixin(object):
|
|
|
30
30
|
class Label(StateMixin, Gtk.Label):
|
|
31
31
|
|
|
32
32
|
def state_set(self, record):
|
|
33
|
-
super(
|
|
33
|
+
super().state_set(record)
|
|
34
34
|
if 'name' in self.attrs and record:
|
|
35
35
|
field = record.group.fields[self.attrs['name']]
|
|
36
36
|
else:
|
|
@@ -61,7 +61,7 @@ class VBox(StateMixin, Gtk.VBox):
|
|
|
61
61
|
class Image(StateMixin, Gtk.Image):
|
|
62
62
|
|
|
63
63
|
def state_set(self, record):
|
|
64
|
-
super(
|
|
64
|
+
super().state_set(record)
|
|
65
65
|
if not record:
|
|
66
66
|
return
|
|
67
67
|
name = self.attrs['name']
|
|
@@ -72,6 +72,8 @@ class Image(StateMixin, Gtk.Image):
|
|
|
72
72
|
if self.attrs.get('type') == 'url':
|
|
73
73
|
pixbuf = common.IconFactory.get_pixbuf_url(
|
|
74
74
|
name, size=size, size_param=self.attrs.get('url_size'))
|
|
75
|
+
elif self.attrs.get('type') == 'color':
|
|
76
|
+
pixbuf = common.SolidColorFactory.get_pixbuf(name, size, size)
|
|
75
77
|
else:
|
|
76
78
|
pixbuf = common.IconFactory.get_pixbuf(name, size)
|
|
77
79
|
self.set_from_pixbuf(pixbuf)
|
|
@@ -82,7 +84,7 @@ class Frame(StateMixin, Gtk.Frame):
|
|
|
82
84
|
def __init__(self, label=None, attrs=None):
|
|
83
85
|
if not label: # label must be None to have no label widget
|
|
84
86
|
label = None
|
|
85
|
-
super(
|
|
87
|
+
super().__init__(label=label, attrs=attrs)
|
|
86
88
|
if not label:
|
|
87
89
|
self.set_shadow_type(Gtk.ShadowType.NONE)
|
|
88
90
|
self.set_border_width(0)
|
|
@@ -93,7 +95,7 @@ class ScrolledWindow(StateMixin, Gtk.ScrolledWindow):
|
|
|
93
95
|
def state_set(self, record):
|
|
94
96
|
# Force to show first to ensure it is displayed in the Notebook
|
|
95
97
|
self.show()
|
|
96
|
-
super(
|
|
98
|
+
super().state_set(record)
|
|
97
99
|
|
|
98
100
|
|
|
99
101
|
class Notebook(StateMixin, Gtk.Notebook):
|
|
@@ -105,7 +107,7 @@ class Expander(StateMixin, Gtk.Expander):
|
|
|
105
107
|
def __init__(self, label=None, attrs=None):
|
|
106
108
|
if not label:
|
|
107
109
|
label = None
|
|
108
|
-
super(
|
|
110
|
+
super().__init__(label=label, attrs=attrs)
|
|
109
111
|
|
|
110
112
|
|
|
111
113
|
class Link(StateMixin, Gtk.Button):
|
|
@@ -20,7 +20,7 @@ class TextBox(Widget, TranslateMixin):
|
|
|
20
20
|
expand = True
|
|
21
21
|
|
|
22
22
|
def __init__(self, view, attrs):
|
|
23
|
-
super(
|
|
23
|
+
super().__init__(view, attrs)
|
|
24
24
|
|
|
25
25
|
self.widget = Gtk.VBox()
|
|
26
26
|
self.scrolledwindow = Gtk.ScrolledWindow()
|
|
@@ -92,7 +92,7 @@ class TextBox(Widget, TranslateMixin):
|
|
|
92
92
|
textview.props.sensitive = not value
|
|
93
93
|
|
|
94
94
|
def _readonly_set(self, value):
|
|
95
|
-
super(
|
|
95
|
+
super()._readonly_set(value)
|
|
96
96
|
self.textview.set_editable(not value)
|
|
97
97
|
|
|
98
98
|
@property
|
|
@@ -120,7 +120,7 @@ class TextBox(Widget, TranslateMixin):
|
|
|
120
120
|
return buf.get_text(iter_start, iter_end, False)
|
|
121
121
|
|
|
122
122
|
def display(self):
|
|
123
|
-
super(
|
|
123
|
+
super().display()
|
|
124
124
|
value = self.field and self.field.get(self.record)
|
|
125
125
|
if not value:
|
|
126
126
|
value = ''
|
|
@@ -153,7 +153,7 @@ class TextBufferLimitSize(Gtk.TextBuffer):
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
def __init__(self, max_length):
|
|
156
|
-
super(
|
|
156
|
+
super().__init__()
|
|
157
157
|
self.max_length = max_length
|
|
158
158
|
|
|
159
159
|
def do_insert_text(self, iter, text, length):
|
|
@@ -10,7 +10,7 @@ from .widget import Widget
|
|
|
10
10
|
class TimeDelta(Widget):
|
|
11
11
|
|
|
12
12
|
def __init__(self, view, attrs):
|
|
13
|
-
super(
|
|
13
|
+
super().__init__(view, attrs)
|
|
14
14
|
|
|
15
15
|
self.widget = Gtk.HBox()
|
|
16
16
|
self.entry = self.mnemonic_widget = Gtk.Entry()
|
|
@@ -37,7 +37,7 @@ class TimeDelta(Widget):
|
|
|
37
37
|
return self.entry.get_text()
|
|
38
38
|
|
|
39
39
|
def display(self):
|
|
40
|
-
super(
|
|
40
|
+
super().display()
|
|
41
41
|
if not self.field:
|
|
42
42
|
value = ''
|
|
43
43
|
else:
|
|
@@ -46,5 +46,5 @@ class TimeDelta(Widget):
|
|
|
46
46
|
reset_position(self.entry)
|
|
47
47
|
|
|
48
48
|
def _readonly_set(self, value):
|
|
49
|
-
super(
|
|
49
|
+
super()._readonly_set(value)
|
|
50
50
|
self.entry.set_editable(not value)
|
|
@@ -22,7 +22,7 @@ class URL(Char):
|
|
|
22
22
|
"url"
|
|
23
23
|
|
|
24
24
|
def __init__(self, view, attrs):
|
|
25
|
-
super(
|
|
25
|
+
super().__init__(view, attrs)
|
|
26
26
|
|
|
27
27
|
self.tooltips = common.Tooltips()
|
|
28
28
|
self.button = Gtk.Button()
|
|
@@ -34,7 +34,7 @@ class URL(Char):
|
|
|
34
34
|
self.button, expand=False, fill=False, padding=0)
|
|
35
35
|
|
|
36
36
|
def display(self):
|
|
37
|
-
super(
|
|
37
|
+
super().display()
|
|
38
38
|
self.set_tooltips()
|
|
39
39
|
if self.record and 'icon' in self.attrs:
|
|
40
40
|
icon = self.attrs['icon']
|
|
@@ -17,7 +17,7 @@ from .graph import Graph
|
|
|
17
17
|
class Bar(Graph):
|
|
18
18
|
|
|
19
19
|
def __init__(self, *args, **kwargs):
|
|
20
|
-
super(
|
|
20
|
+
super().__init__(*args, **kwargs)
|
|
21
21
|
self.bars = []
|
|
22
22
|
|
|
23
23
|
def drawGraph(self, cr, width, height):
|
|
@@ -63,7 +63,7 @@ class Bar(Graph):
|
|
|
63
63
|
return linear
|
|
64
64
|
|
|
65
65
|
def motion(self, widget, event):
|
|
66
|
-
super(
|
|
66
|
+
super().motion(widget, event)
|
|
67
67
|
|
|
68
68
|
if not getattr(self, 'area', None):
|
|
69
69
|
return
|
|
@@ -127,7 +127,7 @@ class Bar(Graph):
|
|
|
127
127
|
maxx - minx + 2, maxy - miny + 2)
|
|
128
128
|
|
|
129
129
|
def action(self):
|
|
130
|
-
super(
|
|
130
|
+
super().action()
|
|
131
131
|
for bar in self.bars:
|
|
132
132
|
if bar.highlight:
|
|
133
133
|
ids = self.ids[bar.xname]
|
|
@@ -171,11 +171,11 @@ class VerticalBar(Bar):
|
|
|
171
171
|
i += 1
|
|
172
172
|
|
|
173
173
|
def XLabels(self):
|
|
174
|
-
xlabels = super(
|
|
174
|
+
xlabels = super().XLabels()
|
|
175
175
|
return [(x[0] + (self.xscale / 2), x[1]) for x in xlabels]
|
|
176
176
|
|
|
177
177
|
def YLabels(self):
|
|
178
|
-
ylabels = super(
|
|
178
|
+
ylabels = super().YLabels()
|
|
179
179
|
if all('timedelta' in f for f in self.yfields):
|
|
180
180
|
converter = {f.get('timedelta') for f in self.yfields}
|
|
181
181
|
if len(converter) == 1:
|
|
@@ -227,11 +227,11 @@ class HorizontalBar(Bar):
|
|
|
227
227
|
i += 1
|
|
228
228
|
|
|
229
229
|
def YLabels(self):
|
|
230
|
-
xlabels = super(
|
|
230
|
+
xlabels = super().XLabels()
|
|
231
231
|
return [(1 - (x[0] + (self.xscale / 2)), x[1]) for x in xlabels]
|
|
232
232
|
|
|
233
233
|
def XLabels(self):
|
|
234
|
-
ylabels = super(
|
|
234
|
+
ylabels = super().YLabels()
|
|
235
235
|
if all('timedelta' in f for f in self.yfields):
|
|
236
236
|
converter = {f.get('timedelta') for f in self.yfields}
|
|
237
237
|
if len(converter) == 1:
|
|
@@ -75,7 +75,7 @@ class Graph(Gtk.DrawingArea):
|
|
|
75
75
|
__gsignals__ = {"draw": "override"}
|
|
76
76
|
|
|
77
77
|
def __init__(self, view, xfield, yfields):
|
|
78
|
-
super(
|
|
78
|
+
super().__init__()
|
|
79
79
|
self.view = view
|
|
80
80
|
self.xfield = xfield
|
|
81
81
|
self.yfields = yfields
|
|
@@ -99,7 +99,7 @@ class Graph(Gtk.DrawingArea):
|
|
|
99
99
|
|
|
100
100
|
def destroy(self):
|
|
101
101
|
self.popup.destroy()
|
|
102
|
-
super(
|
|
102
|
+
super().destroy()
|
|
103
103
|
|
|
104
104
|
def motion(self, widget, event):
|
|
105
105
|
self.popup.set_position(self, event.x, event.y)
|
|
@@ -145,7 +145,7 @@ class Line(Graph):
|
|
|
145
145
|
cr.restore()
|
|
146
146
|
|
|
147
147
|
def drawLegend(self, cr, widht, height):
|
|
148
|
-
super(
|
|
148
|
+
super().drawLegend(cr, widht, height)
|
|
149
149
|
cr.save()
|
|
150
150
|
for point in self.points:
|
|
151
151
|
if point.highlight:
|
|
@@ -237,7 +237,7 @@ class Line(Graph):
|
|
|
237
237
|
int(maxx - minx + 1), int(maxy - miny + 1))
|
|
238
238
|
|
|
239
239
|
def updateXY(self):
|
|
240
|
-
super(
|
|
240
|
+
super().updateXY()
|
|
241
241
|
if self.xrange != 0:
|
|
242
242
|
self.xrange -= 1
|
|
243
243
|
if self.xrange == 0:
|
|
@@ -246,18 +246,18 @@ class Line(Graph):
|
|
|
246
246
|
self.xscale = 1.0 / self.xrange
|
|
247
247
|
|
|
248
248
|
def drawAxis(self, cr, width, height):
|
|
249
|
-
super(
|
|
249
|
+
super().drawAxis(cr, width, height)
|
|
250
250
|
self.drawLine(cr, 1.0, 0)
|
|
251
251
|
|
|
252
252
|
def action(self):
|
|
253
|
-
super(
|
|
253
|
+
super().action()
|
|
254
254
|
for point in self.points:
|
|
255
255
|
if point.highlight:
|
|
256
256
|
ids = self.ids[point.xname]
|
|
257
257
|
self.action_keyword(ids)
|
|
258
258
|
|
|
259
259
|
def YLabels(self):
|
|
260
|
-
ylabels = super(
|
|
260
|
+
ylabels = super().YLabels()
|
|
261
261
|
if all('timedelta' in f for f in self.yfields):
|
|
262
262
|
converter = {f.get('timedelta') for f in self.yfields}
|
|
263
263
|
if len(converter) == 1:
|
|
@@ -110,7 +110,7 @@ class Pie(Graph):
|
|
|
110
110
|
cr.restore()
|
|
111
111
|
|
|
112
112
|
def motion(self, widget, event):
|
|
113
|
-
super(
|
|
113
|
+
super().motion(widget, event)
|
|
114
114
|
|
|
115
115
|
if not getattr(self, 'area', None):
|
|
116
116
|
return
|
|
@@ -172,7 +172,7 @@ class Pie(Graph):
|
|
|
172
172
|
self.queue_draw()
|
|
173
173
|
|
|
174
174
|
def action(self):
|
|
175
|
-
super(
|
|
175
|
+
super().action()
|
|
176
176
|
for slice in self.slices:
|
|
177
177
|
if slice.highlight:
|
|
178
178
|
ids = self.ids[slice.xname]
|
|
@@ -8,13 +8,14 @@ import sys
|
|
|
8
8
|
from collections import defaultdict
|
|
9
9
|
from functools import wraps
|
|
10
10
|
from io import StringIO
|
|
11
|
+
from weakref import WeakValueDictionary
|
|
11
12
|
|
|
12
13
|
from gi.repository import Gdk, GLib, GObject, Gtk
|
|
13
14
|
|
|
14
15
|
import tryton.common as common
|
|
15
16
|
from tryton.common import (
|
|
16
|
-
RPCException, RPCExecute, Tooltips, domain_inversion,
|
|
17
|
-
simplify, unique_value)
|
|
17
|
+
RPCException, RPCExecute, Tooltips, domain_inversion, get_monitor_size,
|
|
18
|
+
node_attributes, simplify, unique_value)
|
|
18
19
|
from tryton.common.cellrendererbutton import CellRendererButton
|
|
19
20
|
from tryton.common.popup_menu import populate, popup
|
|
20
21
|
from tryton.config import CONFIG
|
|
@@ -23,7 +24,6 @@ from tryton.pyson import PYSONDecoder
|
|
|
23
24
|
|
|
24
25
|
from . import View, XMLViewParser
|
|
25
26
|
from .list_gtk.editabletree import EditableTreeView, TreeView
|
|
26
|
-
from .list_gtk.generictreemodel import GenericTreeModel
|
|
27
27
|
from .list_gtk.widget import (
|
|
28
28
|
M2M, M2O, O2M, O2O, URL, Affix, Binary, Boolean, Button, Char, Date, Dict,
|
|
29
29
|
Float, Image, Int, MultiSelection, ProgressBar, Reference, Selection, Text,
|
|
@@ -63,15 +63,30 @@ def path_convert_id2pos(model, id_path):
|
|
|
63
63
|
return tuple(indexes)
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
class
|
|
66
|
+
class ModelGroup(GObject.GObject, Gtk.TreeModel):
|
|
67
67
|
|
|
68
68
|
def __init__(self, group, children_field=None):
|
|
69
|
-
super(
|
|
69
|
+
super().__init__()
|
|
70
|
+
self._pool = WeakValueDictionary()
|
|
70
71
|
self.group = group
|
|
71
|
-
self.set_property('leak_references', False)
|
|
72
72
|
self.children_field = children_field
|
|
73
73
|
self.__removed = None # XXX dirty hack to allow update of has_child
|
|
74
74
|
|
|
75
|
+
def _get_user_data(self, iter):
|
|
76
|
+
return self._pool.get(iter.user_data)
|
|
77
|
+
|
|
78
|
+
def _set_user_data(self, iter, data):
|
|
79
|
+
if data is not None:
|
|
80
|
+
iter.user_data = id(data)
|
|
81
|
+
self._pool[iter.user_data] = data
|
|
82
|
+
else:
|
|
83
|
+
iter.user_data = None
|
|
84
|
+
|
|
85
|
+
def _create_tree_iter(self, data):
|
|
86
|
+
iter = Gtk.TreeIter()
|
|
87
|
+
self._set_user_data(iter, data)
|
|
88
|
+
return iter
|
|
89
|
+
|
|
75
90
|
def added(self, group, record):
|
|
76
91
|
if (group is self.group
|
|
77
92
|
and (record.group is self.group
|
|
@@ -103,7 +118,6 @@ class AdaptModelGroup(GenericTreeModel):
|
|
|
103
118
|
def remove(self, iter_):
|
|
104
119
|
record = self.get_value(iter_, 0)
|
|
105
120
|
record.group.remove(record)
|
|
106
|
-
self.invalidate_iters()
|
|
107
121
|
|
|
108
122
|
def __move(self, record, path, offset=0):
|
|
109
123
|
iter_ = self.get_iter(path)
|
|
@@ -172,43 +186,51 @@ class AdaptModelGroup(GenericTreeModel):
|
|
|
172
186
|
def __len__(self):
|
|
173
187
|
return len(self.group)
|
|
174
188
|
|
|
175
|
-
def
|
|
189
|
+
def do_get_flags(self):
|
|
176
190
|
if not self.children_field:
|
|
177
191
|
return Gtk.TreeModelFlags.LIST_ONLY
|
|
178
192
|
return 0
|
|
179
193
|
|
|
180
|
-
def
|
|
194
|
+
def do_get_n_columns(self):
|
|
181
195
|
# XXX
|
|
182
196
|
return 1
|
|
183
197
|
|
|
184
|
-
def
|
|
198
|
+
def do_get_column_type(self, index):
|
|
185
199
|
# XXX
|
|
186
200
|
return GObject.TYPE_PYOBJECT
|
|
187
201
|
|
|
188
|
-
def
|
|
189
|
-
|
|
202
|
+
def do_get_path(self, iter):
|
|
203
|
+
record = self._get_user_data(iter)
|
|
204
|
+
path = record.get_index_path(self.group)
|
|
205
|
+
if path is None:
|
|
206
|
+
return None
|
|
207
|
+
else:
|
|
208
|
+
return Gtk.TreePath(path)
|
|
190
209
|
|
|
191
|
-
def
|
|
210
|
+
def do_get_iter(self, path):
|
|
192
211
|
group = self.group
|
|
193
212
|
record = None
|
|
194
213
|
for i in path:
|
|
195
214
|
if group is None or i >= len(group):
|
|
196
|
-
return None
|
|
215
|
+
return (False, None)
|
|
197
216
|
record = group[i]
|
|
198
217
|
if not self.children_field:
|
|
199
218
|
break
|
|
200
219
|
group = record.children_group(self.children_field)
|
|
201
|
-
return record
|
|
220
|
+
return (True, self._create_tree_iter(record))
|
|
202
221
|
|
|
203
|
-
def
|
|
204
|
-
return
|
|
222
|
+
def do_get_value(self, iter, column):
|
|
223
|
+
return self._get_user_data(iter)
|
|
205
224
|
|
|
206
|
-
def
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
225
|
+
def do_iter_next(self, iter):
|
|
226
|
+
record = self._get_user_data(iter)
|
|
227
|
+
if record is not None:
|
|
228
|
+
record = record.next.get(id(record.group))
|
|
229
|
+
self._set_user_data(iter, record)
|
|
230
|
+
return record is not None
|
|
210
231
|
|
|
211
|
-
def
|
|
232
|
+
def do_iter_has_child(self, parent):
|
|
233
|
+
record = self._get_user_data(parent) if parent else None
|
|
212
234
|
if record is None or not self.children_field:
|
|
213
235
|
return False
|
|
214
236
|
children = record.children_group(self.children_field)
|
|
@@ -219,40 +241,49 @@ class AdaptModelGroup(GenericTreeModel):
|
|
|
219
241
|
length -= 1
|
|
220
242
|
return bool(length)
|
|
221
243
|
|
|
222
|
-
def
|
|
244
|
+
def do_iter_children(self, parent):
|
|
245
|
+
record = self._get_user_data(parent) if parent else None
|
|
246
|
+
child = None
|
|
223
247
|
if record is None:
|
|
224
248
|
if self.group:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return None
|
|
228
|
-
if self.children_field:
|
|
249
|
+
child = self.group[0]
|
|
250
|
+
elif self.children_field:
|
|
229
251
|
children = record.children_group(self.children_field)
|
|
230
252
|
if children:
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
child = children[0]
|
|
254
|
+
if child:
|
|
255
|
+
return (True, self._create_tree_iter(child))
|
|
256
|
+
else:
|
|
257
|
+
return (False, None)
|
|
233
258
|
|
|
234
|
-
def
|
|
259
|
+
def do_iter_n_children(self, iter):
|
|
260
|
+
record = self._get_user_data(iter) if iter else None
|
|
235
261
|
if record is None:
|
|
236
262
|
return len(self.group)
|
|
237
263
|
if not self.children_field:
|
|
238
264
|
return 0
|
|
239
265
|
return len(record.children_group(self.children_field))
|
|
240
266
|
|
|
241
|
-
def
|
|
267
|
+
def do_iter_nth_child(self, parent, n):
|
|
268
|
+
record = self._get_user_data(parent) if parent else None
|
|
269
|
+
child = None
|
|
242
270
|
if record is None:
|
|
243
|
-
if
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if
|
|
249
|
-
return
|
|
250
|
-
|
|
271
|
+
if n < len(self.group):
|
|
272
|
+
child = self.group[n]
|
|
273
|
+
elif self.children_field:
|
|
274
|
+
if n < len(record.children_group(self.children_field)):
|
|
275
|
+
child = record.children_group(self.children_field)[n]
|
|
276
|
+
if child:
|
|
277
|
+
return (True, self._create_tree_iter(child))
|
|
278
|
+
else:
|
|
279
|
+
return (False, None)
|
|
251
280
|
|
|
252
|
-
def
|
|
253
|
-
if
|
|
254
|
-
|
|
255
|
-
|
|
281
|
+
def do_iter_parent(self, child):
|
|
282
|
+
record = self._get_user_data(child) if child else None
|
|
283
|
+
if record and record.parent:
|
|
284
|
+
return (True, self._create_tree_iter(record.parent))
|
|
285
|
+
else:
|
|
286
|
+
return (False, None)
|
|
256
287
|
|
|
257
288
|
|
|
258
289
|
class TreeXMLViewParser(XMLViewParser):
|
|
@@ -407,19 +438,23 @@ class TreeXMLViewParser(XMLViewParser):
|
|
|
407
438
|
'binary': 200,
|
|
408
439
|
}
|
|
409
440
|
|
|
441
|
+
field_attrs = self.field_attrs.get(attributes['name'], {})
|
|
442
|
+
if field_attrs:
|
|
443
|
+
computed_width = default_width.get(field_attrs['type'], 100)
|
|
444
|
+
if attributes.get('symbol'):
|
|
445
|
+
computed_width += 20
|
|
446
|
+
else:
|
|
447
|
+
computed_width = 80
|
|
448
|
+
|
|
410
449
|
screen = self.view.screen
|
|
411
450
|
width = screen.tree_column_width[screen.model_name].get(column.name)
|
|
412
|
-
field_attrs = self.field_attrs.get(attributes['name'], {})
|
|
413
451
|
if not width:
|
|
414
452
|
if 'width' in attributes:
|
|
415
|
-
width = int(attributes['width'])
|
|
416
|
-
elif field_attrs:
|
|
417
|
-
width = default_width.get(field_attrs['type'], 100)
|
|
418
|
-
if attributes.get('symbol'):
|
|
419
|
-
width += 20
|
|
453
|
+
computed_width = width = int(attributes['width'])
|
|
420
454
|
else:
|
|
421
|
-
width =
|
|
455
|
+
width = computed_width
|
|
422
456
|
column.width = width
|
|
457
|
+
column.computed_width = computed_width
|
|
423
458
|
if width > 0:
|
|
424
459
|
column.set_fixed_width(width)
|
|
425
460
|
column.set_min_width(1)
|
|
@@ -537,6 +572,11 @@ class ViewTree(View):
|
|
|
537
572
|
menuitem.set_active(visible)
|
|
538
573
|
menuitem.connect('toggled', toggle, columns)
|
|
539
574
|
menu.add(menuitem)
|
|
575
|
+
if self.optionals:
|
|
576
|
+
menu.add(Gtk.SeparatorMenuItem())
|
|
577
|
+
menuitem = Gtk.MenuItem(label=_("Reset Column Widths"))
|
|
578
|
+
menuitem.connect('activate', self.reset_width)
|
|
579
|
+
menu.add(menuitem)
|
|
540
580
|
popup(menu, widget)
|
|
541
581
|
|
|
542
582
|
def save_optional(self):
|
|
@@ -551,6 +591,20 @@ class ViewTree(View):
|
|
|
551
591
|
pass
|
|
552
592
|
self.screen.tree_column_optional[self.view_id] = fields
|
|
553
593
|
|
|
594
|
+
def reset_width(self, menuitem):
|
|
595
|
+
try:
|
|
596
|
+
screen_width, _ = get_monitor_size()
|
|
597
|
+
RPCExecute(
|
|
598
|
+
'model', 'ir.ui.view_tree_width', 'reset_width',
|
|
599
|
+
self.screen.model_name, screen_width)
|
|
600
|
+
except RPCException:
|
|
601
|
+
pass
|
|
602
|
+
self.screen.tree_column_width.pop(self.screen.model_name, None)
|
|
603
|
+
|
|
604
|
+
for col in self.treeview.get_columns():
|
|
605
|
+
if col.name:
|
|
606
|
+
col.set_fixed_width(col.computed_width)
|
|
607
|
+
|
|
554
608
|
def get_column_widget(self, column):
|
|
555
609
|
'Return the widget of the column'
|
|
556
610
|
idx = [c for c in self.treeview.get_columns()
|
|
@@ -1048,11 +1102,12 @@ class ViewTree(View):
|
|
|
1048
1102
|
if last_col and last_col.name in fields:
|
|
1049
1103
|
del fields[last_col.name]
|
|
1050
1104
|
|
|
1105
|
+
screen_width, _ = get_monitor_size()
|
|
1051
1106
|
if fields and any(fields.values()):
|
|
1052
1107
|
model_name = self.screen.model_name
|
|
1053
1108
|
try:
|
|
1054
1109
|
RPCExecute('model', 'ir.ui.view_tree_width', 'set_width',
|
|
1055
|
-
model_name, fields)
|
|
1110
|
+
model_name, fields, screen_width)
|
|
1056
1111
|
except RPCException:
|
|
1057
1112
|
pass
|
|
1058
1113
|
self.screen.tree_column_width[model_name].update(fields)
|
|
@@ -1149,7 +1204,7 @@ class ViewTree(View):
|
|
|
1149
1204
|
if (force
|
|
1150
1205
|
or not self.treeview.get_model()
|
|
1151
1206
|
or self.group != self.treeview.get_model().group):
|
|
1152
|
-
model =
|
|
1207
|
+
model = ModelGroup(self.group, self.children_field)
|
|
1153
1208
|
self.treeview.set_model(model)
|
|
1154
1209
|
# __select_changed resets current_record to None
|
|
1155
1210
|
self.record = current_record
|
|
@@ -29,7 +29,7 @@ class TreeView(Gtk.TreeView):
|
|
|
29
29
|
display_counter = 0
|
|
30
30
|
|
|
31
31
|
def __init__(self, view):
|
|
32
|
-
super(
|
|
32
|
+
super().__init__()
|
|
33
33
|
self.view = view
|
|
34
34
|
|
|
35
35
|
def next_column(
|
|
@@ -153,7 +153,7 @@ class EditableTreeView(TreeView):
|
|
|
153
153
|
if cell:
|
|
154
154
|
self.set_cursor_on_cell(path, focus_column, cell, start_editing)
|
|
155
155
|
else:
|
|
156
|
-
super(
|
|
156
|
+
super().set_cursor(
|
|
157
157
|
path, focus_column, start_editing)
|
|
158
158
|
|
|
159
159
|
def set_value(self):
|