[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Folder - Folder.py:1.1.2.1 FolderAdder.py:1.1.2.1 FolderContents.py:1.1.2.1 RootFolder.py:1.1.2.1 __init__.py:1.1.2.1 add.pt:1.1.2.1 add_confirmed.pt:1.1.2.1 main.pt:1.1.2.1 remove_confirmed.pt:1.1.2.1

Stephan Richter srichter@cbu.edu
Sat, 19 Jan 2002 23:57:32 -0500


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

Added Files:
      Tag: Zope-3x-branch
	Folder.py FolderAdder.py FolderContents.py RootFolder.py 
	__init__.py add.pt add_confirmed.pt main.pt 
	remove_confirmed.pt 
Log Message:
- Restructuring the directory structure in Zope.App.OFS
- Added a simple Image support including two views

NOTE: The ImageData.tag() method does not work yet, since absolute_url is 
      not implemented yet.


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/Folder.py ===
# 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.
# 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.

from Zope.App.OFS.IContainer import IContainer
import Persistence
from Zope.App.Security.IAttributeRolePermissionManageable \
     import IAttributeRolePermissionManageable


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

_RAISE_KEYERROR = []

class Folder(Persistence.Persistent):
    """The standard Zope Folder implementation."""

    __implements__ = IFolder, IAttributeRolePermissionManageable

    def __init__(self):
        # XXX - fix this to use a btree when persistence is online.
        self.data = {}

    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. If no default is
           given and the object is not found a KeyError is raised."""
        object = self.data.get(name, default)
        if object is _RAISE_KEYERROR:
            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 = self.data      # Signal a change to Persistence
        self.data[name] = object

    def delObject(self, name):
        """Delete the named object from the folder. Raises a KeyError
           if the object is not found."""
        self.data = self.data      # Signal a change to Persistence
        del self.data[name]






=== Added File Zope3/lib/python/Zope/App/OFS/Folder/FolderAdder.py ===
# 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.
# 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.

"""
    Define adder component for folders.
"""

import os

from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile
from Zope.App.ZMI.Addable import getAddables
from Zope.ComponentArchitecture import createObject

class FolderAdderError( Exception ):
    pass

class DuplicateIDError( FolderAdderError ):
    pass


class FolderAdder( AttributePublisher ):

    __implements__ = AttributePublisher.__implements__
    
    def __init__( self, folder ):
        self._folder = folder

    def _extractAdderInfo( self, addable ):
        info = {}
        info['id'] = addable.id
        info[ 'title' ] = addable.title
        info[ 'desc' ] = addable.description

        # XXX:  We will fake this stuff out for now
        info['icon'] = None

        return info


    def listAddableInfo( self ):
        """
            Return a sequence of mappings for the addables for our
            folder.
        """
        return map( self._extractAdderInfo, getAddables( self._folder ) )


    def action( self, id, type_name, REQUEST=None):
        """
            Instantiate an object and put it in our folder.
        """
        if id in self._folder.objectIds():
            raise DuplicateIDError, "ID '%s' already in use." % id
        self._folder.setObject( id, createObject( self._folder, type_name ) )

        # XXX:  This is horribly broken, but I can't do better until
        #       we have a way to compute absolute URLs.
        if REQUEST is not None:
            # for unit tests
            REQUEST['RESPONSE'].redirect(REQUEST['URL2'])
        return self.confirmed( type_name=type_name, id=id )


    #
    #   Make it possible for 'index' to find the folder.
    #
    def getContext( self ):
        return self._folder

    index = PageTemplateFile('add.pt')
    confirmed = PageTemplateFile('add_confirmed.pt')


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/FolderContents.py ===
# 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.
# 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.

"""
    Define view component for folder contents.
"""

import os

from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.Publisher.Browser.IBrowserPublisher import IBrowserPublisher
from Zope.PageTemplate.PageTemplateFile import PageTemplateFile

class FolderContents( AttributePublisher ):

    __implements__ = AttributePublisher.__implements__
    
    def __init__( self, folder ):
        self._folder = folder


    def _extractContentInfo( self, item ):
        info = {}
        info['id'] = item[0]
        info['object'] = item[1]

        # XXX:  We will fake this stuff out for now
        info[ 'title' ] = info[ 'url' ] = item[0]
        info['icon'] = None

        return info


    def removeObjects(self, ids, REQUEST=None):
        """ """
        for id in ids:
            self.remove(id)

        # XXX:  This is horribly broken, but I can't do better until
        #       we have a way to compute absolute URLs.
        if REQUEST is not None:
            # for unit tests
            REQUEST['RESPONSE'].redirect(REQUEST['URL1'])
        return self.confirmRemoved()
    

    def remove( self, name, silent=0 ):
        """
            Remove the object stored under 'name', or raise a KeyError
            if no such object (pass non-zero 'silent' to suppress the
            exception).
        """
        try:
            self.getContext().delObject( name )
        except KeyError:
            if not silent:
                raise
        return self.confirmRemoved( name=name )

    def listContentInfo( self ):
        
        return map( self._extractContentInfo, self._folder.objectItems() )

    #
    #   Make it possible for 'index' to find the folder.
    #
    def getContext( self ):
        return self._folder

    index = PageTemplateFile('main.pt')
    confirmRemoved = PageTemplateFile('remove_confirmed.pt')


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/RootFolder.py ===
# Copyright (c) 2001 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.
# 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.

from Folder import IFolder, Folder


class IRootFolder(IFolder):
    """The standard Zope root Folder object interface."""


class RootFolder(Folder):
    """The standard Zope root Folder implementation."""

    __implements__ = IRootFolder

    def __call__(self, URL):
        return 'You have reached the wrong number (but the right ' \
               'object!). Please try again later.'


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/__init__.py ===


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/add.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
.TypeListing {
    width: 100%;
}

.Selector {
    width: 10px;
}

.TypeIcon {
    width: 20px;
}

.TypeName {
    text-align: left;
}

.TypeDescription {
    text-align: left;
    font-style: italic;
}
</style>
</head>
<body>

<div metal:fill-slot="body">

<form action="action.html" method="POST">
<table class="TypeListing">

  <caption>Add Content To Folder</caption>

    <tr>
      <td class="Selector"><br /></td>
      <th class="TypeName">Title</th>
    </tr>

    <!--
      ** listAddableInfo returns a sequence of mappings, containing:
      **   'id'    : the ID of the addable type
      **   'title' : the title of the addable type
      **   'desc'  : the description of the addable type
      **   'icon'  : the absolute URL of the icon, for the addable type
                     (may be None)
      -->
    <tbody tal:repeat="info container/listAddableInfo">

    <tr>

      <td class="Selector">
        <input type="radio" name="type_name"
               tal:attributes="value info/id" />
      </td>

      <td class="TypeName">
        <img alt="Folder" src="../../ZMI/www/folder_icon.gif"
             tal:condition="info/icon"
             tal:attributes="src info/icon" />
        <span tal:replace="info/title">Folder</span>
      </td>

    </tr>

    <tr>
      <td class="Selector"><br /></td>
      <td class="TypeDescription" tal:content="info/desc">
          Folders are generic containers for content, including other
          folders.
      </td>
    </tr>

  </tbody>

  <tbody tal:condition="nothing">

    <tr>

      <td class="Selector">
        <input type="radio" name="type_name" value="" />
               
      </td>

      <td class="TypeName">
        <img alt="Folder" src="../../ZMI/www/document_icon.gif" />
        Document
      </td>

    </tr>

    <tr>
      <td class="Selector"><br /></td>
      <td class="TypeDescription">
          Documents are simple textual content.
      </td>
    </tr>

  </tbody>

  <tr>
    <td><br/></td>
    <td><input type="text" name="id" />
        <input type="submit" value=" Add " />
    </td>
  </tr>

</table>
</form>
</div>
</body>
</html>


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/add_confirmed.pt ===
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
      metal:use-macro="presentation/standard_macros/html">
  -->
<body>

<p> Object added successfully. </p>

</body>
</html>


=== Added File Zope3/lib/python/Zope/App/OFS/Folder/main.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
<!--
.ContentListing {
    width: 100%;
}

.ContentIcon {
    width: 20px;
}

.ContentTitle {
    text-align: left;
}
-->
</style>
</head>
<body>
<div metal:fill-slot="body">

<form action="contents;view" method="get">
  <table class="ContentListing">
  
    <caption>Folder Contents <a href="adder;view"> Add... </a> </caption>
  
    <tbody>
  
      <tr>
	<td class="ContentIcon"><br /> </td>
	<th class="ContentTitle">Title</th>
      </tr>
  
      <!--
	** listContentInfo returns a sequence of mappings, containing:
	**   'id'    : the ID of the contained within the container
	**   'url'   : the absolute URL of the contained object
	**   'title' : the title of the contained object
	**   'icon'  : the absolute URL of the icon, for the contained object
		       (may be None)
	-->
      <tr tal:repeat="info container/listContentInfo">
  
	<td class="ContentSelect">
	  <input type="checkbox" name="ids:list" value="id"
		 tal:attributes="value info/id" />
	</td>
  
	<td class="ContentIcon">
	  <img alt="Folder" src="../../ZMI/www/folder_icon.gif"
	       tal:condition="info/url"
	       tal:attributes="src info/url" />
	</td>
  
	<td class="ContentTitle">
	  <a href="subfolder_id"
	     tal:attributes="href info/url"
	     tal:content="info/title"
	  >Folder Title or ID here</a>
	</td>
  
      </tr>
  
      <tr tal:condition="nothing">
  
	<td class="ContentIcon">
	  <img alt="Document" src="../../ZMI/www/document_icon.gif" />
	</td>
  
	<td class="ContentTitle">
	   <a href="document_id">Document Title or ID here</a>
	</td>
  
      </tr>
    </tbody>
  
  </table>
  <br />

  <input type="submit" name="removeObjects:method" value="Delete"
         i18n:attributes="value string:menu_delete_button"> 
</form>

</div>
</body>
</html>






=== Added File Zope3/lib/python/Zope/App/OFS/Folder/remove_confirmed.pt ===
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
      metal:use-macro="presentation/standard_macros/html">
  -->
<body>

<p> Object(s) removed successfully. </p>

</body>
</html>