tryton 7.4.8__py3-none-any.whl → 7.6.0__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/domain_parser.py +8 -6
  11. tryton/common/environment.py +2 -2
  12. tryton/common/number_entry.py +12 -6
  13. tryton/common/selection.py +1 -1
  14. tryton/data/locale/bg/LC_MESSAGES/tryton.mo +0 -0
  15. tryton/data/locale/bg/LC_MESSAGES/tryton.po +26 -16
  16. tryton/data/locale/ca/LC_MESSAGES/tryton.mo +0 -0
  17. tryton/data/locale/ca/LC_MESSAGES/tryton.po +29 -18
  18. tryton/data/locale/cs/LC_MESSAGES/tryton.mo +0 -0
  19. tryton/data/locale/cs/LC_MESSAGES/tryton.po +28 -16
  20. tryton/data/locale/de/LC_MESSAGES/tryton.mo +0 -0
  21. tryton/data/locale/de/LC_MESSAGES/tryton.po +27 -18
  22. tryton/data/locale/es/LC_MESSAGES/tryton.mo +0 -0
  23. tryton/data/locale/es/LC_MESSAGES/tryton.po +25 -16
  24. tryton/data/locale/es_419/LC_MESSAGES/tryton.mo +0 -0
  25. tryton/data/locale/es_419/LC_MESSAGES/tryton.po +26 -16
  26. tryton/data/locale/et/LC_MESSAGES/tryton.mo +0 -0
  27. tryton/data/locale/et/LC_MESSAGES/tryton.po +28 -18
  28. tryton/data/locale/fa/LC_MESSAGES/tryton.mo +0 -0
  29. tryton/data/locale/fa/LC_MESSAGES/tryton.po +28 -18
  30. tryton/data/locale/fi/LC_MESSAGES/tryton.mo +0 -0
  31. tryton/data/locale/fi/LC_MESSAGES/tryton.po +25 -16
  32. tryton/data/locale/fr/LC_MESSAGES/tryton.mo +0 -0
  33. tryton/data/locale/fr/LC_MESSAGES/tryton.po +25 -16
  34. tryton/data/locale/hu/LC_MESSAGES/tryton.mo +0 -0
  35. tryton/data/locale/hu/LC_MESSAGES/tryton.po +28 -18
  36. tryton/data/locale/id/LC_MESSAGES/tryton.mo +0 -0
  37. tryton/data/locale/id/LC_MESSAGES/tryton.po +23 -16
  38. tryton/data/locale/it/LC_MESSAGES/tryton.mo +0 -0
  39. tryton/data/locale/it/LC_MESSAGES/tryton.po +29 -18
  40. tryton/data/locale/ja_JP/LC_MESSAGES/tryton.mo +0 -0
  41. tryton/data/locale/lo/LC_MESSAGES/tryton.mo +0 -0
  42. tryton/data/locale/lo/LC_MESSAGES/tryton.po +26 -18
  43. tryton/data/locale/lt/LC_MESSAGES/tryton.mo +0 -0
  44. tryton/data/locale/lt/LC_MESSAGES/tryton.po +30 -18
  45. tryton/data/locale/nl/LC_MESSAGES/tryton.mo +0 -0
  46. tryton/data/locale/nl/LC_MESSAGES/tryton.po +25 -16
  47. tryton/data/locale/pl/LC_MESSAGES/tryton.mo +0 -0
  48. tryton/data/locale/pl/LC_MESSAGES/tryton.po +31 -18
  49. tryton/data/locale/pt/LC_MESSAGES/tryton.mo +0 -0
  50. tryton/data/locale/pt/LC_MESSAGES/tryton.po +148 -177
  51. tryton/data/locale/ro/LC_MESSAGES/tryton.mo +0 -0
  52. tryton/data/locale/ro/LC_MESSAGES/tryton.po +32 -19
  53. tryton/data/locale/ru/LC_MESSAGES/tryton.mo +0 -0
  54. tryton/data/locale/ru/LC_MESSAGES/tryton.po +28 -16
  55. tryton/data/locale/sl/LC_MESSAGES/tryton.mo +0 -0
  56. tryton/data/locale/sl/LC_MESSAGES/tryton.po +33 -18
  57. tryton/data/locale/tr/LC_MESSAGES/tryton.mo +0 -0
  58. tryton/data/locale/tr/LC_MESSAGES/tryton.po +25 -16
  59. tryton/data/locale/uk/LC_MESSAGES/tryton.mo +0 -0
  60. tryton/data/locale/uk/LC_MESSAGES/tryton.po +31 -18
  61. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.mo +0 -0
  62. tryton/data/locale/zh_CN/LC_MESSAGES/tryton.po +27 -18
  63. tryton/data/pixmaps/tryton/tryton-chat.svg +1 -0
  64. tryton/data/pixmaps/tryton/tryton-note.svg +1 -4
  65. tryton/gui/window/attachment.py +2 -2
  66. tryton/gui/window/board.py +1 -1
  67. tryton/gui/window/form.py +57 -10
  68. tryton/gui/window/note.py +2 -2
  69. tryton/gui/window/tabcontent.py +8 -1
  70. tryton/gui/window/view_board/action.py +1 -1
  71. tryton/gui/window/view_form/model/field.py +38 -29
  72. tryton/gui/window/view_form/model/group.py +4 -4
  73. tryton/gui/window/view_form/model/record.py +17 -4
  74. tryton/gui/window/view_form/screen/screen.py +24 -6
  75. tryton/gui/window/view_form/view/calendar_gtk/calendar_.py +1 -1
  76. tryton/gui/window/view_form/view/calendar_gtk/toolbar.py +1 -1
  77. tryton/gui/window/view_form/view/form.py +2 -1
  78. tryton/gui/window/view_form/view/form_gtk/binary.py +3 -3
  79. tryton/gui/window/view_form/view/form_gtk/calendar_.py +4 -4
  80. tryton/gui/window/view_form/view/form_gtk/char.py +42 -5
  81. tryton/gui/window/view_form/view/form_gtk/checkbox.py +3 -3
  82. tryton/gui/window/view_form/view/form_gtk/dictionary.py +53 -15
  83. tryton/gui/window/view_form/view/form_gtk/float.py +3 -7
  84. tryton/gui/window/view_form/view/form_gtk/image.py +4 -4
  85. tryton/gui/window/view_form/view/form_gtk/integer.py +1 -1
  86. tryton/gui/window/view_form/view/form_gtk/many2many.py +3 -4
  87. tryton/gui/window/view_form/view/form_gtk/many2one.py +2 -2
  88. tryton/gui/window/view_form/view/form_gtk/multiselection.py +3 -3
  89. tryton/gui/window/view_form/view/form_gtk/one2many.py +11 -8
  90. tryton/gui/window/view_form/view/form_gtk/progressbar.py +2 -2
  91. tryton/gui/window/view_form/view/form_gtk/pyson.py +3 -3
  92. tryton/gui/window/view_form/view/form_gtk/reference.py +4 -4
  93. tryton/gui/window/view_form/view/form_gtk/richtextbox.py +5 -5
  94. tryton/gui/window/view_form/view/form_gtk/selection.py +3 -3
  95. tryton/gui/window/view_form/view/form_gtk/state_widget.py +8 -6
  96. tryton/gui/window/view_form/view/form_gtk/textbox.py +4 -4
  97. tryton/gui/window/view_form/view/form_gtk/timedelta.py +3 -3
  98. tryton/gui/window/view_form/view/form_gtk/url.py +2 -2
  99. tryton/gui/window/view_form/view/form_gtk/widget.py +1 -1
  100. tryton/gui/window/view_form/view/graph_gtk/bar.py +7 -7
  101. tryton/gui/window/view_form/view/graph_gtk/graph.py +2 -2
  102. tryton/gui/window/view_form/view/graph_gtk/line.py +5 -5
  103. tryton/gui/window/view_form/view/graph_gtk/pie.py +2 -2
  104. tryton/gui/window/view_form/view/list.py +110 -52
  105. tryton/gui/window/view_form/view/list_gtk/editabletree.py +2 -2
  106. tryton/gui/window/view_form/view/list_gtk/widget.py +22 -20
  107. tryton/gui/window/view_form/view/screen_container.py +13 -1
  108. tryton/gui/window/win_csv.py +2 -2
  109. tryton/gui/window/win_export.py +9 -7
  110. tryton/gui/window/win_form.py +73 -39
  111. tryton/gui/window/win_import.py +5 -6
  112. tryton/gui/window/wizard.py +11 -11
  113. tryton/jsonrpc.py +2 -2
  114. tryton/plugins/__init__.py +0 -1
  115. tryton/pyson.py +18 -18
  116. tryton/rpc.py +7 -5
  117. {tryton-7.4.8.dist-info → tryton-7.6.0.dist-info}/METADATA +6 -6
  118. {tryton-7.4.8.dist-info → tryton-7.6.0.dist-info}/RECORD +122 -120
  119. {tryton-7.4.8.data → tryton-7.6.0.data}/scripts/tryton +0 -0
  120. {tryton-7.4.8.dist-info → tryton-7.6.0.dist-info}/WHEEL +0 -0
  121. {tryton-7.4.8.dist-info → tryton-7.6.0.dist-info}/licenses/LICENSE +0 -0
  122. {tryton-7.4.8.dist-info → tryton-7.6.0.dist-info}/top_level.txt +0 -0
tryton/__init__.py CHANGED
@@ -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__ = "7.4.8"
3
+ __version__ = "7.6.0"
4
4
  import locale
5
5
 
6
6
  import gi
tryton/bus.py CHANGED
@@ -7,6 +7,7 @@ import socket
7
7
  import threading
8
8
  import time
9
9
  import uuid
10
+ from collections import defaultdict
10
11
  from urllib.error import HTTPError
11
12
  from urllib.request import Request, urlopen
12
13
 
@@ -18,82 +19,125 @@ from tryton.jsonrpc import object_hook
18
19
  logger = logging.getLogger(__name__)
19
20
 
20
21
 
21
- ID = str(uuid.uuid4())
22
- CHANNELS = [
23
- 'client:%s' % ID,
24
- ]
22
+ class Bus:
25
23
 
24
+ ID = str(uuid.uuid4())
25
+ current_thread = None
26
+ channel_actions = defaultdict(list)
27
+ listening = False
26
28
 
27
- def listen(connection):
28
- if not CONFIG['thread']:
29
- return
30
- listener = threading.Thread(
31
- target=_listen, args=(connection,), daemon=True)
32
- listener.start()
33
-
34
-
35
- def _listen(connection):
36
- bus_timeout = CONFIG['client.bus_timeout']
37
- session = connection.session
38
- authorization = base64.b64encode(session.encode('utf-8'))
39
- headers = {
40
- 'Content-Type': 'application/json',
41
- 'Authorization': b'Session ' + authorization,
42
- }
43
-
44
- wait = 1
45
- last_message = None
46
- url = None
47
- while connection.session == session:
48
- if url is None:
49
- if connection.url is None:
50
- time.sleep(1)
51
- continue
52
- url = connection.url + '/bus'
53
- request = Request(url,
54
- data=json.dumps({
55
- 'last_message': last_message,
56
- 'channels': CHANNELS,
57
- }).encode('utf-8'),
58
- headers=headers)
59
- logger.info('poll channels %s with last message %s',
60
- CHANNELS, last_message)
61
- try:
62
- response = urlopen(request, timeout=bus_timeout)
63
- wait = 1
64
- except socket.timeout:
65
- wait = 1
66
- continue
67
- except Exception as error:
68
- if isinstance(error, HTTPError):
69
- if error.code in (301, 302, 303, 307, 308):
70
- url = error.headers.get('Location')
29
+ @classmethod
30
+ def listen(cls, connection):
31
+ if not CONFIG['thread']:
32
+ return
33
+ listener = threading.Thread(
34
+ target=cls._listen, args=(connection,), daemon=True)
35
+ listener.start()
36
+ cls.current_thread = listener.ident
37
+
38
+ @classmethod
39
+ def _listen(cls, connection):
40
+ bus_timeout = CONFIG['client.bus_timeout']
41
+ session = connection.session
42
+ authorization = base64.b64encode(session.encode('utf-8'))
43
+ headers = {
44
+ 'Content-Type': 'application/json',
45
+ 'Authorization': b'Session ' + authorization,
46
+ }
47
+
48
+ thread_id = threading.get_ident()
49
+ wait = 1
50
+ last_message = None
51
+ url = None
52
+ while connection.session == session:
53
+ if url is None:
54
+ if connection.url is None:
55
+ time.sleep(1)
71
56
  continue
72
- elif error.code == 501:
73
- logger.info("Bus not supported")
57
+ url = connection.url + '/bus'
58
+ cls.listening = True
59
+
60
+ channels = list(cls.channel_actions)
61
+ request = Request(url,
62
+ data=json.dumps({
63
+ 'last_message': last_message,
64
+ 'channels': channels,
65
+ }).encode('utf-8'),
66
+ headers=headers)
67
+ logger.info('poll channels %s with last message %s',
68
+ channels, last_message)
69
+ try:
70
+ response = urlopen(request, timeout=bus_timeout)
71
+ wait = 1
72
+ except socket.timeout:
73
+ wait = 1
74
+ continue
75
+ except Exception as error:
76
+ if thread_id != cls.current_thread:
74
77
  break
75
- logger.error(
76
- "An exception occurred while connecting to the bus. "
77
- "Sleeping for %s seconds",
78
- wait, exc_info=error)
79
- time.sleep(min(wait, bus_timeout))
80
- wait *= 2
81
- continue
78
+ if isinstance(error, HTTPError):
79
+ if error.code in (301, 302, 303, 307, 308):
80
+ url = error.headers.get('Location')
81
+ continue
82
+ elif error.code == 501:
83
+ logger.info("Bus not supported")
84
+ break
85
+ logger.error(
86
+ "An exception occurred while connecting to the bus. "
87
+ "Sleeping for %s seconds",
88
+ wait, exc_info=error)
89
+ cls.listening = False
90
+ time.sleep(min(wait, bus_timeout))
91
+ wait *= 2
92
+ continue
82
93
 
83
- if connection.session != session:
84
- break
94
+ if connection.session != session:
95
+ break
96
+ if thread_id != cls.current_thread:
97
+ break
85
98
 
86
- data = json.loads(response.read(), object_hook=object_hook)
87
- if data['message']:
88
- last_message = data['message']['message_id']
89
- GLib.idle_add(handle, data['message'])
99
+ data = json.loads(response.read(), object_hook=object_hook)
100
+ if data['message']:
101
+ last_message = data['message']['message_id']
102
+ GLib.idle_add(cls.handle, data['channel'], data['message'])
103
+ cls.listening = False
90
104
 
105
+ @classmethod
106
+ def handle(cls, channel, message):
107
+ for callback in cls.channel_actions[channel]:
108
+ callback(message)
91
109
 
92
- def handle(message):
93
- from tryton.gui.main import Main
110
+ @classmethod
111
+ def register(cls, channel, function):
112
+ from tryton import rpc
113
+
114
+ restart = channel not in cls.channel_actions
115
+ cls.channel_actions[channel].append(function)
116
+ if restart:
117
+ # We can not really abort a thread, so we will just start a new one
118
+ # and ignore the result of the one already running
119
+ Bus.listen(rpc.CONNECTION)
94
120
 
121
+ @classmethod
122
+ def unregister(cls, channel, function):
123
+ try:
124
+ cls.channel_actions[channel].remove(function)
125
+ except ValueError:
126
+ pass
127
+
128
+ if not cls.channel_actions[channel]:
129
+ del cls.channel_actions[channel]
130
+
131
+
132
+ def popup_notification(message):
133
+ if message['type'] != 'notification':
134
+ return
135
+
136
+ from tryton.gui.main import Main
95
137
  app = Main()
96
- if message['type'] == 'notification':
97
- app.show_notification(
98
- message.get('title', ''), message.get('body', ''),
99
- message.get('priority', 1))
138
+ app.show_notification(
139
+ message.get('title', ''), message.get('body', ''),
140
+ message.get('priority', 1))
141
+
142
+
143
+ Bus.register(f'client:{Bus.ID}', popup_notification)
tryton/chat.py ADDED
@@ -0,0 +1,179 @@
1
+ # This file is part of Tryton. The COPYRIGHT file at the top level of
2
+ # this repository contains the full copyright notices and license terms.
3
+ import gettext
4
+
5
+ from gi.repository import Gdk, Gio, GObject, Gtk
6
+
7
+ from tryton import common, rpc
8
+ from tryton.bus import Bus
9
+
10
+ _ = gettext.gettext
11
+
12
+
13
+ class MessageItem(GObject.GObject):
14
+
15
+ def __init__(self, message):
16
+ super().__init__()
17
+ self.message = message
18
+
19
+
20
+ class MessageList(GObject.GObject, Gio.ListModel):
21
+
22
+ def __init__(self):
23
+ super().__init__()
24
+ self._messages = []
25
+ self._items = {}
26
+
27
+ def do_get_item(self, position):
28
+ if position >= len(self._messages):
29
+ return None
30
+ message = self._messages[position]
31
+ if message['id'] not in self._items:
32
+ self._items[message['id']] = MessageItem(message)
33
+ return self._items[message['id']]
34
+
35
+ def do_get_item_type(self):
36
+ return MessageItem
37
+
38
+ def do_get_n_items(self):
39
+ return len(self._messages)
40
+
41
+ def clear(self):
42
+ self.emit('items-changed', 0, len(self._messages), 0)
43
+ self._messages = []
44
+ self._items = {}
45
+
46
+ def append(self, message):
47
+ self._messages.append(message)
48
+ self.emit('items-changed', len(self._messages) - 1, 0, 1)
49
+
50
+
51
+ class Chat:
52
+
53
+ def __init__(self, record):
54
+ self.record = record
55
+ Bus.register(f"chat:{self.record}", self.notify)
56
+ self.widget = self.__build()
57
+
58
+ def unregister(self):
59
+ Bus.unregister(f"chat:{self.record}", self.notify)
60
+
61
+ def send_message(self, message, internal):
62
+ rpc.execute(
63
+ 'model', 'ir.chat.channel', 'post', self.record, message,
64
+ 'internal' if internal else 'public', rpc.CONTEXT)
65
+
66
+ def get_messages(self):
67
+ return rpc.execute(
68
+ 'model', 'ir.chat.channel', 'get', self.record, rpc.CONTEXT)
69
+
70
+ def notify(self, message):
71
+ self.refresh()
72
+
73
+ def refresh(self):
74
+ self._messages.clear()
75
+ for post in self.get_messages():
76
+ self._messages.append(post)
77
+ self.widget.show_all()
78
+
79
+ def scroll_to_bottom(*args):
80
+ self._messages_sw.disconnect(signal_id)
81
+ vadj = self._messages_sw.get_vadjustment()
82
+ vadj.props.value = vadj.get_upper()
83
+ signal_id = self._messages_sw.connect(
84
+ 'size-allocate', scroll_to_bottom)
85
+
86
+ def __build(self):
87
+ widget = Gtk.VBox()
88
+ widget.set_spacing(3)
89
+
90
+ def _submit(button):
91
+ buffer = input_.get_buffer()
92
+ self.send_message(
93
+ buffer.get_text(
94
+ buffer.get_start_iter(), buffer.get_end_iter(), False),
95
+ internal.get_active())
96
+ buffer.set_text('')
97
+ if not Bus.listening:
98
+ self.refresh()
99
+
100
+ def _keypress(entry, event):
101
+ if (event.state & Gdk.ModifierType.CONTROL_MASK
102
+ and event.keyval == Gdk.KEY_Return):
103
+ _submit(None)
104
+ return True
105
+
106
+ self._messages = MessageList()
107
+ chat_messages = Gtk.ListBox.new()
108
+ chat_messages.props.activate_on_single_click = False
109
+ chat_messages.set_selection_mode(Gtk.SelectionMode.NONE)
110
+ chat_messages.bind_model(self._messages, self.create_message)
111
+ self._messages_sw = scrolledwindow = Gtk.ScrolledWindow()
112
+ viewport = Gtk.Viewport()
113
+ viewport.add(chat_messages)
114
+ viewport.set_valign(Gtk.Align.END)
115
+ scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
116
+ scrolledwindow.set_policy(
117
+ Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
118
+ scrolledwindow.add(viewport)
119
+ widget.pack_start(scrolledwindow, True, True, 0)
120
+
121
+ input_ = Gtk.TextView()
122
+ input_.connect('key-press-event', _keypress)
123
+ input_.set_size_request(-1, 100)
124
+ widget.pack_start(input_, False, True, 0)
125
+
126
+ internal = Gtk.CheckButton.new_with_mnemonic(
127
+ _("Make this an _internal message"))
128
+ widget.pack_start(internal, False, True, 0)
129
+
130
+ submit = Gtk.Button.new_with_label(_("Send"))
131
+ submit.connect('clicked', _submit)
132
+ widget.pack_start(submit, False, False, 0)
133
+
134
+ return widget
135
+
136
+ def create_message(self, item):
137
+ message = item.message
138
+
139
+ row = Gtk.ListBoxRow()
140
+ row.set_selectable(False)
141
+ row.set_margin_top(5)
142
+
143
+ hbox = Gtk.HBox(spacing=10)
144
+ row.add(hbox)
145
+
146
+ if avatar_url := message.get('avatar_url'):
147
+ image = Gtk.Image()
148
+ pixbuf = common.IconFactory.get_pixbuf_url(
149
+ avatar_url, size=32, size_param='s',
150
+ callback=image.set_from_pixbuf)
151
+ image.set_from_pixbuf(pixbuf)
152
+ image.set_valign(Gtk.Align.START)
153
+ hbox.pack_start(image, False, False, 0)
154
+
155
+ bubble = Gtk.VBox()
156
+ hbox.pack_end(bubble, True, True, 0)
157
+
158
+ author = Gtk.Label(label=message['author'])
159
+ author.set_xalign(0)
160
+ author.get_style_context().add_class('dim')
161
+ timestamp = Gtk.Label(label=message['timestamp'].strftime('%x %X'))
162
+ timestamp.set_xalign(1)
163
+ timestamp.get_style_context().add_class('dim')
164
+
165
+ meta = Gtk.HBox()
166
+ meta.pack_start(author, True, True, 0)
167
+ meta.pack_end(timestamp, False, False, 0)
168
+
169
+ content = Gtk.Label(label=message['content'])
170
+ content.set_xalign(0)
171
+ content.set_line_wrap(True)
172
+ content.set_selectable(True)
173
+ content.get_style_context().add_class(
174
+ f"chat-content-{message['audience']}")
175
+
176
+ bubble.pack_start(meta, False, False, 0)
177
+ bubble.pack_start(content, False, False, 0)
178
+
179
+ return row
tryton/client.py CHANGED
@@ -33,6 +33,13 @@ def main():
33
33
  label.warning {
34
34
  color: @warning_color;
35
35
  }
36
+ label.dim {
37
+ font-size: smaller;
38
+ font-weight: lighter;
39
+ }
40
+ .chat-content-internal {
41
+ font-weight: lighter;
42
+ }
36
43
  .window-title, .wizard-title {
37
44
  font-size: large;
38
45
  font-weight: bold;
tryton/common/__init__.py CHANGED
@@ -2,17 +2,18 @@
2
2
  # this repository contains the full copyright notices and license terms.
3
3
  from . import timedelta
4
4
  from .common import (
5
- COLOR_SCHEMES, MODELACCESS, MODELHISTORY, MODELNAME, MODELNOTIFICATION,
6
- TRYTON_ICON, VIEW_SEARCH, IconFactory, Logout, RPCContextReload,
7
- RPCException, RPCExecute, RPCProgress, Tooltips, apply_label_attributes,
8
- ask, check_version, concurrency, data2pixbuf, date_format, ellipsize,
9
- error, file_open, file_selection, file_write, filter_domain,
10
- generateColorscheme, get_align, get_credentials, get_gdk_backend,
11
- get_hostname, get_port, get_sensible_widget, get_toplevel_window, hex2rgb,
12
- highlight_rgb, humanize, idle_add, mailto, message, node_attributes,
13
- open_documentation, play_sound, process_exception, resize_pixbuf,
14
- selection, setup_window, slugify, sur, sur_3b, timezoned_date, to_xml,
15
- untimezoned_date, url_open, userwarning, warning)
5
+ COLOR_SCHEMES, MODELACCESS, MODELCHAT, MODELHISTORY, MODELNAME,
6
+ MODELNOTIFICATION, TRYTON_ICON, VIEW_SEARCH, IconFactory, Logout,
7
+ RPCContextReload, RPCException, RPCExecute, RPCProgress, SolidColorFactory,
8
+ Tooltips, apply_label_attributes, ask, check_version, concurrency,
9
+ data2pixbuf, date_format, ellipsize, error, file_open, file_selection,
10
+ file_write, filter_domain, generateColorscheme, get_align, get_credentials,
11
+ get_gdk_backend, get_hostname, get_monitor_size, get_port,
12
+ get_sensible_widget, get_toplevel_window, hex2rgb, highlight_rgb, humanize,
13
+ idle_add, mailto, message, node_attributes, open_documentation, play_sound,
14
+ process_exception, resize_pixbuf, selection, setup_window, slugify, sur,
15
+ sur_3b, timezoned_date, to_xml, untimezoned_date, url_open, userwarning,
16
+ warning)
16
17
  from .domain_inversion import (
17
18
  concat, domain_inversion, eval_domain, extract_reference_models,
18
19
  filter_leaf, inverse_leaf, localize_domain, merge,
@@ -28,10 +29,12 @@ __all__ = [
28
29
  MODELHISTORY,
29
30
  MODELNAME,
30
31
  MODELNOTIFICATION,
32
+ MODELCHAT,
31
33
  RPCContextReload,
32
34
  RPCException,
33
35
  RPCExecute,
34
36
  RPCProgress,
37
+ SolidColorFactory,
35
38
  TRYTON_ICON,
36
39
  Tooltips,
37
40
  VIEW_SEARCH,
@@ -57,6 +60,7 @@ __all__ = [
57
60
  get_credentials,
58
61
  get_gdk_backend,
59
62
  get_hostname,
63
+ get_monitor_size,
60
64
  get_port,
61
65
  get_sensible_widget,
62
66
  get_toplevel_window,
tryton/common/button.py CHANGED
@@ -14,7 +14,7 @@ class Button(Gtk.Button):
14
14
  def __init__(self, attrs=None):
15
15
  self.attrs = attrs or {}
16
16
  self.label = '_' + attrs.get('string', '').replace('_', '__')
17
- super(Button, self).__init__(label=self.label, stock=None,
17
+ super().__init__(label=self.label, stock=None,
18
18
  use_underline=True)
19
19
  self._set_icon(attrs.get('icon'))
20
20
 
@@ -10,7 +10,7 @@ from .cellrendererinteger import CellRendererInteger
10
10
  class CellRendererFloat(CellRendererInteger):
11
11
 
12
12
  def __init__(self):
13
- super(CellRendererFloat, self).__init__()
13
+ super().__init__()
14
14
  self.digits = None
15
15
  self.monetary = False
16
16
  self.convert = float
@@ -6,7 +6,7 @@ from gi.repository import GObject, Gtk
6
6
  class CellRendererText(Gtk.CellRendererText):
7
7
 
8
8
  def __init__(self):
9
- super(CellRendererText, self).__init__()
9
+ super().__init__()
10
10
  self.connect('editing-started', self.__class__.on_editing_started)
11
11
 
12
12
  def on_editing_started(self, editable, path):
@@ -16,7 +16,7 @@ class CellRendererText(Gtk.CellRendererText):
16
16
  class CellRendererTextCompletion(CellRendererText):
17
17
 
18
18
  def __init__(self, set_completion):
19
- super(CellRendererTextCompletion, self).__init__()
19
+ super().__init__()
20
20
  self.set_completion = set_completion
21
21
 
22
22
  def on_editing_started(self, editable, path):