[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Folder - FolderLimit.py:1.1.2.1 LoadedFolder.py:1.1.2.1 LoadedFolderFields.py:1.1.2.1 OrderedFolder.py:1.1.2.1 Folder.py:1.1.2.4.2.1 RootFolder.py:1.1.2.2.2.1 __init__.py:1.1.2.1.4.1 folder.zcml:1.1.2.4.2.1 FolderAdder.py:NONE FolderContents.py:NONE add.pt:NONE add_confirmed.pt:NONE main.pt:NONE remove_confirmed.pt:NONE

Stephan Richter srichter@cbu.edu
Fri, 1 Mar 2002 01:37:40 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Folder
In directory cvs.zope.org:/tmp/cvs-serv10334/Folder

Modified Files:
      Tag: srichter-OFS_Formulator-branch
	Folder.py RootFolder.py __init__.py folder.zcml 
Added Files:
      Tag: srichter-OFS_Formulator-branch
	FolderLimit.py LoadedFolder.py LoadedFolderFields.py 
	OrderedFolder.py 
Removed Files:
      Tag: srichter-OFS_Formulator-branch
	FolderAdder.py FolderContents.py add.pt add_confirmed.pt 
	main.pt remove_confirmed.pt 
Log Message:
Okay, I am finally ready to check this stuff in:

- Reorganized the internal directory structure of every content object. For
  each content object you have now a Views directory that contains further
  directories for different protocols, such as Browser (HTML), XUL, FTP ...

  Note: None of the directories is file-type, but functionality-based. It 
        is a bad idea to create directories for a particular file type, as
        it was common in Zope 2.

- Made Folder, File and Image forms Formulator-based. This allows us now to
  create forms for new protocols. such as XUL very quickly (often just a
  few lines of code). More to Formulator when it is being checked in.

- Cleaned up most files. Almost all files should have now the correct 
  license disclaimer.

- A new object called LoadedFolder was added. LoadedFolder currently 
  provides two new functionalities to folders:
    1. Ordering. You can change the order of the objects. This idea was 
       taking from the Zope 2 product OrderedFolders.
    2. Limit. You can specify the maximal amount of items the folder is 
       allowed to store. This idea was also taken from OrderedFolders.

  Note: Due to much rearranging during this development, there are no tests
        yet written for this. This needs to be done, before we merge with
        the Zoep-3x-branch again.

- Started XUL implementation of screens.

- Fixed some bugs I found lying around.


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/FolderLimit.py ===
##############################################################################
#
# 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: FolderLimit.py,v 1.1.2.1 2002/03/01 06:37:08 srichter Exp $
"""

from Zope.App.OFS.IContainerLimit import IContainerLimit


class FolderLimitExeededError(Exception):
    """Exception that is raised, when the limit of the folder was
       reached."""
    pass


class FolderLimit:
    """Implements a feature that allows to restrict the amount of items in
       a Folder.
    """

    __implements__ =  (IContainerLimit,)

    _limit = 1000

    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.IContainerLimit

    def setLimit(self, limit):
        '''See interface IContainerLimit'''
        self._limit = limit


    def getLimit(self):
        '''See interface IContainerLimit'''
        return self._limit


    def isLimitReached(self):
        '''See interface IContainerLimit'''
        if self.objectCount() >= self._limit:
            return 1
        else:
            return 0

    #
    ############################################################


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/LoadedFolder.py ===
##############################################################################
#
# 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: LoadedFolder.py,v 1.1.2.1 2002/03/01 06:37:08 srichter Exp $

Implemented LoadedFolder Functionality:

- Order Folder items
- Define a max amount of items possible

Todo Functionality:

- Define what content objects can be added (user)
  + add the option to the configuration zpt
  + how does the security work for this? like if this folder is
    created under a folder that doesnt allow images for example?
    so need to figure out how to get a list of "allowed" content
    objects.  also, will what can be added to this folder be
    static or dynamic in the sence of if security settings change
    will this folder know about it?
"""

from Folder import Folder, IFolder
from FolderLimit import FolderLimit, FolderLimitExeededError
from OrderedFolder import OrderedFolder
from Zope.App.Security.IAttributeRolePermissionManageable \
     import IAttributeRolePermissionManageable


class ILoadedFolder(IFolder):
    """The standard Zope Loaded Folder object interface."""



class LoadedFolder(Folder, FolderLimit, OrderedFolder):
    """Implements some nice additional features to the regular
       Folder.
    """

    __implements__ = (
        ILoadedFolder,
        IAttributeRolePermissionManageable,
        ) + \
        Folder.__implements__ + \
        FolderLimit.__implements__ + \
        OrderedFolder.__implements__


    # XXX Reimplementation of some of the IReadContainer API. Shrug.
    
    def objectIds(self):
        """Return a sequence-like object containing the names 
           associated with the objects that appear in the folder
        """
        return self._orderedIds


    def objectValues(self):
        """Return a sequence-like object containing the objects that
           appear in the folder.
        """
        result = []
        for id in self.objectIds():
            result.append(self.data[id])

        return tuple(result)


    def objectItems(self):
        """Return a sequence-like object containing tuples of the form
           (name, object) for the objects that appear in the folder.
        """
        result = []
        for id in self.objectIds():
            result.append((id, self.data[id]))

        return result


    # XXX Reimplementation of some of the IWriteContainer API. Shrug again.

    def setObject(self, name, object):
        """Add the given object to the folder under the given name."""
        if self.isLimitReached():
            raise FolderLimitExeededError, 'The folder\'s limit was exeeded.' 
        else:
            self.data[name] = object
            if name not in self._orderedIds:
                self._orderedIds += (name,)


    def delObject(self, name):
        """Delete the named object from the folder. Raises a KeyError
           if the object is not found."""
        del self.data[name]
        ids = list(self._orderedIds)
        ids.remove(name)
        self._orderedIds = tuple(ids)


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/LoadedFolderFields.py ===
##############################################################################
#
# 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: LoadedFolderFields.py,v 1.1.2.1 2002/03/01 06:37:08 srichter Exp $
"""


from Zope.App.Formulator import getField


LimitField = getField('IntegerField')(
    id='limit',
    title='Limit',
    description='Limit of objects in the container.',
    start=1,
    default=1000 )


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/OrderedFolder.py ===
##############################################################################
#
# 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: OrderedFolder.py,v 1.1.2.1 2002/03/01 06:37:08 srichter Exp $

"""

from Zope.App.OFS.IOrderedContainer import IOrderedContainer
from types import StringType


class OrderedFolder:
    """Adds the Ordering Feature to a Folder
    """

    __implements__ =  (IOrderedContainer,)

    _orderedIds = ()


    def moveObjectsByPositions(self, ids, positionDelta):
        """ """

        if type(ids) is StringType:
            ids = (ids,)

        # Interestingly enough, we need to switch the order when
        # moving, so that the movements won't cancel each
        # other
        if positionDelta > 0:
            ids = list(ids)
            ids.reverse()
            
        moved_objects = 0
        
        for id in ids:
            old_position = self.getObjectPosition(id)
            new_position = old_position + positionDelta
            # Make sure the new position makes sense and is valid
            if not (old_position == new_position  or
                    new_position > self.objectCount() or
                    new_position < 0):
                
                id_list = list(self._orderedIds)
                # now delete the entry ...
                id_list.remove(id)
                # ... and now add it again
                id_list.insert(new_position, id)
                self._orderedIds = tuple(id_list)

                moved_objects += 1

        return moved_objects


    ############################################################
    # Implementation methods for interface
    # Zope.App.OFS.IOrderedContainer

    def getObjectPosition(self, id):
        '''See interface IOrderedContainer'''

        if id in self._orderedIds:
            return list(self._orderedIds).index(id)
        else:
            # If the object was not found, throw an error.
            # Yeah, that is good raise 'ObjectNotFound',
            raise ( 'ObjectNotFound',
                    'The object named %s was not found.' %id)


    def moveObjectsDown(self, ids):
        '''See interface IOrderedContainer'''
        return self.moveObjectsByPositions(ids, +1)


    def moveObjectsUp(self, ids):
        '''See interface IOrderedContainer'''
        return self.moveObjectsByPositions(ids, -1)


    def moveObjectsToTop(self, ids):
        '''See interface IOrderedContainer'''
        if type(ids) is StringType:
            ids = (ids,)

        position_delta = - self.getObjectPosition(ids[0])
        return self.moveObjectsByPositions(ids, position_delta)


    def moveObjectsToBottom(self, ids):
        '''See interface IOrderedContainer'''
        if type(ids) is StringType:
            ids = (ids,)

        # Whee, we will do the reverse twice, but for going to the bottom
        # there is no other choice.
        ids = list(ids)
        ids.reverse()

        position_delta = self.objectCount() - \
                         self.getObjectPosition(ids[-1]) - 1

        return self.moveObjectsByPositions(ids, position_delta)


    def moveObjectToPosition(self, id, position):
        '''See interface IOrderedContainer'''
        return self.moveObjectsByPositions(id,
                   position - self.getObjectPosition(id))

    #
    ############################################################



=== Zope3/lib/python/Zope/App/OFS/Folder/Folder.py 1.1.2.4 => 1.1.2.4.2.1 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors. 
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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.
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+$Id$
+"""
 
 from Zope.App.OFS.IContainer import IContainer
 import Persistence
@@ -18,11 +29,14 @@
 
 _marker = object()
 
+
 class IFolder(IContainer, IServiceManagerContainer):
     """The standard Zope Folder object interface."""
 
 _RAISE_KEYERROR = []
 
+
+
 class Folder(Persistence.Persistent, ServiceManagerContainer):
     """The standard Zope Folder implementation."""
 
@@ -33,27 +47,37 @@
 
     _service_manager = None
 
+
     def __init__(self):
+        """Initialize the Folder"""
         self.data = OOBTree()
 
+
+    ############################################################
+    # Implementation methods for interface
+    # Zope.App.OFS.Folder.Folder.IFolder
+
     def objectIds(self):
         """Return a sequence-like object containing the names 
            associated with the objects that appear in the folder
         """
         return self.data.keys()
 
+
     def objectValues(self):
         """Return a sequence-like object containing the objects that
            appear in the folder.
         """
         return self.data.values()
 
+
     def objectItems(self):
         """Return a sequence-like object containing tuples of the form
            (name, object) for the objects that appear in the folder.
         """
         return self.data.items()
 
+
     def getObject(self, name, default=_RAISE_KEYERROR):
         """Return the named object, or the value of the default 
            argument if given and the named object is not found.
@@ -65,22 +89,26 @@
             raise KeyError, name
         return object
 
+
     def hasObject(self, name):
         """Return true if the named object appears in the folder."""
         return self.data.has_key(name)
 
+
     def objectCount(self):
         """Return the number of objects in the folder."""
         return len(self.data)
 
+
     def setObject(self, name, object):
         """Add the given object to the folder under the given name."""
         self.data[name] = object
 
+
     def delObject(self, name):
         """Delete the named object from the folder. Raises a KeyError
            if the object is not found."""
         del self.data[name]
-
         
-
+    #
+    ############################################################


=== Zope3/lib/python/Zope/App/OFS/Folder/RootFolder.py 1.1.2.2 => 1.1.2.2.2.1 ===
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors. 
+# All Rights Reserved.
 # 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# 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.
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+Revision information: 
+$Id$
+"""
 
 from Folder import IFolder, Folder
 


=== Zope3/lib/python/Zope/App/OFS/Folder/__init__.py 1.1.2.1 => 1.1.2.1.4.1 ===
+#
+# 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
+# 
+##############################################################################
+"""
+
+$Id$
+"""


=== Zope3/lib/python/Zope/App/OFS/Folder/folder.zcml 1.1.2.4 => 1.1.2.4.2.1 ===
    xmlns:security='http://namespaces.zope.org/security'
    xmlns:zmi='http://namespaces.zope.org/zmi'
-   xmlns:browser='http://namespaces.zope.org/browser'
 >
 
-<zmi:provideClass name="Zope.App.OFS.Folder."
-                  permission_id="Zope.ManageContent"
-                  title="Son of Folder"
-                  description="Minimal folder" />
-
-<security:protectClass name="Zope.App.OFS.Folder.FolderContents."
-   permission_id="Zope.View" methods="index" />
-
-<browser:defaultView name="contents"
- for="Zope.App.OFS.Folder.Folder.IFolder."
- factory="Zope.App.OFS.Folder.FolderContents." />
-
-<security:protectClass name="Zope.App.OFS.Folder.FolderAdder."
-   permission_id="Zope.ManageContent" 
-   methods="index, confirmed, action, listAddableInfo" />
-
-<security:protectClass name="Zope.App.OFS.Folder."
-   permission_id="Zope.View">
-  <security:instances permission_id="Zope.View" />
-  <security:protect interface="Zope.ComponentArchitecture.IServiceManagerContainer." 
-	            permission_id="Zope.ManageServices" />
-</security:protectClass>
-
-
-<security:protectClass name="Zope.App.OFS.Folder.FolderContents."
-   permission_id="Zope.ManageContent" 
-   methods="index, listContentInfo, remove, removeObjects, confirmRemoved, addServiceManager"/>
-   
-
-
-<browser:view name="adder"
- for="Zope.App.OFS.Folder.Folder.IFolder."
- factory="Zope.App.OFS.Folder.FolderAdder." />
-
-<!-- tabs for folder -->
-
-<zmi:tabs for="Zope.App.OFS.Folder.Folder.IFolder.">
-  <zmi:tab label="Contents" action="contents;view"/>
-  <zmi:tab label="Role Permissions" action="RolePermissionsManagement;view"/>
-</zmi:tabs>
+  <!-- Simple Folder Directives -->
+
+  <zmi:provideClass name="Zope.App.OFS.Folder."
+                    permission_id="Zope.ManageContent"
+                    title="Son of Folder"
+                    description="Minimal folder" />
+
+  <security:protectClass name="Zope.App.OFS.Folder."
+     permission_id="Zope.View">
+    <security:instances permission_id="Zope.View" />
+    <security:protect interface="Zope.ComponentArchitecture.IServiceManagerContainer." 
+  	            permission_id="Zope.ManageServices" />
+  </security:protectClass>
+
+  <zmi:tabs for="Zope.App.OFS.Folder.Folder.IFolder.">
+    <zmi:tab label="Contents" action="contents;view"/>
+    <zmi:tab label="Role Permissions" action="RolePermissionsManagement;view"/>
+  </zmi:tabs>
+
+
+  <!-- Loaded Folder Directives -->
+
+  <zmi:provideClass name="Zope.App.OFS.Folder.LoadedFolder."
+                    permission_id="Zope.ManageContent"
+                    title="Loaded Folder"
+                    description="A Folder having all the goodies." />
+
+  <security:protectClass name="Zope.App.OFS.Folder.LoadedFolder."
+     permission_id="Zope.View">
+    <security:instances permission_id="Zope.View" />
+    <security:protect interface="Zope.ComponentArchitecture.IServiceManagerContainer." 
+  	            permission_id="Zope.ManageServices" />
+  </security:protectClass>
+
+  <zmi:tabs for="Zope.App.OFS.IContainerLimit.">
+    <zmi:tab label="Limit" action="limit;view"/>
+  </zmi:tabs>
+
+  <zmi:tabs for="Zope.App.OFS.Folder.LoadedFolder.ILoadedFolder.">
+    <zmi:tab label="Contents" action="contents;view"/>
+    <zmi:tab label="Role Permissions" action="RolePermissionsManagement;view"/>
+  </zmi:tabs>
+
+
+  <!-- Further Directives -->
+
+  <include package="Zope.App.OFS.Folder.Views" 
+           file="views.zcml" />
 
 </zopeConfigure>

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/FolderAdder.py ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/FolderContents.py ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/add.pt ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/add_confirmed.pt ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/main.pt ===

=== Removed File Zope3/lib/python/Zope/App/OFS/Folder/remove_confirmed.pt ===