[Checkins] SVN: z3c.formdemo/ A collection of small demo applications for z3c.form and z3c.formui.

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu May 24 10:53:46 EDT 2007


Log message for revision 75942:
  A collection of small demo applications for z3c.form and z3c.formui. 
  Initial import.
  

Changed:
  A   z3c.formdemo/
  A   z3c.formdemo/branches/
  A   z3c.formdemo/tags/
  A   z3c.formdemo/trunk/
  A   z3c.formdemo/trunk/README.txt
  A   z3c.formdemo/trunk/bootstrap.py
  A   z3c.formdemo/trunk/buildout.cfg
  A   z3c.formdemo/trunk/setup.py
  A   z3c.formdemo/trunk/src/
  A   z3c.formdemo/trunk/src/z3c/
  A   z3c.formdemo/trunk/src/z3c/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/
  A   z3c.formdemo/trunk/src/z3c/formdemo/README.txt
  A   z3c.formdemo/trunk/src/z3c/formdemo/SETUP.cfg
  A   z3c.formdemo/trunk/src/z3c/formdemo/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/browser/
  A   z3c.formdemo/trunk/src/z3c/formdemo/browser/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/browser/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/browser/index.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/browser.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.css
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/calculator/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/layer.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/add.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/browser.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/display.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/edit.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/interfaces.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/message.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/message/what-values.csv
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.css
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.js
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/img/
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.gif
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.png
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/json.js
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/template.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/skin/xmlhttp.js
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/browser.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/content.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/formatter.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/ascending.gif
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/decending.gif
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.css
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/table_sorted_header.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/browser.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/interfaces.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/widgets/widgets.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/__init__.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/browser.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/configure.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/content.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb.jpg
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb_active.jpg
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonLeftBG.gif
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonRightBG.gif
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/interfaces.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/step.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/summary.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.css
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.pt
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.py
  A   z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.zcml
  A   z3c.formdemo/trunk/src/z3c/formdemo/z3c.formdemo-configure.zcml

-=-
Added: z3c.formdemo/trunk/README.txt
===================================================================
--- z3c.formdemo/trunk/README.txt	                        (rev 0)
+++ z3c.formdemo/trunk/README.txt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,35 @@
+=====================================================
+Demo Applications for ``z3c.form`` and ``z3c.formui``
+=====================================================
+
+This package contains several small demo applications for the ``z3c.form`` and
+``z3c.formui`` packages.
+
+* TABLE- versus DIV-based layout of all widgets.
+
+* A simple Hello World message application demonstrating the easiest way to
+  write add, edit and display forms.
+
+* A simple calculator showing the flexibility of the new action declaration
+  framework by declaring different classes of buttons.
+
+* A linear wizard shows off the sub-form capabilities of z3c.form. It also
+  demonstrates how one can overcome the short-coming of an object widget.
+
+* A simple table/spreadsheet that allows adding and editing as simple content
+  object. This demo also shows the usage of forms and ``zc.table`` at the same
+  time.
+
+Running the Demo out of the box
+-------------------------------
+
+You can also run the demo directly without manually installing Zope 3:
+
+  $ svn co svn://svn.zope.org/repos/main/z3c.formdemo/trunk formdemo
+  $ python bootstrap.py
+  $ ./bin/buildout
+  $ ./bin/demo fg
+
+Then access the demo site using:
+
+  http://localhost:8080/


Property changes on: z3c.formdemo/trunk/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/bootstrap.py
===================================================================
--- z3c.formdemo/trunk/bootstrap.py	                        (rev 0)
+++ z3c.formdemo/trunk/bootstrap.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)


Property changes on: z3c.formdemo/trunk/bootstrap.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/buildout.cfg
===================================================================
--- z3c.formdemo/trunk/buildout.cfg	                        (rev 0)
+++ z3c.formdemo/trunk/buildout.cfg	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,80 @@
+[buildout]
+develop = .
+parts = demo
+
+[zope3]
+location = .
+
+[form-demo-app]
+recipe = zc.zope3recipes:app
+site.zcml = <configure
+                xmlns="http://namespaces.zope.org/zope"
+                xmlns:browser="http://namespaces.zope.org/browser"
+                i18n_domain="demo">
+            <include package="zope.app.component" file="meta.zcml" />
+            <include package="zope.app.component.browser" file="meta.zcml" />
+            <include package="zope.app.form.browser" file="meta.zcml" />
+            <include package="zope.app.pagetemplate" file="meta.zcml" />
+            <include package="zope.app.publication" file="meta.zcml" />
+            <include package="zope.app.publisher" file="meta.zcml" />
+            <include package="zope.app.security" file="meta.zcml" />
+            <include package="zope.app.securitypolicy" file="meta.zcml" />
+            <include package="zope.viewlet" file="meta.zcml" />
+            <include package="z3c.form" file="meta.zcml" />
+            <include package="z3c.macro" file="meta.zcml" />
+            <include package="z3c.pagelet" file="meta.zcml" />
+            <include package="z3c.template" file="meta.zcml" />
+            <include package="z3c.zrtresource" file="meta.zcml" />
+            <include package="zc.resourcelibrary" file="meta.zcml" />
+
+            <browser:menu id="zmi_views" title="Views" />
+            <browser:menu id="zmi_actions" title="Actions" />
+
+            <include package="zope.app.appsetup" />
+            <include package="zope.app.component" />
+            <include package="zope.app.container" />
+            <include package="zope.app.error" />
+            <include package="zope.app.i18n" />
+            <include package="zope.app.publication" />
+            <include package="zope.app.security" />
+            <include package="zope.app.securitypolicy" />
+            <include package="zope.app.session" />
+            <include package="zope.app.twisted" />
+            <include package="zope.app.wsgi" />
+            <include package="zope.annotation" />
+            <include package="zope.component" />
+            <include package="zope.contentprovider" />
+            <include package="zope.location" />
+            <include package="zope.publisher" />
+            <include package="zope.traversing" />
+            <include package="zope.traversing.browser" />
+            <include package="zope.viewlet" />
+
+            <include package="z3c.form" />
+            <include package="z3c.formui" />
+            <include package="z3c.formdemo" />
+            <include package="z3c.layer.pagelet" />
+            <include package="z3c.macro" />
+            <include package="z3c.pagelet" />
+
+            <include package="zc.resourcelibrary" />
+            <include package="zc.table" />
+
+            <browser:defaultView name="index.html" />
+            <browser:defaultSkin name="Z3CFormDemo" />
+
+            <securityPolicy
+            component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+            <role id="zope.Anonymous" title="Everybody" />
+            <grantAll role="zope.Anonymous" />
+            </configure>
+eggs = z3c.formdemo [app]
+
+[demo]
+recipe = zc.zope3recipes:instance
+application = form-demo-app
+zope.conf = ${database:zconfig}
+
+[database]
+recipe = zc.recipe.filestorage

Added: z3c.formdemo/trunk/setup.py
===================================================================
--- z3c.formdemo/trunk/setup.py	                        (rev 0)
+++ z3c.formdemo/trunk/setup.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,93 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Setup
+
+$Id$
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup (
+    name='z3c.formdemo',
+    version='1.0.0c2',
+    author = "Stephan Richter, Roger Ineichen and the Zope Community",
+    author_email = "zope3-dev at zope.org",
+    description = "A set of demo applications for z3c.form and z3c.formui",
+    long_description=(
+        read('README.txt')
+        ),
+    license = "ZPL 2.1",
+    keywords = "zope3 form widget",
+    classifiers = [
+        'Development Status :: 4 - Beta',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Zope Public License',
+        'Programming Language :: Python',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Topic :: Internet :: WWW/HTTP',
+        'Framework :: Zope3'],
+    url = 'http://svn.zope.org/z3c.formdemo',
+    packages = find_packages('src'),
+    include_package_data = True,
+    package_dir = {'':'src'},
+    namespace_packages = ['z3c'],
+    extras_require = dict(
+        app = ['zope.app.appsetup',
+               'zope.app.authentication',
+               'zope.app.component',
+               'zope.app.container',
+               'zope.app.error',
+               'zope.app.form',
+               'zope.app.publisher',
+               'zope.app.publication',
+               'zope.app.security',
+               'zope.app.securitypolicy',
+               'zope.app.twisted',
+               'zope.app.wsgi',
+               'zope.contentprovider',
+               ],
+        ),
+    install_requires = [
+        'setuptools',
+        'z3c.csvvocabulary',
+        'z3c.form',
+        'z3c.formui',
+        'z3c.layer',
+        'z3c.pagelet',
+        'z3c.template',
+        'z3c.viewlet',
+        'z3c.zrtresource',
+        'zc.resourcelibrary',
+        'zc.table',
+        'zope.annotation',
+        'zope.app.container',
+        'zope.app.pagetemplate',
+        'zope.app.session',
+        'zope.component',
+        'zope.interface',
+        'zope.location',
+        'zope.pagetemplate',
+        'zope.publisher',
+        'zope.schema',
+        'zope.traversing',
+        'zope.viewlet',
+        ],
+    dependency_links = ['http://download.zope.org/distribution'],
+    zip_safe = False,
+    )


Property changes on: z3c.formdemo/trunk/setup.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,8 @@
+try:
+    # Declare this a namespace package if pkg_resources is available.
+    import pkg_resources
+    pkg_resources.declare_namespace('z3c')
+except ImportError:
+    pass
+
+


Property changes on: z3c.formdemo/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/README.txt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/README.txt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/README.txt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,13 @@
+======
+README
+======
+
+This package provides different sample for the z3c.form  and z3c.formui 
+packages.
+
+If you run the Zope3 server at port 8080, you can access the different demos
+with two skins. The Z3CFormDemo skin uses the div based form layout and is 
+accessible via: http://localhost:8080/++skin++Z3CFormDemo/ and the 
+Z3CTableFormDemo skin uses the table based form layout and is accessible via:
+http://localhost:8080/++skin++Z3CFormDemo/. Both skin offer a index.html page
+with a list of demo pages.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/SETUP.cfg
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/SETUP.cfg	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/SETUP.cfg	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  z3c.formdemo-*.zcml
+</data-files>

Added: z3c.formdemo/trunk/src/z3c/formdemo/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/browser/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/browser/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/browser/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/browser/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/browser/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/browser/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,15 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <page
+      name="index.html"
+      for="zope.app.folder.interfaces.IFolder"
+      template="index.pt"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/browser/index.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/browser/index.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/browser/index.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,31 @@
+<h1>Z3C form demos</h1>
+
+<div class="demo">
+  <h4>Div based layout</h4>
+
+  <div>
+    <a href="../++skin++Z3CFormDemo/addHelloWorld.html">Hello World</a>
+  </div>
+  <div>
+    <a href="../++skin++Z3CFormDemo/widgets.html">All widgets</a>
+  </div>
+
+  <h4>Table based layout</h4>
+  <div>
+    <a href="../++skin++Z3CTableFormDemo/addHelloWorld.html">Hello World</a>
+  </div>
+  <div>
+    <a href="../++skin++Z3CTableFormDemo/widgets.html">All widgets</a>
+  </div>
+
+  <h4>Advanced Demos</h4>
+  <div>
+    <a href="../++skin++Z3CFormDemo/calculator.html">Calculator</a>
+  </div>
+  <div>
+    <a href="../++skin++Z3CFormDemo/wizard.html">Wizard</a>
+  </div>
+  <div>
+    <a href="../++skin++Z3CFormDemo/spreadsheet.html">Spreadsheet</a>
+  </div>
+</div>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/browser/index.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/browser.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/browser.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/browser.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,167 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Calculator Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import decimal
+import zope.interface
+from zope.app.session.interfaces import ISession
+from zope.viewlet.viewlet import CSSViewlet
+from z3c.form import button, form, interfaces
+from z3c.formui import layout
+
+SESSION_KEY = 'z3c.formdemo.calculator'
+
+CalculatorCSSViewlet = CSSViewlet('calculator.css')
+
+class SessionProperty(object):
+
+    def __init__(self, name, default=None):
+        self.name = name
+        self.default = default
+
+    def __get__(self, inst, klass):
+        session = ISession(inst.request)[SESSION_KEY]
+        return session.get(self.name, self.default)
+
+    def __set__(self, inst, value):
+        session = ISession(inst.request)[SESSION_KEY]
+        session[self.name] = value
+
+
+class IGridButton(interfaces.IButton):
+    """A button within the grid."""
+
+
+class Literal(button.Button):
+    zope.interface.implements(IGridButton)
+
+    def __init__(self, *args, **kwargs):
+        literal = kwargs.pop('literal', None)
+        super(Literal, self).__init__(*args, **kwargs)
+        if literal is None:
+            self.literal = self.title
+        else:
+            self.literal = literal
+        self.accessKey = self.literal
+
+
+class Operator(button.Button):
+    zope.interface.implements(IGridButton)
+
+    operation = None
+
+    def __init__(self, *args, **kwargs):
+        self.operation = kwargs.pop('operation', None)
+        kwargs['accessKey'] = kwargs['title']
+        super(Operator, self).__init__(*args, **kwargs)
+
+    def operate(self, x, y):
+        return getattr(x, self.operation)(y)
+
+
+class GridButtonActions(button.ButtonActions):
+
+    cols = 4
+
+    def grid(self):
+        rows = []
+        current = []
+        for button in self.values():
+            if not IGridButton.providedBy(button.field):
+                continue
+            current.append(button)
+            if len(current) == self.cols:
+                rows.append(current)
+                current = []
+        if current:
+            current += [None]*(self.cols-len(current))
+            rows.append(current)
+        return rows
+
+
+class Calculator(layout.FormLayoutSupport, form.Form):
+
+    buttons = button.Buttons(
+        Literal('one', title=u'1'),
+        Literal('two', title=u'2'),
+        Literal('three', title=u'3'),
+        Operator('add', title=u'+', operation='__add__'),
+
+        Literal('four', title=u'4'),
+        Literal('five', title=u'5'),
+        Literal('six', title=u'6'),
+        Operator('sub', title=u'-', operation='__sub__'),
+
+        Literal('seven', title=u'7'),
+        Literal('eight', title=u'8'),
+        Literal('nine', title=u'9'),
+        Operator('mul', title=u'*', operation='__mul__'),
+
+        Literal('zero', title=u'0'),
+        Literal('dec', title=u'.'),
+        Operator('eq', title=u'='),
+        Operator('div', title=u'/', operation='__div__'),
+
+        button.Button('clear', title=u'C', accessKey=u"c"),
+        )
+
+    stack = SessionProperty('stack', decimal.Decimal(0))
+    operator = SessionProperty('operator')
+    current = SessionProperty('current', u'')
+
+    maxSize = 12
+
+    def updateActions(self):
+        self.actions = GridButtonActions(self, self.request, self.context)
+        self.actions.update()
+
+    @button.handler(Literal)
+    def handleLiteral(self, action):
+        if len(self.current) < self.maxSize:
+            self.current += action.field.literal
+        if self.operator is None:
+            self.stack = decimal.Decimal(0)
+
+    @button.handler(Operator)
+    def handleOperator(self, action):
+        try:
+            current = decimal.Decimal(self.current)
+        except decimal.DecimalException:
+            current = decimal.Decimal(0)
+        if self.operator is not None:
+            try:
+                self.stack = self.operator.operate(self.stack, current)
+            except decimal.DecimalException, err:
+                self.current = u'-E-'
+                return err
+        else:
+            self.stack = current
+        self.current = u''
+        self.operator = action.field
+
+    @button.handler(buttons['eq'])
+    def handleEqual(self, action):
+        error = self.handleOperator(self, action)
+        if not error:
+            self.operator = None
+            self.current = str(self.stack)
+
+    @button.handler(buttons['clear'])
+    def handleClear(self, action):
+        self.operator = None
+        self.stack = decimal.Decimal(0)
+        self.current = u''


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/browser.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.css
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.css	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.css	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,104 @@
+body {
+  margin: 20px;
+  font-family: Arial, Helvetica;
+}
+
+h1 {
+  font-size: 15px;
+  padding: 0 5px 2px 5px;
+  margin: 0 0 7px 0;
+  border-bottom: 2px solid black;
+  width: auto;
+  height: 15px;
+}
+
+h1 span.name {
+  float: left;
+}
+
+h1 span.version {
+  float: right;
+}
+
+div#calculator {
+  width: 250px;
+  padding: 10px 15px 10px 15px;
+  background: #DDD;
+  border: 2px solid black;
+  -moz-border-radius: 10px;
+}
+
+div#display {
+  width: 100%;
+  border: 2px solid #999;
+  background: #A5BC98;
+  -moz-border-radius: 4px;
+  padding: 0;
+  margin: 0;
+  margin-bottom: 4px;
+}
+
+div#stack {
+  display: none;
+}
+
+div#operator {
+  height: 10px;
+  text-align: right;
+  font-size: 12px;
+  font-weight: bold;
+  padding-right: 5px;
+}
+
+div#operator span.label {
+  display: none;
+}
+
+div#current {
+  height: 30px;
+  text-align: right;
+  font-family: "Digital Readout Upright", Eurostile, Helvetica;
+  font-size: 30px;
+  font-weight: bold;
+  padding: 3px;
+}
+
+div#current span.label {
+  display: none;
+}
+
+input[type=submit] {
+  height: 30px;
+  width: 50px;
+  border-width: 1.5px;
+  font-family: Verdana, Helvetica;
+  font-size: 20px;
+  font-weight: bold;
+  -moz-border-radius: 4px;
+}
+
+div#buttons {
+  text-align: center;
+}
+
+div#buttons table {
+  border-spacing: 0;
+  margin-top: 5px;
+  margin-left: auto;
+  margin-right: auto;
+}
+div#buttons table td {
+  padding: 0px 4px 6px 4px;
+}
+
+input[name="form.buttons.clear"] {
+  width: 224px;
+  background: #FF443E;
+  color: white;
+}
+
+div.info {
+  width: 250px;
+  text-align: center;
+  font-size: 12px;
+}


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,43 @@
+<div id="calculator">
+  <h1>
+    <span class="name">A simple calculator</span>
+    <span class="version">v1.0</span>
+  </h1>
+  <div id="display">
+    <div id="stack">
+      <span class="label">Stack:</span>
+      <span class="value" tal:content="view/stack">4</span>
+    </div>
+    <div id="operator">
+      <span class="label">Operator:</span>
+      <span class="value" tal:content="view/operator/title|nothing">+</span>
+    </div>
+    <div id="current">
+      <span class="label">Current:</span>
+      <span class="value"
+            tal:condition="view/current"
+            tal:content="view/current">4</span>
+      <span class="value"
+            tal:condition="not:view/current"
+            tal:content="view/stack">4</span>
+    </div>
+  </div>
+  <div metal:use-macro="macro:form">
+    <div id="buttons" metal:fill-slot="buttons">
+      <table>
+        <tr tal:repeat="row view/actions/grid">
+          <td tal:repeat="action row">
+            <input tal:replace="structure action/render" />
+          </td>
+        </tr>
+      </table>
+      <input tal:replace="structure view/actions/clear/render" />
+    </div>
+  </div>
+</div>
+<div class="info">
+  <p>This example is best viewed in Firefox with the <a
+    href="http://desktoppub.about.com/library/fonts/dd/uc_digitalreadout.htm"
+    >Digital Readout</a> font installed.
+  <p>
+</div>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/calculator.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/calculator/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/calculator/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/calculator/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,35 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <z3c:pagelet
+      name="calculator.html"
+      for="*"
+      class=".browser.Calculator"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="calculator.pt"
+      for=".browser.Calculator"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <zrt-resource
+      name="calculator.css"
+      file="calculator.css"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <viewlet
+      name="calculator.css"
+      view=".browser.Calculator"
+      manager="z3c.formdemo.skin.ICSS"
+      class=".browser.CalculatorCSSViewlet"
+      permission="zope.Public"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/calculator/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,22 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain="z3c.formdemo">
+
+  <!-- default z3c.form layer -->
+  <interface
+      interface="z3c.formdemo.layer.IDemoBrowserLayer"
+      type="zope.publisher.interfaces.browser.IBrowserSkinType"
+      />
+
+  <include package=".skin" />
+  <include package=".browser" />
+
+  <!-- Examples -->
+
+  <include package=".message" />
+  <include package=".widgets" />
+  <include package=".calculator" />
+  <include package=".wizard" />
+  <include package=".spreadsheet" />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/layer.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/layer.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/layer.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+from z3c.form.interfaces import IFormLayer
+from z3c.layer.pagelet import IPageletBrowserLayer
+
+
+class IDemoBrowserLayer(IFormLayer, IPageletBrowserLayer):
+    """Demo browser layer using div-form layout template."""


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/layer.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/add.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/add.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/add.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,2 @@
+<h1>Hello World Message Add Form</h1>
+<div metal:use-macro="macro:form" />


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/add.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/browser.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/browser.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/browser.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import datetime
+import zope.interface
+import zope.component
+from zope.traversing.browser import absoluteURL
+from zope.pagetemplate.interfaces import IPageTemplate
+
+from z3c.pagelet import browser
+from z3c.form import button, field, form, widget
+from z3c.form.interfaces import IAddForm
+
+from z3c.formdemo.message import interfaces, message
+from z3c.formui import layout
+
+
+DefaultDate = widget.ComputedWidgetAttribute(
+    lambda adapter: datetime.date.today(),
+    field=interfaces.IHelloWorld['when'], view=IAddForm)
+
+class HelloWorldAddForm(layout.AddFormLayoutSupport, form.AddForm):
+    """ A sample add form."""
+
+    template = None
+    layout = None
+    contentName = None
+    label = u'Add Form'
+
+    fields = field.Fields(interfaces.IHelloWorld)
+
+    def create(self, data):
+        return message.HelloWorld(**data)
+
+    def add(self, object):
+        count = 0
+        while 'helloworld-%i' %count in self.context:
+            count += 1;
+        self._name = 'helloworld-%i' %count
+        self.context[self._name] = object
+        return object
+
+    def nextURL(self):
+        return absoluteURL(self.context[self._name], self.request)
+
+
+class HelloWorldEditForm(layout.FormLayoutSupport, form.EditForm):
+    form.extends(form.EditForm)
+    fields = field.Fields(interfaces.IHelloWorld)
+
+    @button.buttonAndHandler(u'Apply and View', name='applyView')
+    def handleApplyView(self, action):
+        self.handleApply(self, action)
+        if not self.widgets.errors:
+            url = absoluteURL(self.context, self.request)
+            self.request.response.redirect(url)
+
+
+class HelloWorldDisplayForm(layout.FormLayoutSupport, form.DisplayForm):
+    fields = field.Fields(interfaces.IHelloWorld)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/browser.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,71 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <permission
+      id="z3c.formdemo.ManageHelloWorld"
+      title="Manage Hello World (z3c.formdemo)"
+      />
+
+  <class class=".message.HelloWorld">
+    <allow
+        interface=".interfaces.IHelloWorld"
+        />
+    <require
+        permission="z3c.formdemo.ManageHelloWorld"
+        set_schema=".interfaces.IHelloWorld"
+        />
+  </class>
+
+  <!-- Default widget value for "when" -->
+  <adapter
+      factory=".browser.DefaultDate"
+      name="default" />
+
+  <!-- Add Form -->
+  <z3c:pagelet
+      name="addHelloWorld.html"
+      for="zope.app.folder.interfaces.IFolder"
+      class=".browser.HelloWorldAddForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="add.pt"
+      for=".browser.HelloWorldAddForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <!-- Display Form -->
+  <z3c:pagelet
+      name="edit.html"
+      for=".interfaces.IHelloWorld"
+      class=".browser.HelloWorldEditForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="edit.pt"
+      for=".browser.HelloWorldEditForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <!-- Display Form -->
+  <z3c:pagelet
+      name="index.html"
+      for=".interfaces.IHelloWorld"
+      class=".browser.HelloWorldDisplayForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="display.pt"
+      for=".browser.HelloWorldDisplayForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/display.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/display.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/display.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,8 @@
+<h1>
+  A <span tal:replace="structure view/widgets/what/render" /> Hello World
+  from <span tal:replace="structure view/widgets/who/render" />
+  on <span tal:replace="structure view/widgets/when/render" />!
+</h1>
+<a href="./edit.html"
+   tal:attributes="href string:${context/@@absolute_url}/edit.html">
+  Edit Message</a>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/display.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/edit.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/edit.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/edit.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,2 @@
+<h1>Hello World Message Edit Form</h1>
+<div metal:use-macro="macro:form" />


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/edit.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/interfaces.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/interfaces.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/interfaces.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Hello World Message Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import os
+import zope.interface
+import zope.schema
+from z3c.csvvocabulary import CSVVocabulary
+
+WhatVocabulary = CSVVocabulary(
+    os.path.join(os.path.dirname(__file__), 'what-values.csv'))
+
+class IHelloWorld(zope.interface.Interface):
+    """Information about a hello world message"""
+
+    who = zope.schema.TextLine(
+        title=u'Who',
+        description=u'Name of the person sending the message',
+        required=True)
+
+    when = zope.schema.Date(
+        title=u'When',
+        description=u'Date of the message sent.',
+        required=True)
+
+    what = zope.schema.Choice(
+        title=u'What',
+        description=u'What type of message it is.',
+        vocabulary=WhatVocabulary,
+        default=u'cool',
+        required=True)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/message.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/message.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/message.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,38 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Hello Worl Message Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import persistent
+import zope.interface
+from zope.location import location
+from zope.schema import fieldproperty
+from z3c.formdemo.message import interfaces
+
+class HelloWorld(location.Location, persistent.Persistent):
+    zope.interface.implements(interfaces.IHelloWorld)
+
+    who = fieldproperty.FieldProperty(interfaces.IHelloWorld['who'])
+    when = fieldproperty.FieldProperty(interfaces.IHelloWorld['when'])
+    what = fieldproperty.FieldProperty(interfaces.IHelloWorld['what'])
+
+    def __init__(self, who, when, what):
+        self.who = who
+        self.when = when
+        self.what = what
+
+    def __repr__(self):
+        return '<%s from %r>' %(self.__class__.__name__, self.who)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/message/message.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/message/what-values.csv
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/message/what-values.csv	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/message/what-values.csv	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,4 @@
+"cool";"cool"
+"sunny";"sunny"
+"silent";"silent"
+"best";"best"

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.viewlet.interfaces import IViewletManager
+from zope.viewlet.viewlet import CSSViewlet
+from zope.viewlet.viewlet import JavaScriptViewlet
+from z3c.pagelet import browser
+from z3c.formui import interfaces
+from z3c.formdemo import layer
+
+
+class IDivDemoBrowserSkin(interfaces.IDivFormLayer, layer.IDemoBrowserLayer):
+    """The ``Z3CFormDemo`` browser skin."""
+
+
+class ITableDemoBrowserSkin(interfaces.ITableFormLayer, 
+    layer.IDemoBrowserLayer):
+    """The ``Z3CTableFormDemo`` browser skin."""
+
+
+class ICSS(interfaces.ICSS):
+    """CSS viewlet manager."""
+
+
+class IJavaScript(IViewletManager):
+    """JavaScript viewlet manager."""
+
+
+DemoCSSViewlet = CSSViewlet('demo.css')
+DemoJavaScriptViewlet = JavaScriptViewlet('demo.js')
+


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,95 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <!-- div layout demo skin -->
+  <zope:interface
+      interface="z3c.formdemo.skin.IDivDemoBrowserSkin"
+      type="zope.publisher.interfaces.browser.IBrowserSkinType"
+      name="Z3CFormDemo"
+      />
+
+  <!-- table layout demo skin -->
+  <zope:interface
+      interface="z3c.formdemo.skin.ITableDemoBrowserSkin"
+      type="zope.publisher.interfaces.browser.IBrowserSkinType"
+      name="Z3CTableFormDemo"
+      />
+
+  <!-- resource -->
+  <zrt-resource
+      name="demo.css"
+      file="demo.css"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <zrt-resource
+      name="demo.js"
+      file="demo.js"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <resourceDirectory
+      name="img"
+      directory="img"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <!-- viewlet managers -->
+  <viewletManager
+      name="ICSS"
+      provides="z3c.formdemo.skin.ICSS"
+      class="z3c.viewlet.manager.WeightOrderedViewletManager"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <viewletManager
+      name="IJavaScript"
+      provides="z3c.formdemo.skin.IJavaScript"
+      class="z3c.viewlet.manager.WeightOrderedViewletManager"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+
+  <!-- viewlets -->
+  <viewlet
+      name="demo.css"
+      for="*"
+      manager="z3c.formdemo.skin.ICSS"
+      class=".DemoCSSViewlet"
+      permission="zope.Public"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <viewlet
+      name="demo.js"
+      for="*"
+      manager="z3c.formdemo.skin.IJavaScript"
+      class=".DemoJavaScriptViewlet"
+      permission="zope.Public"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+
+  <!-- layout template -->
+  <z3c:layout
+      for="*"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      template="template.pt"
+      />
+
+  <!-- ZC Table Resource Library inclusion -->
+
+  <configure package="zc.table">
+    <zope:resourceLibrary
+        name="zc.table"
+        layer="z3c.formdemo.layer.IDemoBrowserLayer">
+      <zope:directory source="resources" include="sorting.js"/>
+    </zope:resourceLibrary>
+  </configure>
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.css
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.css	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.css	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,90 @@
+/* zrt-replace: "./img" tal"string:${context/++resource++img}" */
+
+body {
+    font: 11px Verdana, Helvetica, Arial, sans-serif;
+    margin: 0px;
+    padding: 0px;
+}
+
+/* [ html ]---------------------------------------------------------------- */
+
+form {
+    margin: 0px;
+    padding: 0px;
+}
+
+img {
+    border: 0;
+}
+
+a {
+    color: #D91813;
+    text-decoration: none;
+}
+
+a:link {
+    color: #D91813;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #A68E8E;
+    text-decoration: none;
+}
+
+a:hover {
+    color: #8C100D;
+}
+
+fieldset {
+    padding: 5px;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+    color: Black;
+    clear: left;
+    font: 100% bold Verdana, Helvetica, Arial, sans-serif;
+    margin: 0;
+    padding-top: 0.5em;
+}
+
+h1 {
+    font-size: 160%;
+}
+
+h2 {
+    font-size: 140%;
+}
+
+h3 {
+    height: 20px;
+    font-size: 120%;
+    background-color: #DDDCD0;
+    padding: 2px 0px 0px 5px;
+}
+
+h4 {
+    color: #777777;
+    font-size: 100%;
+    font-weight: bold;
+}
+
+h5 {
+    font-size: 90%;
+}
+
+h6 {
+    font-size: 80%;
+}
+
+
+/* ---[ demo layout tags ]--------------------------------------------------- */
+
+#content {
+    padding: 20px;
+}
+
+div.demo {
+    padding-bottom: 2px;
+}


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.js
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.js	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/demo.js	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,8 @@
+//-----------------------------------------------------------------------------
+// Z3c form demo javascript
+//-----------------------------------------------------------------------------
+
+//---[ on dom load ]-----------------------------------------------------------
+//$(document).ready(function(){
+//    // do something
+//});

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.gif
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.png
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/img/loading.png
___________________________________________________________________
Name: svn:mime-type
   + image/png

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/json.js
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/json.js	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/json.js	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,212 @@
+//----------------------------------------------------------------------------
+/** 
+ * @fileoverview JSON-RPC client implementation 
+ * @author Roger Ineichen roger at tiks.org
+ * @version Initial, not documented 
+ */
+//----------------------------------------------------------------------------
+
+function JSONRPC(url) {
+    this._url = url;
+    this._methods = new Array();
+    this._user = null;
+    this._password = null;
+}
+
+function getJSONRPCProxy(url) {
+    return new JSONRPC(url);
+}
+
+JSONRPC.prototype.addMethod = function(name, callback, requestId) {
+    if (typeof(requestId) == 'undefined') {
+        requestId = "jsonRequest";
+    }
+    var self = this;
+    if(!self[name]){
+        var method = new JSONRPCMethod(this._url, name, callback, requestId, this._user, this._password);
+        self[name] = method;
+        this._methods.push(method);
+    }
+}
+
+JSONRPC.prototype.setAuthentication = function(user, pass) {
+    this._user = user;
+    this._password = pass;
+    for(var i=0;i<this._methods.length;i++){
+        this._methods[i].setAuthentication(user, pass);
+    }
+}
+
+function JSONRPCMethod(url, methodName, callback, requestId, user, pass) {
+    this.methodName = methodName;
+    this.callback = callback;
+    this.requestId = requestId;
+    this.url = url;
+    this.user = user;
+    this.password = pass;
+    var self = this;
+
+    var fn = function(){
+        var args = new Array();
+        for(var i=0;i<arguments.length;i++){
+            args.push(arguments[i]);
+        }
+        if(self.callback) {
+            var data = self.jsonRequest(self.requestId, self.methodName, args);
+            self.postData(self.url, self.user, self.password, data, function(resp){
+                var res = null;
+                var exc =null;
+                try{
+                    res = self.handleResponse(resp);
+                }catch(e){
+                    exc = e;
+                }
+                try{
+                    callback(res, self.requestId, exc);
+                }catch(e){
+                    alert("except callback");
+                }
+                args = null;
+                resp = null;
+            });
+        }
+        else{
+            var data = self.jsonRequest(self.requestId, self.methodName, args);
+            var resp = self.postData(self.url, self.user, self.password, data);
+            return self.handleResponse(resp);
+        }
+    }
+    return fn;
+
+}
+
+JSONRPCMethod.prototype.postData = function(url, user, pass, data, callback) {
+    var xmlhttp = new XMLHttp(url);
+    var header = new Array()
+    header["Content-Type"] = "application/json-rpc";
+    xmlhttp.setHeaders(header);
+    xmlhttp.user = user;
+    xmlhttp.password = pass;
+    xmlhttp.argString = data;
+    if(callback == null){
+        return xmlhttp.post();
+    }else{
+        xmlhttp.post(callback);
+    }
+}
+
+JSONRPCMethod.prototype.jsonRequest = function(id, methodName, args){
+    var ji = toJSON(id);
+    var jm = toJSON(methodName);
+    var ja = toJSON(args);
+    return '{"id":' + ji + ', "method":' + jm + ', "params":' + ja + "}";
+}
+
+JSONRPCMethod.prototype.setAuthentication = function(user, pass){
+    this.user = user;
+    this.password = pass;
+}
+
+JSONRPCMethod.prototype.notify = function(){
+    var args=new Array();
+    for(var i=0;i<arguments.length;i++){
+        args.push(arguments[i]);
+    }
+    var data = this.jsonRequest(null, this.methodName, args);
+    this.postData(this.url, this.user, this.password, data, function(resp){});
+}
+
+JSONRPCMethod.prototype.handleResponse = function(resp){
+    var status=null;
+    try{
+        status = resp.status;
+    }catch(e){
+    }
+    if(status == 200){
+        var respTxt = "";
+        try{
+            respTxt=resp.responseText;
+        }catch(e){
+        }
+        if(respTxt == null || respTxt == ""){
+            alert("The server responded with an empty document.");
+        }else{
+            var res = this.unmarshall(respTxt);
+            if(res.error != null){
+                alert("error " + res.error);
+            }
+            else if (res.requestId != self.requestId) {
+                alert("wrong json id returned");
+            }
+            else{
+                return res.result;
+            }
+        }
+    }else{
+        alert("error " + status);
+    }
+}
+
+JSONRPCMethod.prototype.unmarshall = function(source){
+    try {
+        var obj;
+        eval("obj=" + source);
+        return obj;
+    }catch(e){
+        alert("The server's response could not be parsed.");
+    }
+}
+
+function escapeJSONChar(c) {
+    if(c == "\"" || c == "\\") return "\\" + c;
+    else if (c == "\b") return "\\b";
+    else if (c == "\f") return "\\f";
+    else if (c == "\n") return "\\n";
+    else if (c == "\r") return "\\r";
+    else if (c == "\t") return "\\t";
+    var hex = c.charCodeAt(0).toString(16);
+    if(hex.length == 1) return "\\u000" + hex;
+    else if(hex.length == 2) return "\\u00" + hex;
+    else if(hex.length == 3) return "\\u0" + hex;
+    else return "\\u" + hex;
+}
+
+function escapeJSONString(s) {
+    var parts = s.split("");
+    for(var i=0; i < parts.length; i++) {
+	var c =parts[i];
+	if(c == '"' ||
+	   c == '\\' ||
+	   c.charCodeAt(0) < 32 ||
+	   c.charCodeAt(0) >= 128)
+	    parts[i] = escapeJSONChar(parts[i]);
+    }
+    return "\"" + parts.join("") + "\"";
+}
+
+function toJSON(o) {
+    if(o == null) {
+    	return "null";
+        } else if(o.constructor == String) {
+    	    return escapeJSONString(o);
+        } else if(o.constructor == Number) {
+    	    return o.toString();
+        } else if(o.constructor == Boolean) {
+    	    return o.toString();
+        } else if(o.constructor == Date) {
+    	    return o.valueOf().toString();
+        } else if(o.constructor == Array) {
+    	var v = [];
+    	for(var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
+    	return "[" + v.join(", ") + "]";
+    }
+    else {
+    	var v = [];
+    	for(attr in o) {
+    	    if(o[attr] == null) v.push("\"" + attr + "\": null");
+    	    else if(typeof o[attr] == "function"); // skip
+    	    else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
+    	}
+    	return "{" + v.join(", ") + "}";
+    }
+}

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/template.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/template.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/template.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,25 @@
+<!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" xml:lang="en" lang="en"
+      i18n:domain="z3c.formdemo">
+<head>
+<title>Z3C Demo</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta http-equiv="cache-control" content="no-cache" />
+<meta http-equiv="pragma" content="no-cache" />
+<script type="text/javascript"
+    tal:define="contexturl context/@@absolute_url; 
+                viewurl request/URL"
+    tal:content="string:
+	var contextURL = '${contexturl}';
+	var viewURL = '${viewurl}';"> 
+</script>
+<script tal:replace="structure provider:IJavaScript"> </script>
+<style tal:replace="structure provider:ICSS"> 
+</style>
+</head>
+<body>
+<div id="content">
+  <tal:block replace="structure provider:pagelet" />
+</div>
+</body>
+</html>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/skin/template.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/skin/xmlhttp.js
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/skin/xmlhttp.js	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/skin/xmlhttp.js	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,309 @@
+//----------------------------------------------------------------------------
+/** 
+ * @fileoverview Cross browser XMLHttpRequest implementation
+ * Make sure the response set the Header to 'no-cache'. 
+ *
+ * @author Roger Ineichen roger at tiks.org
+ * @version Draft, not complete documented 
+ */
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// public API
+//----------------------------------------------------------------------------
+
+/**
+ * Construct a new XMLHttp.
+ * @class This is the basic XMLHttp class.
+ * @constructor
+ * @param {string} url URL pointing to the server
+ * @return A new XMLHttp
+ */
+function XMLHttp(url) {
+    this.url = url;
+    this.method = 'GET';
+    this.async = false;
+    this.username = null;
+    this.password = null;
+    this.timeout = null;
+    this.argString = "";
+    this.parameters = new Array();
+    this.headers = new Array();
+    this.headers['Content-Type'] = 'application/x-www-form-urlencoded'
+
+    /* internal status flags */
+    this.isAborted = false;
+    this.isLoading = false;
+    this.isLoaded = false;
+    this.isInteractive = false;
+    this.isComplete = false;
+
+    /* event handlers (attached functions get called if readyState reached) */
+    this.onLoading = null;       // if readyState 1
+    this.onLoaded = null;        // if readyState 2
+    this.onInteractive = null;   // if readyState 3
+    this.onComplete = null;      // if readyState 4
+    this.onError = null;         // if readyState 4 and status != 200
+    this.onTimeout = null;       // if timeout reached
+    this.callback = null;        // if readyState 4 and status == 200
+    this.callbackArgs = null;
+
+    /*  response variables */
+    this.responseText = null;
+    this.responseXML = null;
+
+    /* setup the xmlhttp request now */
+    this.xmlhttp = getXmlHttpRequest()
+}
+
+/**
+ * Set the header information for the XMLHttp instance.
+ * @param {array} args of key, value
+ */
+XMLHttp.prototype.setHeaders = function(args) {
+    for (var i in args) {
+        this.headers[i] = args[i];
+    }
+}
+
+/**
+ * Set the arguments for the request or the XMLHttp instance.
+ * @param {array} args of key, value
+ */
+XMLHttp.prototype.setArguments = function(args) {
+    for (var i in args) {
+        // set parameter to the xmlhttp instance or to the parameter array
+        if (typeof(this[i])=="undefined") {
+            this.parameters[i] = args[i];
+        }
+        else {
+            this[i] = args[i];
+        }
+    }
+}
+
+/**
+ * Process a 'POST' request.
+ * @param {function} callback callback funtion
+ * @param {array} callbackArgs callback arguments
+ */
+XMLHttp.prototype.post = function(callback, callbackArgs) {
+    this.method = 'POST';
+    this.async = false;
+    if (typeof(callback)=="function") {
+        this.callback = callback;
+        this.async = true
+    }
+    if (typeof(callbackArgs)!="undefined") {
+        this.callbackArgs = callbackArgs;
+    }
+    if (this.async) {
+        this.process();
+    }
+    else {
+        return this.process();
+    }
+}
+
+/**
+ * Process a 'GET' request.
+ * @param {function} callback callback funtion
+ * @param {array} callbackArgs callback arguments
+ */
+XMLHttp.prototype.get = function(callback, callbackArgs) {
+    this.method = 'GET';
+    this.async = false;
+    if (typeof(callback)=="function") {
+        this.callback = callback;
+        this.async = true
+    }
+    if (typeof(callbackArgs)!="undefined") {
+        this.callbackArgs = callbackArgs;
+    }
+    if (this.async) {
+        this.process();
+    }
+    else {
+        return this.process();
+    }
+}
+
+
+//----------------------------------------------------------------------------
+// helper methods (can be used directly if you need enhanced access, but the 
+// method post and get are the prefered methods for processing a request.) 
+//----------------------------------------------------------------------------
+
+/** @private */
+XMLHttp.prototype.process = function() {
+
+    if (!this.xmlhttp) return false;
+
+    var self = this;
+    this.xmlhttp.onreadystatechange = function() {
+        if (self.xmlhttp == null) { return; }
+        if (self.xmlhttp.readyState == 1) { self._doLoading(self); }
+        if (self.xmlhttp.readyState == 2) { self._doLoaded(self); }
+        if (self.xmlhttp.readyState == 3) { self._doInteractive(self); }
+        if (self.xmlhttp.readyState == 4) { self._doComplete(self); }
+    };
+
+    try {
+        var args = null;
+        for (var i in this.parameters) {
+            if (this.argString.length>0) { this.argString += "&"; }
+            this.argString += encodeURIComponent(i) + "=" + encodeURIComponent(this.parameters[i]);
+        }
+        if (this.method == "GET") {
+            if (this.argString.length>0) {
+                this.url += ((this.url.indexOf("?")>-1)?"&":"?") + this.argString;
+            }
+            this.xmlhttp.open(this.method, this.url, this.async);
+        }
+        if (this.method == "POST") {
+            this.xmlhttp.open(this.method, this.url, this.async, this.username, this.password);
+            args = this.argString;
+        }
+        if (typeof(this.xmlhttp.setRequestHeader)!="undefined" && this.xmlhttp.readyState == 1) {
+            for (var i in this.headers) {
+                this.xmlhttp.setRequestHeader(i, this.headers[i]);
+            }
+        }
+        if (this.timeout > 0) {
+            setTimeout(this._doTimeout, this.timeout);
+        }
+        this.xmlhttp.send(args);
+    }
+    catch(z) { return false; }
+    /* on async call we return false and on sync calls we return the xmlhttp request */
+    if (this.async) {
+        return false;
+    }
+    else {
+        return this.xmlhttp;
+    }
+}
+
+
+//----------------------------------------------------------------------------
+// helper methods (can be used as a standalone cross browser xmlhttp request)
+//----------------------------------------------------------------------------
+
+/**
+ * Global helper function for a cross browser XMLHttpRequest object.
+ * @class This is a global helper function for a cross browser XMLHttpRequest object.
+ * @constructor 
+ * @return A XMLHttpRequest instance for gecko browsers and a ActiveXObjecct
+ * for ie browsers. Unsuported browsers get null returned.
+ */
+getXmlHttpRequest = function() {
+    if (window.XMLHttpRequest) {
+        var req = new XMLHttpRequest();
+        // some older versions of Moz did not support the readyState property
+        // and the onreadystate event so we patch it!
+        if (req.readyState == null) {
+            req.readyState = 1;
+            req.addEventListener("load", function () {
+                req.readyState = 4;
+                if (typeof req.onreadystatechange == "function") {
+                    req.onreadystatechange();
+                }
+            }, false);
+        }
+        return req;
+    }
+    else if (window.ActiveXObject) {
+        var MSXML_XMLHTTP_IDS = new Array(
+            "MSXML2.XMLHTTP.5.0",
+            "MSXML2.XMLHTTP.4.0",
+            "MSXML2.XMLHTTP.3.0",
+            "MSXML2.XMLHTTP",
+            "Microsoft.XMLHTTP");
+        var success = false;
+        for (var i = 0; i < MSXML_XMLHTTP_IDS.length && !success; i++) {
+            try {
+                return new ActiveXObject(MSXML_XMLHTTP_IDS[i]);
+                success = true;
+            } catch (e) {}
+        }
+    }
+    else {
+        return null;
+    }
+}
+
+
+//----------------------------------------------------------------------------
+// built in helper methods
+//----------------------------------------------------------------------------
+
+/** @private */
+XMLHttp.prototype._doLoading = function(self) {
+    if (self.isLoading) { return; }
+    if (typeof(self.onLoading)=="function") {
+        self.onLoading(self.xmlhttp);
+        }
+    self.isLoading = true;
+}
+
+/** @private */
+XMLHttp.prototype._doLoaded = function(self) {
+    if (self.isLoaded) { return; }
+    if (typeof(self.onLoaded)=="function") {
+        self.onLoaded(self.xmlhttp);
+    }
+    self.isLoaded = true;
+}
+
+/** @private */
+XMLHttp.prototype._doInteractive = function(self) {
+    if (self.isInteractive) { return; }
+    if (typeof(self.onInteractive)=="function") {
+        self.onInteractive(self.xmlhttp);
+    }
+    self.isInteractive = true;
+}
+
+/** @private */
+XMLHttp.prototype._doComplete = function(self) {
+    if (self.isComplete || self.isAborted) { return; }
+    self.isComplete = true;
+    self.status = self.xmlhttp.status;
+    self.statusText = self.xmlhttp.statusText;
+    self.responseText = self.xmlhttp.responseText;
+    self.responseXML = self.xmlhttp.responseXML;
+    if (typeof(self.onComplete)=="function") {
+        self.onComplete(self.xmlhttp);
+    }
+    if (self.xmlhttp.status==200 && typeof(self.callback)=="function") {
+        if (self.callbackArgs) {
+            self.callback(self.xmlhttp, self.callbackArgs);
+        }
+        else {
+            self.callback(self.xmlhttp);
+        }
+    }
+    if (self.xmlhttp.status!=200 && typeof(self.onError)=="function") {
+        self.onError(self.xmlhttp);
+    }
+    if (self.async) {
+        // on async calls, clean up so IE doesn't leak memory
+        delete self.xmlhttp['onreadystatechange'];
+        self.xmlhttp = null;
+    }
+}
+
+/** @private */
+XMLHttp.prototype._doTimeout = function(self) {
+    if (self.xmlhttp!=null && !self.isComplete) {
+        self.xmlhttp.abort();
+        self.isAborted = true;
+        if (typeof(self.onTimeout)=="function") {
+            self.onTimeout(self.xmlhttp);
+        }
+    // Opera won't fire onreadystatechange after abort, but other browsers do. 
+    // So we can't rely on the onreadystate function getting called. Clean up here!
+    delete self.xmlhttp['onreadystatechange'];
+    self.xmlhttp = null;
+    }
+}

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/browser.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/browser.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/browser.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Spreadsheet Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.viewlet.viewlet import CSSViewlet
+from z3c.form import field
+
+from z3c.formdemo.spreadsheet import content, spreadsheet
+
+
+SpreadsheetCSSViewlet = CSSViewlet('spreadsheet.css')
+
+class CandidateSpreadsheet(spreadsheet.Spreadsheet):
+
+    sessionKey = 'z3c.formdemo.spreadsheet.candidate'
+    rowFields = field.Fields(content.ICandidate)
+    columnWidths = (200, 200, 150)
+
+    def getContent(self):
+        return [obj for obj in self.context.values()
+                if content.ICandidate.providedBy(obj)]


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/browser.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,47 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <!-- Resources -->
+
+  <resourceDirectory
+      name="SpreadsheetImages"
+      directory="images/"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <zrt-resource
+      name="spreadsheet.css"
+      file="spreadsheet.css"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <viewlet
+      name="spreadsheet.css"
+      view=".browser.CandidateSpreadsheet"
+      manager="z3c.formdemo.skin.ICSS"
+      class=".browser.SpreadsheetCSSViewlet"
+      permission="zope.Public"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      weight="1000"
+      />
+
+  <!-- Spreadsheet views -->
+
+  <z3c:pagelet
+      name="spreadsheet.html"
+      for="*"
+      class=".browser.CandidateSpreadsheet"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="spreadsheet.pt"
+      for=".browser.CandidateSpreadsheet"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/content.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/content.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/content.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Spreadsheet Content
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+import zope.schema
+from zope.app.container import contained
+from zope.schema.fieldproperty import FieldProperty
+
+
+class ICandidate(zope.interface.Interface):
+
+    lastName = zope.schema.TextLine(
+        title=u'Last Name',
+        description=u'The last name of the person.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    firstName = zope.schema.TextLine(
+        title=u'First Name',
+        description=u'The first name of the person.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    rating = zope.schema.Choice(
+        title=u'Rating',
+        description=u'The rating of the candidate.',
+        values=[u'excellent', u'good', u'average', u'poor'],
+        required=False)
+
+
+class Candidate(contained.Contained):
+    zope.interface.implements(ICandidate)
+
+    lastName = FieldProperty(ICandidate['lastName'])
+    firstName = FieldProperty(ICandidate['firstName'])
+    rating = FieldProperty(ICandidate['rating'])
+
+    def __init__(self, lastName, firstName, rating=None):
+        self.lastName = lastName
+        self.firstName = firstName
+        self.rating = rating
+
+    def __repr__(self):
+        return '<%s %s %s>' %(
+            self.__class__.__name__, self.firstName, self.lastName)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/content.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/formatter.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/formatter.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/formatter.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""List Formatter Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from xml.sax.saxutils import quoteattr
+from zope.app.pagetemplate import ViewPageTemplateFile
+from zope.app.session.interfaces import ISession
+from zc.table import table, column, interfaces
+
+SORTED_ON_KEY = 'reflib.table.sorted-on'
+
+
+class ListFormatter(table.SortingFormatterMixin, table.AlternatingRowFormatter):
+    """Provides a width for each column."""
+
+    sortedHeaderTemplate = ViewPageTemplateFile('table_sorted_header.pt')
+
+    widths = None
+    columnCSS = None
+
+    def __init__(self, *args, **kw):
+        # Figure out sorting situation
+        kw['ignore_request'] = True
+        request = args[1]
+        prefix = kw.get('prefix')
+        session = ISession(request)[SORTED_ON_KEY]
+        if 'sort-on' in request:
+            name = request['sort-on']
+            if prefix and name.startswith(prefix):
+                name = name[len(prefix):]
+                oldName, oldReverse = session.get(prefix, (None, None))
+                if oldName == name:
+                    session[prefix] = (name, not oldReverse)
+                else:
+                    session[prefix] = (name, False)
+        # Now get the sort-on data from the session
+        if prefix in session:
+            kw['sort_on'] = [session[prefix]]
+
+        super(ListFormatter, self).__init__(*args, **kw)
+        self.columnCSS = {}
+
+        self.sortOn = (None, None)
+        if 'sort_on' in kw:
+            for name, reverse in kw['sort_on']:
+                self.columnCSS[name] = 'sorted-on'
+            self.sortOn = kw['sort_on'][0]
+
+    def getHeader(self, column):
+        contents = column.renderHeader(self)
+        if (interfaces.ISortableColumn.providedBy(column)):
+            contents = self._wrapInSortUI(contents, column)
+        return contents
+
+    def _wrapInSortUI(self, header, column):
+        name = column.name
+        if self.prefix:
+            name = self.prefix + name
+        isAscending = self.sortOn[0] == column.name and not self.sortOn[1]
+        isDecending = self.sortOn[0] == column.name and self.sortOn[1]
+        return self.sortedHeaderTemplate(
+            header=header, name=name,
+            isAscending=isAscending, isDecending=isDecending)
+
+    def renderContents(self):
+        """Avoid to render empty table (tr) rows."""
+        rows = self.renderRows()
+        if not rows:
+            return '  <thead%s>\n%s  </thead>\n' % (
+                self._getCSSClass('thead'), self.renderHeaderRow())
+        else:
+            return '  <thead%s>\n%s  </thead>\n  <tbody>\n%s  </tbody>\n' % (
+                self._getCSSClass('thead'), self.renderHeaderRow(),
+                rows)
+
+    def renderHeader(self, column):
+        width = ''
+        if self.widths:
+            idx = list(self.visible_columns).index(column)
+            width = ' width="%i"' %self.widths[idx]
+        klass = self.cssClasses.get('tr', '')
+        if column.name in self.columnCSS:
+            klass += klass and ' ' or '' + self.columnCSS[column.name]
+        return '      <th%s class=%s>\n        %s\n      </th>\n' % (
+            width, quoteattr(klass), self.getHeader(column))
+
+
+    def renderCell(self, item, column):
+        klass = self.cssClasses.get('tr', '')
+        if column.name in self.columnCSS:
+            klass += klass and ' ' or '' + self.columnCSS[column.name]
+        return '    <td class=%s>\n      %s\n    </td>\n' % (
+            quoteattr(klass), self.getCell(item, column))
+
+    def renderExtra(self):
+        """Avoid use of resourcelibrary in original class."""
+        return ''
+
+
+class SelectedItemFormatter(ListFormatter):
+
+    selectedItem = None
+
+    def renderRow(self, item):
+        self.row += 1
+        klass = self.cssClasses.get('tr', '')
+        if klass:
+            klass += ' '
+        if item == self.selectedItem:
+            klass += 'selected'
+        else:
+            klass += self.row_classes[self.row % 2]
+
+        return '  <tr class=%s>\n%s  </tr>\n' % (
+            quoteattr(klass), self.renderCells(item))


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/formatter.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/ascending.gif
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/ascending.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/decending.gif
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/images/decending.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.css
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.css	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.css	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,74 @@
+/* ----[ Layout ]----------------------------------------------------------- */
+
+h1 {
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+/* ----[ Form ]------------------------------------------------------------ */
+
+input.textWidget {
+  width: 150px;
+  padding: 2px;
+  background: white;
+}
+
+select.selectWidget {
+  width: 130px;
+  padding: 2px;
+}
+
+input[type=submit] {
+  background: #D91813;
+  color: white;
+  border: 1px solid #8C100D;
+  font-weight: bold;
+}
+
+/* ----[ Table ]------------------------------------------------------------ */
+
+th {
+  background: #D91813;
+  color: white;
+  padding: 4px;
+}
+
+th a {
+  color: white;
+}
+
+th a:link {
+  color: white;
+}
+
+th a:hover {
+  color: white;
+}
+
+th a:visited {
+  color: white;
+}
+
+th.sorted-on {
+  background: #8C100D;
+}
+
+td {
+  padding: 3px;
+}
+
+td.sorted-on {
+  background: #DDD;
+}
+
+tr.even {
+  background: #EEE;
+}
+
+tr.even td.sorted-on {
+  background: #CCC;
+}
+
+tr.odd {
+  background: #F6F6F6;
+}


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,6 @@
+<h1>Spreadsheet Demo &ndash; Candidate Evaluations</h1>
+
+<div metal:use-macro="macro:form">
+  <div metal:fill-slot="main"
+       tal:replace="structure view/table" />
+</div>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,163 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Spreadsheet Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+from zope.app.session.interfaces import ISession
+from z3c.form import button, field, form, interfaces
+from z3c.formui import layout
+from zc.table import table, column
+
+from z3c.formdemo.spreadsheet import content, formatter
+
+
+class SpreadsheetDataColumn(column.SortingColumn):
+
+    def __init__(self, field):
+        super(SpreadsheetDataColumn, self).__init__(field.title, field.__name__)
+
+    def renderCell(self, item, formatter):
+        return item.widgets[self.name].render()
+
+    def getSortKey(self, item, formatter):
+        return item.widgets[self.name].value
+
+
+class SpreadsheetActionsColumn(column.Column):
+
+    def __init__(self):
+        super(SpreadsheetActionsColumn, self).__init__(
+            u'Actions', 'actions')
+
+    def renderCell(self, item, formatter):
+        return '\n'.join(
+            [action.render() for action in item.actions.values()] )
+
+
+class AddRow(form.AddForm):
+    form.extends(form.AddForm)
+    prefix = 'add.'
+
+    def __init__(self, spreadsheet):
+        super(AddRow, self).__init__(spreadsheet.context, spreadsheet.request)
+        self.fields = spreadsheet.rowFields
+        self.sessionKey = spreadsheet.sessionKey
+
+    def create(self, data):
+        return content.Candidate(**data)
+
+    def add(self, object):
+        count = 0
+        while 'candidate-%i' %count in self.context:
+            count += 1;
+        self._name = 'candidate-%i' %count
+        self.context[self._name] = object
+        return object
+
+    def update(self):
+        super(AddRow, self).update()
+        if self._finishedAdd:
+            # Purposefully do not deactivate add-mode, so that multiple
+            # candidates can be added at once.
+            self.request.response.redirect(self.request.getURL())
+
+    @button.buttonAndHandler(u'Cancel')
+    def handleCancel(self, action):
+        ISession(self.request)[self.sessionKey]['add'] = False
+        self.request.response.redirect(self.request.getURL())
+
+
+class EditRow(form.EditForm):
+
+    def __init__(self, spreadsheet, content):
+        super(EditRow, self).__init__(spreadsheet.context, spreadsheet.request)
+        self.fields = spreadsheet.rowFields
+        self.content = content
+        self.prefix = content.__name__+'.'
+        self.sessionKey = spreadsheet.sessionKey
+
+    @property
+    def edit(self):
+        name = ISession(self.request)[self.sessionKey].get('edit')
+        return self.content.__name__ == name
+
+    def getContent(self):
+        return self.content
+
+    def updateWidgets(self):
+        self.widgets = zope.component.getMultiAdapter(
+            (self, self.request, self.getContent()), interfaces.IWidgets)
+        if not self.edit:
+            self.widgets.mode = interfaces.DISPLAY_MODE
+        self.widgets.update()
+
+    @button.buttonAndHandler(u'Edit', condition=lambda form: not form.edit)
+    def handleEdit(self, action):
+        ISession(self.request)[self.sessionKey]['edit'] = self.content.__name__
+        self.request.response.redirect(self.request.getURL())
+
+    @button.buttonAndHandler(u'Save', condition=lambda form: form.edit)
+    def handleSave(self, action):
+        self.handleApply(self, action)
+        if not self.widgets.errors:
+            ISession(self.request)[self.sessionKey]['edit'] = None
+            self.request.response.redirect(self.request.getURL())
+
+    @button.buttonAndHandler(u'Cancel', condition=lambda form: form.edit)
+    def handleCancel(self, action):
+        ISession(self.request)[self.sessionKey]['edit'] = None
+        self.request.response.redirect(self.request.getURL())
+
+
+class Spreadsheet(layout.FormLayoutSupport, form.Form):
+
+    sessionKey = 'z3c.formdemo.spreadsheet'
+    rowFields = None
+    columnWidths = None
+
+    @property
+    def add(self):
+        return ISession(self.request)[self.sessionKey].get('add', False)
+
+    @button.buttonAndHandler(u'Add', condition=lambda form: not form.add)
+    def handleAdd(self, action):
+        ISession(self.request)[self.sessionKey]['add'] = True
+        self.updateActions()
+
+    def update(self):
+        super(Spreadsheet, self).update()
+
+        rows = []
+        for candidate in self.getContent():
+            row = EditRow(self, candidate)
+            row.update()
+            rows.append(row)
+
+        if self.add:
+            row = AddRow(self)
+            row.update()
+            rows.append(row)
+
+        columns = [SpreadsheetDataColumn(field.field)
+                   for field in self.rowFields.values()]
+        columns.append(SpreadsheetActionsColumn())
+
+        self.table = formatter.SelectedItemFormatter(
+            self.context, self.request, rows,
+            prefix = self.sessionKey + '.', columns=columns,
+            sort_on=[('lastName', False)])
+        self.table.widths = self.columnWidths + (100,)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/spreadsheet.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/table_sorted_header.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/table_sorted_header.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/table_sorted_header.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,16 @@
+<html tal:omit-tag="">
+  <a href=""
+     tal:attributes="href string:${request/URL}?sort-on=${options/name}"
+     tal:content="options/header" />
+  &nbsp;
+  <img src="" width="7" height="4" style="vertical-align: middle"
+       alt="sort ascending"
+       tal:condition="options/isAscending"
+       tal:attributes="src
+           context/++resource++SpreadsheetImages/ascending.gif" />
+  <img src="" width="7" height="4" style="vertical-align: middle"
+       alt="sort ascending"
+       tal:condition="options/isDecending"
+       tal:attributes="src
+           context/++resource++SpreadsheetImages/decending.gif" />
+</html>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/spreadsheet/table_sorted_header.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/widgets/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/widgets/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/widgets/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/widgets/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/widgets/browser.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/widgets/browser.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/widgets/browser.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,83 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Widgets Demo Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import persistent
+import zope.interface
+import zope.component
+from zope.annotation import factory
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.publisher import browser
+from zope.schema.fieldproperty import FieldProperty
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.app.session.interfaces import ISession
+
+from z3c.form.interfaces import IWidgets
+from z3c.form import form, field
+from z3c.formdemo.widgets import interfaces
+from z3c.template.interfaces import ILayoutTemplate
+
+class AllFields(persistent.Persistent):
+
+    zope.interface.implements(interfaces.IAllFields)
+    zope.component.adapts(IAttributeAnnotatable)
+
+    asciiField = FieldProperty(interfaces.IAllFields['asciiField'])
+    asciiLineField = FieldProperty(interfaces.IAllFields['asciiLineField'])
+    boolField = FieldProperty(interfaces.IAllFields['boolField'])
+    bytesField = FieldProperty(interfaces.IAllFields['bytesField'])
+    bytesLineField = FieldProperty(interfaces.IAllFields['bytesLineField'])
+    choiceField = FieldProperty(interfaces.IAllFields['choiceField'])
+    dateField = FieldProperty(interfaces.IAllFields['dateField'])
+    datetimeField = FieldProperty(interfaces.IAllFields['datetimeField'])
+    decimalField = FieldProperty(interfaces.IAllFields['decimalField'])
+    dictField = FieldProperty(interfaces.IAllFields['dictField'])
+    dottedNameField = FieldProperty(interfaces.IAllFields['dottedNameField'])
+    floatField = FieldProperty(interfaces.IAllFields['floatField'])
+    frozenSetField = FieldProperty(interfaces.IAllFields['frozenSetField'])
+    idField = FieldProperty(interfaces.IAllFields['idField'])
+    intField = FieldProperty(interfaces.IAllFields['intField'])
+    listField = FieldProperty(interfaces.IAllFields['listField'])
+    objectField = FieldProperty(interfaces.IAllFields['objectField'])
+    passwordField = FieldProperty(interfaces.IAllFields['passwordField'])
+    setField = FieldProperty(interfaces.IAllFields['setField'])
+    sourceTextField = FieldProperty(interfaces.IAllFields['sourceTextField'])
+    textField = FieldProperty(interfaces.IAllFields['textField'])
+    textLineField = FieldProperty(interfaces.IAllFields['textLineField'])
+    timeField = FieldProperty(interfaces.IAllFields['timeField'])
+    timedeltaField = FieldProperty(interfaces.IAllFields['timedeltaField'])
+    tupleField = FieldProperty(interfaces.IAllFields['tupleField'])
+    uriField = FieldProperty(interfaces.IAllFields['uriField'])
+
+# register the AllField class as a annotation adapter
+getAllFields = factory(AllFields)
+
+
+class AllFieldsForm(form.EditForm):
+    """A form showing all fields."""
+    fields = field.Fields(interfaces.IAllFields).omit(
+        'dictField', 'objectField')
+
+    def getContent(self):
+        return interfaces.IAllFields(self.context)
+
+    def __call__(self):
+        self.update()
+        layout = zope.component.getMultiAdapter((self, self.request),
+            ILayoutTemplate)
+        return layout(self)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/widgets/browser.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/widgets/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/widgets/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/widgets/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,24 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <z3c:pagelet
+      name="widgets.html"
+      for="*"
+      class=".browser.AllFieldsForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="widgets.pt"
+      for=".browser.AllFieldsForm"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <adapter
+      factory=".browser.getAllFields"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/widgets/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/widgets/interfaces.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/widgets/interfaces.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/widgets/interfaces.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,186 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Widgets Demo Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import datetime
+import decimal
+import zope.interface
+import zope.schema
+from zope.schema import vocabulary
+
+vocab = vocabulary.SimpleVocabulary([
+    vocabulary.SimpleVocabulary.createTerm(1, '1', u'One'),
+    vocabulary.SimpleVocabulary.createTerm(2, '2', u'Two'),
+    vocabulary.SimpleVocabulary.createTerm(3, '3', u'Three'),
+    vocabulary.SimpleVocabulary.createTerm(4, '4', u'Four'),
+    vocabulary.SimpleVocabulary.createTerm(5, '5', u'Five')
+    ])
+
+class IObjectSchema(zope.interface.Interface):
+
+    field1 = zope.schema.TextLine(
+        title=u'Field 1')
+
+    field2 = zope.schema.Int(
+        title=u'Field 2')
+
+
+class IAllFields(zope.interface.Interface):
+    """An interface containing all possible fields."""
+
+    asciiField = zope.schema.ASCII(
+        title=u'ASCII',
+        description=u'This is an ASCII field.',
+        default='This is\n ASCII.')
+
+    asciiLineField = zope.schema.ASCIILine(
+        title=u'ASCII Line',
+        description=u'This is an ASCII-Line field.',
+        default='An ASCII line.')
+
+    boolField = zope.schema.Bool(
+        title=u'Boolean',
+        description=u'This is a Bool field.',
+        default=True)
+
+    bytesField = zope.schema.Bytes(
+        title=u'Bytes',
+        description=u'This is a Bytes field.',
+        default='\10\45\n\32')
+
+    bytesLineField = zope.schema.BytesLine(
+        title=u'Bytes Line',
+        description=u'This is a bytes line field.',
+        default='A Bytes line.')
+
+    choiceField = zope.schema.Choice(
+        title=u'Choice',
+        description=u'This is a choice field.',
+        default=3,
+        vocabulary=vocab)
+
+    optionalChoiceField = zope.schema.Choice(
+        title=u'Choice (Not Required)',
+        description=u'This is a non-required choice field.',
+        vocabulary=vocab,
+        required=False)
+
+    dateField = zope.schema.Date(
+        title=u'Date',
+        description=u'This is a Date field.',
+        default=datetime.date(2007, 4, 1))
+
+    datetimeField = zope.schema.Datetime(
+        title=u'Date/Time',
+        description=u'This is a Datetime field.',
+        default=datetime.datetime(2007, 4, 1, 12))
+
+    decimalField = zope.schema.Decimal(
+        title=u'Decimal',
+        description=u'This is a Decimal field.',
+        default=decimal.Decimal('12.87'))
+
+    dictField = zope.schema.Dict(
+        title=u'Dictionary',
+        description=u'This is a Dictionary field.',
+        key_type=zope.schema.TextLine(),
+        value_type=choiceField,
+        default={u'a': 1, u'c': 3})
+
+    dottedNameField = zope.schema.DottedName(
+        title=u'Dotted Name',
+        description=u'This is a DottedName field.',
+        default='z3c.form')
+
+    floatField = zope.schema.Float(
+        title=u'Float',
+        description=u'This is a Float field.',
+        default=12.8)
+
+    frozenSetField = zope.schema.FrozenSet(
+        title=u'Frozen Set',
+        description=u'This is a FrozenSet field.',
+        value_type=choiceField,
+        default=frozenset([1, 3]) )
+
+    idField = zope.schema.Id(
+        title=u'Id',
+        description=u'This is a Id field.',
+        default='z3c.form')
+
+    intField = zope.schema.Int(
+        title=u'Integer',
+        description=u'This is a Int field.',
+        default=12)
+
+    listField = zope.schema.List(
+        title=u'List',
+        description=u'This is a List field.',
+        value_type=choiceField,
+        default=[1, 3])
+
+    objectField = zope.schema.Object(
+        title=u'Object',
+        description=u'This is an Object field.',
+        schema=IObjectSchema)
+
+    passwordField = zope.schema.Password(
+        title=u'Password',
+        description=u'This is a Password field.',
+        default=u'mypwd')
+
+    setField = zope.schema.Set(
+        title=u'Set',
+        description=u'This is a Set field.',
+        value_type=choiceField,
+        default=set([1, 3]) )
+
+    sourceTextField = zope.schema.SourceText(
+        title=u'Source Text',
+        description=u'This is a SourceText field.',
+        default=u'<source />')
+
+    textField = zope.schema.Text(
+        title=u'Text',
+        description=u'This is a Text field.',
+        default=u'Some\n Text.')
+
+    textLineField = zope.schema.TextLine(
+        title=u'Text Line',
+        description=u'This is a TextLine field.',
+        default=u'Some Text line.')
+
+    timeField = zope.schema.Time(
+        title=u'Time',
+        description=u'This is a Time field.',
+        default=datetime.time(12, 0))
+
+    timedeltaField = zope.schema.Timedelta(
+        title=u'Time Delta',
+        description=u'This is a Timedelta field.',
+        default=datetime.timedelta(days=3))
+
+    tupleField = zope.schema.Tuple(
+        title=u'Tuple',
+        description=u'This is a Tuple field.',
+        value_type=choiceField,
+        default=(1, 3))
+
+    uriField = zope.schema.URI(
+        title=u'URI',
+        description=u'This is a URI field.',
+        default='http://zope.org')


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/widgets/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/widgets/widgets.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/widgets/widgets.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/widgets/widgets.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,2 @@
+<h1>Widget Demo</h1>
+<div metal:use-macro="macro:form" />


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/widgets/widgets.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/__init__.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/__init__.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/__init__.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/browser.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/browser.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/browser.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,117 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.app.session.interfaces import ISession
+from z3c.form import button, field, form
+from z3c.formdemo.wizard import content, interfaces, wizard
+from z3c.formui import layout
+
+
+infoSelection = (
+    'firstName', 'lastName', 'phone', 'email', 'street', 'city', 'zip')
+
+class PersonalInfoStep(wizard.Step):
+    label = u'Personal Information'
+    fields = field.Fields(interfaces.IPersonalInfo).select(
+        'firstName', 'lastName', 'phone', 'email')
+
+class AddressStep(wizard.Step):
+    label = u'Address'
+    fields = field.Fields(interfaces.IAddress)
+
+class FatherStep(wizard.Step):
+    label = u'Father'
+    fields = field.Fields(interfaces.IPersonalInfo).select(*infoSelection)
+
+    def getContent(self):
+        return self.context.father
+
+class MotherStep(wizard.Step):
+    label = u'Mother'
+    fields = field.Fields(interfaces.IPersonalInfo).select(*infoSelection)
+
+    def getContent(self):
+        return self.context.mother
+
+class EmployerStep(wizard.Step):
+    label = u'Employer'
+    fields = field.Fields(interfaces.IEmployerInfo).select(
+        'name', 'street', 'city', 'zip')
+
+    def getContent(self):
+        return self.context.employer
+
+
+class PersonWizard(wizard.Wizard):
+    form.extends(wizard.Wizard)
+
+    title = u'Wizard Demo - Person Demographics'
+    sessionKey = 'z3c.formdemo.wizard.person'
+
+    steps = [
+        ('personalInfo', PersonalInfoStep),
+        ('address', AddressStep),
+        ('father', FatherStep),
+        ('mother', MotherStep),
+        ('employer', EmployerStep)]
+
+    def finish(self):
+        self.request.response.redirect('summary.html')
+
+    def getContent(self):
+        session = ISession(self.request)[self.sessionKey]
+        obj = session.get('content')
+        if obj is None:
+            obj = session['content'] = content.Person()
+        return obj
+
+    @button.buttonAndHandler(
+        u'Clear', condition=lambda form: form.isFirstStep(),
+        provides=(interfaces.IBackButton,))
+    def handleClear(self, action):
+        session = ISession(self.request)[self.sessionKey]
+        del session['content']
+        self.request.response.redirect(
+            self.request.getURL() + '?step=' + self.steps[0][0])
+
+
+class PersonSummary(layout.FormLayoutSupport, form.DisplayForm):
+
+    fields = field.Fields(interfaces.IPersonalInfo).select(*infoSelection)
+
+    def getContent(self):
+        session = ISession(self.request)[PersonWizard.sessionKey]
+        return session.get('content')
+
+    def update(self):
+        content = self.getContent()
+        self.father = form.DisplayForm(content.father, self.request)
+        self.father.fields = field.Fields(interfaces.IPersonalInfo).select(
+            *infoSelection)
+        self.father.update()
+
+        self.mother = form.DisplayForm(content.mother, self.request)
+        self.mother.fields = field.Fields(interfaces.IPersonalInfo).select(
+            *infoSelection)
+        self.mother.update()
+
+        self.employer = form.DisplayForm(content.employer, self.request)
+        self.employer.fields = field.Fields(interfaces.IEmployerInfo).select(
+            'name', 'street', 'city', 'zip')
+        self.employer.update()
+
+        super(PersonSummary, self).update()


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/browser.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,34 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <include file="wizard.zcml" />
+
+  <class class=".content.Person">
+    <allow
+        interface=".interfaces.IPerson"
+        />
+    <require
+        permission="zope.Public"
+        set_schema=".interfaces.IPerson"
+        />
+  </class>
+
+  <!-- Summary -->
+
+  <z3c:pagelet
+      name="summary.html"
+      for="*"
+      class=".browser.PersonSummary"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="summary.pt"
+      for=".browser.PersonSummary"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/content.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/content.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/content.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Hello Worl Message Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from z3c.formdemo.wizard import interfaces
+
+class PersonalInfo(object):
+    zope.interface.implements(interfaces.IPersonalInfo)
+
+    lastName = FieldProperty(interfaces.IPersonalInfo['lastName'])
+    firstName = FieldProperty(interfaces.IPersonalInfo['firstName'])
+    email = FieldProperty(interfaces.IPersonalInfo['email'])
+    phone = FieldProperty(interfaces.IPersonalInfo['phone'])
+    street = FieldProperty(interfaces.IPersonalInfo['street'])
+    city = FieldProperty(interfaces.IPersonalInfo['city'])
+    zip = FieldProperty(interfaces.IPersonalInfo['zip'])
+
+    def __repr__(self):
+        return '<%s %s %s>' %(
+            self.__class__.__name__, self.firstName, self.lastName)
+
+
+class Employer(object):
+    zope.interface.implements(interfaces.IEmployerInfo)
+
+    name = FieldProperty(interfaces.IEmployerInfo['name'])
+    street = FieldProperty(interfaces.IEmployerInfo['street'])
+    city = FieldProperty(interfaces.IEmployerInfo['city'])
+    zip = FieldProperty(interfaces.IEmployerInfo['zip'])
+
+    def __repr__(self):
+        return '<%s %s>' %(self.__class__.__name__, self.name)
+
+
+class Person(PersonalInfo):
+
+    def __init__(self):
+        self.father = PersonalInfo()
+        self.mother = PersonalInfo()
+        self.employer = Employer()


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/content.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb.jpg
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb.jpg
___________________________________________________________________
Name: svn:mime-type
   + image/jpeg

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb_active.jpg
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/breadcrumb_active.jpg
___________________________________________________________________
Name: svn:mime-type
   + image/jpeg

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonLeftBG.gif
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonLeftBG.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonRightBG.gif
===================================================================
(Binary files differ)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/images/buttonRightBG.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/interfaces.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/interfaces.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/interfaces.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,122 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Person Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+import zope.schema
+from z3c.form import interfaces
+
+
+# ----[ Wizard Interfaces ]---------------------------------------------------
+
+class ISaveButton(interfaces.IButton):
+    """A button that causes the step data to be saved."""
+
+class IBackButton(interfaces.IButton):
+    """A button that returns to some previous state or screen."""
+
+class IForwardButton(interfaces.IButton):
+    """A button that returns to some next state or screen."""
+
+class IStep(zope.interface.Interface):
+    """An interface marking a step sub-form."""
+
+
+# ----[ Content Interfaces ]--------------------------------------------------
+
+class IAddress(zope.interface.Interface):
+
+    street = zope.schema.TextLine(
+        title=u'Street',
+        description=u'The street address.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    zip = zope.schema.TextLine(
+        title=u'Zip',
+        description=u'The zip code of the location.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    city = zope.schema.TextLine(
+        title=u'City',
+        description=u'The city.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+
+class IPersonalInfo(IAddress):
+
+    lastName = zope.schema.TextLine(
+        title=u'Last Name',
+        description=u'The last name of the person.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    firstName = zope.schema.TextLine(
+        title=u'First Name',
+        description=u'The first name of the person.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+    phone = zope.schema.TextLine(
+        title=u'Phone',
+        description=u'The phone number.',
+        default=u'',
+        missing_value=u'',
+        required=False)
+
+    email = zope.schema.TextLine(
+        title=u'Email',
+        description=u'The email address.',
+        required=False)
+
+
+class IEmployerInfo(IAddress):
+
+    name = zope.schema.TextLine(
+        title=u'Name',
+        description=u'The name of the employer.',
+        default=u'',
+        missing_value=u'',
+        required=True)
+
+
+class IPerson(IPersonalInfo):
+
+    father = zope.schema.Object(
+        title=u'Father',
+        description=u"Father's personal info.",
+        schema=IPersonalInfo,
+        required=True)
+
+    mother = zope.schema.Object(
+        title=u'Mother',
+        description=u"Mother's personal info.",
+        schema=IPersonalInfo,
+        required=True)
+
+    employer = zope.schema.Object(
+        title=u'Mother',
+        description=u"Mother's personal info.",
+        schema=IEmployerInfo,
+        required=True)


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/step.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/step.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/step.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+<div metal:use-macro="macro:widget-rows" />


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/step.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/summary.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/summary.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/summary.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,19 @@
+<h1>Person Summary</h1>
+
+<h2>Basic Information</h2>
+<div metal:use-macro="macro:widget-rows" />
+
+<h2>Father</h2>
+<div tal:define="view nocall:view/father">
+  <div metal:use-macro="macro:widget-rows" />
+</div>
+
+<h2>Mother</h2>
+<div tal:define="view nocall:view/mother">
+  <div metal:use-macro="macro:widget-rows" />
+</div>
+
+<h2>Employer</h2>
+<div tal:define="view nocall:view/employer">
+  <div metal:use-macro="macro:widget-rows" />
+</div>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/summary.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.css
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.css	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.css	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,115 @@
+/* zrt-replace: "images/" tal"string:${context/++resource++WizardImages}/" */
+
+/* [ layout ]--------------------------------------------------------------- */
+
+body {
+  background: #EEE;
+}
+
+div.wizard {
+  width: 600px;
+  font-family: Verdana, Arial, sans-serif;
+  background: white;
+  padding: 20px;
+}
+
+div.header {
+  background-color: #F9CA0B;
+  margin: 0;
+  padding: 10px;
+}
+
+div.header h1 {
+  font-weight: bold;
+  margin: 0;
+  padding: 0;
+}
+
+/* [ breadcrumbs ]---------------------------------------------------------- */
+
+table.breadcrumbs {
+  margin: 10px 0;
+  width: 100%;
+}
+
+table.breadcrumbs td div {
+  height: 25px;
+  width: 25px;
+  background-repeat: no-repeat;
+  background-position: center center;
+  margin-left: auto;
+  margin-right: auto;
+  font-weight: bold;
+  padding-top: 3px;
+  padding-left: 9px;
+}
+
+table.breadcrumbs td.active div {
+  background-image: url("images/breadcrumb_active.jpg");
+  color: #F9CA0B;
+}
+
+table.breadcrumbs td.inactive div {
+  background-image: url("images/breadcrumb.jpg");
+  color: white;
+}
+
+table.breadcrumbs td.inactive a {
+  color: inherit;
+}
+
+/* [ step ]----------------------------------------------------------------- */
+
+fieldset.step {
+  border: 1px solid #F9CA0B;
+  margin: 0;
+  padding: 10px 10px 5px 10px;
+}
+
+fieldset.step legend {
+  border: 1px solid #F9CA0B;
+  padding: 3px 7px;
+  font-size: 12px;
+  font-variant: small-caps;
+}
+
+
+/* [ buttons ]-------------------------------------------------------------- */
+
+div.buttons {
+  height: 15px;
+  margin: 10px 0px 0px 0px;
+  padding: 0;
+}
+
+span.forward {
+  float: right;
+}
+
+span.forward input[type="submit"] {
+    cursor: pointer;
+    border: 0;
+    color: #000000;
+    background-color: #F9CA0B;
+    background-image: url("images/buttonRightBG.gif");
+    background-repeat: no-repeat;
+    background-position: right;
+    border: 1px solid #A28204;
+    padding: 1px 15px 1px 2px;
+}
+
+span.back {
+  float: left;
+}
+
+span.back input[type="submit"] {
+    cursor: pointer;
+    border: 0;
+    color: #000000;
+    background-color: #F9CA0B;
+    background-image: url("images/buttonLeftBG.gif");
+    background-repeat: no-repeat;
+    background-position: left;
+    border: 1px solid #A28204;
+    padding: 1px 2px 1px 15px;
+}


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.css
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.pt
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.pt	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.pt	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,43 @@
+<div class="wizard">
+  <div class="header">
+    <h1 tal:content="view/title">Wizard</h1>
+  </div>
+  <table class="breadcrumbs"><tr>
+    <td tal:repeat="info view/stepsInfo"
+        tal:attributes="class info/class">
+      <div>
+        <span
+           tal:condition="info/active"
+           tal:content="info/number" />
+        <a href=""
+           tal:condition="not:info/active"
+           tal:attributes="href string:${request/URL}?step=${info/name}"
+           tal:content="info/number" />
+      </div>
+    </td>
+  </tr></table>
+  <div metal:use-macro="macro:form">
+    <fieldset class="step"
+              metal:fill-slot="main">
+      <legend tal:content="view/step/label">Label</legend>
+      <div class="status" tal:condition="view/step/status">
+        <div class="summary" tal:content="view/step/status">
+          Form status summary
+        </div>
+      </div>
+      <div tal:content="structure view/step/render" />
+    </fieldset>
+    <div class="buttons" metal:fill-slot="buttons">
+      <span class="back">
+        <input tal:repeat="action view/actions/backActions"
+             tal:replace="structure action/render"
+             />
+      </span>
+      <span class="forward">
+        <input tal:repeat="action view/actions/forwardActions"
+             tal:replace="structure action/render"
+             />
+      </span>
+    </div>
+  </div>
+</div>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.py
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.py	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.py	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,158 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.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.
+#
+##############################################################################
+"""Generic Wizard Implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+from zope.app.session.interfaces import ISession
+from zope.viewlet.viewlet import CSSViewlet
+
+from z3c.form import button, field, form, subform
+from z3c.form.interfaces import IWidgets
+from z3c.formui import layout
+from z3c.formdemo.wizard import interfaces
+
+WizardCSSViewlet = CSSViewlet('wizard.css')
+
+class IWizardButtons(zope.interface.Interface):
+
+    previous = button.Button(
+        title=u'Previous',
+        condition=lambda form: not form.isFirstStep())
+    zope.interface.alsoProvides(
+        previous, (interfaces.ISaveButton, interfaces.IBackButton))
+
+    save = button.Button(
+        title=u'Save')
+    zope.interface.alsoProvides(
+        save, (interfaces.ISaveButton, interfaces.IForwardButton))
+
+    next = button.Button(
+        title=u'Next',
+        condition=lambda form: not form.isLastStep())
+    zope.interface.alsoProvides(
+        next, (interfaces.ISaveButton, interfaces.IForwardButton))
+
+    finish = button.Button(
+        title=u'Finish',
+        condition=lambda form: form.isLastStep())
+    zope.interface.alsoProvides(
+        finish, (interfaces.ISaveButton, interfaces.IForwardButton))
+
+
+class Step(subform.EditSubForm):
+    zope.interface.implements(interfaces.IStep)
+    name = None
+    label = None
+
+    @button.handler(interfaces.ISaveButton)
+    def handleAllButtons(self, action):
+        self.handleApply(self, action)
+
+
+class WizardButtonActions(button.ButtonActions):
+
+    @property
+    def backActions(self):
+        return [action for action in self.values()
+                if interfaces.IBackButton.providedBy(action.field)]
+
+    @property
+    def forwardActions(self):
+        return [action for action in self.values()
+                if interfaces.IForwardButton.providedBy(action.field)]
+
+
+class Wizard(layout.FormLayoutSupport, form.Form):
+
+    sessionKey = 'z3c.formdemo.wizard'
+    buttons = button.Buttons(IWizardButtons)
+
+    title = u'Wizard'
+    steps = None
+    step = None
+
+    def getCurrentStep(self):
+        session = ISession(self.request)[self.sessionKey]
+        if 'step' in self.request:
+            name = self.request['step']
+            step = name, dict(self.steps).get(name)
+        else:
+            step = session.get('step', self.steps[0])
+        session['step'] = step
+        name, klass = step
+        inst = klass(self.getContent(), self.request, self)
+        inst.name = name
+        return inst
+
+    def isFirstStep(self):
+        return isinstance(self.step, self.steps[0][1])
+
+    def isLastStep(self):
+        return isinstance(self.step, self.steps[-1][1])
+
+    @property
+    def stepsInfo(self):
+        info = []
+        for pos, (name, step) in enumerate(self.steps):
+            info.append({
+                'name': name,
+                'number': str(pos+1),
+                'active': isinstance(self.step, step),
+                'class': isinstance(self.step, step) and 'active' or 'inactive'
+                })
+        return info
+
+    def updateActions(self):
+        self.actions = WizardButtonActions(self, self.request, self.context)
+        self.actions.update()
+
+    def update(self):
+        self.step = self.getCurrentStep()
+        self.updateActions()
+        self.step.update()
+        self.actions.execute()
+
+    def finish(self):
+        return NotImplementedError
+
+    @button.handler(IWizardButtons['previous'])
+    def handlePrevious(self, action):
+        if self.step.widgets.errors:
+            return
+        for pos, (name, step) in enumerate(self.steps):
+            if self.step.name == name:
+                break
+        url = self.request.getURL() + '?step=' + self.steps[pos-1][0]
+        self.request.response.redirect(url)
+
+
+    @button.handler(IWizardButtons['next'])
+    def handleNext(self, action):
+        if self.step.widgets.errors:
+            return
+        for pos, (name, step) in enumerate(self.steps):
+            if self.step.name == name:
+                break
+        url = self.request.getURL() + '?step=' + self.steps[pos+1][0]
+        self.request.response.redirect(url)
+
+
+    @button.handler(IWizardButtons['finish'])
+    def handleFinish(self, action):
+        session = ISession(self.request)[self.sessionKey]
+        del session['step']
+        self.finish()


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1,48 @@
+<configure
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="z3c.formdemo">
+
+  <resourceDirectory
+      name="WizardImages"
+      directory="images"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <zrt-resource
+      name="wizard.css"
+      file="wizard.css"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <viewlet
+      name="wizard.css"
+      view=".wizard.Wizard"
+      manager="z3c.formdemo.skin.ICSS"
+      class=".wizard.WizardCSSViewlet"
+      permission="zope.Public"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      weight="1000"
+      />
+
+  <z3c:pagelet
+      name="wizard.html"
+      for="*"
+      class=".browser.PersonWizard"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      permission="zope.Public"
+      />
+
+  <z3c:template
+      template="wizard.pt"
+      for=".wizard.Wizard"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+  <z3c:template
+      template="step.pt"
+      for=".interfaces.IStep"
+      layer="z3c.formdemo.layer.IDemoBrowserLayer"
+      />
+
+</configure>


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/wizard/wizard.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.formdemo/trunk/src/z3c/formdemo/z3c.formdemo-configure.zcml
===================================================================
--- z3c.formdemo/trunk/src/z3c/formdemo/z3c.formdemo-configure.zcml	                        (rev 0)
+++ z3c.formdemo/trunk/src/z3c/formdemo/z3c.formdemo-configure.zcml	2007-05-24 14:53:46 UTC (rev 75942)
@@ -0,0 +1 @@
+<include package="z3c.formdemo" />


Property changes on: z3c.formdemo/trunk/src/z3c/formdemo/z3c.formdemo-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list