[Zope3-checkins] SVN: Zope3/trunk/ Another small milestone:

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Feb 25 05:44:52 EST 2005


Log message for revision 29295:
  Another small milestone:
  
    * User Preferences allow you to customize the behavior while using 
      the tool.
           
    * Using the preferences, you can select which views and adapters you
      want to see by default in the interface details screen.
  
  
  

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/package-includes/apidoc-meta.zcml
  U   Zope3/trunk/src/zope/app/apidoc/browser/apidoc.css
  U   Zope3/trunk/src/zope/app/apidoc/browser/configure.zcml
  U   Zope3/trunk/src/zope/app/apidoc/browser/details_macros.pt
  A   Zope3/trunk/src/zope/app/apidoc/browser/harrow.png
  U   Zope3/trunk/src/zope/app/apidoc/browser/menu_macros.pt
  U   Zope3/trunk/src/zope/app/apidoc/browser/modules.pt
  A   Zope3/trunk/src/zope/app/apidoc/browser/utilities.js
  A   Zope3/trunk/src/zope/app/apidoc/browser/varrow.png
  U   Zope3/trunk/src/zope/app/apidoc/configure.zcml
  U   Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py
  U   Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml
  U   Zope3/trunk/src/zope/app/apidoc/ifacemodule/iface_macros.pt
  U   Zope3/trunk/src/zope/app/apidoc/ifacemodule/index.pt
  A   Zope3/trunk/src/zope/app/apidoc/ifacemodule/interfaces.py
  A   Zope3/trunk/src/zope/app/apidoc/meta.zcml
  A   Zope3/trunk/src/zope/app/apidoc/preference/
  A   Zope3/trunk/src/zope/app/apidoc/preference/README.txt
  A   Zope3/trunk/src/zope/app/apidoc/preference/__init__.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/browser.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/configure.zcml
  A   Zope3/trunk/src/zope/app/apidoc/preference/edit.pt
  A   Zope3/trunk/src/zope/app/apidoc/preference/interfaces.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/menu.pt
  A   Zope3/trunk/src/zope/app/apidoc/preference/meta.zcml
  A   Zope3/trunk/src/zope/app/apidoc/preference/metaconfigure.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/metadirectives.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/preference.py
  A   Zope3/trunk/src/zope/app/apidoc/preference/tests.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/doc/CHANGES.txt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -38,9 +38,15 @@
 
         * Views are now shown in the Interface details screen.
 
-        * Adapters are split into three categories: specific, extended, and
-          generic.
+        * Adapters and Views are split into three categories: specific,
+          extended, and generic.
 
+        * User Preferences allow you to customize the behavior while using the
+          tool.
+         
+        * Using the preferences, you can select which views and adapters you
+          want to see by default in the interface details screen.
+
       - Zope 3 can now listen on specified network interfaces only.  Example
         of a server section in zope.conf:
 

Modified: Zope3/trunk/package-includes/apidoc-meta.zcml
===================================================================
--- Zope3/trunk/package-includes/apidoc-meta.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/package-includes/apidoc-meta.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -1,5 +1 @@
-<configure xmlns:meta="http://namespaces.zope.org/meta">
-  <include package="zope.app.apidoc.codemodule" file="meta.zcml"/>
-  <include package="zope.app.apidoc.bookmodule" file="meta.zcml"/>
-  <meta:provides feature="apidoc" />
-</configure>
+<include package="zope.app.apidoc" file="meta.zcml"/>

Modified: Zope3/trunk/src/zope/app/apidoc/browser/apidoc.css
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/apidoc.css	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/apidoc.css	2005-02-25 10:44:51 UTC (rev 29295)
@@ -10,6 +10,10 @@
   font-size: 120%;
 }
 
+a[href] {
+  color: #0000c0;
+}
+
 ul {
     margin: 0;
     margin-left: 1.5em;
@@ -35,6 +39,11 @@
     font-weight: bold;
 }
 
+#preference_entry {
+    margin-top: 5pt;
+    font-style: italic;
+}
+
 p.small, div.small {
     font-size: 85%;
     padding: 4pt;

Modified: Zope3/trunk/src/zope/app/apidoc/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/configure.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/configure.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -26,6 +26,21 @@
       template="details_macros.pt"
       />
 
+  <resource 
+      name="utilities.js" 
+      file="utilities.js" 
+      />
+
+  <resource 
+      name="harrow.png" 
+      file="harrow.png" 
+      />
+
+  <resource 
+      name="varrow.png" 
+      file="varrow.png" 
+      />
+
   <pages
     for="zope.app.apidoc.apidoc.APIDocumentation"
     class=".apidoc.APIDocumentationView"

Modified: Zope3/trunk/src/zope/app/apidoc/browser/details_macros.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/details_macros.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/details_macros.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -17,6 +17,10 @@
       @import url(/++resource++apidoc.css);
     </style>
 
+    <script type="text/javascript" src="utilities.js"
+            tal:attributes="src string:${context/++resource++utilities.js}" >
+    </script>
+
     <metal:block define-slot="headers" />
     <metal:block define-slot="style_slot" />
     <metal:block define-slot="ecmascript_slot" />
@@ -32,3 +36,39 @@
 </body>
 </html>
 </metal:block>
+
+
+<metal:block define-macro="displaySwitch">
+
+  <a href="javascript:switchDisplay('')" style="text-decoration: none"
+     tal:attributes="href string:javascript:switchDisplay('${elementId}')">
+
+    <img src="/@@/harrow.png" border="0" id=".arrow"
+         style="vertical-align: middle"
+         tal:condition="not:show"
+         tal:attributes="id string:${elementId}.arrow" />
+  
+    <img src="/@@/varrow.png" border="0" id=".arrow"
+         style="vertical-align: middle"
+         tal:condition="show"
+         tal:attributes="id string:${elementId}.arrow" />
+  </a>
+
+</metal:block>
+
+
+<metal:block define-macro="display">
+
+  <div id="" style="display:;"
+       tal:condition="show"
+       tal:attributes="id elementId">
+    <metal:block define-slot="content" />
+  </div>
+
+  <div id="" style="display: none;"
+       tal:condition="not: show"
+       tal:attributes="id elementId">
+    <metal:block define-slot="content" />
+  </div>
+
+</metal:block>

Added: Zope3/trunk/src/zope/app/apidoc/browser/harrow.png
===================================================================
(Binary files differ)


Property changes on: Zope3/trunk/src/zope/app/apidoc/browser/harrow.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: Zope3/trunk/src/zope/app/apidoc/browser/menu_macros.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/menu_macros.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/menu_macros.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -31,7 +31,9 @@
 
 <body>
 
-  <div class="menu" i18n:translate="">Menu</div>
+  <metal:block define-slot="menu-title">
+    <div class="menu" i18n:translate="">Menu</div>
+  </metal:block>
  
   <metal:block define-slot="pre_menu" />
 

Modified: Zope3/trunk/src/zope/app/apidoc/browser/modules.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/modules.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/modules.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -17,6 +17,11 @@
         </a>
       </li>
     </ul>
+    <div id="preference_entry">
+      <a href="./++preferences++/@@menu.html" target="menu">
+        User Preferences
+      </a>
+    </div>
   </div>
 
 </body>

Added: Zope3/trunk/src/zope/app/apidoc/browser/utilities.js
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/browser/utilities.js	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/browser/utilities.js	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,56 @@
+function switchDisplay(id) {
+
+    if(document.getElementById) {
+       // DOM
+       var element = document.getElementById(id);
+    } else {
+        if(document.all) {
+            // Proprietary DOM
+            var element = document.all[id];
+        } else {
+            // Create an object to prevent errors further on
+            var element = new Object();
+        }
+    }
+
+    if(!element) {
+        /* The page has not loaded or the browser claims to support
+        document.getElementById or document.all but cannot actually
+        use either */
+        return;
+    }
+
+    // Reference the style ...
+    if (element.style) { 
+        style = element.style;
+    }
+
+    if (typeof(style.display) == 'undefined' &&
+        !( window.ScriptEngine && ScriptEngine().indexOf('InScript') + 1 ) ) {
+        //The browser does not allow us to change the display style
+        //Alert something sensible (not what I have here ...)
+        window.alert( 'Your browser does not support this' );
+        return;
+    }
+
+    // Change the display style
+    if (style.display == 'none') {
+        style.display = '';
+        switchImage(id, 'varrow.png'); 
+   }
+    else {
+        style.display = 'none'
+        switchImage(id, 'harrow.png'); 
+    }
+}
+
+function switchImage(id, name) {
+    if(document.getElementById) {
+       // DOM
+       var element = document.getElementById(id+'.arrow');
+    } else {
+       // Proprietary DOM
+       var element = document.all[id+'.arrow'];
+    }
+    element.src = '/@@/'+name;
+}
\ No newline at end of file

Added: Zope3/trunk/src/zope/app/apidoc/browser/varrow.png
===================================================================
(Binary files differ)


Property changes on: Zope3/trunk/src/zope/app/apidoc/browser/varrow.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: Zope3/trunk/src/zope/app/apidoc/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/configure.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/configure.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -64,6 +64,7 @@
       />
 
   <include package=".browser" />
+  <include package=".preference" />
 
   <!-- API Documentation Modules -->
   <include package=".bookmodule" />

Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -227,30 +227,29 @@
 
 
     def _prepareViews(self):
-        self.httpViews = []
-        self.browserViews = []
-        self.ftpViews = []
-        self.xmlrpcViews = []
-        self.otherViews = []
+        views = {IBrowserRequest: [], IXMLRPCRequest: [], IHTTPRequest: [],
+                 IFTPRequest: [], None: []}
+        type_map = {IBrowserRequest: 'Browser', IXMLRPCRequest: 'XMLRPC',
+                    IHTTPRequest: 'HTTP', IFTPRequest: 'FTP', None: 'Other'}
+        level_map = {'generic': component.GENERIC_INTERFACE_LEVEL,
+                     'extended': component.EXTENDED_INTERFACE_LEVEL,
+                     'specific': component.SPECIFIC_INTERFACE_LEVEL}
 
-        for reg in presentation.getViews(removeAllProxies(self.context)):
+        iface = removeAllProxies(self.context)
+
+        for reg in presentation.getViews(iface):
             type = presentation.getPresentationType(reg.required[-1])
-            info = presentation.getViewInfoDictionary(reg)
 
-            if type is IBrowserRequest:
-                self.browserViews.append(info)
-            elif type is IXMLRPCRequest:
-                self.xmlrpcViews.append(info)
-            elif type is IHTTPRequest:
-                self.httpViews.append(info)
-            elif type is IFTPRequest:
-                self.ftpViews.append(info)
-            else:
-                self.otherViews.append(info)
+            views[(type in views) and type or None].append(reg)
 
+
         sort_function = lambda x, y: cmp(x['name'], y['name']) 
-        self.httpViews.sort(sort_function)
-        self.browserViews.sort(sort_function)
-        self.ftpViews.sort(sort_function)
-        self.xmlrpcViews.sort(sort_function)
-        self.otherViews.sort(sort_function)
+
+        for type, sel_views in views.items():
+            for level, qualifier in level_map.items():
+                regs = tuple(component.filterAdapterRegistrations(
+                    sel_views, iface, level=qualifier))
+                infos = [presentation.getViewInfoDictionary(reg)
+                         for reg in regs]
+                infos.sort()
+                setattr(self, level+type_map[type]+'Views', infos)

Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -1,6 +1,7 @@
 <configure
     xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser">
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:apidoc="http://namespaces.zope.org/apidoc">
 
   <class class=".ifacemodule.InterfaceModule">
     <allow interface=".ifacemodule.IInterfaceModule" />
@@ -66,4 +67,10 @@
       template="menu.pt"
       />
 
+  <apidoc:preferencesGroup
+      name="InterfaceDetails"
+      schema=".interfaces.IInterfaceDetailsPreferences"
+      title="Interface Details" 
+      />
+
 </configure>

Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/iface_macros.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/iface_macros.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/iface_macros.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -56,6 +56,7 @@
   </div>
 </metal:block>
 
+
 <metal:block define-macro="attributes_fields">
   <div metal:define-slot="header">
     <h2 class="details-section" i18n:translate="">Attributes/Fields</h2>
@@ -83,3 +84,68 @@
 
   </div>
 </metal:block>
+
+
+<metal:block define-macro="views">
+  <div class="indent">    
+    <ul class="attr-list" tal:condition="Views">
+      <li tal:repeat="View Views">
+        <metal:block use-macro="context/@@interface_macros/View" />
+      </li>
+    </ul>
+    <p tal:condition="not:Views">
+      <em i18n:translate="">There are no views available.</em>
+    </p>
+  </div>
+</metal:block>
+
+
+<metal:block define-macro="viewcategory">
+<tal:block define="elementId string:views.${type}.${name}">
+
+  <h4>
+    <metal:block use-macro="context/@@apidoc_macros/displaySwitch" />
+    <span i18n:translate=""><span tal:replace="name" /> Views</span>
+  </h4>
+  <metal:block use-macro="context/@@apidoc_macros/display" >
+  <div metal:fill-slot="content">
+    <metal:block use-macro="context/@@interface_macros/views" />
+  </div>
+  </metal:block>
+
+</tal:block>
+</metal:block>
+
+
+<metal:block define-macro="viewtype">
+<tal:block define="elementId string:views.${type}">
+
+  <h3 class="details-section">
+    <metal:block use-macro="context/@@apidoc_macros/displaySwitch" />
+    <span i18n:translate="" tal:content="type">Browser</span>
+  </h3>
+  <metal:block use-macro="context/@@apidoc_macros/display" >
+  <div class="indent" metal:fill-slot="content">
+
+    <tal:block define="Views specific_views;
+                       name string:Specific;
+                       show show_specific">
+      <metal:block use-macro="context/@@interface_macros/viewcategory" />
+    </tal:block>
+
+    <tal:block define="Views extended_views;
+                       name string:Extended;
+                       show show_extended">
+      <metal:block use-macro="context/@@interface_macros/viewcategory" />
+    </tal:block>
+
+    <tal:block define="Views generic_views;
+                       name string:Generic;
+                       show show_generic">
+      <metal:block use-macro="context/@@interface_macros/viewcategory" />
+    </tal:block>
+
+  </div>
+  </metal:block>
+</tal:block>
+</metal:block>

Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/index.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/index.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/index.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -65,41 +65,79 @@
     
       <h3 i18n:translate="">Adapters where this interface is required:</h3>
     
-      <h4 i18n:translate="">Specific Adapters</h4>
-      <ul class="attr-list" 
-          tal:condition="specific_adapters">
-        <li tal:repeat="adapter specific_adapters">
-          <metal:block use-macro="context/@@interface_macros/adapter" />
-        </li>
-      </ul>
-      <p tal:condition="not:specific_adapters">
-        <em i18n:translate="">There are no specific adapters registered for
-            this interface.</em>
-      </p>
+      <div tal:define="
+  elementId string:adapters.required.specific;
+  show context/++preferences++InterfaceDetails/showSpecificRequiredAdapters">
+
+        <h4 i18n:translate="">
+          <metal:block use-macro="context/@@apidoc_macros/displaySwitch" />
+          Specific Adapters
+        </h4>
+        <metal:block use-macro="context/@@apidoc_macros/display" >
+        <div metal:fill-slot="content">
+          <ul class="attr-list" 
+              tal:condition="specific_adapters">
+            <li tal:repeat="adapter specific_adapters">
+              <metal:block use-macro="context/@@interface_macros/adapter" />
+            </li>
+          </ul>
+          <p tal:condition="not:specific_adapters">
+            <em i18n:translate="">There are no specific adapters registered 
+                for this interface.</em>
+          </p>
+        </div>
+        </metal:block>
+      </div>
     
-      <h4 i18n:translate="">Extended Adapters</h4>
-      <ul class="attr-list" 
-          tal:condition="extended_adapters">
-        <li tal:repeat="adapter extended_adapters">
-          <metal:block use-macro="context/@@interface_macros/adapter" />
-        </li>
-      </ul>
-      <p tal:condition="not:extended_adapters">
-        <em i18n:translate="">There are no extended adapters registered for
-            this interface.</em>
-      </p>
+      <div tal:define="
+  elementId string:adapters.required.extended;
+  show context/++preferences++InterfaceDetails/showExtendedRequiredAdapters">
+
+        <h4>
+          <metal:block use-macro="context/@@apidoc_macros/displaySwitch" />
+          <span i18n:translate="">Extended Adapters</span>
+        </h4>
+        <metal:block use-macro="context/@@apidoc_macros/display" >
+        <div metal:fill-slot="content">
+          <ul class="attr-list" 
+              tal:condition="extended_adapters">
+            <li tal:repeat="adapter extended_adapters">
+              <metal:block use-macro="context/@@interface_macros/adapter" />
+            </li>
+          </ul>
+          <p tal:condition="not:extended_adapters">
+            <em i18n:translate="">There are no extended adapters registered for
+                this interface.</em>
+          </p>
+        </div>
+        </metal:block>
+      </div>
+
+      <div tal:define="
+  elementId string:adapters.required.generic;
+  show context/++preferences++InterfaceDetails/showGenericRequiredAdapters">
+
+        <h4>
+          <metal:block use-macro="context/@@apidoc_macros/displaySwitch" />
+          <span i18n:translate="">Generic Adapters</span>
+        </h4>
+        <metal:block use-macro="context/@@apidoc_macros/display" >
+        <div metal:fill-slot="content">
+          <ul class="attr-list"
+              tal:condition="generic_adapters">
+            <li tal:repeat="adapter generic_adapters">
+              <metal:block use-macro="context/@@interface_macros/adapter" />
+            </li>
+          </ul>
+          <p tal:condition="not:generic_adapters">
+            <em i18n:translate="">
+              There are no generic adapters registered.
+            </em>
+          </p>
+        </div>
+        </metal:block>
+      </div>
     
-      <h4 i18n:translate="">Generic Adapters</h4>
-      <ul class="attr-list"
-          tal:condition="generic_adapters">
-        <li tal:repeat="adapter generic_adapters">
-          <metal:block use-macro="context/@@interface_macros/adapter" />
-        </li>
-      </ul>
-      <p tal:condition="not:generic_adapters">
-        <em i18n:translate="">There are no generic adapters registered.</em>
-      </p>
-    
     </div>
     
     <div class="indent" 
@@ -122,66 +160,100 @@
     </p>
   </div>
 
-  <div tal:define="Views view/browserViews"
-       tal:condition="Views">
+  <div>
 
     <h2 class="details-section" i18n:translate="">Views</h2>
 
     <div class="indent">
 
-      <tal:block condition="view/browserViews">
-        <h3 class="details-section" i18n:translate="">Browser</h3>
-        <div class="indent">    
-          <ul class="attr-list">
-            <li tal:repeat="View view/browserViews">
-              <metal:block use-macro="context/@@interface_macros/View" />
-            </li>
-          </ul>
-        </div>
+      <tal:block define="
+          type string:Browser;
+          specific_views view/specificBrowserViews;
+          extended_views view/extendedBrowserViews;
+          generic_views view/genericBrowserViews;
+          show context/++preferences++InterfaceDetails/showBrowserViews;
+          show_specific 
+            context/++preferences++InterfaceDetails/showSpecificBrowserViews;
+          show_extended
+            context/++preferences++InterfaceDetails/showExtendedBrowserViews;
+          show_generic
+            context/++preferences++InterfaceDetails/showGenericBrowserViews;
+          ">
+
+        <metal:block use-macro="context/@@interface_macros/viewtype" />
+
       </tal:block>
-  
-      <tal:block condition="view/xmlrpcViews">
-        <h3 class="details-section" i18n:translate="">XML-RPC</h3>
-        <div class="indent">    
-          <ul class="attr-list">
-            <li tal:repeat="View view/xmlrpcViews">
-              <metal:block use-macro="context/@@interface_macros/View" />
-            </li>
-          </ul>
-        </div>
+
+      <tal:block define="
+          type string:XML-RPC;
+          specific_views view/specificXMLRPCViews;
+          extended_views view/extendedXMLRPCViews;
+          generic_views view/genericXMLRPCViews;
+          show context/++preferences++InterfaceDetails/showXMLRPCViews;
+          show_specific 
+            context/++preferences++InterfaceDetails/showSpecificXMLRPCViews;
+          show_extended
+            context/++preferences++InterfaceDetails/showExtendedXMLRPCViews;
+          show_generic
+            context/++preferences++InterfaceDetails/showGenericXMLRPCViews;
+          ">
+
+        <metal:block use-macro="context/@@interface_macros/viewtype" />
+
       </tal:block>
-  
-      <tal:block condition="view/httpViews">
-        <h3 class="details-section" i18n:translate="">HTTP</h3>
-        <div class="indent">    
-          <ul class="attr-list">
-            <li tal:repeat="View view/httpViews">
-              <metal:block use-macro="context/@@interface_macros/View" />
-            </li>
-          </ul>
-        </div>
+
+      <tal:block define="
+          type string:HTTP;
+          specific_views view/specificHTTPViews;
+          extended_views view/extendedHTTPViews;
+          generic_views view/genericHTTPViews;
+          show context/++preferences++InterfaceDetails/showHTTPViews;
+          show_specific 
+            context/++preferences++InterfaceDetails/showSpecificHTTPViews;
+          show_extended
+            context/++preferences++InterfaceDetails/showExtendedHTTPViews;
+          show_generic
+            context/++preferences++InterfaceDetails/showGenericHTTPViews;
+          ">
+
+        <metal:block use-macro="context/@@interface_macros/viewtype" />
+
       </tal:block>
-  
-      <tal:block condition="view/ftpViews">
-        <h3 class="details-section" i18n:translate="">FTP</h3>
-        <div class="indent">    
-          <ul class="attr-list">
-            <li tal:repeat="View view/ftpViews">
-              <metal:block use-macro="context/@@interface_macros/View" />
-            </li>
-          </ul>
-        </div>
+
+      <tal:block define="
+          type string:FTP;
+          specific_views view/specificFTPViews;
+          extended_views view/extendedFTPViews;
+          generic_views view/genericFTPViews;
+          show context/++preferences++InterfaceDetails/showFTPViews;
+          show_specific 
+            context/++preferences++InterfaceDetails/showSpecificFTPViews;
+          show_extended
+            context/++preferences++InterfaceDetails/showExtendedFTPViews;
+          show_generic
+            context/++preferences++InterfaceDetails/showGenericFTPViews;
+          ">
+
+        <metal:block use-macro="context/@@interface_macros/viewtype" />
+
       </tal:block>
-  
-      <tal:block condition="view/otherViews">
-        <h3 class="details-section" i18n:translate="">Other</h3>
-        <div class="indent">    
-          <ul class="attr-list">
-            <li tal:repeat="View view/otherViews">
-              <metal:block use-macro="context/@@interface_macros/View" />
-            </li>
-          </ul>
-        </div>
+
+      <tal:block define="
+          type string:Other;
+          specific_views view/specificOtherViews;
+          extended_views view/extendedOtherViews;
+          generic_views view/genericOtherViews;
+          show context/++preferences++InterfaceDetails/showOtherViews;
+          show_specific 
+            context/++preferences++InterfaceDetails/showSpecificOtherViews;
+          show_extended
+            context/++preferences++InterfaceDetails/showExtendedOtherViews;
+          show_generic
+            context/++preferences++InterfaceDetails/showGenericOtherViews;
+          ">
+
+        <metal:block use-macro="context/@@interface_macros/viewtype" />
+
       </tal:block>
 
     </div>

Added: Zope3/trunk/src/zope/app/apidoc/ifacemodule/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/interfaces.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/interfaces.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,168 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Interface Documentation Module Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+import zope.schema
+
+class IInterfaceDetailsPreferences(zope.interface.Interface):
+    """
+    Preferences for API Docs' Interface Details Screen
+
+    It is possible to hide and show various sections of the interface details'
+    screen. The following preferences allow you to choose the sections to be
+    shown by default.
+    """
+
+    showSpecificRequiredAdapters = zope.schema.Bool(
+        title=u"Specific Required Interface Adapters",
+        description=u"Show specific required interface adapters",
+        required=False,
+        default=True)
+
+    showExtendedRequiredAdapters = zope.schema.Bool(
+        title=u"Extended Required Interface Adapters",
+        description=u"Show extended required interface adapters",
+        required=False,
+        default=True)
+
+    showGenericRequiredAdapters = zope.schema.Bool(
+        title=u"Generic Required Interface Adapters",
+        description=u"Show generic required interface adapters",
+        required=False,
+        default=False)
+
+    showBrowserViews = zope.schema.Bool(
+        title=u"Browser Views",
+        description=u"Show browser views",
+        required=False,
+        default=True)
+
+    showSpecificBrowserViews = zope.schema.Bool(
+        title=u"Specific Browser Views",
+        description=u"Show specific browser views",
+        required=False,
+        default=True)
+
+    showExtendedBrowserViews = zope.schema.Bool(
+        title=u"Extended Browser Views",
+        description=u"Show extended browser views",
+        required=False,
+        default=False)
+
+    showGenericBrowserViews = zope.schema.Bool(
+        title=u"Generic Browser Views",
+        description=u"Show generic browser views",
+        required=False,
+        default=False)
+
+    showXMLRPCViews = zope.schema.Bool(
+        title=u"XML-RPC Views",
+        description=u"Show XML-RPC views",
+        required=False,
+        default=False)
+
+    showSpecificXMLRPCViews = zope.schema.Bool(
+        title=u"Specific XML-RPC Views",
+        description=u"Show specific XML-RPC views",
+        required=False,
+        default=True)
+
+    showExtendedXMLRPCViews = zope.schema.Bool(
+        title=u"Extended XML-RPC Views",
+        description=u"Show extended XML-RPC views",
+        required=False,
+        default=False)
+
+    showGenericXMLRPCViews = zope.schema.Bool(
+        title=u"Generic XML-RPC Views",
+        description=u"Show generic XML-RPC views",
+        required=False,
+        default=False)
+
+    showHTTPViews = zope.schema.Bool(
+        title=u"Generic HTTP Views",
+        description=u"Show generic HTTP views",
+        required=False,
+        default=False)
+
+    showSpecificHTTPViews = zope.schema.Bool(
+        title=u"Specific HTTP Views",
+        description=u"Show specific HTTP views",
+        required=False,
+        default=True)
+
+    showExtendedHTTPViews = zope.schema.Bool(
+        title=u"Extended HTTP Views",
+        description=u"Show extended HTTP views",
+        required=False,
+        default=False)
+
+    showGenericHTTPViews = zope.schema.Bool(
+        title=u"Generic HTTP Views",
+        description=u"Show generic HTTP views",
+        required=False,
+        default=False)
+
+    showFTPViews = zope.schema.Bool(
+        title=u"FTP Views",
+        description=u"Show FTP views",
+        required=False,
+        default=False)
+
+    showSpecificFTPViews = zope.schema.Bool(
+        title=u"Specific FTP Views",
+        description=u"Show specific FTP views",
+        required=False,
+        default=True)
+
+    showExtendedFTPViews = zope.schema.Bool(
+        title=u"Extended FTP Views",
+        description=u"Show extended FTP views",
+        required=False,
+        default=False)
+
+    showGenericFTPViews = zope.schema.Bool(
+        title=u"Generic FTP Views",
+        description=u"Show generic FTP views",
+        required=False,
+        default=False)
+
+    showOtherViews = zope.schema.Bool(
+        title=u"Other Views",
+        description=u"Show other (unidentified) views",
+        required=False,
+        default=False)
+
+    showSpecificOtherViews = zope.schema.Bool(
+        title=u"Specific Other Views",
+        description=u"Show specific other views",
+        required=False,
+        default=True)
+
+    showExtendedOtherViews = zope.schema.Bool(
+        title=u"Extended Other Views",
+        description=u"Show extended other views",
+        required=False,
+        default=False)
+
+    showGenericOtherViews = zope.schema.Bool(
+        title=u"Generic Other Views",
+        description=u"Show generic other views",
+        required=False,
+        default=False)
+    


Property changes on: Zope3/trunk/src/zope/app/apidoc/ifacemodule/interfaces.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/meta.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/meta.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/meta.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,6 @@
+<configure xmlns:meta="http://namespaces.zope.org/meta">
+  <include package=".codemodule" file="meta.zcml"/>
+  <include package=".bookmodule" file="meta.zcml"/>
+  <include package=".preference" file="meta.zcml"/>
+  <meta:provides feature="apidoc" />
+</configure>


Property changes on: Zope3/trunk/src/zope/app/apidoc/meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/README.txt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/README.txt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,225 @@
+================
+User Preferences
+================
+
+Implementing user preferences is usually a painful task, since it requires a
+lot of custom coding and constantly changing preferences makes it hard to
+maintain the data and UI. The `preference` package
+
+  >>> from zope.app.apidoc.preference import preference
+
+eases this pain by providing a generic user preferences framework that uses
+schemas to categorize and describe the preferences.
+
+
+Preferences Groups
+------------------
+
+Preferences are grouped in preference groups and the preferences inside a
+group a spcified via the preferences group schema:
+
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IZMIUserSettings(zope.interface.Interface):
+  ...     """Basic User Preferences"""
+  ...
+  ...     email = zope.schema.TextLine(
+  ...         title=u"E-mail Address",
+  ...         description=u"E-mail Address used to send notifications")
+  ...
+  ...     skin = zope.schema.Choice(
+  ...         title=u"Skin",
+  ...         description=u"The skin that should be used for the ZMI.",
+  ...         values=['Rotterdam', 'ZopeTop', 'Basic'],
+  ...         default='Rotterdam')
+  ...
+  ...     showZopeLogo = zope.schema.Bool(
+  ...         title=u"Show Zope Logo",
+  ...         description=u"Specifies whether Zope logo should be displayed "
+  ...                     u"at the top of the screen.",
+  ...         default=True)
+
+Now we can instantiate the preference group. Each preference group must have a
+name by which it can be accessed and has an optional title field for UI
+purposes:
+
+  >>> settings = preference.PreferencesGroup(
+  ...     name="ZMISettings",
+  ...     schema=IZMIUserSettings,
+  ...     title=u"ZMI User Settings")
+
+Note that the preferences group provides the interface it is representing:
+
+  >>> IZMIUserSettings.providedBy(settings)
+  True
+
+and the name, schema and title of the group are directly available:
+
+  >>> settings.name
+  'ZMISettings'
+  >>> settings.schema
+  <InterfaceClass __builtin__.IZMIUserSettings>
+  >>> settings.title
+  u'ZMI User Settings'
+
+So let's ask the group for the skin setting:
+
+  >>> settings.skin #doctest:+ELLIPSIS
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: 
+  (<InterfaceClass ...interfaces.IPrincipalAnnotationUtility>, '')
+
+So why did the lookup fail? Because we have not specified a principal yet, for
+which we want to lookup the preferences. To do that, we have to create a new
+interaction:
+
+  >>> class Principal:
+  ...     def __init__(self, id):
+  ...         self.id = id
+  >>> principal = Principal('zope.user')
+
+  >>> class Participation:
+  ...     interaction = None
+  ...     def __init__(self, principal):
+  ...         self.principal = principal
+
+  >>> participation = Participation(principal)
+
+  >>> import zope.security.management
+  >>> zope.security.management.newInteraction(participation)
+
+We also need a principal annotations utility, in which we store the settings:
+
+  >>> from zope.app.principalannotation.interfaces import \
+  ...         IPrincipalAnnotationUtility
+  >>> class PrincipalAnnotations(dict):
+  ...     zope.interface.implements(IPrincipalAnnotationUtility)
+  ...
+  ...     def getAnnotations(self, principal):
+  ...         return self.setdefault(principal, {})
+
+  >>> annotations = PrincipalAnnotations()
+
+  >>> from zope.app.testing import ztapi
+  >>> ztapi.provideUtility(IPrincipalAnnotationUtility, annotations)
+
+Let's now try to access the settings again:
+
+  >>> settings.skin
+  'Rotterdam'
+
+which is the default value, since we have not set it yet. We can now reassign
+the value:
+
+  >>> settings.skin = 'Basic'
+  >>> settings.skin
+  'Basic'
+
+However, you cannot just enter any value, since it is validated before the
+assignment:
+
+  >>> settings.skin = 'MySkin'
+  Traceback (most recent call last):
+  ...
+  ConstraintNotSatisfied: MySkin  
+
+
+User Preferences
+----------------
+
+The various preferences groups are collectively available via the user
+preferences object:
+
+  >>> prefs = preference.UserPreferences()
+
+Using this objcet, you can access a list of all available groups
+
+  >>> prefs.items()
+  []
+
+But why did our new ZMI user settings group not appear? This is because we
+have to register it first as a preferences group:
+
+  >>> from zope.app.apidoc.preference.interfaces import IPreferencesGroup
+  >>> ztapi.provideUtility(IPreferencesGroup, settings, settings.name)
+
+Note that the name of the utility and the name saved in the group must be the
+same. Now let's try again:
+
+  >>> prefs.items() #doctest:+ELLIPSIS
+  [(u'ZMISettings', 
+    <zope.app.apidoc.preference.preference.PreferencesGroup object at ...>)]
+
+You can also just access one group at a time:
+
+  >>> prefs['ZMISettings'] #doctest:+ELLIPSIS
+  <zope.app.apidoc.preference.preference.PreferencesGroup object at ...>
+
+The entire `IReadContainer` interface is available.
+
+
+Traversal
+---------
+
+Okay, so all these objects are nice, but they do not make it any easier to
+access the preferences in page templates. Thus, a special traversal namespace
+has been created that makes it very simple to access the preferences via a
+traversal path. But before we can use the path expressions, we have to
+register all necessary traversal components and the special `preferences`
+namespace:
+
+  >>> from zope.app.testing import setup
+  >>> setup.setUpTraversal()
+
+  >>> import zope.app.traversing.interfaces
+  >>> ztapi.provideAdapter(None,
+  ...                      zope.app.traversing.interfaces.ITraversable,
+  ...                      preference.preferencesNamespace,
+  ...                      'preferences')
+
+We can now access the preferences as follows:
+
+  >>> from zope.app import zapi
+
+  >>> zapi.traverse(None, '++preferences++ZMISettings/skin')
+  'Basic'
+  >>> zapi.traverse(None, '++preferences++/ZMISettings/skin')
+  'Basic'
+
+
+Security
+--------
+
+You might already wonder under which permissions the preferences are
+available. They are actually available publically (`CheckerPublic`), but that
+is not a problem, since the available values are looked up specifically for
+the current user. And why should a user not have full access to his/her
+preferences? 
+
+Let's create a checker using the function that the security machinery is
+actually using:
+
+  >>> checker = preference.PreferencesGroupChecker(settings)
+  >>> checker.permission_id('skin')
+  Global(CheckerPublic,zope.security.checker)
+  >>> checker.setattr_permission_id('skin')
+  Global(CheckerPublic,zope.security.checker)
+
+The name, title and schema are publically available for access, but are not
+available for mutation at all:
+
+  >>> checker.permission_id('name')
+  Global(CheckerPublic,zope.security.checker)
+  >>> checker.setattr_permission_id('name') is None
+  True
+
+
+The only way security could be compromised is when one could override the
+annotations property. However, this property is not available for public
+consumption at all, including read access:
+
+  >>> checker.permission_id('annotation') is None
+  True
+  >>> checker.setattr_permission_id('annotation') is None
+  True


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/__init__.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/__init__.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1 @@
+# Make a package


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/browser.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/browser.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/browser.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,37 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""User Preferences Browser Views
+
+$Id: menu.py 29269 2005-02-23 22:22:48Z srichter $
+"""
+__docformat__ = 'restructuredtext'
+from zope.security.proxy import removeSecurityProxy
+from zope.app.pagetemplate.simpleviewclass import simple
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.app.form.browser.editview import EditView
+
+from zope.app.apidoc import utilities
+
+
+class EditPreferencesGroup(EditView):
+
+    def __init__(self, context, request):
+        self.__used_for__ = removeSecurityProxy(context.schema)
+        self.schema = removeSecurityProxy(context.schema)
+        self.label = context.title + ' Preferences'
+        super(EditPreferencesGroup, self).__init__(context, request)
+
+    def getIntroduction(self):
+        return utilities.renderText(self.schema.__doc__,
+                                    self.schema.__module__)


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/browser.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/configure.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/configure.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,49 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:browser="http://namespaces.zope.org/browser"
+  xmlns:apidoc="http://namespaces.zope.org/apidoc"
+  i18n_domain="zope">
+
+  <class class=".preference.UserPreferences">
+    <allow interface=".interfaces.IUserPreferences" 
+           attributes="__parent__ __name__" />
+  </class>
+
+  <view
+      name="preferences" type="*"
+      provides="zope.app.traversing.interfaces.ITraversable" for="*"
+      factory=".preference.preferencesNamespace"
+      />
+
+  <adapter
+      name="preferences"
+      provides="zope.app.traversing.interfaces.ITraversable" for="*"
+      factory=".preference.preferencesNamespace"
+      />
+
+  <!-- Browser Views -->
+
+  <browser:page
+      for=".interfaces.IUserPreferences"
+      permission="zope.Public"
+      name="menu.html"
+      template="menu.pt"
+      />
+
+  <browser:page
+      name="edit.html"
+      for=".interfaces.IPreferencesGroup"
+      class=".browser.EditPreferencesGroup"
+      template="edit.pt"
+      permission="zope.Public"
+      />
+
+  <!-- Books Chapter -->
+
+  <apidoc:bookchapter 
+      id="preferences"
+      title="User Preferences API"
+      doc_path="README.txt"
+      />
+
+</configure>


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/edit.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/edit.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/edit.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,123 @@
+<html metal:use-macro="context/@@apidoc_macros/details">
+<head>
+  <style type="text/css" media="all"
+         metal:fill-slot="style_slot">
+ 
+table.prefs {
+  border: 0pt;
+  width: 80%;
+}    
+
+tr {
+  margin: 0pt;
+  padding: 0pt;
+  border: 0pt;
+}
+
+tr.odd {
+  background: #fffbbe;
+}
+
+tr.first td {
+  border-top: 1pt solid #0000C0;
+}
+
+td {
+  padding: 3pt;
+  border-bottom: 1pt solid #0000C0;
+}
+
+td.input {
+  vertical-align: middle;
+  text-align: center;
+}
+
+td.description {
+
+}
+
+td.controls {
+  margin-top: 10pt;
+  border: 0pt;
+  padding: 4pt;
+  background: #ccf;
+  text-align: right;
+}
+
+td.spacer {
+  padding: 5pt;
+  border: 0pt;
+}
+
+div.documentation blockquote {
+  margin: 0pt;
+  padding: 0pt;
+}
+
+div.error {
+  font-weight: bold;
+  margin: 3pt 0pt;
+  color: #ffaa22;
+}
+  </style>
+</head>
+<body metal:fill-slot="contents">
+
+  <h1 tal:content="view/label">Edit something</h1>
+
+  <div class="documentation" tal:content="structure view/getIntroduction">
+    Here is the doc string
+  </div>
+
+  <p tal:define="status view/update"
+     tal:condition="status"
+     tal:content="status" />
+
+  <p tal:condition="view/errors" i18n:translate="">
+    There are <strong tal:content="python:len(view.errors)"
+                      i18n:name="num_errors">6</strong> input errors.
+  </p>
+  <br />
+
+  <form action="." tal:attributes="action request/URL" method="post"
+        enctype="multipart/form-data">
+      
+  <table class="prefs" cellspacing="0" cellpadding="0">
+    <tal:block repeat="widget view/widgets" >
+    <tr class=""
+        tal:define="parity repeat/widget/parity;
+                    firstrow repeat/widget/start"
+        tal:attributes="class python: parity + 
+                                      (firstrow and ' first' or '')">
+      <td class="description">
+        <b tal:content="widget/label">Option</b>
+        <div class="indent small">
+          <div tal:content="widget/hint">
+            Explanation
+          </div>
+          <div class="error" tal:define="error widget/error"
+            tal:condition="error" tal:content="structure error">
+            The Error
+          </div>
+        </div>
+      </td>
+      <td class="input" tal:content="structure widget">
+        <input type="text" style="width:100%"/>
+      </td>
+    </tr>
+    </tal:block>
+    <tr><td class="spacer"></td></tr>
+    <tr>
+      <td colspan="2" class="controls">
+        <input type="submit" value="Refresh" 
+            i18n:attributes="value refresh-button" />
+        <input type="submit" name="UPDATE_SUBMIT" value="Change" 
+            i18n:attributes="value submit-button"/>
+      </td>
+    </tr>
+  </table>
+
+  </form>
+
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/edit.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/interfaces.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/interfaces.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""User Preferences API
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import zope.interface
+import zope.schema
+
+from zope.app.container.interfaces import IReadContainer
+
+class IPreferencesGroup(zope.interface.Interface):
+    """A group of preferences.
+
+    This component represents a logical group of preferences. The preferences
+    contained by this group is defined through the schema. The group has also
+    a name by which it can be accessed.
+    """
+
+    name = zope.schema.TextLine(
+        title=u"Name",
+        description=u"The name of the group.",
+        required=True)
+
+    schema = zope.schema.InterfaceField(
+        title=u"Schema",
+        description=u"Schema describing the preferences of the group.",
+        required=True)
+
+    title = zope.schema.TextLine(
+        title=u"Title",
+        description=u"The title of the group used in the UI.",
+        required=True)
+
+
+class IUserPreferences(IReadContainer):
+    """Component that manages all preference groups."""
+
+    


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/interfaces.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/menu.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/menu.pt	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/menu.pt	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,19 @@
+<html metal:use-macro="views/apidoc_macros/menu">
+<body>
+
+  <div class="menu" metal:fill-slot="menu-title" i18n:translate="">
+    Preferences
+  </div>
+
+  <div metal:fill-slot="menu" class="small">
+    <ul>
+      <li tal:repeat="group context/values">
+        <a href="" target="main"
+           tal:attributes="href string:./${group/name}/edit.html" 
+           tal:content="group/title" />
+      </li>
+    </ul>
+  </div>
+
+</body>
+</html>


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/menu.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/meta.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/meta.zcml	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/meta.zcml	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,16 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta"
+    >
+
+  <meta:directives namespace="http://namespaces.zope.org/apidoc">
+
+    <meta:directive
+        name="preferencesGroup"
+        schema=".metadirectives.IPreferencesGroupDirective"
+        handler=".metaconfigure.preferencesGroup"
+        />
+
+  </meta:directives>
+
+</configure>


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/metaconfigure.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/metaconfigure.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""This module handles the 'apidoc' namespace directives.
+
+$Id: metaconfigure.py 26889 2004-08-04 04:00:36Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+from zope.app.component.metaconfigure import utility
+
+from zope.app.apidoc.preference import preference, interfaces
+
+
+def preferencesGroup(_context, name, schema, title):
+    group = preference.PreferencesGroup(name, schema, title)
+    utility(_context, interfaces.IPreferencesGroup, group, name=name)


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/metaconfigure.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/metadirectives.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/metadirectives.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""``apidoc:preferencesgroup`` ZCML directive interface
+
+$Id: metadirectives.py 26613 2004-07-18 21:50:40Z srichter $
+"""
+__docformat__ = 'restructuredtext'
+from zope.interface import Interface
+from zope.configuration import fields
+
+class IPreferencesGroupDirective(Interface):
+    """Register a preference group."""
+
+    name = fields.PythonIdentifier(
+        title=u"Name",
+        description=u"Name of the preference group used to access the group.",
+        required=True
+        )
+
+    schema = fields.GlobalInterface(
+        title=u"Schema",
+        description=u"Schema of the preference group used defining the "
+                    u"preferences of the group.",
+        required=True        
+        )
+
+    title = fields.MessageID(
+        title=u"Title",
+        description=u"Title of the preference group used in UIs.",
+        required=True
+        )


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/metadirectives.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/preference.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/preference.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/preference.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""User Preference System
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from BTrees.OOBTree import OOBTree
+
+import zope.interface
+from zope.schema import getFields
+from zope.security.checker import CheckerPublic, Checker, defineChecker
+from zope.security.management import getInteraction
+
+from zope.app import zapi
+from zope.app.container.contained import Contained
+from zope.app.location import LocationProxy, locate
+from zope.app.principalannotation.interfaces import IPrincipalAnnotationUtility
+
+from zope.app.apidoc.utilities import ReadContainerBase
+from zope.app.apidoc.preference import interfaces
+
+pref_key = 'zope.app.user.UserPreferences'
+
+class PreferencesGroup(object):
+
+    zope.interface.implements(interfaces.IPreferencesGroup)
+
+    name = None
+    schema = None
+    title = None
+
+    def __init__(self, name, schema, title=u''):
+        self.name = name
+        self.schema = schema
+        self.title = title
+        zope.interface.directlyProvides(self, self.schema)
+
+    def __getattr__(self, key):
+        if key in self.schema:
+            marker = object()
+            value = self.annotations.get(key, marker)
+            if value is marker:
+                return self.schema[key].default
+            return value
+        raise AttributeError, "'%s' is not a preference." %key
+
+    def __setattr__(self, key, value):
+        if self.schema and key in self.schema:
+            # Validate the value
+            bound = self.schema[key].bind(self)
+            bound.validate(value)
+            # Assign value
+            self.annotations[key] = value
+        else:
+            self.__dict__[key] = value
+            
+    def annotations(self):
+        utility = zapi.getUtility(IPrincipalAnnotationUtility)
+        # TODO: what if we have multiple participations
+        principal = getInteraction().participations[0].principal
+        ann = utility.getAnnotations(principal)
+
+        if  ann.get(pref_key) is None:
+            ann[pref_key] = OOBTree()
+        prefs = ann[pref_key]
+
+        if self.name not in prefs.keys():
+            prefs[self.name] = OOBTree()
+
+        return prefs[self.name]
+    annotations = property(annotations)
+
+
+def PreferencesGroupChecker(instance):
+    """A function that can be registered as a Checker in defineChecker()"""
+    read_perm_dict = {'name': CheckerPublic, 'schema': CheckerPublic,
+                      'title': CheckerPublic}
+    write_perm_dict = {}
+
+    for name in getFields(instance.schema):
+        read_perm_dict[name] = CheckerPublic
+        write_perm_dict[name] = CheckerPublic
+
+    return Checker(read_perm_dict, write_perm_dict)
+
+defineChecker(PreferencesGroup, PreferencesGroupChecker)
+
+
+class UserPreferences(ReadContainerBase, Contained):
+
+    zope.interface.implements(interfaces.IUserPreferences)
+
+    def get(self, key, default=None):
+        """See zope.app.container.interfaces.IReadContainer"""
+        group = zapi.queryUtility(interfaces.IPreferencesGroup, key, default)
+        if group == default:
+            return default
+        return LocationProxy(group, self, key)
+
+    def items(self):
+        """See zope.app.container.interfaces.IReadContainer"""
+        items = list(zapi.getUtilitiesFor(interfaces.IPreferencesGroup))
+        return [(key, LocationProxy(group, self, key))
+                for key, group in items]
+
+
+class preferencesNamespace(object):
+    """Used to traverse to an User Preferences."""
+    def __init__(self, ob, request=None):
+        self.context = ob
+        
+    def traverse(self, name, ignore):
+        prefs = UserPreferences()
+        locate(prefs, self.context, '++preferences++')
+        if not name:
+            return prefs
+        return prefs[name]


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/preference.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope3/trunk/src/zope/app/apidoc/preference/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/preference/tests.py	2005-02-25 03:38:07 UTC (rev 29294)
+++ Zope3/trunk/src/zope/app/apidoc/preference/tests.py	2005-02-25 10:44:51 UTC (rev 29295)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Tests for the Preferences System
+
+$Id: tests.py 29143 2005-02-14 22:43:16Z srichter $
+"""
+import unittest
+from zope.testing import doctest, doctestunit
+from zope.component.testing import setUp, tearDown
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite('README.txt',
+                             setUp=setUp, tearDown=tearDown,
+                             globs={'pprint': doctestunit.pprint},
+                             optionflags=doctest.NORMALIZE_WHITESPACE),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(default='test_suite')


Property changes on: Zope3/trunk/src/zope/app/apidoc/preference/tests.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Zope3-Checkins mailing list