tryton 6.6.8__tar.gz → 6.8.1__tar.gz

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 (299) hide show
  1. {tryton-6.6.8 → tryton-6.8.1}/CHANGELOG +15 -27
  2. {tryton-6.6.8 → tryton-6.8.1}/PKG-INFO +6 -6
  3. {tryton-6.6.8 → tryton-6.8.1}/doc/conf.py +4 -1
  4. {tryton-6.6.8 → tryton-6.8.1}/doc/usage.rst +12 -8
  5. {tryton-6.6.8 → tryton-6.8.1}/setup.py +9 -6
  6. tryton-6.8.1/tox.ini +14 -0
  7. {tryton-6.6.8 → tryton-6.8.1}/tryton/__init__.py +1 -1
  8. {tryton-6.6.8 → tryton-6.8.1}/tryton/action/main.py +32 -43
  9. {tryton-6.6.8 → tryton-6.8.1}/tryton/bus.py +2 -0
  10. {tryton-6.6.8 → tryton-6.8.1}/tryton/client.py +3 -0
  11. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/button.py +3 -1
  12. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/common.py +55 -43
  13. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/datetime_.py +14 -2
  14. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/domain_inversion.py +10 -10
  15. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/domain_parser.py +5 -2
  16. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/popup_menu.py +7 -0
  17. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/selection.py +3 -1
  18. {tryton-6.6.8 → tryton-6.8.1}/tryton/config.py +22 -5
  19. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/bg/LC_MESSAGES/tryton.mo +0 -0
  20. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/bg/LC_MESSAGES/tryton.po +45 -39
  21. tryton-6.8.1/tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
  22. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ca/LC_MESSAGES/tryton.po +41 -35
  23. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/cs/LC_MESSAGES/tryton.mo +0 -0
  24. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/cs/LC_MESSAGES/tryton.po +46 -39
  25. tryton-6.8.1/tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
  26. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/de/LC_MESSAGES/tryton.po +41 -35
  27. tryton-6.8.1/tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
  28. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/es/LC_MESSAGES/tryton.po +41 -35
  29. tryton-6.8.1/tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
  30. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/es_419/LC_MESSAGES/tryton.po +171 -167
  31. tryton-6.8.1/tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
  32. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/et/LC_MESSAGES/tryton.po +47 -39
  33. tryton-6.8.1/tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
  34. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/fa/LC_MESSAGES/tryton.po +46 -38
  35. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/fi/LC_MESSAGES/tryton.mo +0 -0
  36. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/fi/LC_MESSAGES/tryton.po +38 -32
  37. tryton-6.8.1/tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
  38. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/fr/LC_MESSAGES/tryton.po +42 -36
  39. tryton-6.8.1/tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
  40. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/hu/LC_MESSAGES/tryton.po +44 -34
  41. tryton-6.8.1/tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
  42. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/id/LC_MESSAGES/tryton.po +40 -34
  43. tryton-6.8.1/tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
  44. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/it/LC_MESSAGES/tryton.po +44 -34
  45. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo +0 -0
  46. tryton-6.8.1/tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
  47. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/lo/LC_MESSAGES/tryton.po +46 -38
  48. tryton-6.8.1/tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
  49. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/lt/LC_MESSAGES/tryton.po +47 -37
  50. tryton-6.8.1/tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
  51. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/nl/LC_MESSAGES/tryton.po +41 -35
  52. tryton-6.8.1/tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
  53. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/pl/LC_MESSAGES/tryton.po +45 -35
  54. tryton-6.8.1/tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
  55. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/pt/LC_MESSAGES/tryton.po +46 -38
  56. tryton-6.8.1/tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
  57. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ro/LC_MESSAGES/tryton.po +50 -48
  58. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ru/LC_MESSAGES/tryton.mo +0 -0
  59. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ru/LC_MESSAGES/tryton.po +45 -39
  60. tryton-6.8.1/tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
  61. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/sl/LC_MESSAGES/tryton.po +47 -38
  62. tryton-6.8.1/tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
  63. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/tr/LC_MESSAGES/tryton.po +39 -33
  64. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/tryton.pot +38 -32
  65. tryton-6.8.1/tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
  66. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/uk/LC_MESSAGES/tryton.po +43 -35
  67. tryton-6.8.1/tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
  68. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po +45 -35
  69. tryton-6.8.1/tryton/data/pixmaps/tryton/tryton-icon.svg +1 -0
  70. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/main.py +54 -61
  71. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/dblogin.py +27 -10
  72. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/form.py +21 -53
  73. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/infobar.py +9 -4
  74. tryton-6.8.1/tryton/gui/window/log.py +95 -0
  75. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_board/action.py +0 -4
  76. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/model/field.py +36 -14
  77. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/model/record.py +22 -9
  78. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/screen/screen.py +45 -76
  79. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/calendar_.py +24 -11
  80. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/calendar_gtk/toolbar.py +6 -5
  81. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form.py +14 -5
  82. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/many2many.py +10 -1
  83. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/many2one.py +1 -0
  84. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/one2many.py +7 -7
  85. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/textbox.py +0 -2
  86. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/widget.py +8 -10
  87. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/list_form.py +61 -5
  88. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/list_gtk/editabletree.py +13 -3
  89. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/list_gtk/widget.py +97 -27
  90. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/win_form.py +6 -5
  91. {tryton-6.6.8 → tryton-6.8.1}/tryton/rpc.py +13 -15
  92. tryton-6.8.1/tryton/tests/test_common.py +46 -0
  93. {tryton-6.6.8 → tryton-6.8.1}/tryton/tests/test_common_domain_parser.py +24 -24
  94. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/PKG-INFO +6 -6
  95. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/SOURCES.txt +3 -0
  96. tryton-6.6.8/tox.ini +0 -10
  97. tryton-6.6.8/tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
  98. tryton-6.6.8/tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
  99. tryton-6.6.8/tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
  100. tryton-6.6.8/tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
  101. tryton-6.6.8/tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
  102. tryton-6.6.8/tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
  103. tryton-6.6.8/tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
  104. tryton-6.6.8/tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
  105. tryton-6.6.8/tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
  106. tryton-6.6.8/tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
  107. tryton-6.6.8/tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
  108. tryton-6.6.8/tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
  109. tryton-6.6.8/tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
  110. tryton-6.6.8/tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
  111. tryton-6.6.8/tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
  112. tryton-6.6.8/tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
  113. tryton-6.6.8/tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
  114. tryton-6.6.8/tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
  115. tryton-6.6.8/tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
  116. tryton-6.6.8/tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
  117. {tryton-6.6.8 → tryton-6.8.1}/COPYRIGHT +0 -0
  118. {tryton-6.6.8 → tryton-6.8.1}/LICENSE +0 -0
  119. {tryton-6.6.8 → tryton-6.8.1}/MANIFEST.in +0 -0
  120. {tryton-6.6.8 → tryton-6.8.1}/README.rst +0 -0
  121. {tryton-6.6.8 → tryton-6.8.1}/bin/tryton +0 -0
  122. {tryton-6.6.8 → tryton-6.8.1}/catalan.nsh +0 -0
  123. {tryton-6.6.8 → tryton-6.8.1}/darwin/gtk-3.0/gdk-pixbuf.loaders +0 -0
  124. {tryton-6.6.8 → tryton-6.8.1}/darwin/gtk-3.0/gtk.immodules +0 -0
  125. {tryton-6.6.8 → tryton-6.8.1}/doc/glossary.rst +0 -0
  126. {tryton-6.6.8 → tryton-6.8.1}/doc/index.rst +0 -0
  127. {tryton-6.6.8 → tryton-6.8.1}/doc/installation.rst +0 -0
  128. {tryton-6.6.8 → tryton-6.8.1}/doc/releases.rst +0 -0
  129. {tryton-6.6.8 → tryton-6.8.1}/english.nsh +0 -0
  130. {tryton-6.6.8 → tryton-6.8.1}/farsi.nsh +0 -0
  131. {tryton-6.6.8 → tryton-6.8.1}/french.nsh +0 -0
  132. {tryton-6.6.8 → tryton-6.8.1}/german.nsh +0 -0
  133. {tryton-6.6.8 → tryton-6.8.1}/make-darwin-installer.sh +0 -0
  134. {tryton-6.6.8 → tryton-6.8.1}/make-win32-installer.sh +0 -0
  135. {tryton-6.6.8 → tryton-6.8.1}/portuguese.nsh +0 -0
  136. {tryton-6.6.8 → tryton-6.8.1}/setup-freeze.py +0 -0
  137. {tryton-6.6.8 → tryton-6.8.1}/setup.cfg +0 -0
  138. {tryton-6.6.8 → tryton-6.8.1}/setup.nsi +0 -0
  139. {tryton-6.6.8 → tryton-6.8.1}/slovenian.nsh +0 -0
  140. {tryton-6.6.8 → tryton-6.8.1}/spanish.nsh +0 -0
  141. {tryton-6.6.8 → tryton-6.8.1}/tryton/action/__init__.py +0 -0
  142. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/__init__.py +0 -0
  143. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrendererbinary.py +0 -0
  144. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrendererbutton.py +0 -0
  145. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrendererclickablepixbuf.py +0 -0
  146. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrenderercombo.py +0 -0
  147. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrendererfloat.py +0 -0
  148. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrendererinteger.py +0 -0
  149. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrenderertext.py +0 -0
  150. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/cellrenderertoggle.py +0 -0
  151. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/completion.py +0 -0
  152. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/entry_position.py +0 -0
  153. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/environment.py +0 -0
  154. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/focus.py +0 -0
  155. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/htmltextbuffer.py +0 -0
  156. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/number_entry.py +0 -0
  157. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/richtext.py +0 -0
  158. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/timedelta.py +0 -0
  159. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/underline.py +0 -0
  160. {tryton-6.6.8 → tryton-6.8.1}/tryton/common/widget_style.py +0 -0
  161. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/locale/ja_JP/LC_MESSAGES/tryton.po +0 -0
  162. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/LICENSE +0 -0
  163. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-add.svg +0 -0
  164. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-archive.svg +0 -0
  165. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-arrow-down.svg +0 -0
  166. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-arrow-left.svg +0 -0
  167. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-arrow-right.svg +0 -0
  168. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-arrow-up.svg +0 -0
  169. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-attach.svg +0 -0
  170. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-back.svg +0 -0
  171. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-bookmark-border.svg +0 -0
  172. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-bookmark.svg +0 -0
  173. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-bookmarks.svg +0 -0
  174. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-cancel.svg +0 -0
  175. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-clear.svg +0 -0
  176. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-close.svg +0 -0
  177. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-copy.svg +0 -0
  178. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-create.svg +0 -0
  179. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-date.svg +0 -0
  180. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-delete.svg +0 -0
  181. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-drag.svg +0 -0
  182. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-email.svg +0 -0
  183. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-error.svg +0 -0
  184. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-exit.svg +0 -0
  185. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-export.svg +0 -0
  186. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-filter.svg +0 -0
  187. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-align-center.svg +0 -0
  188. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-align-justify.svg +0 -0
  189. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-align-left.svg +0 -0
  190. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-align-right.svg +0 -0
  191. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-bold.svg +0 -0
  192. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-color-text.svg +0 -0
  193. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-italic.svg +0 -0
  194. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-format-underline.svg +0 -0
  195. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-forward.svg +0 -0
  196. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-history.svg +0 -0
  197. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-icon.png +0 -0
  198. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-import.svg +0 -0
  199. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-info.svg +0 -0
  200. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-launch.svg +0 -0
  201. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-link.svg +0 -0
  202. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-log.svg +0 -0
  203. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-menu.svg +0 -0
  204. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-note.svg +0 -0
  205. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-ok.svg +0 -0
  206. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-open.svg +0 -0
  207. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-print.svg +0 -0
  208. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-public.svg +0 -0
  209. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-question.svg +0 -0
  210. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-refresh.svg +0 -0
  211. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-remove.svg +0 -0
  212. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-save.svg +0 -0
  213. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-search.svg +0 -0
  214. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-send.svg +0 -0
  215. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-star-border.svg +0 -0
  216. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-star.svg +0 -0
  217. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-switch.svg +0 -0
  218. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-translate.svg +0 -0
  219. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-unarchive.svg +0 -0
  220. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-undo.svg +0 -0
  221. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton-warning.svg +0 -0
  222. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton.icns +0 -0
  223. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton.ico +0 -0
  224. {tryton-6.6.8 → tryton-6.8.1}/tryton/data/pixmaps/tryton/tryton.svg +0 -0
  225. {tryton-6.6.8 → tryton-6.8.1}/tryton/device_cookie.py +0 -0
  226. {tryton-6.6.8 → tryton-6.8.1}/tryton/exceptions.py +0 -0
  227. {tryton-6.6.8 → tryton-6.8.1}/tryton/fingerprints.py +0 -0
  228. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/__init__.py +0 -0
  229. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/__init__.py +0 -0
  230. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/about.py +0 -0
  231. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/attachment.py +0 -0
  232. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/board.py +0 -0
  233. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/email_.py +0 -0
  234. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/limit.py +0 -0
  235. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/nomodal.py +0 -0
  236. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/note.py +0 -0
  237. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/preference.py +0 -0
  238. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/revision.py +0 -0
  239. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/tabcontent.py +0 -0
  240. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_board/__init__.py +0 -0
  241. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_board/view_board.py +0 -0
  242. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/__init__.py +0 -0
  243. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/model/__init__.py +0 -0
  244. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/model/group.py +0 -0
  245. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/screen/__init__.py +0 -0
  246. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/__init__.py +0 -0
  247. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/calendar_gtk/__init__.py +0 -0
  248. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/calendar_gtk/calendar_.py +0 -0
  249. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/calendar_gtk/dates_period.py +0 -0
  250. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/__init__.py +0 -0
  251. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/binary.py +0 -0
  252. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/calendar_.py +0 -0
  253. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/char.py +0 -0
  254. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/checkbox.py +0 -0
  255. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/dictionary.py +0 -0
  256. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/document.py +0 -0
  257. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/float.py +0 -0
  258. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/image.py +0 -0
  259. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/integer.py +0 -0
  260. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/multiselection.py +0 -0
  261. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/one2one.py +0 -0
  262. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/progressbar.py +0 -0
  263. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/pyson.py +0 -0
  264. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/reference.py +0 -0
  265. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/richtextbox.py +0 -0
  266. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/selection.py +0 -0
  267. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/state_widget.py +0 -0
  268. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/timedelta.py +0 -0
  269. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/form_gtk/url.py +0 -0
  270. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph.py +0 -0
  271. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph_gtk/__init__.py +0 -0
  272. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph_gtk/bar.py +0 -0
  273. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph_gtk/graph.py +0 -0
  274. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph_gtk/line.py +0 -0
  275. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/graph_gtk/pie.py +0 -0
  276. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/list.py +0 -0
  277. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/list_gtk/__init__.py +0 -0
  278. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/view_form/view/screen_container.py +0 -0
  279. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/win_csv.py +0 -0
  280. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/win_export.py +0 -0
  281. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/win_import.py +0 -0
  282. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/win_search.py +0 -0
  283. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/window.py +0 -0
  284. {tryton-6.6.8 → tryton-6.8.1}/tryton/gui/window/wizard.py +0 -0
  285. {tryton-6.6.8 → tryton-6.8.1}/tryton/jsonrpc.py +0 -0
  286. {tryton-6.6.8 → tryton-6.8.1}/tryton/plugins/__init__.py +0 -0
  287. {tryton-6.6.8 → tryton-6.8.1}/tryton/plugins/translation/__init__.py +0 -0
  288. {tryton-6.6.8 → tryton-6.8.1}/tryton/pyson.py +0 -0
  289. {tryton-6.6.8 → tryton-6.8.1}/tryton/tests/__init__.py +0 -0
  290. {tryton-6.6.8 → tryton-6.8.1}/tryton/tests/test_common_selection.py +0 -0
  291. {tryton-6.6.8 → tryton-6.8.1}/tryton/tests/test_common_timedelta.py +0 -0
  292. {tryton-6.6.8 → tryton-6.8.1}/tryton/translate.py +0 -0
  293. {tryton-6.6.8 → tryton-6.8.1}/tryton.desktop +0 -0
  294. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/dependency_links.txt +0 -0
  295. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/not-zip-safe +0 -0
  296. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/requires.txt +0 -0
  297. {tryton-6.6.8 → tryton-6.8.1}/tryton.egg-info/top_level.txt +0 -0
  298. {tryton-6.6.8 → tryton-6.8.1}/win32/gtk-3.0/gdk-pixbuf.loaders +0 -0
  299. {tryton-6.6.8 → tryton-6.8.1}/win32/gtk-3.0/gtk.immodules +0 -0
@@ -1,37 +1,25 @@
1
1
 
2
- Version 6.6.8 - 2023-05-17
2
+ Version 6.8.1 - 2023-05-17
3
3
  --------------------------
4
4
  * Bug fixes (see mercurial logs for details)
5
5
 
6
6
 
7
- Version 6.6.7 - 2023-05-03
8
- --------------------------
9
- * Bug fixes (see mercurial logs for details)
10
-
11
-
12
- Version 6.6.6 - 2023-03-04
13
- --------------------------
14
- * Bug fixes (see mercurial logs for details)
15
-
16
- Version 6.6.5 - 2023-02-17
17
- --------------------------
18
- * Bug fixes (see mercurial logs for details)
19
-
20
- Version 6.6.4 - 2023-02-05
21
- --------------------------
22
- * Bug fixes (see mercurial logs for details)
23
-
24
- Version 6.6.3 - 2023-01-15
25
- --------------------------
26
- * Bug fixes (see mercurial logs for details)
27
-
28
- Version 6.6.2 - 2023-01-02
29
- --------------------------
30
- * Bug fixes (see mercurial logs for details)
31
-
32
- Version 6.6.1 - 2022-11-17
7
+ Version 6.8.0 - 2023-05-01
33
8
  --------------------------
34
9
  * Bug fixes (see mercurial logs for details)
10
+ * Include events to logs
11
+ * Add option to disable thread
12
+ * Remove support for Python 3.7
13
+ * Add support for Python 3.11
14
+ * Save and Restore tree state on List Form
15
+ * Do record (pre)validation and saving on selection change for list-form views
16
+ * Eagerly read string value of selection fields
17
+ * Do not select first record by default
18
+ * Use ``&`` and ``|`` as boolean operator in search widget
19
+ * Use toggle button and label on translate dialog
20
+ * Manage domain on id in single value list as unique
21
+ * Do not validate domain nor enforce uniqueness for empty fields unless they're required or invisible
22
+ * Display the number of selected records on xxx2Many
35
23
 
36
24
  Version 6.6.0 - 2022-10-31
37
25
  --------------------------
@@ -1,16 +1,16 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tryton
3
- Version: 6.6.8
3
+ Version: 6.8.1
4
4
  Summary: Tryton desktop client
5
5
  Home-page: http://www.tryton.org/
6
- Download-URL: http://downloads.tryton.org/6.6/
6
+ Download-URL: http://downloads.tryton.org/6.8/
7
7
  Author: Tryton
8
- Author-email: bugs@tryton.org
8
+ Author-email: foundation@tryton.org
9
9
  License: GPL-3
10
10
  Project-URL: Bug Tracker, https://bugs.tryton.org/
11
11
  Project-URL: Documentation, https://docs.tryton.org/
12
12
  Project-URL: Forum, https://www.tryton.org/forum
13
- Project-URL: Source Code, https://hg.tryton.org/tryton
13
+ Project-URL: Source Code, https://code.tryton.org/tryton
14
14
  Keywords: business application ERP
15
15
  Platform: any
16
16
  Classifier: Development Status :: 5 - Production/Stable
@@ -42,12 +42,12 @@ Classifier: Natural Language :: Japanese
42
42
  Classifier: Natural Language :: Ukrainian
43
43
  Classifier: Operating System :: OS Independent
44
44
  Classifier: Programming Language :: Python :: 3
45
- Classifier: Programming Language :: Python :: 3.7
46
45
  Classifier: Programming Language :: Python :: 3.8
47
46
  Classifier: Programming Language :: Python :: 3.9
48
47
  Classifier: Programming Language :: Python :: 3.10
48
+ Classifier: Programming Language :: Python :: 3.11
49
49
  Classifier: Topic :: Office/Business
50
- Requires-Python: >=3.7
50
+ Requires-Python: >=3.8
51
51
  Provides-Extra: calendar
52
52
  License-File: LICENSE
53
53
 
@@ -30,7 +30,10 @@ def get_info():
30
30
  [sys.executable, 'setup.py', '--version'],
31
31
  stdout=subprocess.PIPE, check=True, cwd=module_dir)
32
32
  version = result.stdout.decode('utf-8').strip()
33
- if 'dev' in version:
33
+ major_version, minor_version, _ = version.split('.', 2)
34
+ major_version = int(major_version)
35
+ minor_version = int(minor_version)
36
+ if minor_version % 2:
34
37
  info['series'] = 'latest'
35
38
  else:
36
39
  info['series'] = '.'.join(version.split('.', 2)[:2])
@@ -512,22 +512,26 @@ It is possible to escape special characters in values by using double quotes.
512
512
  Clause composition
513
513
  ++++++++++++++++++
514
514
 
515
- The clauses can be composed using the two boolean operators ``and`` and ``or``.
516
- By default, there is an implicit ``and`` between each clause if no operator is
515
+ The clauses can be composed using the two boolean operators ``&`` (for `logical
516
+ conjunction`_) and ``|`` (for `logical disjunction`_).
517
+ By default, there is an implicit ``&`` between each clause if no operator is
517
518
  specified.
518
519
 
519
520
  For example: ``Name: Michael Amount: 100``
520
521
 
521
- is the same as ``Name: Michael and Amount: 100``
522
+ is the same as ``Name: Michael & Amount: 100``
522
523
 
523
- The ``and`` operator has a highest precedence than ``or`` but you can change it
524
- by using parenthesis.
524
+ The ``&`` operator has a highest precedence than ``|`` but you can change it by
525
+ using parenthesis.
525
526
 
526
- For example: ``(Name: Michael or Name: Pam) and Amount: 100``
527
+ For example: ``(Name: Michael | Name: Pam) & Amount: 100``
527
528
 
528
- is different than ``Name: Michael or Name: Pam and Amount: 100``
529
+ is different than ``Name: Michael | Name: Pam & Amount: 100``
529
530
 
530
- which is evaluated as ``Name: Michael or (Name: Pam and Amount: 100)``
531
+ which is evaluated as ``Name: Michael | (Name: Pam & Amount: 100)``
532
+
533
+ .. _logical conjunction: https://en.wikipedia.org/wiki/Logical_conjunction
534
+ .. _logical disjunction: https://en.wikipedia.org/wiki/Logical_disjunction
531
535
 
532
536
  RichText Editor
533
537
  ^^^^^^^^^^^^^^^
@@ -68,22 +68,25 @@ major_version = int(major_version)
68
68
  minor_version = int(minor_version)
69
69
  name = 'tryton'
70
70
 
71
- download_url = 'http://downloads.tryton.org/%s.%s/' % (
72
- major_version, minor_version)
71
+ if minor_version % 2:
72
+ download_url = ''
73
+ else:
74
+ download_url = 'http://downloads.tryton.org/%s.%s/' % (
75
+ major_version, minor_version)
73
76
 
74
77
  dist = setup(name=name,
75
78
  version=version,
76
79
  description='Tryton desktop client',
77
80
  long_description=read('README.rst'),
78
81
  author='Tryton',
79
- author_email='bugs@tryton.org',
82
+ author_email='foundation@tryton.org',
80
83
  url='http://www.tryton.org/',
81
84
  download_url=download_url,
82
85
  project_urls={
83
86
  "Bug Tracker": 'https://bugs.tryton.org/',
84
87
  "Documentation": 'https://docs.tryton.org/',
85
88
  "Forum": 'https://www.tryton.org/forum',
86
- "Source Code": 'https://hg.tryton.org/tryton',
89
+ "Source Code": 'https://code.tryton.org/tryton',
87
90
  },
88
91
  keywords='business application ERP',
89
92
  packages=find_packages(),
@@ -120,15 +123,15 @@ dist = setup(name=name,
120
123
  'Natural Language :: Ukrainian',
121
124
  'Operating System :: OS Independent',
122
125
  'Programming Language :: Python :: 3',
123
- 'Programming Language :: Python :: 3.7',
124
126
  'Programming Language :: Python :: 3.8',
125
127
  'Programming Language :: Python :: 3.9',
126
128
  'Programming Language :: Python :: 3.10',
129
+ 'Programming Language :: Python :: 3.11',
127
130
  'Topic :: Office/Business',
128
131
  ],
129
132
  platforms='any',
130
133
  license='GPL-3',
131
- python_requires='>=3.7',
134
+ python_requires='>=3.8',
132
135
  install_requires=[
133
136
  'pycairo',
134
137
  "python-dateutil",
tryton-6.8.1/tox.ini ADDED
@@ -0,0 +1,14 @@
1
+ [tox]
2
+ envlist = py38,py39,py310,py311
3
+
4
+ [testenv]
5
+ usedevelop = true
6
+ commands =
7
+ coverage run --omit=*/tests/* -m xmlrunner discover -s tryton.tests {posargs}
8
+ commands_post =
9
+ coverage report
10
+ coverage xml
11
+ deps =
12
+ coverage
13
+ unittest-xml-reporting
14
+ passenv = *
@@ -1,6 +1,6 @@
1
1
  # This file is part of Tryton. The COPYRIGHT file at the top level of
2
2
  # this repository contains the full copyright notices and license terms.
3
- __version__ = "6.6.8"
3
+ __version__ = "6.8.1"
4
4
  import locale
5
5
 
6
6
  import gi
@@ -6,7 +6,6 @@ import webbrowser
6
6
  import tryton.rpc as rpc
7
7
  from tryton.common import (
8
8
  RPCException, RPCExecute, file_open, file_write, message, selection)
9
- from tryton.config import CONFIG
10
9
  from tryton.pyson import PYSONDecoder
11
10
 
12
11
  _ = gettext.gettext
@@ -91,14 +90,15 @@ class Action(object):
91
90
  return name
92
91
 
93
92
  data['action_id'] = action['id']
93
+ params = {
94
+ 'icon': action.get('icon.rec_name') or '',
95
+ }
94
96
  if action['type'] == 'ir.action.act_window':
95
- view_ids = []
96
- view_mode = None
97
97
  if action.get('views', []):
98
- view_ids = [x[0] for x in action['views']]
99
- view_mode = [x[1] for x in action['views']]
98
+ params['view_ids'] = [x[0] for x in action['views']]
99
+ params['view_mode'] = [x[1] for x in action['views']]
100
100
  elif action.get('view_id', False):
101
- view_ids = [action['view_id'][0]]
101
+ params['view_ids'] = [action['view_id'][0]]
102
102
 
103
103
  action.setdefault('pyson_domain', '[]')
104
104
  ctx = {
@@ -109,58 +109,47 @@ class Action(object):
109
109
  ctx.update(rpc.CONTEXT)
110
110
  ctx['_user'] = rpc._USER
111
111
  decoder = PYSONDecoder(ctx)
112
- action_ctx = context.copy()
113
- action_ctx.update(
112
+ params['context'] = context.copy()
113
+ params['context'].update(
114
114
  decoder.decode(action.get('pyson_context') or '{}'))
115
- ctx.update(action_ctx)
115
+ ctx.update(params['context'])
116
116
 
117
117
  ctx['context'] = ctx
118
118
  decoder = PYSONDecoder(ctx)
119
- domain = decoder.decode(action['pyson_domain'])
120
- order = decoder.decode(action['pyson_order'])
121
- search_value = decoder.decode(action['pyson_search_value'] or '[]')
122
- tab_domain = [(n, decoder.decode(d), c)
123
- for n, d, c in action['domains']]
119
+ params['domain'] = decoder.decode(action['pyson_domain'])
120
+ params['order'] = decoder.decode(action['pyson_order'])
121
+ params['search_value'] = decoder.decode(
122
+ action['pyson_search_value'] or '[]')
123
+ params['tab_domain'] = [
124
+ (n, decoder.decode(d), c) for n, d, c in action['domains']]
124
125
 
125
126
  name = action.get('name', '')
126
127
  if action.get('keyword', ''):
127
- name = add_name_suffix(name, action_ctx)
128
+ name = add_name_suffix(name, params['context'])
129
+ params['name'] = name
128
130
 
129
131
  res_model = action.get('res_model', data.get('res_model'))
130
- res_id = action.get('res_id', data.get('res_id'))
132
+ params['res_id'] = action.get('res_id', data.get('res_id'))
133
+ params['context_model'] = action.get('context_model')
134
+ params['context_domain'] = action.get('context_domain')
131
135
  limit = action.get('limit')
132
- if limit is None:
133
- limit = CONFIG['client.limit']
134
-
135
- Window.create(res_model,
136
- view_ids=view_ids,
137
- res_id=res_id,
138
- domain=domain,
139
- context=action_ctx,
140
- order=order,
141
- mode=view_mode,
142
- name=name,
143
- limit=limit,
144
- search_value=search_value,
145
- icon=(action.get('icon.rec_name') or ''),
146
- tab_domain=tab_domain,
147
- context_model=action['context_model'],
148
- context_domain=action['context_domain'])
136
+ if limit is not None:
137
+ params['limit'] = limit
138
+
139
+ Window.create(res_model, **params)
149
140
  elif action['type'] == 'ir.action.wizard':
141
+ params['context'] = context
142
+ params['window'] = action.get('window')
150
143
  name = action.get('name', '')
151
144
  if action.get('keyword', 'form_action') == 'form_action':
152
145
  name = add_name_suffix(name, context)
153
- Window.create_wizard(action['wiz_name'], data,
154
- direct_print=action.get('direct_print', False),
155
- name=name,
156
- context=context, icon=(action.get('icon.rec_name') or ''),
157
- window=action.get('window', False))
158
-
146
+ params['name'] = name
147
+ Window.create_wizard(action['wiz_name'], data, **params)
159
148
  elif action['type'] == 'ir.action.report':
160
- Action.exec_report(
161
- action['report_name'], data,
162
- direct_print=action.get('direct_print', False),
163
- context=context)
149
+ params['direct_print'] = action.get('direct_print', False)
150
+ params['context'] = context
151
+ del params['icon']
152
+ Action.exec_report(action['report_name'], data, **params)
164
153
 
165
154
  elif action['type'] == 'ir.action.url':
166
155
  if action['url']:
@@ -25,6 +25,8 @@ CHANNELS = [
25
25
 
26
26
 
27
27
  def listen(connection):
28
+ if not CONFIG['thread']:
29
+ return
28
30
  listener = threading.Thread(
29
31
  target=_listen, args=(connection,), daemon=True)
30
32
  listener.start()
@@ -30,6 +30,9 @@ def main():
30
30
  label.editable {
31
31
  font-style: italic;
32
32
  }
33
+ label.warning {
34
+ color: @warning_color;
35
+ }
33
36
  .window-title, .wizard-title {
34
37
  font-size: large;
35
38
  font-weight: bold;
@@ -37,7 +37,9 @@ class Button(Gtk.Button):
37
37
  self.hide()
38
38
  else:
39
39
  self.show()
40
- self.set_sensitive(not states.get('readonly', False))
40
+ self.set_sensitive(
41
+ not (record.readonly if record else False)
42
+ and not states.get('readonly', False))
41
43
  self._set_icon(states.get('icon', self.attrs.get('icon')))
42
44
 
43
45
  if self.attrs.get('rule'):
@@ -23,7 +23,6 @@ try:
23
23
  except ImportError:
24
24
  from http import client as HTTPStatus
25
25
 
26
- import _thread
27
26
  import shlex
28
27
  import socket
29
28
  import sys
@@ -34,6 +33,7 @@ import urllib.request
34
33
  import webbrowser
35
34
  from functools import lru_cache, wraps
36
35
  from string import Template
36
+ from threading import Lock, Thread
37
37
 
38
38
  import tryton.rpc as rpc
39
39
  from tryton.config import CONFIG, PIXMAPS_DIR, TRYTON_ICON
@@ -43,9 +43,8 @@ try:
43
43
  except ImportError:
44
44
  ssl = None
45
45
  import zipfile
46
- from threading import Lock
47
46
 
48
- from gi.repository import Gdk, GdkPixbuf, GLib, GObject, Gtk
47
+ from gi.repository import Gdk, GdkPixbuf, Gio, GLib, GObject, Gtk
49
48
 
50
49
  from tryton import __version__
51
50
  from tryton.exceptions import TrytonError, TrytonServerError
@@ -104,6 +103,8 @@ class IconFactory:
104
103
  try:
105
104
  icon_ref = (cls._name2id[iconname], iconname)
106
105
  except KeyError:
106
+ logger.error(f"Unknown icon {iconname}")
107
+ cls._icons[iconname] = None
107
108
  return
108
109
  idx = cls._tryton_icons.index(icon_ref)
109
110
  to_load = slice(max(0, idx - cls.batchnum // 2),
@@ -128,13 +129,14 @@ class IconFactory:
128
129
  colors = CONFIG['icon.colors'].split(',')
129
130
  cls.register_icon(iconname)
130
131
  if iconname not in cls._pixbufs[(size, badge)]:
132
+ data = None
131
133
  if iconname in cls._icons:
132
134
  data = cls._icons[iconname]
133
135
  elif iconname in cls._local_icons:
134
136
  path = cls._local_icons[iconname]
135
137
  with open(path, 'rb') as fp:
136
138
  data = fp.read()
137
- else:
139
+ if not data:
138
140
  logger.error("Unknown icon %s" % iconname)
139
141
  return
140
142
  if not color:
@@ -439,16 +441,8 @@ def file_selection(title, filename='',
439
441
  action=Gtk.FileChooserAction.OPEN, preview=True, multi=False,
440
442
  filters=None):
441
443
  parent = get_toplevel_window()
442
- if action == Gtk.FileChooserAction.OPEN:
443
- buttons = (set_underline(_("Cancel")), Gtk.ResponseType.CANCEL,
444
- set_underline(_("Select")), Gtk.ResponseType.OK)
445
- else:
446
- buttons = (set_underline(_("Cancel")), Gtk.ResponseType.CANCEL,
447
- set_underline(_("Save")), Gtk.ResponseType.OK)
448
- win = Gtk.FileChooserDialog(
444
+ win = Gtk.FileChooserNative(
449
445
  title=title, transient_for=parent, action=action)
450
- win.add_buttons(*buttons)
451
- win.set_icon(TRYTON_ICON)
452
446
  if filename:
453
447
  if action in (Gtk.FileChooserAction.SAVE,
454
448
  Gtk.FileChooserAction.CREATE_FOLDER):
@@ -459,7 +453,6 @@ def file_selection(title, filename='',
459
453
  if hasattr(win, 'set_do_overwrite_confirmation'):
460
454
  win.set_do_overwrite_confirmation(True)
461
455
  win.set_select_multiple(multi)
462
- win.set_default_response(Gtk.ResponseType.OK)
463
456
  if filters is not None:
464
457
  for filt in filters:
465
458
  win.add_filter(filt)
@@ -484,7 +477,7 @@ def file_selection(title, filename='',
484
477
  win.connect('update-preview', update_preview_cb, img_preview)
485
478
 
486
479
  button = win.run()
487
- if button != Gtk.ResponseType.OK:
480
+ if button != Gtk.ResponseType.ACCEPT:
488
481
  result = None
489
482
  elif not multi:
490
483
  result = PurePath(win.get_filename())
@@ -546,10 +539,8 @@ def file_open(filename, type=None, print_p=False):
546
539
  file_open(zfilename, type=ztype, print_p=True)
547
540
  return
548
541
 
549
- if os.name == 'nt':
550
- operation = 'open'
551
- if print_p:
552
- operation = 'print'
542
+ if hasattr(os, 'startfile'):
543
+ operation = 'print' if print_p else 'open'
553
544
  try:
554
545
  os.startfile(os.path.normpath(filename), operation)
555
546
  except WindowsError:
@@ -574,12 +565,20 @@ def file_open(filename, type=None, print_p=False):
574
565
  except OSError:
575
566
  save()
576
567
  else:
568
+ uri = GLib.filename_to_uri(filename)
577
569
  try:
578
- subprocess.Popen(['xdg-open', filename])
579
- except OSError:
570
+ Gio.AppInfo.launch_default_for_uri(uri)
571
+ except GLib.Error:
580
572
  save()
581
573
 
582
574
 
575
+ def webbrowser_open(url):
576
+ try:
577
+ Gio.AppInfo.launch_default_for_uri(url)
578
+ except GLib.Error:
579
+ webbrowser.open(url)
580
+
581
+
583
582
  def url_open(uri):
584
583
  try:
585
584
  return urllib.request.urlopen(uri)
@@ -640,7 +639,7 @@ def mailto(to=None, cc=None, subject=None, body=None, attachment=None):
640
639
  url += "&body=" + urllib.parse.quote(body, "")
641
640
  if attachment:
642
641
  url += "&attachment=" + urllib.parse.quote(attachment, "")
643
- webbrowser.open(url, new=1)
642
+ webbrowser_open(url, new=1)
644
643
 
645
644
 
646
645
  class UniqueDialog(object):
@@ -882,7 +881,7 @@ class ErrorDialog(UniqueDialog):
882
881
  CONFIG['bug.url'], _("Report Bug"))
883
882
  button_roundup.get_child().set_halign(Gtk.Align.START)
884
883
  button_roundup.connect('activate-link',
885
- lambda widget: webbrowser.open(CONFIG['bug.url'], new=2))
884
+ lambda widget: webbrowser_open(CONFIG['bug.url'], new=2))
886
885
  dialog.vbox.pack_start(
887
886
  button_roundup, expand=False, fill=False, padding=0)
888
887
 
@@ -892,8 +891,7 @@ class ErrorDialog(UniqueDialog):
892
891
  if isinstance(title, Exception):
893
892
  title = "%s: %s" % (title.__class__.__name__, title)
894
893
  details += '\n' + title
895
- log = logging.getLogger(__name__)
896
- log.error(details)
894
+ logger.error(details)
897
895
  return super(ErrorDialog, self).__call__(title, details)
898
896
 
899
897
 
@@ -903,7 +901,7 @@ error = ErrorDialog()
903
901
  def check_version(box, version=__version__):
904
902
  def info_bar_response(info_bar, response, box, url):
905
903
  if response == Gtk.ResponseType.ACCEPT:
906
- webbrowser.open(url)
904
+ webbrowser_open(url)
907
905
  box.remove(info_bar)
908
906
 
909
907
  class HeadRequest(urllib.request.Request):
@@ -955,7 +953,7 @@ def open_documentation():
955
953
  version = 'latest'
956
954
  else:
957
955
  version = '.'.join(version)
958
- webbrowser.open(CONFIG['doc.url'] % {
956
+ webbrowser_open(CONFIG['doc.url'] % {
959
957
  'lang': CONFIG['client.lang'],
960
958
  'version': version,
961
959
  })
@@ -1049,7 +1047,7 @@ def get_credentials(user_id=None):
1049
1047
  query['renew'] = user_id
1050
1048
  url_parts[4] = urlencode(query)
1051
1049
  url = urlunparse(url_parts)
1052
- webbrowser.open(url)
1050
+ webbrowser_open(url)
1053
1051
 
1054
1052
  class RequestHandler(BaseHTTPRequestHandler):
1055
1053
  def do_GET(self):
@@ -1213,7 +1211,7 @@ class RPCProgress(object):
1213
1211
  else:
1214
1212
  if not self.res:
1215
1213
  self.error = True
1216
- if self.callback:
1214
+ if self.callback and CONFIG['thread']:
1217
1215
  # Post to GTK queue to be run by the main thread
1218
1216
  GLib.idle_add(self.process)
1219
1217
  return True
@@ -1222,12 +1220,12 @@ class RPCProgress(object):
1222
1220
  self.process_exception_p = process_exception_p
1223
1221
  self.callback = callback
1224
1222
 
1225
- if callback:
1223
+ if callback and CONFIG['thread']:
1226
1224
  # Parent is only useful if it is asynchronous
1227
1225
  # otherwise the cursor is not updated.
1228
1226
  self.parent = get_toplevel_window()
1229
1227
  self._cursor_timeout = GLib.timeout_add(3000, self._set_cursor)
1230
- _thread.start_new_thread(self.start, ())
1228
+ Thread(target=self.start).start()
1231
1229
  return
1232
1230
  else:
1233
1231
  self.start()
@@ -1365,14 +1363,29 @@ def untimezoned_date(date):
1365
1363
 
1366
1364
 
1367
1365
  def humanize(size, suffix=''):
1368
- for u in ['', 'K', 'M', 'G', 'T', 'P']:
1369
- if size <= 1000:
1370
- if isinstance(size, int) or size.is_integer():
1371
- size = locale.localize('{0:.0f}'.format(size))
1372
- else:
1373
- size = locale.localize('{0:.{1}f}'.format(size, 2).rstrip('0'))
1374
- return ''.join([size, u, suffix])
1375
- size /= 1000.0
1366
+ if 0 < abs(size) < 1:
1367
+ for u in ['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y', 'r', 'q']:
1368
+ if abs(size) >= 0.01:
1369
+ break
1370
+ size *= 1000.0
1371
+ else:
1372
+ size /= 1000.0
1373
+ else:
1374
+ for u in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q']:
1375
+ if abs(size) <= 1000:
1376
+ break
1377
+ size /= 1000.0
1378
+ else:
1379
+ size *= 1000.0
1380
+ if isinstance(size, int) or size.is_integer():
1381
+ size = locale.localize(str(int(size)))
1382
+ elif abs(size) < 0.01:
1383
+ size = locale.localize(
1384
+ '{0:f}'.format(size).rstrip('0').rstrip('.'))
1385
+ else:
1386
+ size = locale.localize(
1387
+ '{0:.{1}f}'.format(size, 2).rstrip('0').rstrip('.'))
1388
+ return ''.join([size, u, suffix])
1376
1389
 
1377
1390
 
1378
1391
  def get_hostname(netloc):
@@ -1445,13 +1458,12 @@ def ellipsize(string, length):
1445
1458
  def get_align(float_, expand=True):
1446
1459
  "Convert float align into Gtk.Align"
1447
1460
  value = float(float_)
1461
+ if expand:
1462
+ return Gtk.Align.FILL
1448
1463
  if value < 0.5:
1449
1464
  return Gtk.Align.START
1450
1465
  elif value == 0.5:
1451
- if expand:
1452
- return Gtk.Align.FILL
1453
- else:
1454
- return Gtk.Align.CENTER
1466
+ return Gtk.Align.CENTER
1455
1467
  else:
1456
1468
  return Gtk.Align.END
1457
1469
 
@@ -129,8 +129,9 @@ class Date(Gtk.Entry):
129
129
  self.__date.month - 1, self.__date.year)
130
130
  self.__calendar.select_day(self.__date.day)
131
131
  self.__cal_popup.set_transient_for(self.get_toplevel())
132
- popup_position(self, self.__cal_popup)
132
+ # Show popup before because position needs the popup allocation
133
133
  popup_show(self.__cal_popup)
134
+ popup_position(self, self.__cal_popup)
134
135
 
135
136
  def cal_popup_changed(self, calendar):
136
137
  year, month, day = self.__calendar.get_date()
@@ -532,8 +533,19 @@ GObject.type_register(DateTime)
532
533
 
533
534
  def popup_position(widget, popup):
534
535
  allocation = widget.get_allocation()
536
+ popup_allocation = popup.get_allocation()
535
537
  x, y = widget.get_window().get_root_coords(allocation.x, allocation.y)
536
- popup.move(x, y + allocation.height)
538
+ display = widget.get_display()
539
+ monitor = display.get_monitor_at_window(widget.get_window())
540
+ monitor_geometry = monitor.get_geometry()
541
+ if (monitor_geometry.height
542
+ < y + allocation.height + popup_allocation.height):
543
+ y -= popup_allocation.height
544
+ else:
545
+ y += allocation.height
546
+ if monitor_geometry.width < x + popup_allocation.width:
547
+ x -= popup_allocation.width
548
+ popup.move(x, y)
537
549
 
538
550
 
539
551
  def popup_show(popup):
@@ -381,16 +381,16 @@ def unique_value(domain):
381
381
  "Return if unique, the field and the value"
382
382
  if (isinstance(domain, list)
383
383
  and len(domain) == 1):
384
- domain, = domain
385
- name = domain[0]
386
- value = domain[2]
387
- count = 0
388
- if len(domain) == 4 and name[-3:] == '.id':
389
- count = 1
390
- model = domain[3]
391
- value = [model, value]
392
- if name.count('.') == count and domain[1] == '=':
393
- return True, name, value
384
+ name, operator, value, *model = domain[0]
385
+ if operator == '=' or (operator == 'in' and len(value) == 1):
386
+ value = value if operator == '=' else value[0]
387
+ count = 0
388
+ if model and name.endswith('.id'):
389
+ count = 1
390
+ model = model[0]
391
+ value = [model, value]
392
+ if name.count('.') == count:
393
+ return True, name, value
394
394
  return False, None, None
395
395
 
396
396