[Zope3-checkins] CVS: Zope3/src/zope/app/interfaces -
container.py:1.3.2.2 copypastemove.py:1.6.24.1 event.py:1.10.20.1
Jim Fulton
jim at zope.com
Fri Sep 12 15:16:00 EDT 2003
Update of /cvs-repository/Zope3/src/zope/app/interfaces
In directory cvs.zope.org:/tmp/cvs-serv13470/src/zope/app/interfaces
Modified Files:
Tag: parentgeddon-branch
container.py copypastemove.py event.py
Log Message:
Can't have the tests passing, can we?
=== Zope3/src/zope/app/interfaces/container.py 1.3.2.1 => 1.3.2.2 ===
--- Zope3/src/zope/app/interfaces/container.py:1.3.2.1 Mon Sep 8 14:21:21 2003
+++ Zope3/src/zope/app/interfaces/container.py Fri Sep 12 15:15:29 2003
@@ -16,7 +16,7 @@
$Id$
"""
-from zope.interface import Interface, Attribute
+from zope.interface import Interface, Attribute, implements
from zope.component.interfaces import IView
from zope.interface.common.mapping import IItemMapping
from zope.interface.common.mapping import IReadMapping, IEnumerableMapping
@@ -49,19 +49,12 @@
class IWriteContainer(Interface):
"""An interface for the write aspects of a container."""
- def setObject(key, object):
+ def __setitem__(key, object):
"""Add the given object to the container under the given key.
The container might choose to add a different object than the
one passed to this method.
- Raises a ValueError if key is an empty string, unless the
- container chooses a different key.
-
- Raises a TypeError if the key is not a unicode or ascii string.
-
- Returns the key used, which might be different than the given key.
-
If the object doesn't implement IContained, then one of two
things must be done:
@@ -111,6 +104,29 @@
##############################################################################
+# Moving Objects
+
+class IObjectMovedEvent(IObjectEvent):
+ """An object has been moved"""
+
+ oldParent = Attribute("The old location parent for the object.")
+ oldName = Attribute("The old location name for the object.")
+ newParent = Attribute("The new location parent for the object.")
+ newName = Attribute("The new location name for the object.")
+
+class IMoveNotifiable(Interface):
+ """Interface for notification of being deleted, added, or moved."""
+
+ def moveNotify(event):
+ """Notify of a move event
+
+ This is called after the object has been added to the new
+ location and before it has been deleted from the old.
+
+ """
+
+
+##############################################################################
# Adding objects
class UnaddableError(ContainerError):
@@ -125,7 +141,15 @@
return ("%(obj)s cannot be added "
"to %(container)s%(message)s" % self.__dict__)
-# See zope.app.interfaces.event.IObjectAddedEvent
+class IObjectAddedEvent(IObjectMovedEvent):
+ """An object has been added to a container."""
+
+class IAddNotifiable(Interface):
+ """Interface for notification of being added."""
+
+ def addNotify(event):
+ """Hook method will call after an object is added to container.
+ """
class IAdding(IView):
@@ -158,202 +182,32 @@
decide what page to display after content is added.
"""
-class IAddNotifiable(Interface):
- """Interface for notification of being added."""
-
- def afterAddHook(object, container):
- """Hook method will call after an object is added to container."""
-
-
-class IAddTarget(Interface):
-
- def acceptsObject(key, obj):
- '''Allow the container to say if it accepts the given object.
-
- Returns True if the object would be accepted as contents of
- this container. Otherwise, returns False.
- '''
-
- def addObject(key, obj):
- '''Add the given object to the container under the given key.
-
- Raises a ValueError if key is an empty string, unless the
- this object chooses a different key.
-
- Returns the key used, which might be different than the
- given key.
+class INameChooser(Interface):
- This method must issue an IObjectAddedEvent, and it must
- call the afterAddHook hook of the object.
- It must publish an IObjectModified event for the
- container.
- '''
+ def checkName(name, object):
+ """Check whether an object name is valid.
-class INameChooser(Interface):
+ Raise a user error if the name is not valid.
+ """
def chooseName(name, object):
- """Choose a name for the object
+ """Choose a unique valid name for the object
The given name and object may be taken into account when
choosing the name.
"""
-class IPasteTarget(Interface):
-
- def acceptsObject(key, obj):
- '''Allow the container to say if it accepts the given wrapped object.
-
- Returns True if the object would be accepted as contents of
- this container. Otherwise, returns False.
- '''
-
- def pasteObject(key, obj):
- '''Add the given object to the container under the given key.
-
- Raises a ValueError if key is an empty string, unless the
- this object chooses a different key.
-
- Returns the key used, which might be different than the
- given key.
-
- This method must not issue an IObjectAddedEvent, nor must it
- call the afterAddHook hook of the object.
- However, it must publish an IObjectModified event for the
- container.
- '''
-
-class IPasteNamesChooser(Interface):
- """Containers automatically chooses a new name for the object if the
- given one is already choosen.
- """
-
- def getNewName(obj, key):
- """ Should return a choosen name based on object and key to be used
- for pasting. This may not be reliable all the time as
- the name you choose is not guaranteed to be reserved between the time
- you get it and the time you paste the object, so be careful."""
-
+##############################################################################
# Removing objects
-class IObjectRemovedEvent(IObjectEvent):
+class IObjectRemovedEvent(IObjectMovedEvent):
"""An object has been removed from a container"""
- fromLocation = Attribute("The old location for the object.")
-
-class IDeleteNotifiable(Interface):
+class IRemoveNotifiable(Interface):
"""Interface for notification of being deleted."""
- def beforeDeleteHook(object, container):
+ def removeNotify(object, container):
"""Hook method will call before object is removed from container."""
-
-class IRemoveSource(Interface):
-
- def removeObject(key):
- '''Remove the object with the given key
-
- This method should publish an IObjectRemovedEvent, and should
- call the afterDeleteHook method of the object.
- It must publish an IObjectModified event for the container.
- '''
-
-# Copying objects
-
-class ICopyNotifiable(IAddNotifiable):
-
- def afterAddHook(object, container, copiedFrom=None):
- """Hook method. Will be called after an object is added to a
- container.
-
- If the object is being copied, 'copiedFrom' will
- be the unicode path the object was copied from.
-
- If the object is simply being added and not being copied,
- 'copiedFrom' will be None.
-
- Clients calling this method must be careful to use
- 'copiededFrom' as a keyword argument rather than a positional
- argument, to avoid confusion if the object is both
- IMoveNotifiable and ICopyNotifiable. """
-
-
-class CopyException(Exception):
- """An error that occurred within a copy operation."""
-
- def __init__(self, container, key, message=""):
- self.container = container
- self.key = key
- self.message = message and ": %s" % message
-
- def __str__(self):
- return ("%(key)s cannot be copied "
- "from %(container)s%(message)s" % self.__dict__)
-
-class ICopySource(Interface):
-
- def copyObject(key, copyingTo):
- '''Return the object with the given key, as the first part of a
- copy.
-
- copyingTo is the unicode path for where the copy is to.
- '''
-
-class INoChildrenCopySource(ICopySource):
-
- def copyObjectWithoutChildren(key, copyingTo):
- '''Return the object with the given key, without any children,
- as the first part of a copy.
-
- copyingTo is the unicode path for where the copy is to.
-
- May return None if its not possible to get a copy without children.
- '''
-
-# Moving Objects
-
-class MoveException(Exception):
- """An error that occurred within a move operation."""
-
- def __init__(self, container, key, message=""):
- self.container = container
- self.key = key
- self.message = message and ": %s" % message
-
- def __str__(self):
- return ("%(key)s cannot be copied "
- "from %(container)s%(message)s" % self.__dict__)
-
-class IMoveNotifiable(IDeleteNotifiable, IAddNotifiable):
- """Interface for notification of being deleted, added, or moved."""
-
- def beforeDeleteHook(object, container, movingTo=None):
- """Hook method will call before object is removed from container.
-
- If the object is being moved, 'movingTo' will be the unicode path
- the object is being moved to.
- If the object is simply being deleted and not being moved, 'movingTo'
- will be None.
- """
-
- def afterAddHook(object, container, movedFrom=None):
- """Hook method will call after an object is added to container.
-
- If the object is being moved, 'movedFrom' will be the unicode path
- the object was moved from.
- If the object is simply being added and not being moved, 'movedFrom'
- will be None.
- """
-
-class IMoveSource(Interface):
-
- def removeObject(key, movingTo):
- '''Remove and return the object with the given key, as the
- first part of a move.
-
- movingTo is the unicode path for where the move is to.
- This method should not publish an IObjectRemovedEvent, nor should
- it call the afterDeleteHook method of the object.
- However, it must publish an IObjectModified event for the container.
- '''
=== Zope3/src/zope/app/interfaces/copypastemove.py 1.6 => 1.6.24.1 ===
--- Zope3/src/zope/app/interfaces/copypastemove.py:1.6 Fri Jun 13 13:41:18 2003
+++ Zope3/src/zope/app/interfaces/copypastemove.py Fri Sep 12 15:15:29 2003
@@ -13,185 +13,6 @@
##############################################################################
"""Copy and Move support
-XXX The theory is unclear about whether copy and move are about
- containers or not. Many of the relevent interfaces are in
- zope.app.interfaces.container, even though they are supposed not
- to be indepenent of IContainer.
-
- Perhaps we should just say that this is about containers and move
- these interfaces there.
-
-
-Problem
-
- Zope 3 needs to support three kinds of cut/copy/paste behaviour.
-
- * Renaming an object to a different name in the same container.
-
- * Moving an object from one place to another.
-
- * Copying an object to another place.
-
- The design for this needs to provide the right capabilities and
- introspection to the user-interface. The appropriate events need
- to be issued. The appropriate hooks, such as IDeleteNotifiable,
- need to be called.
-
-
-Approach
-
- Events and hooks
-
- First, I need to explain events and hooks.
-
- When an object is added to a container, if the object has an
- IAddNotifiable adapter, that adapter's 'manage_afterAdd' method
- is called. Then, an IObjectAddedEvent is published for the object.
- Then an IObjectModifiedEvent is published for the container.
-
- When an object is removed from a container, if the object has an
- IDeleteNotifiable adapter, that adapter's 'manage_beforeDelete' method
- is called. Then, an IObjectRemovedEvent is published for the object.
- Then an IObjectModifiedEvent is published for the container.
-
- When an object gets moved, it is a bit like being deleted and then added.
- For many kinds of things you'd want to do in manage_afterAdd and
- manage_beforeDelete, it is entirely appropriate to do these things
- when an object is moved. However, in other cases you want special
- behaviour on a move. So, IMoveNotifiable extends both IDeleteNotifiable
- and IAddNotifiable, adds no further methods, but extends the method
- signatures. This avoids the problem of an object that needs to be
- notified of moves and of deletes, and do something different in each
- case.
-
- See zope.app.interrfaces.container.IMoveNotifiable and
- zope.app.interrfaces.container.ICopyNotifiable.
-
- The IZopeContainerAdapter is responsible for calling the hooks and
- sending the events when you add or remove things from a container.
-
- Renaming
-
- Renaming an object is performed by moving it.
-
- The ZopeContainerAdapter should be extended with a 'rename' method
- for renaming an object in a container. This will be used by the
- simple UI gesture for renaming something.
-
- The rename method looks like this::
-
- def rename(currentKey, newKey):
- '''Put the object found at 'currentKey' under 'newKey' instead.
-
- The container can choose different or modified 'newKey'. The
- 'newKey' that was used is returned.
-
- If the object at 'currentKey' is IMoveNotifiable, its
- manage_beforeDelete method is called, with a movingTo
- argument of the container's path plus the 'newKey'.
- Otherwise, if the object at 'currentKey' is IDeleteNotifiable,
- its manage_beforeDelete method is called.
-
- Then, the object is removed from the container using the
- container's __del__ method.
-
- Then, If the object is IMoveNotifiable, its manage_afterAdd
- method is called, with a movedFrom argument of the container's
- path plus the 'currentKey'.
- Otherwise, if the object is IAddNotifiable, its manage_afterAdd
- method is called.
-
- Then, an IObjectMovedEvent is published.
- '''
-
- Note that zope.app.interfaces.event.IObjectMovedEvent extends
- both zope.app.interfaces.event.IObjectRemovedEvent and
- zope.app.interfaces.event.IObjectAddedEvent.
-
- Similarly zope.app.interfaces.event.IObjectCopiedEvent extends
- should be made to IObjectAddedEvent.
-
- Moving and copying
-
- IObjectMover is what you adapt an object to when you want to move
- it. The adapter is responsible for calling the manage_beforeDelete and
- manage_afterAdd methods on an I(Add|Delete|Move)Notifiable adapter of
- the object, as described above.
- The IObjectMover adapter is also responsible for publishing an
- IObjectMoved event in the context of the original container.
-
- The 'moveTo()' method will get hold of an IMoveSource for
- the object's container, and an IPasteTarget for the container the object
- is being moved to.
-
- Likewise, IObjectCopier is what you adapt an object to when you want to
- copy it. The IObjectCopier adapter is responsible for calling a
- manage_afterAdd hook on an I(Add|Copy)Notifiable adapter of the object.
-
- The zope.app.interrfaces.container.IPasteTarget,
- zope.app.interrfaces.container.IMoveSource, and
- zope.app.interrfaces.container.ICopySource interfaces are designed
- to be independent of IContainer. Adapters will be available for
- IContainer, though. The idea is that it should be easy for
- non-container classes to implement copy and paste, without having to
- be containers.
-
- A zope.app.interrfaces.container.IPasteTarget adapter must be
- available for the object you want to copy or move something into.
-
- A zope.app.interrfaces.container.IMoveSource adapter must be
- available for an object you want to move something from.
-
- Similarly, a zope.app.interrfaces.container.ICopySource adapter must
- be available for an object you want to copy something from.
-
-Stepped out examples
-
- These examples are simplified, and assume things, such as that an
- IPasteTarget adapter is unconditionally available, and copying across
- databases is not supported.
-
- Copying the object at '/foo/bar/baz' to '/fish/tree/zab'
-
- Basic application code::
-
- obj = traverse(context, '/foo/bar/baz')
- target = traverse(context, '/fish/tree')
- copier = getAdapter(obj, IObjectCopier)
- if copier.copyableTo(target, 'zab'):
- copier.copy(target, 'zab')
-
- Inside the 'copier.copyableTo()' method::
-
- def copyableTo(self, target, name=None):
- obj = self.context
- if name is None:
- name = getName(obj)
- pastetarget = getAdapter(target, IPasteTarget)
- return pastetarget.acceptsObject(name, obj)
-
- Inside the 'copier.copy()' method::
-
- def copy(self, target, name=None):
- obj = self.context
- if name is None:
- name = getName(obj)
- copysource = getAdapter(getParent(obj), ICopySource)
- obj = copysource.copyObject(name, target)
- pastetarget = getAdapter(target, IPasteTarget)
- new_obj = self._pickle_then_unpickle(obj)
- # publish an ObjectCreatedEvent (perhaps...?)
- new_name = pastetarget.pasteObject(name, new_obj)
- # call manage_afterAdd hook
- # publish ObjectCopiedEvent
- return new_name
-
- def _pickle_then_unpickle(self, obj):
- # Remove proxies from obj, pickle and then unpickle it.
- # Return the result. Or, something like that
- ....
-
-
$Id$
"""
@@ -240,27 +61,12 @@
False.
'''
-class INoChildrenObjectCopier(IObjectCopier):
- """Interface for adapters that can copy an containerish object
- without its children"""
-
- def copyTo(target, new_name=None):
- """Copy this object without chidren to the target given.
-
- Returns the new name within the target, or None
- if the target doesn't do names.
- Typically, the target is adapted to IPasteTarget.
- After the copy is added to the target container, publish
- an IObjectCopied event in the context of the target container.
- If a new object is created as part of the copying process, then
- an IObjectCreated event should be published.
- """
-
class IPrincipalClipboard(Interface):
'''Interface for adapters that store/retrieve clipboard information
for a principal.
- Clipboard information consists on tuples of {'action':action, 'target':target}.
+ Clipboard information consists on tuples of
+ {'action':action, 'target':target}.
'''
def clearContents():
=== Zope3/src/zope/app/interfaces/event.py 1.10 => 1.10.20.1 ===
--- Zope3/src/zope/app/interfaces/event.py:1.10 Wed Jun 25 11:20:37 2003
+++ Zope3/src/zope/app/interfaces/event.py Fri Sep 12 15:15:29 2003
@@ -275,15 +275,13 @@
object = Attribute("The subject of the event.")
- location = Attribute("An optional object location.")
-
class IObjectCreatedEvent(IObjectEvent):
"""An object has been created.
The location will usually be None for this event."""
-class IObjectAddedEvent(IObjectEvent):
- """An object has been added to a container."""
+class IObjectCopiedEvent(IObjectCreatedEvent):
+ """An object has been copied"""
class IObjectModifiedEvent(IObjectEvent):
"""An object has been modified"""
@@ -293,19 +291,6 @@
class IObjectContentModifiedEvent(IObjectModifiedEvent):
"""An object's content has been modified"""
-
-class IObjectRemovedEvent(IObjectEvent):
- """An object has been removed from a container"""
-
-class IObjectMovedEvent(IObjectRemovedEvent, IObjectAddedEvent):
- """An object has been moved"""
-
- fromLocation = Attribute("The old location for the object.")
-
-class IObjectCopiedEvent(IObjectAddedEvent):
- """An object has been copied"""
-
- fromLocation = Attribute("The old location for the object.")
class IDatabaseOpenedEvent(IEvent):
"""The main database has been opened."""
More information about the Zope3-Checkins
mailing list