[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