Permalink
Browse files

qobserver: fix a bug where we would respond to redundant notifications

When setting a text field Qt triggers a callback.  We catch this callback
and update our model accordingly.  When the model updates, it triggers
another callback which causes a feedback loop that eventually resolves
with the text field getting set twice.  This is problematic since
it makes entering text problematic.

We now detect this situation and stop the notification loop accordingly.

Signed-off-by: David Aguilar <davvid@gmail.com>
  • Loading branch information...
1 parent 1e35239 commit c8c4838f488be76751457275ae32eac2fe603d8f @davvid davvid committed Dec 5, 2008
Showing with 14 additions and 11 deletions.
  1. +0 −10 cola/controllers/createbranch.py
  2. +14 −1 cola/qobserver.py
@@ -28,16 +28,6 @@ def init(self, model, view):
tag_radio = self.display_model)
self.display_model()
- def subject_changed(self, param, value):
- """We intercept subject_changed so that we don't
- reset user input when typing in the branch name.
- """
- # We do want to capture when remote branches are clicked,
- # so we flag that with _remoteclicked
- if param == 'local_branch' and not self._remoteclicked:
- return
- QObserver.subject_changed(self, param, value)
-
#+--------------------------------------------------------------------
#+ Qt callbacks
def create_branch(self):
View
@@ -49,6 +49,8 @@ def __init__(self, model, view, *args, **kwargs):
self.__model_to_view = {}
self.__view_to_model = {}
self.__connected = set()
+ self.__in_slot = False
+ self.__in_callback = False
# Call the subclass's startup routine
self.init(model, view, *args, **kwargs)
@@ -60,6 +62,8 @@ def SLOT(self, *args):
"""Default slot to handle all Qt callbacks.
This method delegates to callbacks from add_signals."""
+ self.__in_slot = True
+
widget = self.sender()
sender = str(widget.objectName())
@@ -121,12 +125,15 @@ def SLOT(self, *args):
model.get_param(model_param)[idx])
else:
model.set_param(model_param+'_item', '')
-
+
else:
print("SLOT(): Unknown widget:", sender, widget)
+ self.__in_callback = True
if sender in self.__callbacks:
self.__callbacks[sender](*args)
+ self.__in_callback = False
+ self.__in_slot = False
def connect(self, obj, signal_str, *args):
"""Convenience function so that subclasses do not have
@@ -223,6 +230,12 @@ def add_actions(self, **kwargs):
def subject_changed(self, param, value):
"""Sends a model param to the view(model->view)"""
+ if self.__in_slot and not self.__in_callback:
+ # A slot has changed the model and we're not in
+ # a user callback. In this case the event is causing
+ # a feedback loop so skip redundant work and return.
+ return
+
if param in self.__model_to_view:
notify = self.model.get_notify()
self.model.set_notify(False)

0 comments on commit c8c4838

Please sign in to comment.