summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshio Kuratomi <a.badger@gmail.com>2017-01-21 14:47:14 -0800
committerToshio Kuratomi <a.badger@gmail.com>2017-01-21 16:28:48 -0800
commit4f85c63becc3267241b5940b32ed586a4da304a9 (patch)
tree4dd53376aa03704e071c7f0996662fb0d373cf23
parentcad6c144bf9940aa672611a36f2174655c579af7 (diff)
downloadurwid-4f85c63becc3267241b5940b32ed586a4da304a9.tar.gz
Implement postchange signal for Edit widget.
The Edit widget in 1.3.0 has a "change" signal which fires before the edit_text is updated. This means that change signal handlers cannot update the edit_text; the text is updated by the signal emitter after the change handler has finished running. To remedy this, in a backwards compatible way, create a second signal, "postchange" which fires after edit_text has been changed. "postchange" sends the widget's old text value as a parameter so that change handlers can use the former value if needed (for instance, to revert a change because the new_text was invalid)
-rw-r--r--urwid/widget.py22
1 files changed, 18 insertions, 4 deletions
diff --git a/urwid/widget.py b/urwid/widget.py
index a3e39d8..945a77f 100644
--- a/urwid/widget.py
+++ b/urwid/widget.py
@@ -1101,11 +1101,22 @@ class Edit(Text):
deletion. A caption may prefix the editing area. Uses text class
for text layout.
- Users of this class to listen for ``"change"`` events
- sent when the value of edit_text changes. See :func:``connect_signal``.
+ Users of this class may listen for ``"change"`` or ``"postchange"``
+ events. See :func:``connect_signal``.
+
+ * ``"change"`` is sent just before the value of edit_text changes.
+ It receives the new text as an argument. Note that ``"change"`` cannot
+ change the text in question as edit_text changes the text afterwards.
+ * ``"postchange"`` is sent after the value of edit_text changes.
+ It receives the old value of the text as an argument and thus is
+ appropriate for changing the text. It is possible for a ``"postchange"``
+ event handler to get into a loop of changing the text and then being
+ called when the event is re-emitted. It is up to the event
+ handler to guard against this case (for instance, by not changing the
+ text if it is signaled for for text that it has already changed once).
"""
# (this variable is picked up by the MetaSignals metaclass)
- signals = ["change"]
+ signals = ["change", "postchange"]
def valid_char(self, ch):
"""
@@ -1160,6 +1171,7 @@ class Edit(Text):
self.allow_tab = allow_tab
self._edit_pos = 0
self.set_caption(caption)
+ self._edit_text = ''
self.set_edit_text(edit_text)
if edit_pos is None:
edit_pos = len(edit_text)
@@ -1354,10 +1366,12 @@ class Edit(Text):
"""
text = self._normalize_to_caption(text)
self.highlight = None
+ self._emit("change", text)
+ old_text = self._edit_text
self._edit_text = text
if self.edit_pos > len(text):
self.edit_pos = len(text)
- self._emit("change", text)
+ self._emit("postchange", old_text)
self._invalidate()
def get_edit_text(self):