[z3-checkins] r20253 - in z3/Five/branch/Five-1.2: . tests

efge at codespeak.net efge at codespeak.net
Fri Nov 25 19:42:27 CET 2005


Author: efge
Date: Fri Nov 25 19:42:27 2005
New Revision: 20253

Modified:
   z3/Five/branch/Five-1.2/CHANGES.txt
   z3/Five/branch/Five-1.2/event.py
   z3/Five/branch/Five-1.2/monkey.py
   z3/Five/branch/Five-1.2/tests/event.txt
Log:
Made Five send a ContainerModifiedEvent when appropriate.

This event is new in very recent Zope 3.2, so a monkey patch of Zope 3
is needed until 3.2 final is released or stiched in Zope 2.8.



Modified: z3/Five/branch/Five-1.2/CHANGES.txt
==============================================================================
--- z3/Five/branch/Five-1.2/CHANGES.txt	(original)
+++ z3/Five/branch/Five-1.2/CHANGES.txt	Fri Nov 25 19:42:27 2005
@@ -5,6 +5,11 @@
 Five 1.3 branch
 ===============
 
+Bugfixes
+--------
+
+* Made Five send a ContainerModifiedEvent when appropriate.
+
 Restructuring
 -------------
 
@@ -81,6 +86,8 @@
 
 * Fixed loops in zcml loading due to events in some cases.
 
+* Made Five send a ContainerModifiedEvent when appropriate.
+
 Restructuring
 -------------
 

Modified: z3/Five/branch/Five-1.2/event.py
==============================================================================
--- z3/Five/branch/Five-1.2/event.py	(original)
+++ z3/Five/branch/Five-1.2/event.py	Fri Nov 25 19:42:27 2005
@@ -25,6 +25,7 @@
 from AccessControl import getSecurityManager
 from ZODB.POSException import ConflictError
 from OFS import Moniker
+from OFS.CopySupport import CopyContainer
 from OFS.CopySupport import CopyError # Yuck, a string exception
 from OFS.CopySupport import eNoData, eNotFound, eInvalid, eNotSupported
 from OFS.CopySupport import cookie_path, sanity_check, _cb_decode
@@ -34,6 +35,7 @@
 from zope.app.container.contained import ObjectMovedEvent
 from zope.app.container.contained import ObjectAddedEvent
 from zope.app.container.contained import ObjectRemovedEvent
+from zope.app.container.contained import notifyContainerModified
 from zope.app.event.objectevent import ObjectCopiedEvent
 from OFS.event import ObjectWillBeMovedEvent
 from OFS.event import ObjectWillBeAddedEvent
@@ -128,6 +130,7 @@
 
     if not suppress_events:
         notify(ObjectAddedEvent(ob, self, id))
+        notifyContainerModified(self)
 
     compatibilityCall('manage_afterAdd', ob, ob, self)
 
@@ -169,6 +172,7 @@
 
     if not suppress_events:
         notify(ObjectAddedEvent(ob, self, id))
+        notifyContainerModified(self)
 
     compatibilityCall('manage_afterAdd', ob, ob, self)
 
@@ -204,6 +208,7 @@
 
     if not suppress_events:
         notify(ObjectRemovedEvent(ob, self, id))
+        notifyContainerModified(self)
 
 
 # From BTreeFolder2
@@ -219,6 +224,7 @@
 
     if not suppress_events:
         notify(ObjectRemovedEvent(ob, self, id))
+        notifyContainerModified(self)
 
 # From CopyContainer
 def manage_renameObject(self, id, new_id, REQUEST=None):
@@ -263,6 +269,7 @@
     ob = self._getOb(new_id)
 
     notify(ObjectMovedEvent(ob, self, id, self, new_id))
+    notifyContainerModified(self)
 
     ob._postCopy(self, op=1)
 
@@ -389,6 +396,9 @@
             ob = self._getOb(id)
 
             notify(ObjectMovedEvent(ob, orig_container, orig_id, self, id))
+            notifyContainerModified(orig_container)
+            if aq_base(orig_container) is not aq_base(self):
+                notifyContainerModified(self)
 
             ob._postCopy(self, op=1)
             # try to make ownership implicit if possible
@@ -445,6 +455,31 @@
 
     return ob
 
+# From OrderSupport
+def moveObjectsByDelta(self, ids, delta, subset_ids=None,
+                       suppress_events=False):
+    """ Move specified sub-objects by delta.
+    """
+    res = self.__five_original_moveObjectsByDelta(ids, delta, subset_ids)
+    if not suppress_events:
+        notifyContainerModified(self)
+    return res
+
+def moveObjectToPosition(self, id, position, suppress_events=False):
+    """ Move specified object to absolute position.
+    """
+    delta = position - self.getObjectPosition(id)
+    return self.moveObjectsByDelta(id, delta, suppress_events=suppress_events)
+
+def OS_manage_renameObject(self, id, new_id, REQUEST=None):
+    """ Rename a particular sub-object without changing its position.
+    """
+    old_position = self.getObjectPosition(id)
+    res = CopyContainer.manage_renameObject(self, id, new_id, REQUEST)
+    self.moveObjectToPosition(new_id, old_position, suppress_events=True)
+    return res
+
+
 ##################################################
 # Fix OFS.Application's creation of some objects.
 #
@@ -521,7 +556,6 @@
 
 from OFS.SimpleItem import Item
 from OFS.ObjectManager import ObjectManager
-from OFS.CopySupport import CopyContainer
 from OFS.OrderSupport import OrderSupport
 from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2Base
 from OFS.Application import AppInitializer
@@ -563,8 +597,12 @@
     patchMethod(CopyContainer, 'manage_clone',
                 manage_clone)
 
-    patchMethod(OrderSupport, '_old_manage_renameObject',
-                manage_renameObject)
+    patchMethod(OrderSupport, 'moveObjectsByDelta',
+                moveObjectsByDelta)
+    patchMethod(OrderSupport, 'moveObjectToPosition',
+                moveObjectToPosition)
+    patchMethod(OrderSupport, 'manage_renameObject',
+                OS_manage_renameObject)
 
     patchMethod(AppInitializer, 'install_errorlog',
                 install_errorlog)

Modified: z3/Five/branch/Five-1.2/monkey.py
==============================================================================
--- z3/Five/branch/Five-1.2/monkey.py	(original)
+++ z3/Five/branch/Five-1.2/monkey.py	Fri Nov 25 19:42:27 2005
@@ -27,6 +27,7 @@
     interfaces.monkey()
     i18n.monkey()
     localsites_monkey()
+    zope3_monkey()
 
 def localsites_monkey():
     from Acquisition import aq_inner, aq_parent
@@ -71,3 +72,49 @@
 
     from ZPublisher.BaseRequest import BaseRequest
     BaseRequest.close = close
+
+def zope3_monkey():
+    """Fix Zope 3 to have the proper ContainerModifiedEvent that has
+    been added for 3.2.
+    """
+    try:
+        from zope.app.container.contained import notifyContainerModified
+    except ImportError:
+        pass
+    else:
+        return
+
+    # BBB: goes away when Zope 3.2 >= r40368 is stiched in
+
+    from zope.event import notify
+    from zope.interface import implements
+    import zope.app.container.contained
+    import zope.app.container.interfaces
+    from zope.app.event.objectevent import ObjectModifiedEvent
+    from zope.app.event.interfaces import IObjectModifiedEvent
+
+    class IContainerModifiedEvent(IObjectModifiedEvent):
+        """The container has been modified.
+
+        This event is specific to "containerness" modifications, which
+        means addition, removal or reordering of sub-objects.
+        """
+
+    zope.app.container.interfaces.IContainerModifiedEvent = \
+        IContainerModifiedEvent
+
+
+    class ContainerModifiedEvent(ObjectModifiedEvent):
+        """The container has been modified."""
+        implements(IContainerModifiedEvent)
+
+    zope.app.container.contained.ContainerModifiedEvent = \
+        ContainerModifiedEvent
+
+
+    def notifyContainerModified(object, *descriptions):
+        """Notify that the container was modified."""
+        notify(ContainerModifiedEvent(object, *descriptions))
+
+    zope.app.container.contained.notifyContainerModified = \
+        notifyContainerModified

Modified: z3/Five/branch/Five-1.2/tests/event.txt
==============================================================================
--- z3/Five/branch/Five-1.2/tests/event.txt	(original)
+++ z3/Five/branch/Five-1.2/tests/event.txt	Fri Nov 25 19:42:27 2005
@@ -207,6 +207,7 @@
   ObjectWillBeAddedEvent sub
   ObjectAddedEvent sub
   old manage_afterAdd sub sub folder
+  ContainerModifiedEvent folder
   'sub'
   >>> sub = folder.sub
   >>> ob = MyContent('dog')
@@ -214,6 +215,7 @@
   ObjectWillBeAddedEvent dog
   ObjectAddedEvent dog
   old manage_afterAdd dog dog sub
+  ContainerModifiedEvent sub
   'dog'
 
 And when we rename the subfolder, manage_beforeDelete is also called
@@ -228,6 +230,7 @@
   old manage_afterAdd marine marine folder
   ObjectMovedEvent dog
   old manage_afterAdd dog marine folder
+  ContainerModifiedEvent folder
 
 Same thing for clone::
 
@@ -239,6 +242,7 @@
   old manage_afterAdd tank tank folder
   ObjectAddedEvent dog
   old manage_afterAdd dog tank folder
+  ContainerModifiedEvent folder
   ObjectClonedEvent tank
   old manage_afterClone tank tank
   ObjectClonedEvent dog
@@ -264,6 +268,7 @@
   ObjectWillBeAddedEvent lassie
   ObjectAddedEvent lassie
   old manage_afterAdd lassie lassie folder
+  ContainerModifiedEvent folder
   'lassie'
 
 And when we delete the object, manage_beforeDelete is also called and
@@ -273,6 +278,7 @@
   ObjectWillBeRemovedEvent lassie
   old manage_beforeDelete lassie lassie folder
   ObjectRemovedEvent lassie
+  ContainerModifiedEvent folder
 
 The old behavior happens for a move or a copy, with events too.
 For a move::
@@ -282,6 +288,7 @@
   ObjectWillBeAddedEvent blueberry
   ObjectAddedEvent blueberry
   old manage_afterAdd blueberry blueberry folder
+  ContainerModifiedEvent folder
   'blueberry'
   >>> cp = folder.manage_cutObjects('blueberry')
   >>> folder.manage_pasteObjects(cp)
@@ -289,6 +296,7 @@
   old manage_beforeDelete blueberry blueberry folder
   ObjectMovedEvent blueberry
   old manage_afterAdd blueberry blueberry folder
+  ContainerModifiedEvent folder
   [{'new_id': 'blueberry', 'id': 'blueberry'}]
 
 Old behavior with events for a copy::
@@ -299,6 +307,7 @@
   ObjectWillBeAddedEvent copy_of_blueberry
   ObjectAddedEvent copy_of_blueberry
   old manage_afterAdd copy_of_blueberry copy_of_blueberry folder
+  ContainerModifiedEvent folder
   ObjectClonedEvent copy_of_blueberry
   old manage_afterClone copy_of_blueberry copy_of_blueberry
   [{'new_id': 'copy_of_blueberry', 'id': 'blueberry'}]
@@ -310,6 +319,7 @@
   old manage_beforeDelete copy_of_blueberry copy_of_blueberry folder
   ObjectMovedEvent myrtille
   old manage_afterAdd myrtille myrtille folder
+  ContainerModifiedEvent folder
 
 Old behavior with events for a clone::
 
@@ -318,6 +328,7 @@
   ObjectWillBeAddedEvent strawberry
   ObjectAddedEvent strawberry
   old manage_afterAdd strawberry strawberry folder
+  ContainerModifiedEvent folder
   ObjectClonedEvent strawberry
   old manage_afterClone strawberry strawberry
   >>> res.getId()
@@ -330,12 +341,14 @@
   ObjectWillBeAddedEvent luckyluke
   ObjectAddedEvent luckyluke
   old manage_afterAdd luckyluke luckyluke btfolder
+  ContainerModifiedEvent btfolder
   'luckyluke'
 
   >>> btfolder.manage_delObjects('luckyluke')
   ObjectWillBeRemovedEvent luckyluke
   old manage_beforeDelete luckyluke luckyluke btfolder
   ObjectRemovedEvent luckyluke
+  ContainerModifiedEvent btfolder
 
 Here is what happens for a tree of objects. Let's create a simple one::
 
@@ -344,6 +357,7 @@
   ObjectWillBeAddedEvent subfolder
   ObjectAddedEvent subfolder
   old manage_afterAdd subfolder subfolder folder
+  ContainerModifiedEvent folder
   'subfolder'
   >>> subfolder = folder.subfolder
   >>> ob = MyContent('donald')
@@ -351,6 +365,7 @@
   ObjectWillBeAddedEvent donald
   ObjectAddedEvent donald
   old manage_afterAdd donald donald subfolder
+  ContainerModifiedEvent subfolder
   'donald'
 
 Renaming a tree of objects. Note that manage_beforeDelete is called
@@ -365,6 +380,7 @@
   old manage_afterAdd pluto pluto folder
   ObjectMovedEvent donald
   old manage_afterAdd donald pluto folder
+  ContainerModifiedEvent folder
 
 Cloning a tree of objects::
 
@@ -376,6 +392,7 @@
   old manage_afterAdd mickey mickey folder
   ObjectAddedEvent donald
   old manage_afterAdd donald mickey folder
+  ContainerModifiedEvent folder
   ObjectClonedEvent mickey
   old manage_afterClone mickey mickey
   ObjectClonedEvent donald
@@ -393,9 +410,10 @@
   >>> app = MyApp('')
   >>> root['app'] = app
   >>> folder = MyNewFolder('folder')
-  >>> app._setObject('folder', folder)
+  >>> app._setObject('folder', folder) # doctest: +NORMALIZE_WHITESPACE
   ObjectWillBeAddedEvent folder
   ObjectAddedEvent folder
+  ContainerModifiedEvent
   'folder'
   >>> folder = app.folder
 
@@ -403,10 +421,12 @@
   >>> folder._setObject('dogbert', ob)
   ObjectWillBeAddedEvent dogbert
   ObjectAddedEvent dogbert
+  ContainerModifiedEvent folder
   'dogbert'
   >>> folder.manage_delObjects('dogbert')
   ObjectWillBeRemovedEvent dogbert
   ObjectRemovedEvent dogbert
+  ContainerModifiedEvent folder
 
 Now move::
 
@@ -414,11 +434,13 @@
   >>> folder._setObject('dilbert', ob)
   ObjectWillBeAddedEvent dilbert
   ObjectAddedEvent dilbert
+  ContainerModifiedEvent folder
   'dilbert'
   >>> cp = folder.manage_cutObjects('dilbert')
   >>> folder.manage_pasteObjects(cp)
   ObjectWillBeMovedEvent dilbert
   ObjectMovedEvent dilbert
+  ContainerModifiedEvent folder
   [{'new_id': 'dilbert', 'id': 'dilbert'}]
 
 And copy::
@@ -428,6 +450,7 @@
   ObjectCopiedEvent copy_of_dilbert
   ObjectWillBeAddedEvent copy_of_dilbert
   ObjectAddedEvent copy_of_dilbert
+  ContainerModifiedEvent folder
   ObjectClonedEvent copy_of_dilbert
   [{'new_id': 'copy_of_dilbert', 'id': 'dilbert'}]
 
@@ -436,6 +459,7 @@
   >>> folder.manage_renameObject('copy_of_dilbert', 'wally')
   ObjectWillBeMovedEvent copy_of_dilbert
   ObjectMovedEvent wally
+  ContainerModifiedEvent folder
 
 Or copy using manage_clone::
 
@@ -443,6 +467,7 @@
   ObjectCopiedEvent phb
   ObjectWillBeAddedEvent phb
   ObjectAddedEvent phb
+  ContainerModifiedEvent folder
   ObjectClonedEvent phb
   >>> res.getId()
   'phb'
@@ -453,13 +478,16 @@
   >>> btfolder._setObject('alice', ob)
   ObjectWillBeAddedEvent alice
   ObjectAddedEvent alice
+  ContainerModifiedEvent btfolder
   'alice'
   >>> btfolder.manage_renameObject('alice', 'rabbit')
   ObjectWillBeMovedEvent alice
   ObjectMovedEvent rabbit
+  ContainerModifiedEvent btfolder
   >>> btfolder.manage_delObjects('rabbit')
   ObjectWillBeRemovedEvent rabbit
   ObjectRemovedEvent rabbit
+  ContainerModifiedEvent btfolder
 
 Now for a tree of objects. Let's create a simple one::
 
@@ -467,12 +495,14 @@
   >>> folder._setObject('subfolder', subfolder)
   ObjectWillBeAddedEvent subfolder
   ObjectAddedEvent subfolder
+  ContainerModifiedEvent folder
   'subfolder'
   >>> subfolder = folder.subfolder
   >>> ob = MyNewContent('mel')
   >>> subfolder._setObject('mel', ob)
   ObjectWillBeAddedEvent mel
   ObjectAddedEvent mel
+  ContainerModifiedEvent subfolder
   'mel'
 
 Renaming a tree of objects::
@@ -482,6 +512,7 @@
   ObjectWillBeMovedEvent mel
   ObjectMovedEvent firefly
   ObjectMovedEvent mel
+  ContainerModifiedEvent folder
 
 Cloning a tree of objects::
 
@@ -491,6 +522,7 @@
   ObjectWillBeAddedEvent mel
   ObjectAddedEvent serenity
   ObjectAddedEvent mel
+  ContainerModifiedEvent folder
   ObjectClonedEvent serenity
   ObjectClonedEvent mel
   >>> res.getId()
@@ -503,23 +535,34 @@
   ObjectWillBeAddedEvent ofolder
   ObjectAddedEvent ofolder
   old manage_afterAdd ofolder ofolder
+  ContainerModifiedEvent
   'ofolder'
   >>> ob1 = MyNewContent('ob1')
   >>> ofolder._setObject('ob1', ob1)
   ObjectWillBeAddedEvent ob1
   ObjectAddedEvent ob1
+  ContainerModifiedEvent ofolder
   'ob1'
   >>> ob2 = MyNewContent('ob2')
   >>> ofolder._setObject('ob2', ob2)
   ObjectWillBeAddedEvent ob2
   ObjectAddedEvent ob2
+  ContainerModifiedEvent ofolder
   'ob2'
   >>> ofolder.manage_renameObject('ob1', 'ob4')
   ObjectWillBeMovedEvent ob1
   ObjectMovedEvent ob4
+  ContainerModifiedEvent ofolder
   >>> ofolder.objectIds()
   ['ob4', 'ob2']
 
+When subobjects are reordered, an event about the container is sent::
+
+  >>> ofolder.moveObjectsUp('ob2')
+  ContainerModifiedEvent ofolder
+  1
+  >>> ofolder.objectIds()
+  ['ob2', 'ob4']
 
 Now cleanup all the monkey patches::
 


More information about the z3-checkins mailing list