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.

Files changed (122) hide show
  1. tryton/__init__.py +1 -1
  2. tryton/bus.py +113 -69
  3. tryton/chat.py +179 -0
  4. tryton/client.py +7 -0
  5. tryton/common/__init__.py +15 -11
  6. tryton/common/button.py +1 -1
  7. tryton/common/cellrendererfloat.py +1 -1
  8. tryton/common/cellrenderertext.py +2 -2
  9. tryton/common/common.py +91 -19
  10. tryton/common/environment.py +2 -2
  11. tryton/common/number_entry.py +12 -6
  12. tryton/common/selection.py +1 -1
  13. tryton/data/locale/bg/LC_MESSAGES/tryton.mo +0 -0
  14. tryton/data/locale/bg/LC_MESSAGES/tryton.po +26 -16
  15. tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
  16. tryton/data/locale/ca/LC_MESSAGES/tryton.po +29 -18
  17. tryton/data/locale/cs/LC_MESSAGES/tryton.mo +0 -0
  18. tryton/data/locale/cs/LC_MESSAGES/tryton.po +28 -16
  19. tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
  20. tryton/data/locale/de/LC_MESSAGES/tryton.po +27 -18
  21. tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
  22. tryton/data/locale/es/LC_MESSAGES/tryton.po +25 -16
  23. tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
  24. tryton/data/locale/es_419/LC_MESSAGES/tryton.po +26 -16
  25. tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
  26. tryton/data/locale/et/LC_MESSAGES/tryton.po +28 -18
  27. tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
  28. tryton/data/locale/fa/LC_MESSAGES/tryton.po +28 -18
  29. tryton/data/locale/fi/LC_MESSAGES/tryton.mo +0 -0
  30. tryton/data/locale/fi/LC_MESSAGES/tryton.po +25 -16
  31. tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
  32. tryton/data/locale/fr/LC_MESSAGES/tryton.po +25 -16
  33. tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
  34. tryton/data/locale/hu/LC_MESSAGES/tryton.po +28 -18
  35. tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
  36. tryton/data/locale/id/LC_MESSAGES/tryton.po +23 -16
  37. tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
  38. tryton/data/locale/it/LC_MESSAGES/tryton.po +29 -18
  39. tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo +0 -0
  40. tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
  41. tryton/data/locale/lo/LC_MESSAGES/tryton.po +26 -18
  42. tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
  43. tryton/data/locale/lt/LC_MESSAGES/tryton.po +30 -18
  44. tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
  45. tryton/data/locale/nl/LC_MESSAGES/tryton.po +25 -16
  46. tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
  47. tryton/data/locale/pl/LC_MESSAGES/tryton.po +31 -18
  48. tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
  49. tryton/data/locale/pt/LC_MESSAGES/tryton.po +148 -177
  50. tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
  51. tryton/data/locale/ro/LC_MESSAGES/tryton.po +32 -19
  52. tryton/data/locale/ru/LC_MESSAGES/tryton.mo +0 -0
  53. tryton/data/locale/ru/LC_MESSAGES/tryton.po +28 -16
  54. tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
  55. tryton/data/locale/sl/LC_MESSAGES/tryton.po +33 -18
  56. tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
  57. tryton/data/locale/tr/LC_MESSAGES/tryton.po +25 -16
  58. tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
  59. tryton/data/locale/uk/LC_MESSAGES/tryton.po +31 -18
  60. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
  61. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po +27 -18
  62. tryton/data/pixmaps/tryton/tryton-chat.svg +1 -0
  63. tryton/data/pixmaps/tryton/tryton-note.svg +1 -4
  64. tryton/gui/window/attachment.py +2 -2
  65. tryton/gui/window/board.py +1 -1
  66. tryton/gui/window/form.py +57 -10
  67. tryton/gui/window/note.py +2 -2
  68. tryton/gui/window/tabcontent.py +8 -1
  69. tryton/gui/window/view_board/action.py +1 -1
  70. tryton/gui/window/view_form/model/field.py +34 -28
  71. tryton/gui/window/view_form/model/group.py +4 -4
  72. tryton/gui/window/view_form/model/record.py +19 -4
  73. tryton/gui/window/view_form/screen/screen.py +24 -4
  74. tryton/gui/window/view_form/view/calendar_gtk/calendar_.py +1 -1
  75. tryton/gui/window/view_form/view/calendar_gtk/toolbar.py +1 -1
  76. tryton/gui/window/view_form/view/form.py +2 -1
  77. tryton/gui/window/view_form/view/form_gtk/binary.py +3 -3
  78. tryton/gui/window/view_form/view/form_gtk/calendar_.py +4 -4
  79. tryton/gui/window/view_form/view/form_gtk/char.py +42 -5
  80. tryton/gui/window/view_form/view/form_gtk/checkbox.py +3 -3
  81. tryton/gui/window/view_form/view/form_gtk/dictionary.py +53 -15
  82. tryton/gui/window/view_form/view/form_gtk/float.py +3 -7
  83. tryton/gui/window/view_form/view/form_gtk/image.py +4 -4
  84. tryton/gui/window/view_form/view/form_gtk/integer.py +1 -1
  85. tryton/gui/window/view_form/view/form_gtk/many2many.py +3 -4
  86. tryton/gui/window/view_form/view/form_gtk/many2one.py +2 -2
  87. tryton/gui/window/view_form/view/form_gtk/multiselection.py +3 -3
  88. tryton/gui/window/view_form/view/form_gtk/one2many.py +11 -8
  89. tryton/gui/window/view_form/view/form_gtk/progressbar.py +2 -2
  90. tryton/gui/window/view_form/view/form_gtk/pyson.py +3 -3
  91. tryton/gui/window/view_form/view/form_gtk/reference.py +4 -4
  92. tryton/gui/window/view_form/view/form_gtk/richtextbox.py +5 -5
  93. tryton/gui/window/view_form/view/form_gtk/selection.py +3 -3
  94. tryton/gui/window/view_form/view/form_gtk/state_widget.py +8 -6
  95. tryton/gui/window/view_form/view/form_gtk/textbox.py +4 -4
  96. tryton/gui/window/view_form/view/form_gtk/timedelta.py +3 -3
  97. tryton/gui/window/view_form/view/form_gtk/url.py +2 -2
  98. tryton/gui/window/view_form/view/form_gtk/widget.py +1 -1
  99. tryton/gui/window/view_form/view/graph_gtk/bar.py +7 -7
  100. tryton/gui/window/view_form/view/graph_gtk/graph.py +2 -2
  101. tryton/gui/window/view_form/view/graph_gtk/line.py +5 -5
  102. tryton/gui/window/view_form/view/graph_gtk/pie.py +2 -2
  103. tryton/gui/window/view_form/view/list.py +107 -52
  104. tryton/gui/window/view_form/view/list_gtk/editabletree.py +2 -2
  105. tryton/gui/window/view_form/view/list_gtk/widget.py +22 -20
  106. tryton/gui/window/view_form/view/screen_container.py +13 -1
  107. tryton/gui/window/win_csv.py +2 -2
  108. tryton/gui/window/win_export.py +9 -7
  109. tryton/gui/window/win_form.py +74 -39
  110. tryton/gui/window/win_import.py +5 -6
  111. tryton/gui/window/wizard.py +11 -11
  112. tryton/jsonrpc.py +2 -2
  113. tryton/plugins/__init__.py +0 -1
  114. tryton/pyson.py +18 -18
  115. tryton/rpc.py +7 -5
  116. {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/METADATA +5 -5
  117. {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/RECORD +121 -120
  118. tryton/gui/window/view_form/view/list_gtk/generictreemodel.py +0 -426
  119. {tryton-7.4.10.data → tryton-7.6.1.data}/scripts/tryton +0 -0
  120. {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/WHEEL +0 -0
  121. {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/licenses/LICENSE +0 -0
  122. {tryton-7.4.10.dist-info → tryton-7.6.1.dist-info}/top_level.txt +0 -0
@@ -186,7 +186,7 @@ class Affix(Cell):
186
186
  expand = False
187
187
 
188
188
  def __init__(self, view, attrs, protocol=None):
189
- super(Affix, self).__init__()
189
+ super().__init__()
190
190
  self.attrs = attrs
191
191
  self.protocol = protocol
192
192
  self.icon = attrs.get('icon')
@@ -221,6 +221,8 @@ class Affix(Cell):
221
221
  pixbuf = common.IconFactory.get_pixbuf_url(
222
222
  value, size_param=self.attrs.get('url_size'),
223
223
  callback=callback)
224
+ elif self.attrs.get('icon_type') == 'color':
225
+ pixbuf = common.SolidColorFactory.get_pixbuf(value)
224
226
  else:
225
227
  pixbuf = common.IconFactory.get_pixbuf(
226
228
  value, Gtk.IconSize.BUTTON)
@@ -284,7 +286,7 @@ class GenericText(Cell):
284
286
  editing = None
285
287
 
286
288
  def __init__(self, view, attrs, renderer=None):
287
- super(GenericText, self).__init__()
289
+ super().__init__()
288
290
  self.attrs = attrs
289
291
  if renderer is None:
290
292
  renderer = CellRendererText
@@ -395,7 +397,7 @@ class Char(GenericText):
395
397
  @realized
396
398
  @CellCache.cache
397
399
  def setter(self, column, cell, store, iter_, user_data=None):
398
- super(Char, self).setter(column, cell, store, iter_, user_data)
400
+ super().setter(column, cell, store, iter_, user_data)
399
401
  cell.set_property('single-paragraph-mode', True)
400
402
 
401
403
 
@@ -409,7 +411,7 @@ class Int(GenericText):
409
411
  def __init__(self, view, attrs, renderer=None):
410
412
  if renderer is None:
411
413
  renderer = CellRendererInteger
412
- super(Int, self).__init__(view, attrs, renderer=renderer)
414
+ super().__init__(view, attrs, renderer=renderer)
413
415
  self.factor = float(attrs.get('factor', 1))
414
416
  self.symbol = attrs.get('symbol')
415
417
  self.grouping = bool(int(attrs.get('grouping', 1)))
@@ -449,7 +451,7 @@ class Boolean(GenericText):
449
451
  renderer=None):
450
452
  if renderer is None:
451
453
  renderer = CellRendererToggle
452
- super(Boolean, self).__init__(view, attrs, renderer=renderer)
454
+ super().__init__(view, attrs, renderer=renderer)
453
455
  self.renderer.connect('toggled', self._sig_toggled)
454
456
 
455
457
  def _sig_toggled(self, renderer, path):
@@ -471,7 +473,7 @@ class URL(Char):
471
473
  @realized
472
474
  @CellCache.cache
473
475
  def setter(self, column, cell, store, iter_, user_data=None):
474
- super(URL, self).setter(column, cell, store, iter_, user_data)
476
+ super().setter(column, cell, store, iter_, user_data)
475
477
  record, field = self._get_record_field_from_iter(iter_, store)
476
478
  field.state_set(record, states=('readonly',))
477
479
  readonly = field.get_state_attrs(record).get('readonly', False)
@@ -483,13 +485,13 @@ class Date(GenericText):
483
485
  def __init__(self, view, attrs, renderer=None):
484
486
  if renderer is None:
485
487
  renderer = CellRendererDate
486
- super(Date, self).__init__(view, attrs, renderer=renderer)
488
+ super().__init__(view, attrs, renderer=renderer)
487
489
 
488
490
  @realized
489
491
  def setter(self, column, cell, store, iter_, user_data=None):
490
492
  record, field = self._get_record_field_from_iter(iter_, store)
491
493
  self.renderer.props.format = self.get_format(record, field)
492
- super(Date, self).setter(column, cell, store, iter_, user_data)
494
+ super().setter(column, cell, store, iter_, user_data)
493
495
 
494
496
  def get_format(self, record, field):
495
497
  if field and record:
@@ -523,7 +525,7 @@ class Time(Date):
523
525
  def __init__(self, view, attrs, renderer=None):
524
526
  if renderer is None:
525
527
  renderer = CellRendererTime
526
- super(Time, self).__init__(view, attrs, renderer=renderer)
528
+ super().__init__(view, attrs, renderer=renderer)
527
529
 
528
530
  def get_format(self, record, field):
529
531
  if field and record:
@@ -558,12 +560,12 @@ class Float(Int):
558
560
  def __init__(self, view, attrs, renderer=None):
559
561
  if renderer is None:
560
562
  renderer = CellRendererFloat
561
- super(Float, self).__init__(view, attrs, renderer=renderer)
563
+ super().__init__(view, attrs, renderer=renderer)
562
564
  self.renderer.monetary = attrs.get('monetary', False)
563
565
 
564
566
  @realized
565
567
  def setter(self, column, cell, store, iter_, user_data=None):
566
- super(Float, self).setter(column, cell, store, iter_, user_data)
568
+ super().setter(column, cell, store, iter_, user_data)
567
569
  record, field = self._get_record_field_from_iter(iter_, store)
568
570
  digits = field.digits(record, factor=self.factor)
569
571
  cell.digits = digits
@@ -575,7 +577,7 @@ class Binary(GenericText):
575
577
  def __init__(self, view, attrs, renderer=None):
576
578
  if renderer is None:
577
579
  renderer = CellRendererText
578
- super(Binary, self).__init__(view, attrs, renderer=renderer)
580
+ super().__init__(view, attrs, renderer=renderer)
579
581
  self.renderer.set_property('editable', False)
580
582
  self.renderer.set_property('xalign', self.align)
581
583
  self._cell_save = _BinarySave(self)
@@ -782,7 +784,7 @@ class Image(GenericText):
782
784
  def __init__(self, view, attrs=None, renderer=None):
783
785
  if renderer is None:
784
786
  renderer = Gtk.CellRendererPixbuf
785
- super(Image, self).__init__(view, attrs, renderer)
787
+ super().__init__(view, attrs, renderer)
786
788
  self.height = int(attrs.get('height', 100))
787
789
  self.width = int(attrs.get('width', 300))
788
790
  self.renderer.set_fixed_size(self.width, self.height)
@@ -825,7 +827,7 @@ class M2O(GenericText):
825
827
  def __init__(self, view, attrs, renderer=None):
826
828
  if renderer is None and int(attrs.get('completion', 1)):
827
829
  renderer = partial(CellRendererTextCompletion, self.set_completion)
828
- super(M2O, self).__init__(view, attrs, renderer=renderer)
830
+ super().__init__(view, attrs, renderer=renderer)
829
831
  self._popup = False
830
832
 
831
833
  def get_model(self, record, field):
@@ -859,7 +861,7 @@ class M2O(GenericText):
859
861
  win.show()
860
862
 
861
863
  def editing_started(self, cell, editable, path):
862
- super(M2O, self).editing_started(cell, editable, path)
864
+ super().editing_started(cell, editable, path)
863
865
  record, field = self._get_record_field_from_path(path)
864
866
  model = self.get_model(record, field)
865
867
 
@@ -1140,7 +1142,7 @@ class Selection(GenericText, SelectionMixin, PopdownMixin):
1140
1142
  def __init__(self, *args, **kwargs):
1141
1143
  if 'renderer' not in kwargs:
1142
1144
  kwargs['renderer'] = CellRendererCombo
1143
- super(Selection, self).__init__(*args, **kwargs)
1145
+ super().__init__(*args, **kwargs)
1144
1146
  if self.view and self.view.editable:
1145
1147
  self.init_selection()
1146
1148
  # Use a variable let Python holding reference when calling
@@ -1180,7 +1182,7 @@ class Selection(GenericText, SelectionMixin, PopdownMixin):
1180
1182
  self.set_popdown_value(self.editable, value)
1181
1183
 
1182
1184
  def editing_started(self, cell, editable, path):
1183
- super(Selection, self).editing_started(cell, editable, path)
1185
+ super().editing_started(cell, editable, path)
1184
1186
  record, field = self._get_record_field_from_path(path)
1185
1187
  gdk_backend = get_gdk_backend()
1186
1188
  if gdk_backend == 'x11':
@@ -1266,7 +1268,7 @@ class MultiSelection(GenericText, SelectionMixin):
1266
1268
  class Reference(M2O):
1267
1269
 
1268
1270
  def __init__(self, view, attrs, renderer=None):
1269
- super(Reference, self).__init__(view, attrs, renderer=renderer)
1271
+ super().__init__(view, attrs, renderer=renderer)
1270
1272
  self._cell_selection = _ReferenceSelection(view, attrs)
1271
1273
 
1272
1274
  @property
@@ -1357,7 +1359,7 @@ class ProgressBar(Cell):
1357
1359
  }
1358
1360
 
1359
1361
  def __init__(self, view, attrs):
1360
- super(ProgressBar, self).__init__()
1362
+ super().__init__()
1361
1363
  self.view = view
1362
1364
  self.attrs = attrs
1363
1365
  self.renderer = Gtk.CellRendererProgress()
@@ -1402,7 +1404,7 @@ class ProgressBar(Cell):
1402
1404
  class Button(Cell):
1403
1405
 
1404
1406
  def __init__(self, view, attrs):
1405
- super(Button, self).__init__()
1407
+ super().__init__()
1406
1408
  self.attrs = attrs
1407
1409
  self.renderer = CellRendererButton(attrs.get('string', _('Unknown')))
1408
1410
  self.view = view
@@ -151,14 +151,20 @@ class Numbers(Between):
151
151
  class Selection(Gtk.ScrolledWindow):
152
152
 
153
153
  def __init__(self, selections):
154
- super(Selection, self).__init__()
154
+ super().__init__()
155
155
  self.treeview = Gtk.TreeView()
156
156
  model = Gtk.ListStore(GObject.TYPE_STRING)
157
157
  for selection in selections:
158
158
  model.append((selection,))
159
159
  self.treeview.set_model(model)
160
160
 
161
+ t_selection = self.treeview.get_selection()
161
162
  column = Gtk.TreeViewColumn()
163
+ select_cell = Gtk.CellRendererToggle()
164
+ select_cell.set_sensitive(False)
165
+ column.pack_start(select_cell, expand=False)
166
+ column.set_cell_data_func(
167
+ select_cell, self._select_data_func, t_selection)
162
168
  cell = Gtk.CellRendererText()
163
169
  column.pack_start(cell, expand=True)
164
170
  column.add_attribute(cell, 'text', 0)
@@ -182,6 +188,9 @@ class Selection(Gtk.ScrolledWindow):
182
188
  values.append(model.get_value(iter_, 0))
183
189
  return ';'.join(quote(v) for v in values)
184
190
 
191
+ def _select_data_func(self, column, cell, model, iter_, selection):
192
+ cell.set_property('active', selection.iter_is_selected(iter_))
193
+
185
194
 
186
195
  class ScreenContainer(object):
187
196
 
@@ -349,6 +358,9 @@ class ScreenContainer(object):
349
358
 
350
359
  tooltips.enable()
351
360
 
361
+ def grab_focus(self):
362
+ self.search_entry.grab_focus()
363
+
352
364
  def widget_get(self):
353
365
  return self.vbox
354
366
 
@@ -33,7 +33,7 @@ encodings = ["ascii", "big5", "big5hkscs", "cp037", "cp424", "cp437", "cp500",
33
33
 
34
34
  class WinCSV(NoModal):
35
35
  def __init__(self, *args, **kwargs):
36
- super(WinCSV, self).__init__(*args, **kwargs)
36
+ super().__init__(*args, **kwargs)
37
37
 
38
38
  self.languages = RPCExecute(
39
39
  'model', 'ir.lang', 'search_read', [
@@ -310,7 +310,7 @@ class WinCSV(NoModal):
310
310
  return self.csv_enc.get_active_text() or 'utf_8'
311
311
 
312
312
  def destroy(self):
313
- super(WinCSV, self).destroy()
313
+ super().destroy()
314
314
  self.dialog.destroy()
315
315
 
316
316
  def show(self):
@@ -24,6 +24,7 @@ from tryton.rpc import CONNECTION, clear_cache
24
24
  from .infobar import InfoBar
25
25
 
26
26
  _ = gettext.gettext
27
+ N_ = gettext.ngettext
27
28
 
28
29
 
29
30
  class WinExport(WinCSV, InfoBar):
@@ -33,7 +34,7 @@ class WinExport(WinCSV, InfoBar):
33
34
  self.name = name
34
35
  self.screen = screen
35
36
  self.fields = {}
36
- super(WinExport, self).__init__()
37
+ super().__init__()
37
38
  self.dialog.set_title(_('CSV Export: %s') % name)
38
39
  self.dialog.vbox.pack_start(
39
40
  self.create_info_bar(), expand=False, fill=True, padding=0)
@@ -237,8 +238,9 @@ class WinExport(WinCSV, InfoBar):
237
238
  def fill_predefwin(self):
238
239
  try:
239
240
  exports = RPCExecute(
240
- 'model', 'ir.export', 'get', self.model,
241
- ['name', 'header', 'records', 'export_fields.name'],
241
+ 'model', 'ir.export', 'get', self.model, [
242
+ 'name', 'header', 'records', 'ignore_search_limit',
243
+ 'export_fields.name'],
242
244
  context=self.context)
243
245
  except RPCException:
244
246
  return
@@ -281,6 +283,7 @@ class WinExport(WinCSV, InfoBar):
281
283
  'records': (
282
284
  'selected' if self.selected_records.get_active()
283
285
  else 'listed'),
286
+ 'ignore_search_limit': self.ignore_search_limit.get_active(),
284
287
  }
285
288
  if not pref_id:
286
289
  values.update({
@@ -349,6 +352,8 @@ class WinExport(WinCSV, InfoBar):
349
352
  self.add_field_names.set_active(values.get('header'))
350
353
  self.selected_records.set_active(
351
354
  int(values.get('records') == 'selected'))
355
+ self.ignore_search_limit.set_active(
356
+ values.get('ignore_search_limit'))
352
357
 
353
358
  def sel_field(self, name):
354
359
  string_, relation = self.fields[name]
@@ -435,10 +440,7 @@ class WinExport(WinCSV, InfoBar):
435
440
  size = len(data)
436
441
  if header:
437
442
  size -= 1
438
- if size <= 1:
439
- message = _('%d record saved.') % size
440
- else:
441
- message = _('%d records saved.') % size
443
+ message = N_('%d record saved.', '%d records saved.', size) % size
442
444
  self.info_bar_add(message, Gtk.MessageType.INFO)
443
445
  return True
444
446
  except (IOError, UnicodeEncodeError, csv.Error) as exception:
@@ -26,6 +26,10 @@ class WinForm(NoModal, InfoBar):
26
26
  save_current=False, title='', defaults=None):
27
27
  tooltips = common.Tooltips()
28
28
  NoModal.__init__(self)
29
+
30
+ self._position = None
31
+ self._length = 0
32
+
29
33
  self.screen = screen
30
34
  self.callback = callback
31
35
  self.many = many
@@ -171,13 +175,14 @@ class WinForm(NoModal, InfoBar):
171
175
  hbox.set_halign(Gtk.Align.END)
172
176
  access = common.MODELACCESS[screen.model_name]
173
177
 
174
- but_switch = Gtk.Button()
175
- tooltips.set_tip(but_switch, _('Switch'))
176
- but_switch.connect('clicked', self.switch_view)
177
- but_switch.add(common.IconFactory.get_image(
178
+ self.but_switch = Gtk.Button()
179
+ tooltips.set_tip(self.but_switch, _('Switch'))
180
+ self.but_switch.connect('clicked', self.switch_view)
181
+ self.but_switch.add(common.IconFactory.get_image(
178
182
  'tryton-switch', Gtk.IconSize.SMALL_TOOLBAR))
179
- but_switch.set_relief(Gtk.ReliefStyle.NONE)
180
- hbox.pack_start(but_switch, expand=False, fill=False, padding=0)
183
+ self.but_switch.set_relief(Gtk.ReliefStyle.NONE)
184
+ hbox.pack_start(
185
+ self.but_switch, expand=False, fill=False, padding=0)
181
186
 
182
187
  self.but_pre = Gtk.Button()
183
188
  tooltips.set_tip(self.but_pre, _('Previous'))
@@ -266,7 +271,7 @@ class WinForm(NoModal, InfoBar):
266
271
  if not access['delete'] or readonly:
267
272
  self.but_undel.set_sensitive(False)
268
273
 
269
- but_switch.props.sensitive = screen.number_of_views > 1
274
+ self.but_switch.props.sensitive = screen.number_of_views > 1
270
275
 
271
276
  tooltips.enable()
272
277
  hbox.show_all()
@@ -353,43 +358,73 @@ class WinForm(NoModal, InfoBar):
353
358
  win.show()
354
359
 
355
360
  def record_message(self, position, size, *args):
361
+ self._position = position
362
+ self._length = size
363
+ name = str(position) if position else '_'
364
+ selected = len(self.screen.selected_records)
365
+ if selected > 1:
366
+ name += '#%i' % selected
367
+ name = '(%s/%s)' % (name, common.humanize(size))
368
+ if hasattr(self, 'label'):
369
+ self.label.set_text(name)
370
+ self._set_button_sensitive()
371
+
372
+ def record_modified(self, *args):
373
+ self.info_bar_refresh()
374
+ self._set_button_sensitive()
375
+
376
+ def _set_button_sensitive(self):
356
377
  if self.view_type != 'tree':
357
378
  return
358
- name = '_'
359
379
  access = common.MODELACCESS[self.screen.model_name]
360
- deletable = True
361
- if self.screen.current_record:
362
- deletable = self.screen.current_record.deletable
380
+
381
+ first = last = False
382
+ if isinstance(self._position, int):
383
+ first = self._position <= 1
384
+ last = self._position >= self._length
385
+ deletable = (
386
+ self.screen.deletable
387
+ and any(
388
+ not r.deleted and not r.removed
389
+ for r in self.screen.selected_records))
390
+ undeletable = any(
391
+ r.deleted or r.removed for r in self.screen.selected_records)
392
+ view_type = self.screen.current_view.view_type
393
+ has_views = self.screen.number_of_views > 1
363
394
  readonly = self.screen.group.readonly
364
- if position >= 1:
365
- name = str(position)
366
- if self.domain is not None:
367
- self.but_remove.set_sensitive(True)
368
- if position < size:
369
- self.but_next.set_sensitive(True)
370
- else:
371
- self.but_next.set_sensitive(False)
372
- if position > 1:
373
- self.but_pre.set_sensitive(True)
374
- else:
375
- self.but_pre.set_sensitive(False)
376
- self.but_del.set_sensitive(bool(
377
- not readonly
378
- and access['delete']
379
- and deletable))
380
- self.but_undel.set_sensitive(bool(not readonly))
381
- else:
382
- self.but_del.set_sensitive(False)
383
- self.but_undel.set_sensitive(False)
384
- self.but_next.set_sensitive(False)
385
- self.but_pre.set_sensitive(False)
386
- if self.domain is not None:
387
- self.but_remove.set_sensitive(False)
388
- line = '(%s/%s)' % (name, position)
389
- self.label.set_text(line)
390
395
 
391
- def record_modified(self, *args):
392
- self.info_bar_refresh()
396
+ self.but_switch.set_sensitive(
397
+ (self._position or view_type == 'form') and has_views)
398
+ self.but_new.set_sensitive(bool(
399
+ not readonly
400
+ and access['create']))
401
+ self.but_del.set_sensitive(bool(
402
+ not readonly
403
+ and access['delete']
404
+ and deletable
405
+ and self._position is not None))
406
+ self.but_undel.set_sensitive(bool(
407
+ not readonly
408
+ and undeletable
409
+ and self._position is not None))
410
+ self.but_next.set_sensitive(bool(
411
+ self._length
412
+ and not last))
413
+ self.but_pre.set_sensitive(bool(
414
+ self._length
415
+ and not first))
416
+ if self.domain is not None:
417
+ self.but_add.set_sensitive(bool(
418
+ not readonly
419
+ and self.write_access
420
+ and access['read']))
421
+ self.but_remove.set_sensitive(bool(
422
+ not readonly
423
+ and self._position is not None
424
+ and access['write']
425
+ and access['read']))
426
+ self.wid_text.set_sensitive(self.but_add.get_sensitive())
427
+ self.wid_text.set_editable(self.but_add.get_sensitive())
393
428
 
394
429
  def close(self, widget):
395
430
  widget.stop_emission_by_name('close')
@@ -14,7 +14,8 @@ from tryton.common import IconFactory, RPCException, RPCExecute
14
14
  from tryton.common.underline import set_underline
15
15
  from tryton.gui.window.win_csv import WinCSV
16
16
 
17
- _ = gettext.gettext
17
+ _ = gettext
18
+ N_ = gettext.ngettext
18
19
 
19
20
 
20
21
  class WinImport(WinCSV):
@@ -27,7 +28,7 @@ class WinImport(WinCSV):
27
28
  self.fields_data = {}
28
29
  self.fields = {}
29
30
  self.fields_invert = {}
30
- super(WinImport, self).__init__()
31
+ super().__init__()
31
32
  self.dialog.set_title(_('CSV Import: %s') % name)
32
33
 
33
34
  button_cancel = self.dialog.add_button(
@@ -256,8 +257,6 @@ class WinImport(WinCSV):
256
257
  context=self.context)
257
258
  except RPCException:
258
259
  return
259
- if count == 1:
260
- common.message(_('%d record imported.') % count)
261
- else:
262
- common.message(_('%d records imported.') % count)
260
+ common.message(
261
+ N_('%d record imported.', '%d records imported.', count) % count)
263
262
  return count
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
25
25
  class Wizard(InfoBar):
26
26
 
27
27
  def __init__(self, name=''):
28
- super(Wizard, self).__init__()
28
+ super().__init__()
29
29
  self.widget = Gtk.VBox(spacing=3)
30
30
  self.widget.show()
31
31
  self.name = name or _('Wizard')
@@ -255,7 +255,7 @@ class WizardForm(Wizard, TabContent):
255
255
  "Wizard"
256
256
 
257
257
  def __init__(self, name=''):
258
- super(WizardForm, self).__init__(name=name)
258
+ super().__init__(name=name)
259
259
  self.hbuttonbox = Gtk.HButtonBox()
260
260
  self.hbuttonbox.set_spacing(5)
261
261
  self.hbuttonbox.set_layout(Gtk.ButtonBoxStyle.END)
@@ -267,19 +267,19 @@ class WizardForm(Wizard, TabContent):
267
267
  }
268
268
 
269
269
  def clean(self):
270
- super(WizardForm, self).clean()
270
+ super().clean()
271
271
  for button in self.hbuttonbox.get_children():
272
272
  self.hbuttonbox.remove(button)
273
273
 
274
274
  def _get_button(self, state):
275
- button = super(WizardForm, self)._get_button(state)
275
+ button = super()._get_button(state)
276
276
  response = len(self.states)
277
277
  button.connect('clicked', self.response, response)
278
278
  self.hbuttonbox.pack_start(button, expand=True, fill=True, padding=0)
279
279
  return button
280
280
 
281
281
  def update(self, view, buttons):
282
- super(WizardForm, self).update(view, buttons)
282
+ super().update(view, buttons)
283
283
  self.widget.pack_start(
284
284
  self.hbuttonbox, expand=False, fill=True, padding=0)
285
285
 
@@ -289,14 +289,14 @@ class WizardForm(Wizard, TabContent):
289
289
  return self.state == self.end_state
290
290
 
291
291
  def destroy(self, action=None):
292
- super(WizardForm, self).destroy(action=action)
292
+ super().destroy(action=action)
293
293
  if action == 'reload menu':
294
294
  RPCContextReload(Main().sig_win_menu)
295
295
  elif action == 'reload context':
296
296
  RPCContextReload()
297
297
 
298
298
  def end(self, callback=None):
299
- super(WizardForm, self).end(callback=callback)
299
+ super().end(callback=callback)
300
300
  Main()._win_del(self.widget)
301
301
 
302
302
  def set_cursor(self):
@@ -331,13 +331,13 @@ class WizardDialog(Wizard, NoModal):
331
331
  self.register()
332
332
 
333
333
  def clean(self):
334
- super(WizardDialog, self).clean()
334
+ super().clean()
335
335
  while self._buttons:
336
336
  button = self._buttons.pop()
337
337
  button.get_parent().remove(button)
338
338
 
339
339
  def _get_button(self, definition):
340
- button = super(WizardDialog, self)._get_button(definition)
340
+ button = super()._get_button(definition)
341
341
  response = len(self.states)
342
342
  self.dia.add_action_widget(button, response)
343
343
  self._buttons.add(button)
@@ -353,7 +353,7 @@ class WizardDialog(Wizard, NoModal):
353
353
  return button
354
354
 
355
355
  def update(self, view, buttons):
356
- super(WizardDialog, self).update(view, buttons)
356
+ super().update(view, buttons)
357
357
  current_view = self.screen.current_view
358
358
  self.scrolledwindow.set_policy(
359
359
  Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
@@ -368,7 +368,7 @@ class WizardDialog(Wizard, NoModal):
368
368
  Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
369
369
 
370
370
  def destroy(self, action=None):
371
- super(WizardDialog, self).destroy(action=action)
371
+ super().destroy(action=action)
372
372
  self.dia.destroy()
373
373
  NoModal.destroy(self)
374
374
  main = Main()
tryton/jsonrpc.py CHANGED
@@ -51,7 +51,7 @@ class ResponseError(xmlrpc.client.ResponseError):
51
51
  class Fault(xmlrpc.client.Fault):
52
52
 
53
53
  def __init__(self, faultCode, faultString='', **extra):
54
- super(Fault, self).__init__(faultCode, faultString, **extra)
54
+ super().__init__(faultCode, faultString, **extra)
55
55
  self.args = faultString
56
56
 
57
57
  def __str__(self):
@@ -119,7 +119,7 @@ class JSONEncoder(json.JSONEncoder):
119
119
  return {'__class__': 'Decimal',
120
120
  'decimal': str(obj),
121
121
  }
122
- return super(JSONEncoder, self).default(obj)
122
+ return super().default(obj)
123
123
 
124
124
 
125
125
  class JSONParser(object):
@@ -14,7 +14,6 @@ MODULES = []
14
14
 
15
15
 
16
16
  def register():
17
- global MODULES
18
17
  paths = [
19
18
  os.path.join(get_config_dir(), 'plugins'),
20
19
  os.path.join(CURRENT_DIR, 'plugins'),