commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r9450 - in trunk/gnue-forms/src: . GFObjects input/displayHandler


From: reinhard
Subject: [gnue] r9450 - in trunk/gnue-forms/src: . GFObjects input/displayHandlers
Date: Tue, 27 Mar 2007 13:13:58 -0500 (CDT)

Author: reinhard
Date: 2007-03-27 13:13:56 -0500 (Tue, 27 Mar 2007)
New Revision: 9450

Modified:
   trunk/gnue-forms/src/GFForm.py
   trunk/gnue-forms/src/GFObjects/GFField.py
   trunk/gnue-forms/src/input/displayHandlers/Cursor.py
Log:
Update field value on every keypress in an entry, not only on focus-out. This
makes sure the field value and record status are as correct as possible at any
given point in time.


Modified: trunk/gnue-forms/src/GFForm.py
===================================================================
--- trunk/gnue-forms/src/GFForm.py      2007-03-27 18:12:35 UTC (rev 9449)
+++ trunk/gnue-forms/src/GFForm.py      2007-03-27 18:13:56 UTC (rev 9450)
@@ -685,23 +685,16 @@
 
     def event_begin (self):
         """
-        Set the form into a defined state to prepare event handling.
+        Start handling of a user event.
 
-        This function sets the form into a consistent and defined state so that
-        event handling code (like triggers and actions) can rely on everything
-        being ok.
-
-        Most notably, this function updates the field value for the currently
-        edited entry and shows an hourglass mouse cursor.
-
         This function has to be called at the beginning of each user event
         being handled. At the end of handling the user event, L{event_end} has
         to be called.
+
+        Currently, these functions only turn on and off the hourglass mouse
+        cursor.
         """
 
-        if hasattr(self._currentEntry, '_displayHandler'):
-            # FIXME: what if this fails?
-            self._currentEntry._displayHandler.updateFieldValue()
         if self.uiWidget is not None:
             self.uiWidget._ui_begin_wait_()
 
@@ -712,17 +705,13 @@
 
     def event_end (self):
         """
-        Set the form into a defined state to finalize event handling.
+        End handling of a user event.
 
-        This function sets the form into a consistent and defined state after
-        event handling code (like triggers and actions) has been run.
-
-        Most notably, this function resets the mouse cursor from hourglass to
-        normal and updates the field values shown on the form to reflect any
-        data modifications done in the event handling code.
-
         This function has to be called at the end of each user event being
         handled, just like L{event_begin} is called at the beginning.
+
+        Currently, these functions only turn on and off the hourglass mouse
+        cursor.
         """
 
         if self.uiWidget is not None:
@@ -1405,17 +1394,19 @@
         Enters the form into Query mode.
         """
 
-        # self.endEditing()             # happens via _focus_out()
+        # self.endEditing()         # happens via _focus_out()
 
-        try:
-            # We *must* run _focus_out() here: letting the user leave an entry
-            # with an invalid value here would make it possible to enter an
-            # invalid value, switch to query mode, move the focus somewhere
-            # else, cancel the query (and so getting back the original result
-            # set) and then saving the unchecked data.
-            if self._currentBlock is not None:
-                self._currentBlock._focus_out()
+        # We *must* run _focus_out() here: letting the user leave an entry
+        # with an invalid value here would make it possible to enter an
+        # invalid value, switch to query mode, move the focus somewhere
+        # else, cancel the query (and so getting back the original result
+        # set) and then saving the unchecked data.
+        # The _focus_out() can run outside the try-except block because it
+        # already does the beginEditing in case of an exception.
+        if self._currentBlock is not None:
+            self._currentBlock._focus_out()
 
+        try:
             if not self._must_save():
                 # We must refresh the UI events now as otherwise the query
                 # button will stick in.
@@ -1439,13 +1430,14 @@
         Copies the Query, ie brings back conditions from the last query.
         """
 
-        # self.endEditing()             # happens via focus_out()
+        # self.endEditing()         # happens via focus_out()
 
-        try:
-            if self._currentBlock is not None:
-                self._currentBlock._focus_out()
+        if self._currentBlock is not None:
+            self._currentBlock._focus_out()
 
+        try:
             if not self._must_save():
+                self.refreshUIEvents()
                 self.beginEditing()
                 return
 
@@ -1683,13 +1675,6 @@
         @return: boolean, True if all the blocks are committed.
         """
 
-        # Is the current entry changed?
-        if (self._currentEntry is not None and \
-            self._currentEntry._type != 'GFButton' and \
-            self._currentEntry._field._bound and \
-            self._currentEntry._displayHandler.isPending()):
-          return False
-
         # Are there any not yet posted changes in any of the blocks?
         for block in self._logic._blockList:
             if block.is_pending():
@@ -1697,8 +1682,8 @@
 
         # Does a connection have any pending (already posted but not yet
         # committed) changes?
-        for connection in (self.__get_connections ()).values ():
-          if connection.isPending ():
+        for connection in (self.__get_connections()).itervalues():
+          if connection.isPending():
             return False
 
         return True

Modified: trunk/gnue-forms/src/GFObjects/GFField.py
===================================================================
--- trunk/gnue-forms/src/GFObjects/GFField.py   2007-03-27 18:12:35 UTC (rev 
9449)
+++ trunk/gnue-forms/src/GFObjects/GFField.py   2007-03-27 18:13:56 UTC (rev 
9450)
@@ -75,6 +75,10 @@
         self.__lookup_dict = None               # {db_value: user_value}
         self.__lookup_dict_reverse = {}         # {user_value: db_value}
 
+        # Autoquery support
+        self.__autoquery_value = None
+        self.__in_autoquery = False
+
         # These are only here because "rows" and "gap" is passed from GFBlock
         # through GFField to GFEntry.
         self._rows = 1
@@ -292,6 +296,8 @@
 
         if value is None:
             return None
+        elif isinstance(value, datatypes.InvalidValueType):
+            return value
         elif value in self.__lookup_dict_reverse:
             return self.__lookup_dict_reverse[value]
         else:
@@ -347,6 +353,9 @@
 
         value = self._block.get_value(self, offset)
 
+        if isinstance(value, datatypes.InvalidValueType):
+            raise value.exception
+
         # FIXME: This conversion should be in gnue-common.
         try:
             value = datatypes.convert(value, self.datatype, self.length,
@@ -385,23 +394,22 @@
                 if self.ltrim:
                     value = value.lstrip()
         
-            if self.minLength and value is not None and len(value) \
+            if self.minLength and isinstance(value, basestring) \
                     and len(value) < self.minLength:
                 raise MinimumLengthError(self.name, value, self.minLength)
 
-        # Auto-query support     
-        if self._block.mode != 'query' \
-                and ((self.autoquery == 'Y') \
-                    or (self.autoquery == 'new' \
-                        and self._block.get_record_status() == 'empty')):
-            self._block.query({self.field: value})
-            if self._block.get_record_status() == 'empty':
-                # Query returned no result, so set the field value
-                self._block.set_value(self, value)
-        else:
-          self._block.set_value(self, value)
+        # If this is an autoquery field, don't pass the value to the block, but
+        # save it for later.
+        if (self.autoquery == 'Y') \
+                or (self.autoquery == 'new' \
+                            and self._block.get_record_status() == 'empty'):
+            if not self.__in_autoquery:
+                self.__autoquery_value = value
+                return
 
+        self._block.set_value(self, value)
 
+
     # -------------------------------------------------------------------------
     # Notification of value change
     # -------------------------------------------------------------------------
@@ -466,6 +474,20 @@
         if self._block.mode == 'normal':
             self.processTrigger('PRE-FOCUSOUT', ignoreAbort=False)
 
+            if self.__autoquery_value is not None and not self.__in_autoquery:
+                if (self.autoquery == 'Y') \
+                        or (self.autoquery == 'new' \
+                            and self._block.get_record_status() == 'empty'):
+                    self.__in_autoquery = True
+                    try:
+                        self._block.query({self.field: self.__autoquery_value})
+                        if self._block.get_record_status() == 'empty':
+                            # Query returned no result, so set the field value
+                            self.__set_value(self.__autoquery_value)
+                        self.__autoquery_value = None
+                    finally:
+                        self.__in_autoquery = False
+
     # -------------------------------------------------------------------------
 
     def focus_out(self):

Modified: trunk/gnue-forms/src/input/displayHandlers/Cursor.py
===================================================================
--- trunk/gnue-forms/src/input/displayHandlers/Cursor.py        2007-03-27 
18:12:35 UTC (rev 9449)
+++ trunk/gnue-forms/src/input/displayHandlers/Cursor.py        2007-03-27 
18:13:56 UTC (rev 9450)
@@ -36,6 +36,7 @@
 
 import sys
 from gnue.common import events
+from gnue.common.utils import datatypes
 
 
 class BaseCursor(events.EventAware):
@@ -131,12 +132,6 @@
             selection1, selection2 = selection
             self.entry.uiWidget._ui_set_selected_area_(index, selection1, 
selection2)
 
-    def isPending(self):
-        """
-        Return True if the display handler is in edit mode and has modified 
text
-        """
-        return self.editing and self.modified
-
     #####################
     #
     # Editing methods
@@ -342,9 +337,8 @@
         self.entry._form.refreshUIEvents()
 
         # Update the field. This means PRE-CHANGE and POST-CHANGE will get
-        # fired now. For now, only do this here if we are a lookup.
-        if hasattr(self.field, 'fk_source'):
-            self.updateFieldValue()
+        # fired now.
+        self.updateFieldValue()
 
     # -------------------------------------------------------------------------
     # Do autocompletion
@@ -591,13 +585,18 @@
         """
         try:
             self.__updateFieldValue()
-        except:
-            pass
+        except Exception, exception:
+            # We don't want to raise the exception now as the user is still
+            # typing. However, we archive the exception in an InvalidValueType
+            # object and store that as the current field value. If any trigger
+            # code now tries to access the field, the GFField.get_value will
+            # raise the exception.
+            self.field.set_value(datatypes.InvalidValueType(exception))
 
 
     def __updateFieldValue(self):
 
-        if not self.__updating and self.isPending():
+        if not self.__updating and self.modified:
             # Make sure that this function isn't called twice recursively. This
             # would happen when the field is autoquery, so the
             # field.set_value() would cause a query to run, which in turns





reply via email to

[Prev in Thread] Current Thread [Next in Thread]