tryton 7.0.7__py3-none-any.whl → 7.4.4__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 (105) hide show
  1. tryton/__init__.py +1 -1
  2. tryton/cache.py +34 -0
  3. tryton/common/common.py +149 -73
  4. tryton/common/completion.py +2 -2
  5. tryton/common/datetime_.py +3 -1
  6. tryton/common/domain_inversion.py +2 -1
  7. tryton/common/domain_parser.py +22 -11
  8. tryton/common/popup_menu.py +1 -1
  9. tryton/common/selection.py +6 -3
  10. tryton/common/tempfile.py +34 -0
  11. tryton/config.py +4 -5
  12. tryton/data/locale/bg/LC_MESSAGES/tryton.mo +0 -0
  13. tryton/data/locale/bg/LC_MESSAGES/tryton.po +69 -20
  14. tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
  15. tryton/data/locale/ca/LC_MESSAGES/tryton.po +70 -25
  16. tryton/data/locale/cs/LC_MESSAGES/tryton.mo +0 -0
  17. tryton/data/locale/cs/LC_MESSAGES/tryton.po +68 -21
  18. tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
  19. tryton/data/locale/de/LC_MESSAGES/tryton.po +71 -26
  20. tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
  21. tryton/data/locale/es/LC_MESSAGES/tryton.po +68 -23
  22. tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
  23. tryton/data/locale/es_419/LC_MESSAGES/tryton.po +72 -22
  24. tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
  25. tryton/data/locale/et/LC_MESSAGES/tryton.po +73 -23
  26. tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
  27. tryton/data/locale/fa/LC_MESSAGES/tryton.po +74 -25
  28. tryton/data/locale/fi/LC_MESSAGES/tryton.mo +0 -0
  29. tryton/data/locale/fi/LC_MESSAGES/tryton.po +63 -20
  30. tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
  31. tryton/data/locale/fr/LC_MESSAGES/tryton.po +73 -28
  32. tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
  33. tryton/data/locale/hu/LC_MESSAGES/tryton.po +75 -23
  34. tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
  35. tryton/data/locale/id/LC_MESSAGES/tryton.po +72 -23
  36. tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
  37. tryton/data/locale/it/LC_MESSAGES/tryton.po +73 -24
  38. tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo +0 -0
  39. tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
  40. tryton/data/locale/lo/LC_MESSAGES/tryton.po +74 -25
  41. tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
  42. tryton/data/locale/lt/LC_MESSAGES/tryton.po +73 -23
  43. tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
  44. tryton/data/locale/nl/LC_MESSAGES/tryton.po +72 -27
  45. tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
  46. tryton/data/locale/pl/LC_MESSAGES/tryton.po +113 -78
  47. tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
  48. tryton/data/locale/pt/LC_MESSAGES/tryton.po +73 -24
  49. tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
  50. tryton/data/locale/ro/LC_MESSAGES/tryton.po +87 -36
  51. tryton/data/locale/ru/LC_MESSAGES/tryton.mo +0 -0
  52. tryton/data/locale/ru/LC_MESSAGES/tryton.po +72 -25
  53. tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
  54. tryton/data/locale/sl/LC_MESSAGES/tryton.po +77 -26
  55. tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
  56. tryton/data/locale/tr/LC_MESSAGES/tryton.po +64 -20
  57. tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
  58. tryton/data/locale/uk/LC_MESSAGES/tryton.po +75 -23
  59. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
  60. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po +76 -24
  61. tryton/device_cookie.py +1 -1
  62. tryton/gui/main.py +14 -12
  63. tryton/gui/window/about.py +1 -1
  64. tryton/gui/window/dblogin.py +2 -2
  65. tryton/gui/window/email_.py +2 -2
  66. tryton/gui/window/form.py +10 -5
  67. tryton/gui/window/log.py +24 -2
  68. tryton/gui/window/tabcontent.py +2 -2
  69. tryton/gui/window/view_form/model/field.py +84 -34
  70. tryton/gui/window/view_form/model/group.py +7 -2
  71. tryton/gui/window/view_form/model/record.py +70 -31
  72. tryton/gui/window/view_form/screen/screen.py +98 -47
  73. tryton/gui/window/view_form/view/calendar_gtk/calendar_.py +15 -9
  74. tryton/gui/window/view_form/view/form.py +6 -12
  75. tryton/gui/window/view_form/view/form_gtk/char.py +5 -6
  76. tryton/gui/window/view_form/view/form_gtk/dictionary.py +49 -29
  77. tryton/gui/window/view_form/view/form_gtk/document.py +15 -10
  78. tryton/gui/window/view_form/view/form_gtk/many2many.py +49 -7
  79. tryton/gui/window/view_form/view/form_gtk/many2one.py +21 -13
  80. tryton/gui/window/view_form/view/form_gtk/multiselection.py +15 -5
  81. tryton/gui/window/view_form/view/form_gtk/one2many.py +42 -10
  82. tryton/gui/window/view_form/view/form_gtk/state_widget.py +6 -2
  83. tryton/gui/window/view_form/view/form_gtk/url.py +8 -4
  84. tryton/gui/window/view_form/view/graph_gtk/graph.py +3 -1
  85. tryton/gui/window/view_form/view/list.py +116 -48
  86. tryton/gui/window/view_form/view/list_gtk/editabletree.py +2 -1
  87. tryton/gui/window/view_form/view/list_gtk/widget.py +58 -23
  88. tryton/gui/window/view_form/view/screen_container.py +3 -5
  89. tryton/gui/window/win_csv.py +6 -12
  90. tryton/gui/window/win_export.py +49 -26
  91. tryton/gui/window/win_form.py +9 -7
  92. tryton/gui/window/win_import.py +45 -15
  93. tryton/gui/window/wizard.py +13 -10
  94. tryton/jsonrpc.py +75 -34
  95. tryton/plugins/__init__.py +5 -3
  96. tryton/pyson.py +57 -6
  97. tryton/rpc.py +18 -0
  98. tryton/tests/test_common_domain_parser.py +31 -2
  99. tryton/translate.py +5 -2
  100. {tryton-7.0.7.data → tryton-7.4.4.data}/scripts/tryton +8 -7
  101. {tryton-7.0.7.dist-info → tryton-7.4.4.dist-info}/METADATA +6 -6
  102. {tryton-7.0.7.dist-info → tryton-7.4.4.dist-info}/RECORD +105 -103
  103. {tryton-7.0.7.dist-info → tryton-7.4.4.dist-info}/WHEEL +1 -1
  104. {tryton-7.0.7.dist-info → tryton-7.4.4.dist-info}/LICENSE +0 -0
  105. {tryton-7.0.7.dist-info → tryton-7.4.4.dist-info}/top_level.txt +0 -0
@@ -75,7 +75,8 @@ class Screen:
75
75
  self.__current_record = None
76
76
  self.new_group(context or {})
77
77
  self.current_record = None
78
- self.screen_container = ScreenContainer(attributes.get('tab_domain'))
78
+ self.screen_container = ScreenContainer(
79
+ self, attributes.get('tab_domain'))
79
80
  self.screen_container.alternate_view = attributes.get(
80
81
  'alternate_view', False)
81
82
  self.widget = self.screen_container.widget_get()
@@ -116,11 +117,10 @@ class Screen:
116
117
  return child
117
118
 
118
119
  # Remove first level Viewport and ScrolledWindow to fill the Vbox
119
- for widget in [
120
- self.context_screen.screen_container.viewport,
121
- self.context_screen.current_view.widget.get_children()[0],
122
- ]:
123
- remove_bin(widget)
120
+ remove_bin(self.context_screen.screen_container.viewport)
121
+ if self.context_screen.current_view:
122
+ remove_bin(
123
+ self.context_screen.current_view.widget.get_children()[0])
124
124
 
125
125
  self.screen_container.filter_vbox.pack_start(
126
126
  context_widget, expand=False, fill=True, padding=0)
@@ -164,7 +164,6 @@ class Screen:
164
164
 
165
165
  def search_active(self, active=True):
166
166
  if active and not self.parent:
167
- self.screen_container.set_screen(self)
168
167
  self.screen_container.show_filter()
169
168
  else:
170
169
  self.screen_container.hide_filter()
@@ -308,7 +307,8 @@ class Screen:
308
307
  try:
309
308
  self.search_count = RPCExecute(
310
309
  'model', self.model_name, 'search_count',
311
- domain, 0, self.count_limit, context=context)
310
+ domain, 0, self.count_limit, context=context,
311
+ process_exception=False)
312
312
  except RPCException:
313
313
  self.search_count = 0
314
314
  else:
@@ -323,6 +323,7 @@ class Screen:
323
323
  if only_ids:
324
324
  return ids
325
325
  self.clear()
326
+ GLib.idle_add(self.screen_container.search_entry.grab_focus)
326
327
  self.load(ids)
327
328
  self.count_tab_domain()
328
329
  return bool(ids)
@@ -520,7 +521,8 @@ class Screen:
520
521
  self.group.destroy()
521
522
 
522
523
  def default_row_activate(self):
523
- if (self.current_view.view_type == 'tree'
524
+ if (self.current_view
525
+ and self.current_view.view_type == 'tree'
524
526
  and int(self.current_view.attributes.get('keyword_open', 0))):
525
527
  return Action.exec_keyword('tree_open', {
526
528
  'model': self.model_name,
@@ -536,6 +538,19 @@ class Screen:
536
538
  def number_of_views(self):
537
539
  return len(self.views) + len(self.view_to_load)
538
540
 
541
+ @property
542
+ def view_index(self):
543
+ return self.__current_view
544
+
545
+ @property
546
+ def next_view_type(self):
547
+ views = self.views + self.view_to_load
548
+ next_view_index = (self.view_index + 1) % len(views)
549
+ next_view = views[next_view_index]
550
+ if next_view and not isinstance(next_view, str):
551
+ next_view = next_view.view_type
552
+ return next_view
553
+
539
554
  def switch_view(
540
555
  self, view_type=None, view_id=None, creatable=None, display=True):
541
556
  if view_id is not None:
@@ -642,7 +657,7 @@ class Screen:
642
657
 
643
658
  def new(self, default=True, defaults=None):
644
659
  previous_view = self.current_view
645
- if self.current_view.view_type == 'calendar':
660
+ if self.current_view and self.current_view.view_type == 'calendar':
646
661
  selected_date = self.current_view.get_selected_date()
647
662
  if self.current_view and not self.current_view.creatable:
648
663
  self.switch_view(creatable=True)
@@ -695,16 +710,19 @@ class Screen:
695
710
 
696
711
  def save_current(self):
697
712
  if not self.current_record:
698
- if self.current_view.view_type == 'tree' and len(self.group):
713
+ if (self.current_view
714
+ and self.current_view.view_type == 'tree'
715
+ and len(self.group)):
699
716
  self.current_record = self.group[0]
700
717
  else:
701
718
  return True
702
- self.current_view.set_value()
703
719
  saved = False
704
720
  record_id = None
705
- fields = self.current_view.get_fields()
721
+ if self.current_view:
722
+ self.current_view.set_value()
723
+ fields = self.current_view.get_fields()
706
724
  path = self.current_record.get_path(self.group)
707
- if self.current_view.view_type == 'tree':
725
+ if self.current_view and self.current_view.view_type == 'tree':
708
726
  # False value must be not saved
709
727
  saved = all((
710
728
  x is not False and x >= 0
@@ -714,7 +732,7 @@ class Screen:
714
732
  record_id = self.current_record.save(force_reload=True)
715
733
  # False value must be not saved
716
734
  saved = record_id is not False and record_id >= 0
717
- else:
735
+ elif self.current_view:
718
736
  self.set_cursor()
719
737
  self.current_view.display()
720
738
  return False
@@ -742,17 +760,19 @@ class Screen:
742
760
  def get(self):
743
761
  if not self.current_record:
744
762
  return None
745
- self.current_view.set_value()
763
+ if self.current_view:
764
+ self.current_view.set_value()
746
765
  return self.current_record.get()
747
766
 
748
767
  def get_on_change_value(self):
749
768
  if not self.current_record:
750
769
  return None
751
- self.current_view.set_value()
770
+ if self.current_view:
771
+ self.current_view.set_value()
752
772
  return self.current_record.get_on_change_value()
753
773
 
754
774
  def modified(self):
755
- if self.current_view.view_type != 'tree':
775
+ if self.current_view and self.current_view.view_type != 'tree':
756
776
  if self.current_record:
757
777
  if self.current_record.modified or self.current_record.id < 0:
758
778
  return True
@@ -760,7 +780,7 @@ class Screen:
760
780
  for record in self.group:
761
781
  if record.modified or record.id < 0:
762
782
  return True
763
- if self.current_view.modified:
783
+ if self.current_view and self.current_view.modified:
764
784
  return True
765
785
  return False
766
786
 
@@ -782,6 +802,7 @@ class Screen:
782
802
  records = records or self.selected_records
783
803
  if not records:
784
804
  return
805
+ current_record = self.current_record
785
806
  if delete:
786
807
  # Must delete children records before parent
787
808
  records.sort(key=lambda r: r.depth, reverse=True)
@@ -795,6 +816,9 @@ class Screen:
795
816
  record.group.remove(
796
817
  record, remove=remove, modified=False,
797
818
  force_remove=force_remove)
819
+ # set current_record to None to prevent __select_changed
820
+ # to set deleted record as current_record
821
+ self.current_record = None
798
822
  # call only once
799
823
  record.set_modified()
800
824
 
@@ -809,7 +833,10 @@ class Screen:
809
833
  record.parent.save(force_reload=False)
810
834
  record.destroy()
811
835
 
812
- self.current_record = None
836
+ if current_record and not current_record.destroyed:
837
+ self.current_record = current_record
838
+ else:
839
+ self.current_record = None
813
840
  self.set_cursor()
814
841
  self.display()
815
842
  return True
@@ -821,11 +848,16 @@ class Screen:
821
848
  context=self.context)
822
849
  except RPCException:
823
850
  return False
824
- self.load(new_ids, position=self.new_position)
851
+ self.group.load(new_ids, position=self.new_position)
852
+ if new_ids:
853
+ self.current_record = self.group.get(new_ids[0])
854
+ self.display(set_cursor=True)
825
855
  return True
826
856
 
827
857
  def set_tree_state(self):
828
858
  view = self.current_view
859
+ if not view:
860
+ return
829
861
  if view.view_type not in {'tree', 'form', 'list-form'}:
830
862
  return
831
863
  if id(view) in self.tree_states_done:
@@ -920,7 +952,7 @@ class Screen:
920
952
  json_paths, json_selected_path,
921
953
  process_exception=False)
922
954
  clear_cache('model.ir.ui.view_tree_state.get')
923
- except Exception:
955
+ except RPCException:
924
956
  logger.warn(
925
957
  _('Unable to set view tree state'), exc_info=True)
926
958
 
@@ -935,12 +967,13 @@ class Screen:
935
967
 
936
968
  def load(self, ids, set_cursor=True, modified=False, position=-1):
937
969
  self.group.load(ids, modified=modified, position=position)
938
- self.current_view.reset()
970
+ if self.current_view:
971
+ self.current_view.reset()
939
972
  self.current_record = None
940
973
  self.display(set_cursor=set_cursor)
941
974
 
942
975
  def display(self, set_cursor=False):
943
- if self.views:
976
+ if self.views and self.current_view:
944
977
  self.search_active(self.current_view.view_type
945
978
  in ('tree', 'graph', 'calendar'))
946
979
  for view in self.views:
@@ -972,7 +1005,8 @@ class Screen:
972
1005
 
973
1006
  def _get_next_record(self, test=False):
974
1007
  view = self.current_view
975
- if (view.view_type in {'tree', 'form'}
1008
+ if (view
1009
+ and view.view_type in {'tree', 'form'}
976
1010
  and self.current_record
977
1011
  and self.current_record.group):
978
1012
  group = self.current_record.group
@@ -1000,12 +1034,14 @@ class Screen:
1000
1034
  record = next
1001
1035
  break
1002
1036
  return record
1003
- elif (view.view_type == 'list-form' and len(self.group)
1037
+ elif (view
1038
+ and view.view_type == 'list-form'
1039
+ and len(self.group)
1004
1040
  and self.current_record in self.group):
1005
1041
  idx = self.group.index(self.current_record)
1006
1042
  if 0 <= idx < len(self.group) - 1:
1007
1043
  return self.group[idx + 1]
1008
- elif view.view_type == 'calendar':
1044
+ elif view and view.view_type == 'calendar':
1009
1045
  record = self.current_record
1010
1046
  goocalendar = view.widgets.get('goocalendar')
1011
1047
  if goocalendar:
@@ -1039,15 +1075,18 @@ class Screen:
1039
1075
 
1040
1076
  def display_next(self):
1041
1077
  view = self.current_view
1042
- view.set_value()
1078
+ if view:
1079
+ view.set_value()
1043
1080
  self.set_cursor(reset_view=False)
1044
1081
  self.current_record = self._get_next_record()
1045
1082
  self.set_cursor(reset_view=False)
1046
- view.display()
1083
+ if view:
1084
+ view.display()
1047
1085
 
1048
1086
  def _get_prev_record(self, test=False):
1049
1087
  view = self.current_view
1050
- if (view.view_type in {'tree', 'form'}
1088
+ if (view
1089
+ and view.view_type in {'tree', 'form'}
1051
1090
  and self.current_record
1052
1091
  and self.current_record.group):
1053
1092
  group = self.current_record.group
@@ -1065,7 +1104,7 @@ class Screen:
1065
1104
  if parent and record.model_name == parent.model_name:
1066
1105
  record = parent
1067
1106
  return record
1068
- elif view.view_type == 'calendar':
1107
+ elif view and view.view_type == 'calendar':
1069
1108
  record = self.current_record
1070
1109
  goocalendar = view.widgets.get('goocalendar')
1071
1110
  if goocalendar:
@@ -1090,7 +1129,9 @@ class Screen:
1090
1129
  if prev_id >= 0:
1091
1130
  return events[prev_id].record
1092
1131
  break
1093
- elif (view.view_type == 'list-form' and len(self.group)
1132
+ elif (view
1133
+ and view.view_type == 'list-form'
1134
+ and len(self.group)
1094
1135
  and self.current_record in self.group):
1095
1136
  idx = self.group.index(self.current_record)
1096
1137
  if 0 < idx <= len(self.group) - 1:
@@ -1104,11 +1145,13 @@ class Screen:
1104
1145
 
1105
1146
  def display_prev(self):
1106
1147
  view = self.current_view
1107
- view.set_value()
1148
+ if view:
1149
+ view.set_value()
1108
1150
  self.set_cursor(reset_view=False)
1109
1151
  self.current_record = self._get_prev_record()
1110
1152
  self.set_cursor(reset_view=False)
1111
- view.display()
1153
+ if view:
1154
+ view.display()
1112
1155
 
1113
1156
  def invalid_message(self, record=None):
1114
1157
  if record is None:
@@ -1142,6 +1185,8 @@ class Screen:
1142
1185
  def selected_paths(self):
1143
1186
  if self.current_view and self.current_view.view_type == 'tree':
1144
1187
  return self.current_view.get_selected_paths()
1188
+ else:
1189
+ return []
1145
1190
 
1146
1191
  @property
1147
1192
  def listed_records(self):
@@ -1181,7 +1226,7 @@ class Screen:
1181
1226
  if not self.selected_records:
1182
1227
  return []
1183
1228
 
1184
- buttons = self.current_view.get_buttons()
1229
+ buttons = self.current_view.get_buttons() if self.current_view else []
1185
1230
 
1186
1231
  for record in self.selected_records:
1187
1232
  buttons = [b for b in buttons if is_active(record, b)]
@@ -1191,8 +1236,9 @@ class Screen:
1191
1236
 
1192
1237
  def button(self, button):
1193
1238
  'Execute button on the selected records'
1194
- self.current_view.set_value()
1195
- fields = self.current_view.get_fields()
1239
+ if self.current_view:
1240
+ self.current_view.set_value()
1241
+ fields = self.current_view.get_fields()
1196
1242
  for record in self.selected_records:
1197
1243
  domain = record.expr_eval(
1198
1244
  button.get('states', {})).get('pre_validate', [])
@@ -1206,9 +1252,9 @@ class Screen:
1206
1252
  if button.get('confirm', False) and not sur(button['confirm']):
1207
1253
  return
1208
1254
  if button.get('type', 'class') == 'class':
1209
- if not self.current_record.save(force_reload=False):
1255
+ record_id = self.current_record.save(force_reload=False)
1256
+ if record_id is False or record_id < 0:
1210
1257
  return
1211
- if button.get('type', 'class') == 'class':
1212
1258
  self._button_class(button)
1213
1259
  else:
1214
1260
  self._button_instance(button)
@@ -1217,6 +1263,7 @@ class Screen:
1217
1263
  record = self.current_record
1218
1264
  args = record.expr_eval(button.get('change', []))
1219
1265
  values = record._get_on_change_args(args)
1266
+ values['id'] = record.id
1220
1267
  try:
1221
1268
  changes = RPCExecute('model', self.model_name, button['name'],
1222
1269
  values, context=self.context)
@@ -1237,6 +1284,7 @@ class Screen:
1237
1284
  except RPCException:
1238
1285
  action = None
1239
1286
  self.reload(ids, written=True)
1287
+ self.record_saved()
1240
1288
  if isinstance(action, str):
1241
1289
  self.client_action(action)
1242
1290
  elif action:
@@ -1273,7 +1321,9 @@ class Screen:
1273
1321
  elif action.startswith('switch'):
1274
1322
  self.switch_view(*action.split(None, 2)[1:])
1275
1323
  elif action == 'reload':
1276
- if (self.current_view.view_type in ['tree', 'graph', 'calendar']
1324
+ if (self.current_view
1325
+ and self.current_view.view_type in [
1326
+ 'tree', 'graph', 'calendar']
1277
1327
  and not self.parent):
1278
1328
  self.search_filter()
1279
1329
  elif action == 'reload menu':
@@ -1297,13 +1347,13 @@ class Screen:
1297
1347
  if name:
1298
1348
  query_string.append(
1299
1349
  ('name', json.dumps(name, separators=(',', ':'))))
1300
- if self.screen_container.tab_domain:
1301
- query_string.append(('tab_domain', json.dumps(
1302
- self.screen_container.tab_domain,
1303
- cls=JSONEncoder, separators=(',', ':'))))
1304
1350
  path = [CONFIG['login.db'], 'model', self.model_name]
1305
1351
  view_ids = [v.view_id for v in self.views] + self.view_ids
1306
- if self.current_view.view_type != 'form':
1352
+ if self.current_view and self.current_view.view_type != 'form':
1353
+ if self.screen_container.tab_domain:
1354
+ query_string.append(('tab_domain', json.dumps(
1355
+ self.screen_container.tab_domain,
1356
+ cls=JSONEncoder, separators=(',', ':'))))
1307
1357
  if self.search_value:
1308
1358
  search_value = self.search_value
1309
1359
  else:
@@ -1315,8 +1365,9 @@ class Screen:
1315
1365
  separators=(',', ':'))))
1316
1366
  elif self.current_record and self.current_record.id > -1:
1317
1367
  path.append(str(self.current_record.id))
1318
- i = view_ids.index(self.current_view.view_id)
1319
- view_ids = view_ids[i:] + view_ids[:i]
1368
+ if self.current_view:
1369
+ i = view_ids.index(self.current_view.view_id)
1370
+ view_ids = view_ids[i:] + view_ids[:i]
1320
1371
  if view_ids:
1321
1372
  query_string.append(('views', json.dumps(
1322
1373
  view_ids, separators=(',', ':'))))
@@ -63,17 +63,23 @@ class Calendar_(goocalendar.Calendar):
63
63
  return False
64
64
 
65
65
  def current_domain(self):
66
- first_datetime, last_datetime = \
67
- self.current_domain_period.get_dates(True)
66
+ start, end = self.current_domain_period.get_dates(True)
68
67
  dtstart = self.attrs['dtstart']
69
68
  dtend = self.attrs.get('dtend') or dtstart
70
- domain = ['OR',
71
- ['AND', (dtstart, '>=', first_datetime),
72
- (dtstart, '<', last_datetime)],
73
- ['AND', (dtend, '>=', first_datetime),
74
- (dtend, '<', last_datetime)],
75
- ['AND', (dtstart, '<', first_datetime),
76
- (dtend, '>', last_datetime)]]
69
+ fields = self.view_calendar.screen.group.fields
70
+ if fields[dtstart].attrs['type'] == 'date':
71
+ start = start.date()
72
+ if fields[dtend].attrs['type'] == 'date':
73
+ end = end.date()
74
+ domain = [
75
+ (dtstart, '!=', None),
76
+ (dtend, '!=', None),
77
+ ['OR',
78
+ ['AND', (dtstart, '>=', start), (dtstart, '<', end)],
79
+ ['AND', (dtend, '>=', start), (dtend, '<', end)],
80
+ ['AND', (dtstart, '<', start), (dtend, '>', end)],
81
+ ],
82
+ ]
77
83
  return domain
78
84
 
79
85
  def get_colors(self, record):
@@ -230,6 +230,9 @@ class FormXMLViewParser(XMLViewParser):
230
230
  self.container.add(None, attributes)
231
231
  return
232
232
 
233
+ if int(attributes.get('visible', 0)):
234
+ self.field_attrs[name]['visible'] = True
235
+
233
236
  widget = self.WIDGETS[attributes['widget']](self.view, attributes)
234
237
  self.view.widgets[name].append(widget)
235
238
 
@@ -340,18 +343,7 @@ class FormXMLViewParser(XMLViewParser):
340
343
  int(attributes.get('width', -1)),
341
344
  int(attributes.get('height', -1)))
342
345
 
343
- # Force to display the first time it switches on a page
344
- # This avoids glitch in position of widgets
345
- def switch(notebook, page, page_num):
346
- if not self.view.widget:
347
- # Not yet finish to parse
348
- return
349
- notebook.grab_focus()
350
- self.view.display()
351
- notebook.disconnect(handler_id)
352
- handler_id = notebook.connect('switch-page', switch)
353
346
  self.view.state_widgets.append(notebook)
354
-
355
347
  self.view.notebooks.append(notebook)
356
348
  self.container.add(notebook, attributes)
357
349
  self.parse_child(node, notebook)
@@ -390,7 +382,6 @@ class FormXMLViewParser(XMLViewParser):
390
382
  group = Container.constructor(
391
383
  int(attributes.get('col', 4)),
392
384
  attributes.get('homogeneous', False))
393
- self.parse_child(node, group)
394
385
 
395
386
  if 'name' in attributes and attributes['name'] == self.exclude_field:
396
387
  self.container.add(None, attributes)
@@ -414,6 +405,9 @@ class FormXMLViewParser(XMLViewParser):
414
405
  bool(attributes.get('yexpand'))))
415
406
  self.view.state_widgets.append(widget)
416
407
  self.container.add(widget, attributes)
408
+ # Parse the children at the end to preserve the order of the state
409
+ # widgets
410
+ self.parse_child(node, group)
417
411
 
418
412
  def _parse_hpaned(self, node, attributes):
419
413
  self._parse_paned(node, attributes, Gtk.HPaned)
@@ -171,10 +171,9 @@ class Password(Char):
171
171
  self.widget.pack_start(
172
172
  self.visibility_checkbox, expand=False, fill=True, padding=0)
173
173
 
174
- def _readonly_set(self, value):
175
- super(Char, self)._readonly_set(value)
176
- self.entry.set_editable(not value)
177
- self.visibility_checkbox.props.visible = not value
178
-
179
174
  def toggle_visibility(self, button):
180
- self.entry.props.visibility = not self.entry.props.visibility
175
+ if self.autocomplete:
176
+ entry = self.entry.get_child()
177
+ else:
178
+ entry = self.entry
179
+ entry.props.visibility = not self.entry.props.visibility