[Zope3-checkins] CVS: Zope3/src/zope/app/container - copy.py:1.2 configure.zcml:1.8 traversal.py:1.6 zopecontainer.py:1.9

Sidnei da Silva sidnei@x3ng.com.br
Tue, 11 Feb 2003 11:00:12 -0500


Update of /cvs-repository/Zope3/src/zope/app/container
In directory cvs.zope.org:/tmp/cvs-serv3664/src/zope/app/container

Modified Files:
	configure.zcml traversal.py zopecontainer.py 
Added Files:
	copy.py 
Log Message:
Merging paris-copypasterename-branch. Not very fun :(

=== Zope3/src/zope/app/container/copy.py 1.1 => 1.2 ===
--- /dev/null	Tue Feb 11 11:00:12 2003
+++ Zope3/src/zope/app/container/copy.py	Tue Feb 11 10:59:41 2003
@@ -0,0 +1,164 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from zope.app.interfaces.container import IOptionalNamesContainer
+from zope.app.interfaces.container import IContainerNamesContainer
+from zope.app.interfaces.container import IMoveSource
+from zope.app.interfaces.container import ICopySource
+from zope.app.interfaces.container import IPasteTarget
+from zope.app.interfaces.container import IPasteNamesChooser
+from zope.component import getAdapter
+from zope.proxy.introspection import removeAllProxies
+from zope.app.event.objectevent import ObjectModifiedEvent
+from zope.proxy.context import ContextWrapper
+from zope.app.event import publish
+from types import StringTypes
+
+class PasteTarget:
+
+    __implements__ = IPasteTarget
+
+    def __init__(self, container):
+        self.context = container
+
+    def acceptsObject(self, 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.
+        '''
+        container = self.context
+        nameschooser = getAdapter(container, IPasteNamesChooser)
+        key = nameschooser.getNewName(obj, key)
+        if key in container:
+            return False
+        return True
+        
+        
+    def pasteObject(self, 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 manage_afterAdd hook of the object.
+        However, it must publish an IObjectModified event for the
+        container.
+        '''
+        if not isinstance(key, StringTypes):
+            raise TypeError("Item name is not a string.")
+
+        container = self.context
+
+        if not key:
+            if not (IOptionalNamesContainer.isImplementedBy(container)
+                    or IContainerNamesContainer.isImplementedBy(container)):
+                raise ValueError("Empty names are not allowed")
+
+        # We remove the proxies from the object before adding it to
+        # the container, because we can't store proxies.
+        obj = removeAllProxies(obj)
+
+        nameschooser = getAdapter(container, IPasteNamesChooser)
+        key = nameschooser.getNewName(obj, key)
+
+        # Add the object
+        key = container.setObject(key, obj)
+
+        # we dont publish the added event here
+        # and dont call the after add hook
+
+        publish(container, ObjectModifiedEvent(container))
+        return key
+        
+class MoveSource:
+
+    __implements__ = IMoveSource
+
+    def __init__(self, container):
+        self.context = container
+          
+    def removeObject(self, 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 manage_afterDelete method of the object.
+        However, it must publish an IObjectModified event for the
+        container.
+        '''
+        container = self.context
+ 
+        object = container[key]
+        object = ContextWrapper(object, container, name=key)
+
+        # here, we dont call the before delete hook
+        del container[key]
+
+        # and we dont publish an ObjectRemovedEvent
+        publish(container, ObjectModifiedEvent(container))
+
+        return object
+
+class CopySource:
+
+    __implements__ = ICopySource
+
+    def __init__(self, container):
+        self.context = container
+
+    def copyObject(self, 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.
+        '''
+        value = self.context.get(key, None)
+        if value is not None:
+            return ContextWrapper(value, self.context, name=key)
+        
+class PasteNamesChooser:
+
+    __implements__ = IPasteNamesChooser
+
+    def __init__(self, container):
+        self.context = container
+
+    def getNewName(self, obj, key):
+        '''See IPasteNamesChooser'''
+        new_key = key
+        container = self.context
+
+        if key not in container:
+            return key
+
+        n = 1 
+        while new_key in container:
+            if n > 1:
+                new_key = 'copy%s_of_%s' % (n, key)
+            else:
+                new_key = 'copy_of_%s' % key
+            n += 1
+        return new_key


=== Zope3/src/zope/app/container/configure.zcml 1.7 => 1.8 ===
--- Zope3/src/zope/app/container/configure.zcml:1.7	Fri Feb  7 10:48:40 2003
+++ Zope3/src/zope/app/container/configure.zcml	Tue Feb 11 10:59:41 2003
@@ -38,7 +38,36 @@
            provides="zope.app.interfaces.size.ISized"
            for="zope.app.interfaces.container.IContainer" 
            />
+
+  <adapter 
+     provides="zope.app.interfaces.container.ICopySource"
+     for="zope.app.interfaces.content.folder.IFolder"
+     permission="zope.ManageContent" 
+     factory="zope.app.container.copy.CopySource" 
+     />
+
+  <adapter 
+     provides="zope.app.interfaces.container.IMoveSource"
+     for="zope.app.interfaces.content.folder.IFolder"
+     permission="zope.ManageContent" 
+     factory="zope.app.container.copy.MoveSource" 
+     />
+
+  <adapter 
+     provides="zope.app.interfaces.container.IPasteTarget"
+     for="zope.app.interfaces.content.folder.IFolder"
+     permission="zope.ManageContent" 
+     factory="zope.app.container.copy.PasteTarget" 
+     />
            
+  <adapter 
+     provides="zope.app.interfaces.container.IPasteNamesChooser"
+     for="zope.app.interfaces.content.folder.IFolder"
+     permission="zope.ManageContent" 
+     factory="zope.app.container.copy.PasteNamesChooser" 
+     />
+
+
   <event:subscribe 
       subscriber = ".dependency.CheckDependency"
       event_types = "zope.app.interfaces.event.IObjectRemovedEvent"


=== Zope3/src/zope/app/container/traversal.py 1.5 => 1.6 ===


=== Zope3/src/zope/app/container/zopecontainer.py 1.8 => 1.9 ===
--- Zope3/src/zope/app/container/zopecontainer.py:1.8	Mon Feb  3 12:13:48 2003
+++ Zope3/src/zope/app/container/zopecontainer.py	Tue Feb 11 10:59:41 2003
@@ -28,13 +28,7 @@
             ObjectMovedEvent
 from zope.app.interfaces.container import IAddNotifiable
 from zope.app.interfaces.container import IDeleteNotifiable
-from zope.app.interfaces.container import IMoveNotifiable
-from zope.app.interfaces.container import IMoveSource
-from zope.app.interfaces.container import IPasteTarget
-from zope.app.interfaces.container import IPasteTarget
-from zope.app.interfaces.container import IContainerCopyPasteMoveSupport
 from zope.app.interfaces.copy import IObjectMover
-from zope.app.interfaces.traversing import IPhysicallyLocatable
 from types import StringTypes
 from zope.proxy.introspection import removeAllProxies
 
@@ -42,7 +36,7 @@
 
 class ZopeContainerAdapter:
 
-    __implements__ =  (IZopeContainer, IContainerCopyPasteMoveSupport)
+    __implements__ = IZopeContainer
 
     def __init__(self, container):
         self.context = container
@@ -180,27 +174,16 @@
         object = self.get(currentKey)
         mover = getAdapter(object, IObjectMover)
         container = self.context
-        target = getAdapter(container, IPasteTarget)
-
+        target = container
+        
         if mover.moveable() and mover.moveableTo(target, newKey):
-            physical = getAdapter(container, IPhysicallyLocatable)
-            target_path = physical.getPhysicalPath()
-
-            if queryAdapter(object, IMoveNotifiable):
-              object.manage_beforeDelete(object, container, \
-              movingTo=target_path)
-            elif queryAdapter(object, IDeleteNotifiable):
-              object.manage_beforeDelete(object, container)
 
-            source = getAdapter(container, IMoveSource)
-            object = source.removeObject(currentKey, target_path)
+            # the mover will call manage_beforeDelete hook for us
 
             mover = getAdapter(object, IObjectMover)
             mover.moveTo(target, newKey)
-          
-            publish(container, ObjectMovedEvent(object))
-
-
 
+            # the mover will call the manage_afterAdd hook for us
+            # the mover will publish an ObjectMovedEvent for us