[Zope3-checkins] CVS: Zope3/src/zope/app/interfaces -
copypastemove.py:1.7
Jim Fulton
jim at zope.com
Sun Sep 21 13:30:09 EDT 2003
Update of /cvs-repository/Zope3/src/zope/app/interfaces
In directory cvs.zope.org:/tmp/cvs-serv11813/src/zope/app/interfaces
Modified Files:
copypastemove.py
Log Message:
Refactored the copy/paste/move framework:
- Got rid of CopySource, MoveSource, and PasteTarget.
- The mover and copier no longer generate events. This is done by
containers.
- For now, allow moving copying between and only only between
containers with the same class. This will change when
http://dev.zope.org/Zope3/ContainmentConstraints is done.
- Use INameChooser to pick new names when moving or copying.
- The copier and mover have to remove security proxied before saving
in the container. This used to be done by the containment
decorator, so this is not a change of policy.
We need to think about the security model for copy and move.
- Got rid of the NoChildrenObjectCopier and associated interfaces and
adapters.
Simpified the container interface to use __setitem__ rather than
setObject.
Added a "rename" helper function.
=== Zope3/src/zope/app/interfaces/copypastemove.py 1.6 => 1.7 ===
--- Zope3/src/zope/app/interfaces/copypastemove.py:1.6 Fri Jun 13 13:41:18 2003
+++ Zope3/src/zope/app/interfaces/copypastemove.py Sun Sep 21 13:30:09 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():
More information about the Zope3-Checkins
mailing list