[z3-checkins] r13139 - in z3/zopejam/trunk: pics src src/zcmledit src/zcmledit/tests src/zcmledit/tests/package src/zcmledit/tests/preserve src/zopejam src/zopejam/icons src/zopejam/icons/menu src/zopejam/icons/other src/zopejam/icons/toolbar tools

hathawsh at codespeak.net hathawsh at codespeak.net
Tue Jun 7 07:45:51 CEST 2005


Author: hathawsh
Date: Tue Jun  7 07:45:25 2005
New Revision: 13139

Added:
   z3/zopejam/trunk/pics/
   z3/zopejam/trunk/pics/zopejam.svg
   z3/zopejam/trunk/src/
   z3/zopejam/trunk/src/zcmledit/
   z3/zopejam/trunk/src/zcmledit/__init__.py
   z3/zopejam/trunk/src/zcmledit/configfile.py
   z3/zopejam/trunk/src/zcmledit/exceptions.py
   z3/zopejam/trunk/src/zcmledit/tests/
   z3/zopejam/trunk/src/zcmledit/tests/__init__.py
   z3/zopejam/trunk/src/zcmledit/tests/package/
   z3/zopejam/trunk/src/zcmledit/tests/package/__init__.py
   z3/zopejam/trunk/src/zcmledit/tests/preserve/
   z3/zopejam/trunk/src/zcmledit/tests/preserve/browser.zcml
   z3/zopejam/trunk/src/zcmledit/tests/preserve/conditions.zcml
   z3/zopejam/trunk/src/zcmledit/tests/preserve/root.zcml
   z3/zopejam/trunk/src/zcmledit/tests/root.zcml
   z3/zopejam/trunk/src/zcmledit/tests/test_configfile.py
   z3/zopejam/trunk/src/zopejam/
   z3/zopejam/trunk/src/zopejam/__init__.py
   z3/zopejam/trunk/src/zopejam/icons/
   z3/zopejam/trunk/src/zopejam/icons/COPYING.txt
   z3/zopejam/trunk/src/zopejam/icons/menu/
   z3/zopejam/trunk/src/zopejam/icons/menu/bomb.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/contents.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/editcopy.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/editcut.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/editdelete.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/editpaste.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/exit.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/fileclose.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/filenew.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/fileopen.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/filesave.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/filesaveas.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/filter.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/find.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/launch.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/project_open.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/redo.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/save_all.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/undo.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/menu/zopejam.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/other/
   z3/zopejam/trunk/src/zopejam/icons/other/clear_left.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/other/configure_toolbars.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/other/help.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/other/tree.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/other/zopejam.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/
   z3/zopejam/trunk/src/zopejam/icons/toolbar/back.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/editcopy.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/editcut.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/editpaste.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/fileclose.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/filenew.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/fileopen.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/filesave.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/filesaveas.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/filter.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/find.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/forward.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/launch.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/project_open.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/redo.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/save_all.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/icons/toolbar/undo.png   (contents, props changed)
   z3/zopejam/trunk/src/zopejam/main.py
   z3/zopejam/trunk/src/zopejam/resources.xrc
   z3/zopejam/trunk/tools/
   z3/zopejam/trunk/tools/cleanxrc.py
Log:
Initial import.


Added: z3/zopejam/trunk/pics/zopejam.svg
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/pics/zopejam.svg	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,617 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xap="http://ns.adobe.com/xap/1.0/"
+   xmlns:xapGImg="http://ns.adobe.com/xap/1.0/g/img/"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:ns="http://ns.adobe.com/SaveForWeb/1.0/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:xapMM="http://ns.adobe.com/xap/1.0/mm/"
+   xmlns:pdf="http://ns.adobe.com/pdf/1.3/"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+   xmlns:x="adobe:ns:meta/"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   width="48pt"
+   height="48pt"
+   viewBox="0 0 256 256"
+   overflow="visible"
+   enable-background="new 0 0 256 256"
+   xml:space="preserve"
+   id="svg3232"
+   sodipodi:version="0.34"
+   sodipodi:docname="/home/shane/zopejam.svg"
+   inkscape:version="0.37"
+   sodipodi:docbase="/home/shane/"><defs
+   id="defs3296"><linearGradient
+   id="linearGradient795"><stop
+   offset="0"
+   style="stop-color:#0053bd;stop-opacity:1;"
+   id="stop796" /><stop
+   offset="1"
+   style="stop-color:#0032a4;stop-opacity:1;"
+   id="stop797" /></linearGradient><linearGradient
+   id="linearGradient694"><stop
+   offset="0"
+   style="stop-color:#ffffff;stop-opacity:1;"
+   id="stop696" /><stop
+   offset="1"
+   style="stop-color:#94caff;stop-opacity:1;"
+   id="stop695" /></linearGradient><linearGradient
+   id="linearGradient690"><stop
+   offset="0"
+   style="stop-color:#ffffff;stop-opacity:1;"
+   id="stop693" /><stop
+   offset="0.59549999"
+   style="stop-color:#57adff;stop-opacity:1;"
+   id="stop692" /><stop
+   offset="0.99440002"
+   style="stop-color:#c9e6ff;stop-opacity:1;"
+   id="stop691" /></linearGradient><linearGradient
+   id="linearGradient1086"
+   gradientUnits="userSpaceOnUse"
+   x1="128.9995"
+   y1="11"
+   x2="128.9995"
+   y2="245.0005"><stop
+   offset="0.00000000"
+   style="stop-color:#494949;stop-opacity:1;"
+   id="stop1088" /><radialGradient
+   id="XMLID_16_"
+   cx="-57.0214996"
+   cy="439.631805"
+   r="97.9882965"
+   fx="-57.0214996"
+   fy="439.631805"
+   gradientTransform="matrix(1,0,0,-1,178.5,523.5)"
+   gradientUnits="userSpaceOnUse"
+   spreadMethod="pad"
+   xlink:href="#linearGradient690"><a:midPointStop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3969" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3970" /><a:midPointStop
+   offset="0.5955"
+   style="stop-color:#57ADFF"
+   id="midPointStop3971" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#57ADFF"
+   id="midPointStop3972" /><a:midPointStop
+   offset="0.9944"
+   style="stop-color:#C9E6FF"
+   id="midPointStop3973" /></radialGradient><linearGradient
+   id="XMLID_18_"
+   gradientUnits="userSpaceOnUse"
+   x1="-52.2509995"
+   y1="457.030304"
+   x2="-52.2509995"
+   y2="361.421997"
+   gradientTransform="matrix(1,0,0,-1,178.5,523.5)"
+   spreadMethod="pad"
+   xlink:href="#linearGradient694"><a:midPointStop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3988" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3989" /><a:midPointStop
+   offset="1"
+   style="stop-color:#94CAFF"
+   id="midPointStop3990" /></linearGradient><stop
+   offset="1.00000000"
+   style="stop-color:#000000;stop-opacity:1;"
+   id="stop1090" /><a:midPointStop
+   offset="0"
+   style="stop-color:#494949"
+   id="midPointStop1092" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#494949"
+   id="midPointStop1094" /><a:midPointStop
+   offset="1"
+   style="stop-color:#000000"
+   id="midPointStop1096" /></linearGradient><linearGradient
+   id="XMLID_7_"
+   gradientUnits="userSpaceOnUse"
+   x1="128.9995"
+   y1="11"
+   x2="128.9995"
+   y2="245.0005"><stop
+   offset="0"
+   style="stop-color:#494949"
+   id="stop3239" /><stop
+   offset="1"
+   style="stop-color:#000000"
+   id="stop3240" /><a:midPointStop
+   offset="0"
+   style="stop-color:#494949"
+   id="midPointStop3241" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#494949"
+   id="midPointStop3242" /><a:midPointStop
+   offset="1"
+   style="stop-color:#000000"
+   id="midPointStop3243" /></linearGradient><linearGradient
+   id="XMLID_8_"
+   gradientUnits="userSpaceOnUse"
+   x1="29.0532"
+   y1="29.0532"
+   x2="226.9471"
+   y2="226.9471"><stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3247" /><stop
+   offset="1"
+   style="stop-color:#DADADA"
+   id="stop3248" /><a:midPointStop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3249" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3250" /><a:midPointStop
+   offset="1"
+   style="stop-color:#DADADA"
+   id="midPointStop3251" /></linearGradient><linearGradient
+   id="XMLID_9_"
+   gradientUnits="userSpaceOnUse"
+   x1="128.0024"
+   y1="39.8628"
+   x2="128.0024"
+   y2="216.1587"><stop
+   offset="0"
+   style="stop-color:#003333"
+   id="stop3256" /><stop
+   offset="1"
+   style="stop-color:#006600"
+   id="stop3257" /><a:midPointStop
+   offset="0"
+   style="stop-color:#003333"
+   id="midPointStop3258" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#003333"
+   id="midPointStop3259" /><a:midPointStop
+   offset="1"
+   style="stop-color:#006600"
+   id="midPointStop3260" /></linearGradient><linearGradient
+   id="XMLID_10_"
+   gradientUnits="userSpaceOnUse"
+   x1="127.7437"
+   y1="211.125"
+   x2="127.7436"
+   y2="44.9092"><stop
+   offset="0"
+   style="stop-color:#009933"
+   id="stop3263" /><stop
+   offset="1"
+   style="stop-color:#00FF00"
+   id="stop3264" /><a:midPointStop
+   offset="0"
+   style="stop-color:#009933"
+   id="midPointStop3265" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#009933"
+   id="midPointStop3266" /><a:midPointStop
+   offset="1"
+   style="stop-color:#00FF00"
+   id="midPointStop3267" /></linearGradient><linearGradient
+   id="XMLID_11_"
+   gradientUnits="userSpaceOnUse"
+   x1="126.2256"
+   y1="55.0059"
+   x2="126.2256"
+   y2="283.1829"><stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3271" /><stop
+   offset="0.382"
+   style="stop-color:#00FF00"
+   id="stop3272" /><stop
+   offset="0.4331"
+   style="stop-color:#00FB02"
+   id="stop3273" /><stop
+   offset="0.4874"
+   style="stop-color:#00EE09"
+   id="stop3274" /><stop
+   offset="0.5432"
+   style="stop-color:#00D913"
+   id="stop3275" /><stop
+   offset="0.5997"
+   style="stop-color:#00BB22"
+   id="stop3276" /><stop
+   offset="0.6517"
+   style="stop-color:#009933"
+   id="stop3277" /><stop
+   offset="0.8258"
+   style="stop-color:#006600"
+   id="stop3278" /><a:midPointStop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3279" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3280" /><a:midPointStop
+   offset="0.382"
+   style="stop-color:#00FF00"
+   id="midPointStop3281" /><a:midPointStop
+   offset="0.6947"
+   style="stop-color:#00FF00"
+   id="midPointStop3282" /><a:midPointStop
+   offset="0.6517"
+   style="stop-color:#009933"
+   id="midPointStop3283" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#009933"
+   id="midPointStop3284" /><a:midPointStop
+   offset="0.8258"
+   style="stop-color:#006600"
+   id="midPointStop3285" /></linearGradient><radialGradient
+   id="XMLID_12_"
+   cx="100.5962"
+   cy="124.4897"
+   r="86.1955"
+   fx="100.5962"
+   fy="124.4897"
+   gradientTransform="matrix(0.826 -0.0247 -0.0247 0.738 18.1722 45.3572)"
+   gradientUnits="userSpaceOnUse"><stop
+   offset="0.3933"
+   style="stop-color:#FFFFFF"
+   id="stop3288" /><stop
+   offset="0.7303"
+   style="stop-color:#00E100"
+   id="stop3289" /><a:midPointStop
+   offset="0.3933"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3290" /><a:midPointStop
+   offset="0.5"
+   style="stop-color:#FFFFFF"
+   id="midPointStop3291" /><a:midPointStop
+   offset="0.7303"
+   style="stop-color:#00E100"
+   id="midPointStop3292" /></radialGradient><linearGradient
+   xlink:href="#linearGradient795"
+   id="linearGradient1084"
+   x1="-6.40992401e-3"
+   y1="0.45161226"
+   x2="1.00641036"
+   y2="0.45806444" /><radialGradient
+   xlink:href="#linearGradient690"
+   id="radialGradient1085"
+   cx="116.040085"
+   cy="-50.4208717"
+   r="150.534378"
+   fx="116.040085"
+   fy="-50.4208717"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="scale(1,-1)"
+   spreadMethod="pad" /><linearGradient
+   xlink:href="#linearGradient795"
+   id="linearGradient798" /><linearGradient
+   xlink:href="#linearGradient795"
+   id="linearGradient799"
+   x1="0.49640277"
+   y1="7.81239849e-3"
+   x2="0.49640277"
+   y2="0.94531262" /></defs><sodipodi:namedview
+   id="base"
+   inkscape:zoom="6.41666667"
+   inkscape:cx="24"
+   inkscape:cy="24"
+   inkscape:window-width="400"
+   inkscape:window-height="501"
+   inkscape:window-x="257"
+   inkscape:window-y="283" /><metadata
+   id="metadata3233"><ns:sfw><ns:slices><ns:slice
+   x="0"
+   y="0"
+   width="256"
+   height="256"
+   sliceID="124165071" /></ns:slices><ns:sliceSourceBounds
+   x="0"
+   y="0"
+   width="256"
+   height="256"
+   bottomLeftOrigin="true" /><ns:optimizationSettings><ns:targetSettings
+   fileFormat="PNG24Format"
+   targetSettingsID="0"><ns:PNG24Format
+   transparency="true"
+   includeCaption="false"
+   interlaced="false"
+   noMatteColor="false"
+   matteColor="#FFFFFF"
+   filtered="false" /></ns:targetSettings></ns:optimizationSettings></ns:sfw><xpacket>begin='' id='W5M0MpCehiHzreSzNTczkc9d'</xpacket><x:xmpmeta
+   x:xmptk="XMP toolkit 3.0-29, framework 1.6"><rdf:RDF><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43"><pdf:Producer>
+Adobe PDF library 5.00</pdf:Producer></rdf:Description><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43" /><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43" /><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43"><xap:CreateDate>
+2004-01-26T11:58:28+02:00</xap:CreateDate><xap:ModifyDate>
+2004-03-28T20:35:22Z</xap:ModifyDate><xap:CreatorTool>
+Adobe Illustrator 10.0</xap:CreatorTool><xap:MetadataDate>
+2004-02-16T23:09:30+01:00</xap:MetadataDate><xap:Thumbnails><rdf:Alt><rdf:li
+   rdf:parseType="Resource"><xapGImg:format>
+JPEG</xapGImg:format><xapGImg:width>
+256</xapGImg:width><xapGImg:height>
+256</xapGImg:height><xapGImg:image>
+/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
+AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
+DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
+Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER
+AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
+AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
+UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
+1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
+qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
+obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
+0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
++DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
+FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqlvmDzFo
+3l7TJdT1e5W1tItuTbszHoiKN2Y+AxV4j5g/5ydvTcMnl/SYlgU0Se/LOzDxMcTIF/4M4qk//QzP
+nv8A5YNL/wCRVx/2UYq7/oZnz3/ywaX/AMirj/soxV3/AEMz57/5YNL/AORVx/2UYq7/AKGZ89/8
+sGl/8irj/soxV3/QzPnv/lg0v/kVcf8AZRirv+hmfPf/ACwaX/yKuP8AsoxV3/QzPnv/AJYNL/5F
+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
+FX//2Q==</xapGImg:image></rdf:li></rdf:Alt></xap:Thumbnails></rdf:Description><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43"><xapMM:DocumentID>
+uuid:ed137d39-db88-465a-86b4-e2eb2fd20abb</xapMM:DocumentID></rdf:Description><rdf:Description
+   rdf:about="uuid:6fb7133e-0d42-4d20-8954-32780fe62e43"><dc:format>
+image/svg+xml</dc:format><dc:title><rdf:Alt><rdf:li
+   xml:lang="x-default">
+mime.ai</rdf:li></rdf:Alt></dc:title></rdf:Description></rdf:RDF></x:xmpmeta><xpacket>end='w'</xpacket></metadata><path
+   fill="url(#XMLID_15_)"
+   d="M 58.83625 58.89484 C 39.59918 78.00364 29.00373 103.2714 29.00373 130.044 C 29.00373 185.7817 74.46665 231.1257 130.3488 231.1257 C 186.2372 231.1257 231.7017 185.7817 231.7017 130.044 C 231.7017 74.48474 186.2372 29.28044 130.3488 29.28044 C 103.4539 29.28364 78.05772 39.79844 58.83625 58.89484 z "
+   id="path803"
+   style="font-size:12;fill:#000000;opacity:0.2156;fill-opacity:1;" /><path
+   fill="url(#XMLID_15_)"
+   d="M 56.35883 56.41743 C 37.12176 75.52625 26.52632 100.794 26.52632 127.5666 C 26.52632 183.3043 71.98923 228.6483 127.8713 228.6483 C 183.7597 228.6483 229.2242 183.3043 229.2242 127.5666 C 229.2242 72.00731 183.7597 26.80305 127.8713 26.80305 C 100.9765 26.80616 75.5803 37.32105 56.35883 56.41743 z "
+   id="path3962"
+   style="font-size:12;fill:#000000;opacity:0.3958;fill-opacity:1;" /><path
+   fill="url(#XMLID_18_)"
+   enable-background="new    "
+   d="M 125.8747 104.7783 C 158.6185 104.7783 187.1046 94.55378 201.7597 79.48209 C 187.0015 53.95461 158.4854 36.53116 125.7336 36.53116 C 93.26706 36.53259 64.71442 53.89571 49.86267 79.35136 C 64.47981 94.492 93.03402 104.7783 125.8747 104.7783 z "
+   id="path3991"
+   style="font-size:12;fill:url(#XMLID_18_);opacity:0.5521;" /><path
+   fill="url(#XMLID_16_)"
+   d="M 126.2196 223.2482 C 180.5628 223.2482 224.6499 178.9784 224.6499 124.6682 C 224.6499 70.70555 180.566 26.42924 126.2196 26.42924 C 72.26167 26.43087 27.80074 70.70555 27.80074 124.6682 C 27.80074 178.9784 72.2633 223.2482 126.2196 223.2482 z "
+   id="path3974"
+   style="font-size:12;fill:url(#radialGradient1085);opacity:1;fill-rule:evenodd;" /><text
+   style="fill:url(#linearGradient799);stroke:none;font-family:helvetica;font-style:normal;font-weight:normal;font-size:12px;fill-opacity:1;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;"
+   x="2.1332933"
+   y="11.9244692"
+   id="text685"
+   transform="scale(21.67246,15.99746)"><tspan
+   id="tspan686"
+   style="stroke:none;stroke-opacity:1;fill:url(#linearGradient799);fill-opacity:1;">Z</tspan></text><path
+   fill="url(#XMLID_18_)"
+   enable-background="new    "
+   d="M 126.2893 104.7783 C 159.9232 104.7783 189.1838 94.67739 204.2372 79.78808 C 189.0777 54.56949 159.7866 37.35685 126.1445 37.35685 C 92.79536 37.35829 63.46657 54.51129 48.21108 79.65893 C 63.22557 94.61638 92.556 104.7783 126.2893 104.7783 z "
+   id="path800"
+   style="font-size:12;fill:url(#XMLID_18_);opacity:0.7031;" /><path
+   fill="url(#XMLID_16_)"
+   d="M 125.3939 219.9451 C 177.9134 219.9451 220.521 177.347 220.521 125.0875 C 220.521 73.16263 177.9165 30.55826 125.3939 30.55826 C 73.24694 30.55983 30.27815 73.16263 30.27815 125.0875 C 30.27815 177.347 73.24852 219.9451 125.3939 219.9451 z "
+   id="path689"
+   style="font-size:12;fill:none;stroke:url(#linearGradient1084);stroke-width:11.54162;stroke-opacity:1;" /><path
+   opacity="0.2"
+   d="M 129.61 37.54335 C 127.821 38.36235 126.666 40.16135 126.666 42.12735 L 126.838 43.43035 C 126.838 43.43035 155.096 148.8934 155.981 152.1944 C 151.968 150.9984 147.7 150.2194 143.232 149.9284 C 134.699 149.3744 126.659 150.6304 121.175 153.3734 C 121.219 153.3524 121.277 153.3214 121.322 153.3024 C 110.442 157.7684 101.4 167.1724 98.28597 177.2624 C 97.51397 179.7644 97.12197 182.2734 97.12197 184.7174 C 97.12197 188.9154 98.30197 192.9074 100.535 196.2634 C 105.263 204.0514 113.33 209.6794 123.231 212.0764 C 132.77 214.3864 143.638 213.6024 153.833 209.8704 C 153.9 209.8444 153.979 209.8144 153.979 209.8144 C 166.778 204.4834 175.32 197.1804 178.745 188.6724 C 179.844 185.9394 180.401 183.1184 180.401 180.2904 C 180.401 177.2304 179.738 174.0984 178.439 170.9784 C 178.419 170.9054 158.104 95.09135 157.133 91.46735 C 159.373 92.36335 162.854 93.75435 162.854 93.75435 C 170.139 96.56035 178.396 99.74135 185.319 104.6354 C 192.919 110.0084 197.692 116.6484 199.912 124.9354 C 200.584 127.4414 203.021 129.0204 205.583 128.6094 C 208.145 128.1984 209.966 125.9344 209.818 123.3434 C 208.203 95.08135 191.013 83.91035 172.815 72.08335 C 159.912 63.69435 146.577 55.02635 135.881 39.29235 C 134.492 37.25135 131.855 36.51535 129.61 37.54335 z "
+   id="path3253"
+   style="font-size:12;opacity:0.2;" /><path
+   opacity="0.2"
+   d="M 127.61 36.54335 C 125.821 37.36235 124.666 39.16135 124.666 41.12735 L 124.838 42.43035 C 124.838 42.43035 153.096 147.8934 153.981 151.1944 C 149.968 149.9984 145.7 149.2194 141.232 148.9284 C 132.699 148.3744 124.659 149.6304 119.175 152.3734 C 119.219 152.3524 119.277 152.3214 119.322 152.3024 C 108.442 156.7684 99.39997 166.1724 96.28597 176.2624 C 95.51397 178.7644 95.12197 181.2734 95.12197 183.7174 C 95.12197 187.9154 96.30197 191.9074 98.53497 195.2634 C 103.263 203.0514 111.33 208.6794 121.231 211.0764 C 130.77 213.3864 141.638 212.6024 151.833 208.8704 C 151.9 208.8444 151.979 208.8144 151.979 208.8144 C 164.778 203.4834 173.32 196.1804 176.745 187.6724 C 177.844 184.9394 178.401 182.1184 178.401 179.2904 C 178.401 176.2304 177.738 173.0984 176.439 169.9784 C 176.419 169.9054 156.104 94.09135 155.133 90.46735 C 157.373 91.36335 160.854 92.75435 160.854 92.75435 C 168.139 95.56035 176.396 98.74135 183.319 103.6354 C 190.919 109.0084 195.692 115.6484 197.912 123.9354 C 198.584 126.4414 201.021 128.0204 203.583 127.6094 C 206.145 127.1984 207.966 124.9344 207.818 122.3434 C 206.203 94.08135 189.013 82.91035 170.815 71.08435 C 157.912 62.69535 144.577 54.02735 133.881 38.29335 C 132.492 36.25135 129.855 35.51535 127.61 36.54335 z "
+   id="path3254"
+   style="font-size:12;opacity:0.2;" /><path
+   fill="url(#XMLID_9_)"
+   d="M 125.61 34.54335 C 123.821 35.36235 122.666 37.16135 122.666 39.12735 L 122.838 40.43035 C 122.838 40.43035 151.096 145.8934 151.981 149.1944 C 147.968 147.9984 143.7 147.2194 139.232 146.9284 C 130.699 146.3744 122.659 147.6304 117.175 150.3734 C 117.219 150.3524 117.277 150.3214 117.322 150.3024 C 106.442 154.7684 97.39997 164.1724 94.28597 174.2624 C 93.51397 176.7644 93.12197 179.2734 93.12197 181.7174 C 93.12197 185.9154 94.30197 189.9074 96.53497 193.2634 C 101.263 201.0514 109.33 206.6794 119.231 209.0764 C 128.77 211.3864 139.638 210.6024 149.834 206.8704 C 149.901 206.8444 149.979 206.8144 149.979 206.8144 C 162.778 201.4834 171.32 194.1804 174.745 185.6724 C 175.844 182.9394 176.401 180.1184 176.401 177.2904 C 176.401 174.2304 175.738 171.0984 174.439 167.9784 C 174.419 167.9054 154.104 92.09135 153.133 88.46735 C 155.373 89.36335 158.854 90.75435 158.854 90.75435 C 166.139 93.56035 174.396 96.74135 181.319 101.6354 C 188.919 107.0084 193.692 113.6484 195.912 121.9354 C 196.584 124.4404 199.021 126.0194 201.583 125.6084 C 204.145 125.1974 205.966 122.9334 205.818 120.3424 C 204.203 92.08035 187.013 80.90935 168.815 69.08335 C 155.912 60.69435 142.577 52.02635 131.881 36.29235 C 130.492 34.25135 127.855 33.51535 125.61 34.54335 z "
+   id="path3261"
+   style="font-size:12;fill:url(#XMLID_9_);" /><path
+   fill="url(#XMLID_10_)"
+   d="M 145.046 78.72135 C 156.868 88.04435 192.418 90.36435 200.527 120.6324 C 198.002 76.40035 154.369 78.72135 127.455 39.12835 L 159.28 157.9054 C 148.102 150.9014 128.812 150.0674 119.175 154.8854 C 103.453 161.2234 92.71497 178.8504 100.493 190.4924 C 108.882 204.4764 128.772 209.1134 147.845 202.1354 C 164.598 195.1554 175.466 183.5104 169.383 169.5494 L 145.046 78.72135 z "
+   id="path3268"
+   style="font-size:12;fill:url(#XMLID_10_);" /><path
+   fill="#FFFFFF"
+   d="M 161.242 157.3794 C 161.288 157.5534 161.309 157.7294 161.309 157.9044 C 161.309 158.5374 161.012 159.1464 160.487 159.5354 C 159.816 160.0314 158.911 160.0644 158.205 159.6234 C 147.214 152.7364 128.687 152.3964 120.083 156.6994 C 120.035 156.7224 119.985 156.7464 119.935 156.7654 C 110.844 160.4314 103.33 168.1174 100.79 176.3474 C 99.73697 179.7594 99.12297 184.7884 102.181 189.3654 C 102.2 189.3924 102.217 189.4224 102.234 189.4494 C 105.989 195.7094 112.526 200.2384 120.642 202.2034 C 128.824 204.1834 138.223 203.4864 147.11 200.2424 C 157.879 195.7484 165.273 189.6374 167.93 183.0314 C 168.683 181.1624 169.059 179.2464 169.059 177.2974 C 169.059 175.0244 168.547 172.7054 167.524 170.3594 C 167.485 170.2674 167.452 170.1714 167.425 170.0744 L 143.087 79.24635 C 143.041 79.07135 143.018 78.89535 143.018 78.72135 C 143.018 78.05035 143.351 77.40835 143.931 77.02735 C 144.661 76.54635 145.617 76.58735 146.303 77.12835 C 149.554 79.69235 154.926 81.76135 161.143 84.15635 C 168.814 87.11235 177.509 90.46235 185.148 95.86235 C 189.281 98.78435 192.705 102.0414 195.465 105.6684 C 193.699 101.0384 191.168 96.87835 187.801 93.02535 C 181.729 86.07535 173.461 80.70235 164.708 75.01335 C 154.094 68.11535 142.316 60.44435 132.058 48.46635 C 136.502 65.05235 161.242 157.3794 161.242 157.3794 z "
+   id="path3269"
+   style="font-size:12;fill:#ffffff;" /><path
+   fill="url(#XMLID_11_)"
+   d="M 161.242 157.3794 C 161.288 157.5534 161.309 157.7294 161.309 157.9044 C 161.309 158.5374 161.012 159.1464 160.487 159.5354 C 159.816 160.0314 158.911 160.0644 158.205 159.6234 C 147.214 152.7364 128.687 152.3964 120.083 156.6994 C 120.035 156.7224 119.985 156.7464 119.935 156.7654 C 110.844 160.4314 103.33 168.1174 100.79 176.3474 C 99.73697 179.7594 99.12297 184.7884 102.181 189.3654 C 102.2 189.3924 102.217 189.4224 102.234 189.4494 C 105.989 195.7094 112.526 200.2384 120.642 202.2034 C 128.824 204.1834 138.223 203.4864 147.11 200.2424 C 157.879 195.7484 165.273 189.6374 167.93 183.0314 C 168.683 181.1624 169.059 179.2464 169.059 177.2974 C 169.059 175.0244 168.547 172.7054 167.524 170.3594 C 167.485 170.2674 167.452 170.1714 167.425 170.0744 L 143.087 79.24635 C 143.041 79.07135 143.018 78.89535 143.018 78.72135 C 143.018 78.05035 143.351 77.40835 143.931 77.02735 C 144.661 76.54635 145.617 76.58735 146.303 77.12835 C 149.554 79.69235 154.926 81.76135 161.143 84.15635 C 168.814 87.11235 177.509 90.46235 185.148 95.86235 C 189.281 98.78435 192.705 102.0414 195.465 105.6684 C 193.699 101.0384 191.168 96.87835 187.801 93.02535 C 181.729 86.07535 173.461 80.70235 164.708 75.01335 C 154.094 68.11535 142.316 60.44435 132.058 48.46635 C 136.502 65.05235 161.242 157.3794 161.242 157.3794 z "
+   id="path3286"
+   style="font-size:12;fill:url(#XMLID_11_);" /><path
+   fill="url(#XMLID_12_)"
+   d="M 108.657 170.7484 C 110.056 176.1014 119.285 178.3224 129.268 175.7114 C 139.251 173.1014 146.209 166.6454 144.809 161.2914 C 143.409 155.9384 134.18 153.7174 124.198 156.3274 C 114.214 158.9394 107.256 165.3954 108.657 170.7484 z "
+   id="path3293"
+   style="font-size:12;fill:url(#XMLID_12_);" /><rect
+   id="_x3C_Slice_x3E_"
+   fill="none"
+   width="256"
+   height="256"
+   style="font-size:12;fill:none;" /></svg>

Added: z3/zopejam/trunk/src/zcmledit/__init__.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/__init__.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1 @@
+

Added: z3/zopejam/trunk/src/zcmledit/configfile.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/configfile.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,508 @@
+
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+"""ZCML file reader and writer.
+
+This parser collects directives, but only interprets a few of them.
+It also retains XML comments and applies the ZCML indentation standards.
+"""
+
+import errno
+from glob import glob
+import os
+import sys
+from xml.parsers import expat
+from xml.sax.saxutils import quoteattr
+
+from zcmledit.exceptions import PackageSpecError, NoPackageError
+from zcmledit.exceptions import InvalidRelativePackageError
+from zcmledit.exceptions import MissingPackageError
+
+
+ZCML_CONDITION = (u"http://namespaces.zope.org/zcml", u"condition")
+XMLNS_NS = u"http://www.w3.org/2000/xmlns/" # URI for XML NS declarations
+
+
+class ConfigurationFile:
+
+    def __init__(self, filename, package_name=None):
+        self.filename = filename
+        # package_name is None or the absolute package name that was
+        # used for including this config file
+        self.package_name = package_name
+        self.root = None    # A DirectiveElement
+        self.output = None   # [line, DirectiveElement, line, ...]
+
+    def load(self):
+        """Parse the file into a tree of DirectiveElements.
+
+        Stores the result in self.root.
+        """
+        fn = self.filename
+        try:
+            f = open(fn, 'rb')
+        except IOError, (code, msg):
+            fn = filename + ".in"
+            if code != errno.ENOENT or not os.path.exists(fn):
+                raise
+            f = open(fn, 'rb')
+
+        try:
+            h = ConfigurationFileHandler(self)
+            self.root, self.output = h.parse(f)
+            if self.package_name:
+                self.root._setDefaultPackage(self.package_name)
+        finally:
+            f.close()
+
+    def generateXML(self):
+        """Returns a list of XML lines."""
+        lines = []
+        for item in self.output:
+            if isinstance(item, DirectiveElement):
+                lines.extend(item.generateXML())
+            else:
+                lines.append(item)
+        return lines
+
+
+class DirectiveElement:
+    """An XML element that specifies a ZCML directive"""
+
+    def __init__(self, config_file, parent, name, data,
+                 attr_order, extra_attrs, condition, prefix_uri):
+        self.config_file = config_file
+        self.parent = parent
+        self.name = name  # (ns, localname)
+        self.data = data  # {localname: value}
+        self.attr_order = attr_order  # list of (ns, localname)
+        self.extra_attrs = extra_attrs  # {(ns, localname): value}
+        self.condition = condition
+        self.prefix_uri = prefix_uri  # {prefix: uri}
+
+        # uri_prefix is used for generating a prefix given a URI
+        self.uri_prefix = {}  # {uri: prefix}
+        m = prefix_uri.items()
+        m.sort()
+        for prefix, uri in m:
+            if not self.uri_prefix.has_key(uri):
+                self.uri_prefix[uri] = prefix
+
+        # the following are populated by ConfigurationFileHandler
+        self.child_elems = []  # [DirectiveElement]
+        self.output = []       # [line, DirectiveElement, line, ...]
+
+        # Collect information from certain XML attributes
+        ns, localname = name
+        if localname == 'configure':
+            # This directive can modify the context package name
+            p = data.get('package')
+            if p:
+                p = p.strip()
+        else:
+            p = None
+        self._package_name = p
+
+        if localname in ('include', 'includeOverrides'):
+            self._is_include = True
+        else:
+            self._is_include = False
+
+    def _setDefaultPackage(self, package_name):
+        if not self._package_name:
+            self._package_name = package_name
+
+    def flattened(self):
+        """Returns a list containing this directive and all descendants"""
+        res = [self]
+        for e in self.child_elems:
+            res.extend(e.flattened())
+        return res
+
+    def getAbsolutePackageName(self):
+        """Returns the absolute package name in context of this directive.
+
+        Used for resolving relative package names.
+        """
+        my_pn = self._package_name
+        if not my_pn:
+            # inherit
+            elem = self.parent
+            while elem is not None:
+                if elem._package_name:
+                    return elem.getAbsolutePackageName()
+            raise NoPackageError("No absolute package has been set")
+        elif not my_pn.startswith('.'):
+            return my_pn
+
+        # my_pn is relative, so resolve it.
+        if self.parent is not None:
+            parent_pn = self.parent.getAbsolutePackageName()
+        else:
+            raise NoPackageError("No absolute package has been set")
+        return join_package(parent_pn, my_pn)
+
+    def isIncludeDirective(self):
+        """Returns True if this is an include directive"""
+        return self._is_include
+
+    def getIncludeResolver(self, pythonpath):
+        assert self._is_include, "not an include directive"
+        return IncludeResolver(self, pythonpath)
+
+    def getXMLName(self, ns, localname):
+        """Returns the tag or attribute for a given namespace and localname"""
+        if not ns:
+            return localname
+        if ns == XMLNS_NS:
+            if localname:
+                return u'xmlns:%s' % localname
+            else:
+                return u'xmlns'
+        elem = self
+        while elem is not None:
+            prefix = elem.uri_prefix.get(ns)
+            if prefix is not None:
+                if prefix:
+                    return u'%s:%s' % (prefix, localname)
+                else:
+                    return localname
+            elem = elem.parent
+        # The following error should only happen if some code adds an
+        # attribute to this element without declaring a prefix for the
+        # attribute's namespace.
+        raise ValueError(
+            "No declared prefix maps to namespace '%s'" % ns)
+
+    def generateStartTag(self, indent='', end=False):
+        """Generates the start tag for this directive as a list of lines"""
+
+        if end:
+            tag_end = u' />'
+        else:
+            tag_end = u'>'
+
+        ns, localname = self.name
+        tag_name = self.getXMLName(ns, localname)
+
+        # Build 'out_attrs', a dictionary of attributes to put in the tag
+        out_attrs = self.extra_attrs.copy()
+        for key, value in self.data.items():
+            out_attrs[(u'', key)] = value
+        for prefix, uri in self.prefix_uri.items():
+            if not prefix:
+                key = XMLNS_NS, ''
+            else:
+                key = XMLNS_NS, prefix
+            out_attrs[key] = uri
+        if self.condition:
+            out_attrs[ZCML_CONDITION] = self.condition
+
+        if not out_attrs:
+            line = u'%s<%s%s' % (indent, tag_name, tag_end)
+            return [line]
+
+        if len(out_attrs) == 1:
+            # generate a single line
+            (ns, localname), value = out_attrs.items()[0]
+            attr = self.getXMLName(ns, localname)
+            line = u'%s<%s %s=%s%s' % (
+                indent, tag_name, attr, quoteattr(value), tag_end)
+            return [line]
+
+        # generate multiple lines
+        lines = [u'%s<%s' % (indent, tag_name)]
+        for key in self.attr_order:
+            value = out_attrs.get(key)
+            if value is None:
+                continue
+            ns, localname = key
+            attr = self.getXMLName(ns, localname)
+            line = u'%s    %s=%s' % (indent, attr, quoteattr(value))
+            lines.append(line)
+            del out_attrs[key]
+
+        # include attributes not listed in attr_order
+        new_attrs = out_attrs.items()
+        new_attrs.sort()
+        for (ns, localname), value in new_attrs:
+            attr = self.getXMLName(ns, localname)
+            line = u'%s    %s="%s"' % (indent, attr, xmlescape(value))
+            lines.append(line)
+
+        lines.append(u'%s    %s' % (indent, tag_end.lstrip()))
+        return lines
+
+    def generateXML(self, indent=''):
+        """Returns a list of lines containing XML for this element"""
+        if not self.output:
+            return self.generateStartTag(indent=indent, end=True)
+
+        lines = self.generateStartTag(indent=indent, end=False)
+        indent2 = indent + u'  '
+        for item in self.output:
+            if isinstance(item, DirectiveElement):
+                lines.extend(item.generateXML(indent2))
+            else:
+                lines.append((indent2 + item).rstrip())
+        ns, localname = self.name
+        tag_name = self.getXMLName(ns, localname)
+        lines.append(indent + u'</%s>' % tag_name)
+        return lines
+
+
+class ConfigurationFileHandler:
+    """Generates a DirectiveElement tree from Expat parser events"""
+
+    def __init__(self, cf):
+        self.cf = cf
+        self.root = None
+        self.dir_stack = []      # [DirectiveElement]
+        self.ns_stack = [{}]     # [{prefix: namespace}]
+        self.output_stack = [[]]  # [[text, DirectiveElement, text, ...]]
+
+    def parse(self, f):
+        p = expat.ParserCreate(None, ' ')
+        p.ordered_attributes = True
+        p.returns_unicode = True
+        for attr in (
+            'StartNamespaceDeclHandler',
+            'StartElementHandler',
+            'EndElementHandler',
+            'DefaultHandler',
+            ):
+            setattr(p, attr, getattr(self, attr))
+        p.ParseFile(f)
+        output = convert_to_lines(self.output_stack.pop(), file_scope=True)
+        return self.root, output
+
+    def StartNamespaceDeclHandler(self, prefix, uri):
+        if prefix is None:
+            prefix = ''
+        self.ns_stack[-1][prefix] = uri
+
+    def StartElementHandler(self, name, attrs):
+        condition = None
+        attr_order = []
+        data = {}  # {localname: value}
+        extra_attrs = {}  # {(ns, localname): value}
+
+        if ' ' in name:
+            name = name.split(' ', 1)
+        else:
+            name = '', name
+
+        pm = self.ns_stack[-1]
+        items = pm.items()
+        items.sort()
+        for prefix, uri in items:
+            attr_order.append((XMLNS_NS, prefix))
+
+        # attrs is a list of alternating names and values.
+        # gather its contents, preserving the attribute order.
+        for i in range(0, len(attrs), 2):
+            key = attrs[i]
+            value = attrs[i + 1]
+            if ' ' in key:
+                key = tuple(key.split(' ', 1))
+            else:
+                key = '', key
+            attr_order.append(key)
+
+            ns, localname = key
+            if key == ZCML_CONDITION:
+                condition = value
+            elif not ns or ns == name[0]:
+                data[localname] = value
+            else:
+                extra_attrs[key] = value
+
+        # create a directive element from this XML element.
+        if self.dir_stack:
+            parent = self.dir_stack[-1]
+        else:
+            parent = None
+        d = DirectiveElement(
+            self.cf, parent, name, data, attr_order, extra_attrs,
+            condition, pm)
+        self.dir_stack.append(d)
+        self.output_stack[-1].append(d)
+        self.output_stack.append([])
+        self.ns_stack.append({})
+
+        if parent is not None:
+            # add to a DirectiveElement
+            parent.child_elems.append(d)
+        else:
+            # create the root DirectiveElement
+            self.root = d
+
+    def EndElementHandler(self, name):
+        self.ns_stack.pop()
+        d = self.dir_stack.pop()
+        items = self.output_stack.pop()
+        d.output = convert_to_lines(items, file_scope=False)
+
+    def DefaultHandler(self, text):
+        self.output_stack[-1].append(text)
+
+
+class IncludeResolver:
+
+    def __init__(self, element, pythonpath):
+        files = element.data.get('files')
+        file = element.data.get('file')
+        package = element.data.get('package')
+
+        if files and file:
+            raise ValueError("Must specify only one of file or files")
+        if not files and not file:
+            file = 'configure.zcml'
+
+        # figure out the absolute package name, which may be None.
+        if not package:
+            try:
+                abs_package = element.getAbsolutePackageName()
+            except NoPackageError:
+                # Not in a package, but that's okay because the
+                # directive didn't ask for a package. The directive is
+                # referring to a file relative to the file containing
+                # the include directive.
+                abs_package = None
+        elif package.startswith('.'):
+            # Turn the relative package name into an absolute package
+            # name.  In this case, the directive did specify a
+            # package, so complain if there is no absolute package
+            # name in this context.
+            parent = element.getAbsolutePackageName()
+            abs_package = join_package(parent, package)
+        else:
+            abs_package = package
+
+        fn = os.path.normpath(files or file)
+        if not os.path.isabs(fn):
+            # convert to an absolute path
+            if abs_package:
+                basepath = find_package(abs_package, pythonpath)
+            else:
+                cfn = element.config_file.filename
+                basepath = os.path.abspath(os.path.dirname(cfn))
+            fn = os.path.join(basepath, fn)
+
+        self.abs_package = abs_package
+        self.filename = fn
+        self.glob = bool(files)
+
+    def listFiles(self):
+        """Returns the list of files to include."""
+        if self.glob:
+            return glob(self.filename)
+        else:
+            return self.filename
+
+
+def join_package(parent, child):
+    """Joins an absolute package name with a relative package name."""
+    if child == '.':
+        return parent
+    if child.endswith('.'):
+        raise PackageSpecError("Package names must not end with '.'")
+    if not child.startswith('.'):
+        return child
+    if not parent:
+        raise NoPackageError("No absolute package has been set")
+    pnames = parent.split('.') + ['']
+    cnames = child.split('.')
+    while cnames and not cnames[0]:
+        cnames.pop(0)
+        try:
+            pnames.pop()
+        except IndexError:
+            raise InvalidRelativePackageError(
+                "Can't join absolute package '%s' with "
+                "relative package '%s'" % (parent, child))
+    return '.'.join(pnames + cnames)
+
+
+def find_package(package, pythonpath):
+    """Returns the directory containing the specified Python package name."""
+    parts = package.split('.')
+    check_dirs = []
+    for i in range(len(parts), 0, -1):
+        check_dirs.append(os.path.join(*parts[:i]))
+    subpath = check_dirs[0]
+
+    candidate = None
+    for base in pythonpath:
+        res = os.path.join(base, subpath)
+        if not os.path.isdir(res):
+            # No such directory.  Keep searching.
+            continue
+        # Found a candidate directory.  Verify there are __init__ files.
+        candidate = res
+        valid = True
+        for dir in check_dirs:
+            fn = os.path.join(base, dir, '__init__.py')
+            for suffix in ('', 'c', 'o'):
+                if os.path.isfile(fn + suffix):
+                    break
+            else:
+                # No __init__ found, so this isn't really a Python package.
+                valid = False
+                break
+        if valid:
+            # Found it.
+            return res
+
+    msg = "Can't find a Python package named '%s'." % package
+    if candidate:
+        # Remind the user to add __init__.py files
+        msg += ("  (Directory '%s' is a candidate, but one "
+                "or more '__init__.py' files are required.)" % candidate)
+    raise MissingPackageError(msg)
+
+
+def convert_to_lines(items, file_scope):
+    """Returns lines and directives from a list of text and directives.
+
+    Unindents the lines, removes trailing whitespace, and tries to
+    preserve the right number of lines.
+    """
+    res = []
+    buf = []
+    first_line = file_scope
+    for obj in items + [None]:
+        is_directive = isinstance(obj, DirectiveElement)
+        if is_directive or obj is None:
+            # Gather the accumulated text.  If there are non-blank
+            # lines or extra blank lines, add a list of lines.
+            lines = ''.join(buf).split('\n')
+            buf = []
+            lines = [line.rstrip() for line in lines]
+            if not first_line:
+                if lines and not lines[0]:
+                    del lines[0]
+            if lines and not lines[-1]:
+                del lines[-1]
+            if lines:
+                res.extend(unindent(lines))
+            first_line = False
+        if is_directive:
+            res.append(obj)
+        elif obj:
+            buf.append(obj)
+    return res
+
+
+def unindent(lines):
+    count = sys.maxint
+    for line in lines:
+        length = len(line)
+        n = length - len(line.lstrip())
+        if n < length and n < count:
+            count = n
+    if count == sys.maxint:
+        # no content
+        return lines
+    return [line[count:] for line in lines]

Added: z3/zopejam/trunk/src/zcmledit/exceptions.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/exceptions.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,15 @@
+
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+class PackageSpecError(Exception):
+    """Failed package specification"""
+
+class NoPackageError(PackageSpecError):
+    """No absolute package specified for resolving relative package names"""
+
+class InvalidRelativePackageError(PackageSpecError):
+    """A relative package spec is not valid"""
+
+class MissingPackageError(PackageSpecError):
+    """Could not find the specified package"""

Added: z3/zopejam/trunk/src/zcmledit/tests/__init__.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/__init__.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1 @@
+

Added: z3/zopejam/trunk/src/zcmledit/tests/package/__init__.py
==============================================================================

Added: z3/zopejam/trunk/src/zcmledit/tests/preserve/browser.zcml
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/preserve/browser.zcml	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,53 @@
+<configure 
+    xmlns="http://namespaces.zope.org/browser"
+    xmlns:zope="http://namespaces.zope.org/zope"
+    i18n_domain="zope"
+    >
+
+  <!-- Cookie Browser Id Manager -->
+
+  <addMenuItem
+      title="Cookie Client Id Manager"
+      description="Uses a cookie to uniquely identify a client"
+      class=".http.CookieClientIdManager"
+      permission="zope.ManageServices"
+      />
+
+  <editform
+      schema=".http.ICookieClientIdManager"
+      label="Cookie Client Id Manager Properties"
+      name="edit.html"
+      menu="zmi_views"
+      title="Edit"
+      permission="zope.ManageServices"
+      />
+
+  <!-- PersistentSessionDataContainer -->
+
+  <addMenuItem
+      title="Persistent Session Data Container"
+      description="Stores session data persistently in the ZODB"
+      class=".session.PersistentSessionDataContainer"
+      permission="zope.ManageServices"
+      />
+
+  <!-- RAMSessionDataContainer -->
+
+  <addMenuItem
+      title="RAM Session Data Container"
+      description="Stores session data in RAM"
+      class=".session.RAMSessionDataContainer"
+      permission="zope.ManageServices"
+      />
+
+  <!-- ISessionDataContainer -->
+  <editform
+      schema=".interfaces.ISessionDataContainer"
+      label="Session Data Container Properties"
+      name="edit.html"
+      menu="zmi_views"
+      title="Edit"
+      permission="zope.ManageServices"
+      />
+
+</configure>

Added: z3/zopejam/trunk/src/zcmledit/tests/preserve/conditions.zcml
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/preserve/conditions.zcml	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,78 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta"
+    xmlns:test="http://sample.namespaces.zope.org/test"
+    xmlns:zcml="http://namespaces.zope.org/zcml"
+    >
+
+  <meta:directive
+      name="register"
+      namespace="http://sample.namespaces.zope.org/test"
+      schema=".test_conditions.IRegister"
+      handler=".test_conditions.register"
+      >
+    This registers a directive which creates registrations we can test.
+  </meta:directive>
+
+  <test:register id="unqualified.registration" />
+
+  <meta:provides feature="testfeature" />
+  <meta:provides feature="anothertestfeature" />
+
+  <configure zcml:condition="have testfeature">
+    ZCML directives inside here should be included.
+
+    <configure>
+      <test:register id="nested.true.condition" />
+    </configure>
+
+    <!-- These registrations stand on the basis of their own
+         conditions: -->
+    <test:register
+        zcml:condition="have anothertestfeature"
+        id="true.condition.nested.in.true"
+        />
+
+    <test:register
+        zcml:condition="have undefinedfeature"
+        id="false.condition.nested.in.true"
+        />
+
+  </configure>
+
+  <test:register
+      zcml:condition="have testfeature"
+      id="direct.true.condition"
+      >
+    This registration should be included.
+  </test:register>
+
+  <configure zcml:condition="have undefinedfeature">
+    ZCML directives inside here should be ignored.
+
+    <configure>
+      <test:register id="nested.false.condition" />
+    </configure>
+
+    <!-- These registrations are ignored, since the container is
+         ignored: -->
+    <test:register
+        zcml:condition="have testfeature"
+        id="true.condition.nested.in.false"
+        />
+
+    <test:register
+        zcml:condition="have undefinedfeature"
+        id="false.condition.nested.in.false"
+        />
+
+  </configure>
+
+  <test:register
+      zcml:condition="have undefinedfeature"
+      id="direct.false.condition"
+      >
+    This registration should be ignored.
+  </test:register>
+
+</configure>

Added: z3/zopejam/trunk/src/zcmledit/tests/preserve/root.zcml
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/preserve/root.zcml	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,13 @@
+
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include files="includes/*-meta.zcml" />
+
+  <include package="zcmledit.tests.package" />
+
+  <include files="includes/*-configure.zcml" />
+
+  <!-- Provide local overrides of standard configurations-->
+  <includeOverrides file="overrides.zcml" />
+
+</configure>

Added: z3/zopejam/trunk/src/zcmledit/tests/root.zcml
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/root.zcml	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,13 @@
+
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include files="includes/*-meta.zcml" />
+
+  <include package="zcmledit.tests.package" />
+
+  <include files="includes/*-configure.zcml" />
+
+  <!-- Provide local overrides of standard configurations-->
+  <includeOverrides file="overrides.zcml" />
+
+</configure>

Added: z3/zopejam/trunk/src/zcmledit/tests/test_configfile.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zcmledit/tests/test_configfile.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,87 @@
+
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+import os
+import py.test
+import sys
+
+import zcmledit
+from zcmledit.configfile import ConfigurationFile
+from zcmledit.configfile import join_package, find_package
+from zcmledit.exceptions import PackageSpecError, NoPackageError
+from zcmledit.exceptions import InvalidRelativePackageError
+from zcmledit.exceptions import MissingPackageError
+
+
+def test_join_package():
+    assert join_package('zope', '.app') == 'zope.app'
+    assert join_package('zope', '..os') == 'os'
+    assert join_package('zope.app', '.content') == 'zope.app.content'
+    assert join_package('zope.app', '..configuration') == 'zope.configuration'
+    assert join_package('zope.app', '...os') == 'os'
+    assert join_package('zope.app', '...os.path') == 'os.path'
+    assert join_package('zope.app', 'os.path') == 'os.path'
+    assert join_package('zope.app', '.') == 'zope.app'
+    assert join_package('', 'zope') == 'zope'
+
+    py.test.raises(NoPackageError, join_package, '', '.foo')
+    py.test.raises(PackageSpecError, join_package, 'zope', '.foo.')
+    py.test.raises(InvalidRelativePackageError, join_package, 'zope', '...os')
+
+
+def test_find_package():
+    base = os.path.dirname(os.path.dirname(zcmledit.__file__))
+
+    assert find_package('zcmledit', sys.path) == os.path.join(base, 'zcmledit')
+    assert find_package('zcmledit.tests', sys.path) == os.path.join(
+        base, 'zcmledit', 'tests')
+    py.test.raises(
+        MissingPackageError, find_package, 'zcmledit.nonexistentpackage',
+        sys.path)
+    # zcmledit.configfile is a module, not a package
+    py.test.raises(
+        MissingPackageError, find_package, 'zcmledit.configfile', sys.path)
+
+    try:
+        find_package('zcmledit.tests.preserve', sys.path)
+    except MissingPackageError, e:
+        # The error message should suggest that __init__.py be added
+        # to the tests/preserve directory.  (Which shouldn't actually
+        # be done, or this test will break. ;-) )
+        expect = os.path.join(base, 'zcmledit', 'tests', 'preserve')
+        assert expect in e.args[0]
+
+def load_root():
+    fn = os.path.join(os.path.dirname(zcmledit.__file__), 'tests', 'root.zcml')
+    cf = ConfigurationFile(fn)
+    cf.load()
+    return cf
+
+def test_load_root():
+    cf = load_root()
+    dirs = cf.root.flattened()
+    assert len(dirs) == 5
+
+def test_format_preservation():
+    """Verify that rewriting correctly formatted ZCML does not change it"""
+    dir = os.path.join(os.path.dirname(zcmledit.__file__), 'tests', 'preserve')
+    names = os.listdir(dir)
+    for name in names:
+        if name.endswith('.zcml'):
+            fn = os.path.join(dir, name)
+            yield try_one_preservation, fn
+
+def try_one_preservation(fn):
+    cf = ConfigurationFile(fn)
+    cf.load()
+    f = open(fn, 'rb')
+    file_contents = [line.rstrip() for line in f.readlines()]
+    f.close()
+    generated = cf.generateXML()
+    for i in range(len(file_contents)):
+        assert len(generated) > i, "%s: generated file is too short" % fn
+        assert file_contents[i] == generated[i], (
+            "%s: mismatch on line %d. generated: %s; expected: %s" % (
+            fn, i + 1, repr(generated[i]), repr(file_contents[i])))
+

Added: z3/zopejam/trunk/src/zopejam/__init__.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zopejam/__init__.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1 @@
+

Added: z3/zopejam/trunk/src/zopejam/icons/COPYING.txt
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zopejam/icons/COPYING.txt	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,36 @@
+
+This copyright and license notice covers the CrystalSVG images in this
+directory.  Note the license notice contains an add-on.
+************************************************************************
+KDE Crystal theme icons.
+Copyright (C) 2002 and following years KDE Artists
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation,
+version 2.1 of the License.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    **** NOTE THIS ADD-ON ****
+The GNU Lesser General Public License or LGPL is written for software libraries
+in the first place. We expressly want the LGPL to be valid for this artwork
+library too.
+KDE Crystal theme icons is a special kind of software library, it is an
+artwork library, it's elements can be used in a Graphical User Interface, or
+GUI.
+Source code, for this library means:
+ - for vectors svg;
+ - for pixels, if applicable, the multi-layered formats xcf or psd, or
+otherwise png.
+The LGPL in some sections obliges you to make the files carry
+notices. With images this is in some cases impossible or hardly useful.
+With this library a notice is placed at a prominent place in the directory
+containing the elements. You may follow this practice.
+The exception in section 6 of the GNU Lesser General Public License covers
+the use of elements of this art library in a GUI.
+kde-artists [at] kde.org
+

Added: z3/zopejam/trunk/src/zopejam/icons/menu/bomb.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/contents.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/editcopy.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/editcut.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/editdelete.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/editpaste.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/exit.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/fileclose.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/filenew.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/fileopen.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/filesave.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/filesaveas.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/filter.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/find.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/launch.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/project_open.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/redo.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/save_all.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/undo.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/menu/zopejam.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/other/clear_left.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/other/configure_toolbars.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/other/help.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/other/tree.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/other/zopejam.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/back.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/editcopy.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/editcut.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/editpaste.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/fileclose.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/filenew.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/fileopen.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/filesave.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/filesaveas.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/filter.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/find.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/forward.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/launch.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/project_open.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/redo.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/save_all.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/icons/toolbar/undo.png
==============================================================================
Binary file. No diff available.

Added: z3/zopejam/trunk/src/zopejam/main.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zopejam/main.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,296 @@
+
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+"""Zope Jam main
+"""
+
+# Note: all development currently uses wxPython 2.6.
+
+import os
+import sys
+import time
+import wx
+from wx import xrc
+
+VERSION = '0.1'
+restarting = False
+
+here = os.path.abspath(os.path.dirname(__file__))
+
+
+class JamGUI:
+
+    _menuitem_names = [
+        # File menu
+        'new', 'open', 'openproject',
+        'save', 'saveas', 'saveacopy', 'saveall',
+        'rename', 'close', 'quit',
+        # Edit menu
+        'undo', 'redo', 'cut', 'copy', 'paste', 'delete',
+        'filter', 'find',
+        # Tools menu
+        'test', 'restart',
+        # Help menu
+        'contents', 'about',
+        ]
+
+    _tool_names = [
+        'new', 'open', 'openproject',
+        'save', 'saveall', 'close',
+        'undo', 'redo', 'cut', 'copy', 'paste',
+        'filter', 'find',
+        'test',
+        ]
+
+    def __init__(self, resources):
+        self.resources = resources
+        self.frame = resources.LoadFrame(None, 'jam_frame')
+        menubar = resources.LoadMenuBarOnFrame(self.frame, 'jam_menubar')
+        self.commands = CommandTable()
+        self.commands.addFromFrame(
+            self.frame, self._menuitem_names, self._tool_names)
+        self.commands.addCallbacks(self)
+        self.alldirs = DirectiveList(
+            self, xrc.XRCCTRL(self.frame, 'directive_list_panel'))
+        self.frame.Fit()
+
+    def cmd_default(self, event, name):
+        wx.MessageDialog(
+            self.frame, "Command not yet implemented: %s" % name, "Oops",
+            wx.OK | wx.CENTRE).ShowModal()
+
+    def cmd_quit(self, event):
+        self.frame.Close()
+
+    def cmd_about(self, event):
+        win = self.resources.LoadDialog(self.frame, 'about_dialog')
+
+        t = xrc.XRCCTRL(win, 'versiontext')
+        s = t.GetLabel()
+        s = s.replace('{zopejam.version}', VERSION)
+        py_ver = '%d.%d.%d %s' % sys.version_info[:4]
+        if sys.version_info[4]:
+            py_ver += str(sys.version_info[4])
+        s = s.replace('{python.version}', py_ver)
+        s = s.replace('{wxpython.version}', '%d.%d.%d.%d%s' % wx.VERSION)
+        s = s.replace('{os.description}', wx.GetOsDescription())
+        t.SetLabel(s)
+
+        b = xrc.XRCCTRL(win, 'close')
+        b.Bind(wx.EVT_BUTTON, lambda event: win.Close())
+
+        for name in ('homelink', 'zopelink'):
+            c = xrc.XRCCTRL(win, name)
+            c.GetParent().SetCursor(wx.StockCursor(wx.CURSOR_HAND))
+            def browse(event, url=c.GetLabel()):
+                open_browser_thread(url)
+                win.Close()
+            c.Bind(wx.EVT_LEFT_UP, browse)
+
+        win.Fit()
+        win.ShowModal()
+
+    def cmd_restart(self, event):
+        global restarting
+        restarting = True
+        self.frame.Close()
+
+
+class FilterRow:
+    _ctrl_names = [
+        'before_text', 'field_choice', 'operator_choice',
+        'value_box', 'clear_button', 'and_button',
+        ]
+
+    def __init__(self, gui, dir_list, row_index):
+        self.gui = gui
+        self.dir_list = dir_list
+        self.suppress_event = False
+        filter_list = xrc.XRCCTRL(self.dir_list.panel, 'filter_list_panel')
+        self.panel = gui.resources.LoadPanel(filter_list, 'filter_panel')
+
+        for name in self._ctrl_names:
+            c = xrc.XRCCTRL(self.panel, name)
+            assert c is not None
+            setattr(self, name, c)
+
+        self.setRowIndex(row_index)
+        filter_list.GetSizer().Insert(row_index, self.panel, flag=wx.EXPAND)
+        self.dir_list.panel.Layout()
+
+        self.timer = wx.Timer(self.value_box)
+        self.field_choice.Bind(wx.EVT_CHOICE, self.onChange)
+        self.operator_choice.Bind(wx.EVT_CHOICE, self.onChange)
+        self.value_box.Bind(wx.EVT_COMBOBOX, self.onChange)
+        self.value_box.Bind(wx.EVT_TEXT, self.onDelayChange)
+        self.value_box.Bind(wx.EVT_TEXT_ENTER, self.onChange)
+        self.value_box.Bind(wx.EVT_TIMER, self.onChange)
+        self.clear_button.Bind(wx.EVT_BUTTON, self.onClear)
+        self.and_button.Bind(wx.EVT_BUTTON, self.onAnd)
+
+    def setRowIndex(self, i):
+        if i == 0:
+            self.before_text.SetLabel('Filter:')
+        else:
+            self.before_text.SetLabel('and')
+
+    def onDelayChange(self, event):
+        self.timer.Start(1000, oneShot=True)
+
+    def onChange(self, event):
+        self.timer.Stop()
+        if not self.suppress_event:
+            self.dir_list.onChangeFilter(event)
+
+    def onClear(self, event):
+        self.timer.Stop()
+        rows = self.dir_list.filter_rows
+        i = rows.index(self)
+        self.suppress_event = True
+        try:
+            if i > 0 or len(rows) > 1:
+                # Remove this row
+                filter_list = xrc.XRCCTRL(
+                    self.dir_list.panel, 'filter_list_panel')
+                sizer = filter_list.GetSizer()
+                sizer.Detach(self.panel)
+                self.panel.Destroy()
+                self.dir_list.panel.Layout()
+                del rows[i]
+                while i < len(rows):
+                    rows[i].setRowIndex(i)
+                    i += 1
+                sizer.Layout()
+            else:
+                # Clear this row
+                self.field_choice.SetSelection(0)
+                self.operator_choice.SetSelection(0)
+                self.value_box.SetValue('')
+        finally:
+            self.suppress_event = False
+        self.dir_list.onChangeFilter(event)
+
+    def onAnd(self, event):
+        self.timer.Stop()
+        rows = self.dir_list.filter_rows
+        i = rows.index(self) + 1
+        self.suppress_event = True
+        try:
+            row = FilterRow(self.gui, self.dir_list, i)
+            rows.insert(i, row)
+        finally:
+            self.suppress_event = False
+
+
+class DirectiveList:
+
+    def __init__(self, gui, panel):
+        self.gui = gui
+        self.panel = panel
+        row = FilterRow(gui, self, 0)
+        self.filter_rows = [row]
+        self.listctrl = xrc.XRCCTRL(panel, 'dir_list')
+        images = wx.ImageList(16, 16)
+        image = wx.Image(os.path.join(here, 'icons', 'other', 'tree.png'))
+        bitmap = wx.BitmapFromImage(image)
+        images.Add(bitmap)
+        self.listctrl.AssignImageList(images, wx.IMAGE_LIST_SMALL)
+        treecol = wx.ListItem()
+        treecol.SetImage(0)
+        treecol.SetWidth(32)
+        self.listctrl.InsertColumnItem(0, treecol)
+        self.listctrl.InsertColumn(1, 'Type')
+        self.listctrl.InsertColumn(2, 'Name')
+        self.listctrl.InsertStringItem(0, 'test')
+
+    def onChangeFilter(self, event):
+        pass
+
+
+class Command:
+
+    def __init__(self, name):
+        self.name = name
+        self.menuitems = []
+        self.tools = []
+
+    def enable(self, enable=True):
+        for c in self.menuitems + self.tools:
+            c.Enable(enable)
+
+    def bind(self, callback):
+        for c in self.menuitems:
+            frame = c.GetMenu().GetMenuBar().GetParent()
+            frame.Bind(wx.EVT_MENU, callback, id=c.GetId())
+        for c in self.tools:
+            toolbar = c.GetToolBar()
+            toolbar.Bind(wx.EVT_TOOL, callback, id=c.GetId())
+
+
+class CommandTable:
+    def __init__(self):
+        self._commands = {}  # { name -> Command }
+
+    def _prepareCommand(self, name):
+        comm = self._commands.get(name)
+        if comm is None:
+            if hasattr(self, name):
+                raise AttributeError("attribute name clash on '%s'" % name)
+            comm = Command(name)
+            self._commands[name] = comm
+            setattr(self, name, comm)
+        return comm
+
+    def addFromFrame(self, frame, menuitem_names, tool_names):
+        menubar = frame.GetMenuBar()
+        for name in menuitem_names:
+            c = menubar.FindItemById(xrc.XRCID(name))
+            if c is None:
+                raise KeyError("Can't find menuitem '%s'" % name)
+            self._prepareCommand(name).menuitems.append(c)
+        toolbar = frame.GetToolBar()
+        for name in tool_names:
+            c = toolbar.FindById(xrc.XRCID(name))
+            if c is None:
+                raise KeyError("Can't find tool '%s'" % name)
+            self._prepareCommand(name).tools.append(c)
+
+    def addCallbacks(self, handler):
+        for name, command in self._commands.items():
+            m = getattr(handler, 'cmd_%s' % name, None)
+            if m is None:
+                m1 = getattr(handler, 'cmd_default', None)
+                if m1 is not None:
+                    def m(event, m1=m1, name=name):
+                        return m1(event, name)
+            if m is not None:
+                command.bind(m)
+
+
+class JamApp(wx.App):
+
+    def OnInit(self):
+        resources = xrc.XmlResource(os.path.join(here, "resources.xrc"))
+        gui = JamGUI(resources)
+        gui.frame.Show(1)
+        self.SetTopWindow(gui.frame)
+        return True
+
+
+def open_browser(url):
+    import webbrowser
+    webbrowser.open_new(url)
+
+def open_browser_thread(url):
+    import thread
+    thread.start_new_thread(open_browser, (url,))
+
+def main():
+    app = JamApp()
+    app.MainLoop()
+    if restarting:
+        os.execv(sys.executable, (sys.executable,) + tuple(sys.argv))
+
+if __name__ == '__main__':
+    main()

Added: z3/zopejam/trunk/src/zopejam/resources.xrc
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/src/zopejam/resources.xrc	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,502 @@
+<?xml version="1.0" encoding="ascii"?>
+<resource>
+  <object class="wxPanel" name="filter_panel">
+    <object class="wxFlexGridSizer">
+      <cols>6</cols>
+      <object class="sizeritem">
+        <object class="wxStaticText" name="before_text">
+          <label>Filter:</label>
+                        </object>
+        <flag>wxRIGHT|wxALIGN_CENTRE_VERTICAL</flag>
+                      </object>
+      <object class="sizeritem">
+        <object class="wxChoice" name="field_choice">
+          <content>
+            <item>directive</item>
+            <item>name</item>
+            <item>type</item>
+            <item>class</item>
+          </content>
+        </object>
+        <flag>wxALIGN_CENTRE</flag>
+      </object>
+      <object class="sizeritem">
+        <object class="wxChoice" name="operator_choice">
+          <content>
+            <item>contains</item>
+            <item>is</item>
+            <item>regex</item>
+          </content>
+          <selection>0</selection>
+        </object>
+        <flag>wxALIGN_CENTRE</flag>
+                      </object>
+      <hgap>8</hgap>
+      <object class="sizeritem">
+        <object class="wxComboBox" name="value_box">
+          <content/>
+                        </object>
+        <flag>wxEXPAND|wxALIGN_CENTRE</flag>
+                      </object>
+      <object class="sizeritem">
+        <object class="wxButton" name="clear_button">
+          <label>Clear</label>
+                        </object>
+        <flag>wxALIGN_CENTRE</flag>
+                      </object>
+      <growablecols>3</growablecols>
+      <object class="sizeritem">
+        <object class="wxButton" name="and_button">
+          <label>And...</label>
+                        </object>
+        <flag>wxALIGN_CENTRE</flag>
+                      </object>
+    </object>
+  </object>
+  <object class="wxMenuBar" name="jam_menubar">
+    <object class="wxMenu" name="filemenu">
+      <label>&amp;File</label>
+      <object class="wxMenuItem" name="new">
+        <label>&amp;New...</label>
+        <bitmap>icons/menu/filenew.png</bitmap>
+        <accel>Ctrl+N</accel>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="open">
+        <label>&amp;Open...</label>
+        <bitmap>icons/menu/fileopen.png</bitmap>
+        <accel>Ctrl+O</accel>
+      </object>
+      <object class="wxMenuItem" name="openproject">
+        <label>Open Project...</label>
+        <bitmap>icons/menu/project_open.png</bitmap>
+      </object>
+      <object class="wxMenu" name="openrecent">
+        <label>Open &amp;recent</label>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="save">
+        <label>&amp;Save</label>
+        <bitmap>icons/menu/filesave.png</bitmap>
+        <accel>Ctrl+S</accel>
+      </object>
+      <object class="wxMenuItem" name="saveas">
+        <label>Save &amp;as...</label>
+        <bitmap>icons/menu/filesaveas.png</bitmap>
+        <accel>Shift+Ctrl+S</accel>
+      </object>
+      <object class="wxMenuItem" name="saveacopy">
+        <label>Save a cop&amp;y...</label>
+      </object>
+      <object class="wxMenuItem" name="saveall">
+        <label>Sa&amp;ve all</label>
+        <bitmap>icons/menu/save_all.png</bitmap>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="rename">
+        <label>R&amp;ename...</label>
+      </object>
+      <object class="wxMenuItem" name="close">
+        <label>&amp;Close</label>
+        <bitmap>icons/menu/fileclose.png</bitmap>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="quit">
+        <label>&amp;Quit</label>
+        <bitmap>icons/menu/exit.png</bitmap>
+        <accel>Ctrl+Q</accel>
+      </object>
+    </object>
+    <object class="wxMenu" name="editmenu">
+      <label>&amp;Edit</label>
+      <object class="wxMenuItem" name="undo">
+        <label>&amp;Undo</label>
+        <bitmap>icons/menu/undo.png</bitmap>
+        <accel>Ctrl+Z</accel>
+      </object>
+      <object class="wxMenuItem" name="redo">
+        <label>&amp;Redo</label>
+        <bitmap>icons/menu/redo.png</bitmap>
+        <accel>Ctrl+Y</accel>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="cut">
+        <label>Cut</label>
+        <bitmap>icons/menu/editcut.png</bitmap>
+        <accel>Ctrl+X</accel>
+      </object>
+      <object class="wxMenuItem" name="copy">
+        <label>&amp;Copy</label>
+        <bitmap>icons/menu/editcopy.png</bitmap>
+        <accel>Ctrl+C</accel>
+      </object>
+      <object class="wxMenuItem" name="paste">
+        <label>&amp;Paste</label>
+        <bitmap>icons/menu/editpaste.png</bitmap>
+        <accel>Ctrl+V</accel>
+      </object>
+      <object class="wxMenuItem" name="delete">
+        <label>&amp;Delete</label>
+        <bitmap>icons/menu/editdelete.png</bitmap>
+        <accel>Ctrl+D</accel>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="filter">
+        <label>&amp;Filiter</label>
+        <checkable>1</checkable>
+        <checked>1</checked>
+      </object>
+      <object class="wxMenuItem" name="find">
+        <label>&amp;Find...</label>
+        <bitmap>icons/menu/find.png</bitmap>
+        <accel>Ctrl+F</accel>
+      </object>
+    </object>
+    <object class="wxMenu" name="addmenu">
+      <label>&amp;Add</label>
+    </object>
+    <object class="wxMenu" name="toolsmenu">
+      <label>&amp;Tools</label>
+      <object class="wxMenuItem" name="test">
+        <label>&amp;Test configuration</label>
+        <bitmap>icons/menu/launch.png</bitmap>
+      </object>
+      <object class="separator"/>
+      <object class="wxMenuItem" name="restart">
+        <label>&amp;Restart</label>
+        <bitmap>icons/menu/bomb.png</bitmap>
+      </object>
+    </object>
+    <object class="wxMenu" name="helpmenu">
+      <label>&amp;Help</label>
+      <object class="wxMenuItem" name="contents">
+        <label>&amp;Contents...</label>
+        <bitmap>icons/menu/contents.png</bitmap>
+        <accel>F1</accel>
+      </object>
+      <object class="wxMenuItem" name="about">
+        <label>&amp;About...</label>
+        <bitmap>icons/menu/zopejam.png</bitmap>
+      </object>
+    </object>
+  </object>
+  <object class="wxFrame" name="jam_frame">
+    <title>Zope Jam</title>
+    <object class="wxToolBar">
+      <object class="tool" name="new">
+        <bitmap>icons/toolbar/filenew.png</bitmap>
+        <tooltip>Create a new configuration file</tooltip>
+        <label>New</label>
+      </object>
+      <object class="tool" name="open">
+        <bitmap>icons/toolbar/fileopen.png</bitmap>
+        <tooltip>Open a configuration file</tooltip>
+        <label>Open</label>
+      </object>
+      <object class="tool" name="openproject">
+        <bitmap>icons/toolbar/project_open.png</bitmap>
+        <tooltip>Open a project</tooltip>
+        <label>Open Project</label>
+      </object>
+      <object class="separator"/>
+      <object class="tool" name="save">
+        <bitmap>icons/toolbar/filesave.png</bitmap>
+        <tooltip>Save this file</tooltip>
+        <label>Save</label>
+      </object>
+      <object class="tool" name="saveall">
+        <bitmap>icons/toolbar/save_all.png</bitmap>
+        <tooltip>Save all files</tooltip>
+        <label>Save All</label>
+      </object>
+      <object class="tool" name="close">
+        <bitmap>icons/toolbar/fileclose.png</bitmap>
+        <tooltip>Close this file</tooltip>
+        <label>Close</label>
+      </object>
+      <object class="separator"/>
+      <object class="tool" name="undo">
+        <bitmap>icons/toolbar/undo.png</bitmap>
+        <tooltip>Undo</tooltip>
+        <label>Undo</label>
+      </object>
+      <object class="tool" name="redo">
+        <bitmap>icons/toolbar/redo.png</bitmap>
+        <tooltip>Redo</tooltip>
+        <label>Redo</label>
+      </object>
+      <object class="tool" name="cut">
+        <bitmap>icons/toolbar/editcut.png</bitmap>
+        <tooltip>Cut</tooltip>
+        <label>Cut</label>
+      </object>
+      <object class="tool" name="copy">
+        <bitmap>icons/toolbar/editcopy.png</bitmap>
+        <tooltip>Copy</tooltip>
+        <label>Copy</label>
+      </object>
+      <object class="tool" name="paste">
+        <bitmap>icons/toolbar/editpaste.png</bitmap>
+        <tooltip>Paste</tooltip>
+        <label>Paste</label>
+      </object>
+      <object class="separator"/>
+      <object class="tool" name="filter">
+        <bitmap>icons/toolbar/filter.png</bitmap>
+        <toggle>1</toggle>
+        <tooltip>Filter the list of directives</tooltip>
+        <label>Filter</label>
+      </object>
+      <object class="tool" name="find">
+        <bitmap>icons/toolbar/find.png</bitmap>
+        <tooltip>Find directives</tooltip>
+        <label>Find</label>
+      </object>
+      <object class="separator"/>
+      <object class="tool" name="test">
+        <bitmap>icons/toolbar/launch.png</bitmap>
+        <tooltip>Test the configuration</tooltip>
+        <label>Test</label>
+      </object>
+    </object>
+    <object class="wxFlexGridSizer">
+      <object class="sizeritem">
+        <object class="wxSplitterWindow" name="frame_split">
+          <object class="wxNotebook" name="side_notebook">
+            <object class="notebookpage">
+              <label>Palette</label>
+              <object class="wxSplitterWindow" name="palette_split">
+                <orientation>horizontal</orientation>
+                <object class="wxListCtrl" name="palette">
+                  <style>wxLC_ICON</style>
+                </object>
+                <object class="wxListCtrl" name="palette_list">
+                  <style>wxLC_ICON</style>
+                </object>
+              </object>
+            </object>
+            <object class="notebookpage">
+              <label>Files</label>
+              <object class="wxTreeCtrl" name="file_tree"/>
+            </object>
+          </object>
+          <object class="wxSplitterWindow" name="main_split">
+            <orientation>horizontal</orientation>
+            <object class="wxNotebook" name="files_notebook">
+              <object class="notebookpage">
+                <label>All Directives</label>
+                <object class="wxPanel" name="directive_list_panel">
+                  <object class="wxFlexGridSizer">
+                    <object class="sizeritem">
+                      <object class="wxPanel" name="filter_list_panel">
+                        <object class="wxFlexGridSizer">
+                          <cols>1</cols>
+                          <vgap>4</vgap>
+                          <growablecols>0</growablecols>
+                        </object>
+                      </object>
+                      <flag>wxALL|wxEXPAND</flag>
+                    </object>
+                    <cols>1</cols>
+                    <growablerows>1</growablerows>
+                    <growablecols>0</growablecols>
+                    <object class="sizeritem">
+                      <object class="wxPanel">
+                        <object class="wxFlexGridSizer">
+                          <cols>2</cols>
+                          <object class="sizeritem">
+                            <object class="wxBitmapButton" name="select_columns_button">
+                              <bitmap>icons/other/configure_toolbars.png</bitmap>
+                          </object>
+                        </object>
+                          <object class="sizeritem">
+                            <object class="wxListCtrl" name="dir_list">
+                              <style>wxLC_REPORT</style>
+                              <bg>#FFFFFF</bg>
+                            </object>
+                            <flag>wxEXPAND</flag>
+                </object>
+                          <growablerows>0</growablerows>
+                          <growablecols>1</growablecols>
+                        </object>
+                        <style>wxSUNKEN_BORDER</style>
+                        <bg>#FFFFFF</bg>
+                      </object>
+                      <flag>wxEXPAND</flag>
+                    </object>
+                  </object>
+                </object>
+              </object>
+            </object>
+            <object class="wxNotebook" name="directive_notebook">
+              <object class="notebookpage">
+                <label>Properties</label>
+                <object class="wxScrolledWindow" name="properties_tab">
+                  <object class="wxPanel" name="properties_panel">
+                    <object class="wxBoxSizer">
+                      <orient>wxVERTICAL</orient>
+                      <object class="sizeritem">
+                        <object class="wxFlexGridSizer">
+                          <cols>4</cols>
+                          <vgap>8</vgap>
+                          <object class="sizeritem">
+                            <object class="wxStaticText">
+                              <label>Name</label>
+                                  </object>
+                            <flag>wxRIGHT|wxALIGN_CENTRE_VERTICAL</flag>
+                            <border>8</border>
+                                </object>
+                          <object class="sizeritem">
+                            <object class="wxTextCtrl">
+                              <value>Foo</value>
+                                  </object>
+                            <flag>wxEXPAND|wxALIGN_CENTRE</flag>
+                                </object>
+                          <object class="sizeritem">
+                            <object class="wxBitmapButton">
+                              <bitmap>icons/other/clear_left.png</bitmap>
+                              <style>wxNO_BORDER</style>
+                                  </object>
+                            <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                                </object>
+                          <object class="sizeritem">
+                            <object class="wxBitmapButton">
+                              <bitmap>icons/other/help.png</bitmap>
+                              <style>wxNO_BORDER</style>
+                                  </object>
+                            <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                                </object>
+                          <growablecols>1</growablecols>
+                        </object>
+                        <flag>wxALL|wxEXPAND</flag>
+                        <border>8</border>
+                            </object>
+                    </object>
+                  </object>
+                </object>
+                <selected>1</selected>
+                    </object>
+              <style></style>
+              <object class="notebookpage">
+                <label>Source</label>
+                <object class="wxHtmlWindow" name="source_tab">
+                  <htmlcode>&lt;a href=&quot;#&quot;&gt;/home/shane/src/zope/app/bigpackage/littlepackage/configure.zcml&lt;/a&gt;&lt;br /&gt;
+line &lt;a href=&quot;#&quot;&gt;105&lt;/a&gt;&lt;br /&gt;
+&amp;lt;browser:page x=&quot;y&quot;&amp;gt;
+</htmlcode>
+                      </object>
+                    </object>
+              <object class="notebookpage">
+                <label>Adapters</label>
+                <object class="wxPanel" name="adapters_tab"/>
+                    </object>
+              <object class="notebookpage">
+                <label>Views</label>
+                <object class="wxPanel" name="views_tab"/>
+                    </object>
+              <object class="notebookpage">
+                <label>Code</label>
+                <object class="wxHtmlWindow" name="code_tab"/>
+                    </object>
+            </object>
+          </object>
+          <orientation>vertical</orientation>
+          <sashpos>200</sashpos>
+          <style></style>
+        </object>
+        <flag>wxEXPAND</flag>
+        <minsize>750, 550</minsize>
+      </object>
+      <cols>1</cols>
+      <growablerows>0</growablerows>
+      <growablecols>0</growablecols>
+    </object>
+    <centered>1</centered>
+  </object>
+  <object class="wxDialog" name="about_dialog">
+    <title>About Zope Jam</title>
+    <object class="wxBoxSizer">
+      <orient>wxVERTICAL</orient>
+      <object class="sizeritem">
+        <object class="wxFlexGridSizer">
+          <cols>1</cols>
+          <vgap>10</vgap>
+          <growablecols>0</growablecols>
+          <object class="sizeritem">
+            <object class="wxStaticBitmap">
+              <bitmap>icons/other/zopejam.png</bitmap>
+                      </object>
+            <flag>wxALIGN_CENTRE</flag>
+                    </object>
+          <object class="sizeritem">
+            <object class="wxStaticText">
+              <label>Zope Jam</label>
+              <font>
+                <size>24</size>
+                <style>default</style>
+                <weight>normal</weight>
+                <family>normal</family>
+                <underlined>0</underlined>
+              </font>
+            </object>
+            <flag>wxALIGN_CENTRE</flag>
+          </object>
+          <object class="sizeritem">
+            <object class="wxStaticText" name="versiontext">
+              <label>Zope 3 Configuration Editor
+Version {zopejam.version}
+
+Copyright (c) 2005 Shane Hathaway
+Licensed under ZPL 2.1
+
+Python {python.version}
+wxPython {wxpython.version}
+Operating system: {os.description}
+</label>
+              <style>wxALIGN_CENTRE</style>
+            </object>
+            <flag>wxALIGN_CENTRE_HORIZONTAL</flag>
+          </object>
+          <object class="sizeritem">
+            <object class="wxPanel">
+              <object class="wxBoxSizer">
+                <orient>wxVERTICAL</orient>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="homelink">
+                    <label>http://hathawaymix.org/Software/ZopeJam</label>
+                    <fg>#0000FF</fg>
+            </object>
+                </object>
+              </object>
+            </object>
+            <flag>wxALIGN_CENTRE</flag>
+          </object>
+          <object class="sizeritem">
+            <object class="wxPanel">
+              <object class="wxBoxSizer">
+                <orient>wxVERTICAL</orient>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="zopelink">
+                    <label>http://zope.org</label>
+                    <fg>#0000FF</fg>
+            </object>
+          </object>
+              </object>
+            </object>
+            <flag>wxALIGN_CENTRE</flag>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="close">
+              <label>Close</label>
+            </object>
+            <flag>wxALIGN_CENTRE</flag>
+          </object>
+        </object>
+        <flag>wxALL|wxEXPAND</flag>
+        <border>16</border>
+      </object>
+    </object>
+    <centered>1</centered>
+    <bg>#FFFFFF</bg>
+  </object>
+</resource>

Added: z3/zopejam/trunk/tools/cleanxrc.py
==============================================================================
--- (empty file)
+++ z3/zopejam/trunk/tools/cleanxrc.py	Tue Jun  7 07:45:25 2005
@@ -0,0 +1,39 @@
+
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+"""Sanitize an XRC file by removing unnecessary blank space"""
+
+
+import sys
+
+def main():
+    fn = sys.argv[1]
+    lines = open(fn, 'rb').readlines()
+    lines = [line.rstrip() for line in lines]
+    i = 0
+    while i < len(lines):
+        if lines[i]:
+            i += 1
+            continue
+        # If this series of blank lines starts and ends with
+        # XML tags, collapse this series.
+        if i > 0 and lines[i - 1].lstrip().startswith('<'):
+            j = i + 1
+            while j < len(lines):
+                if lines[j]:
+                    if not lines[j].lstrip().startswith('<'):
+                        # don't collapse
+                        j = -1
+                    break
+                j += 1
+            if j > i:
+                del lines[i:j]
+        i += 1
+
+    f = open(fn, 'wb')
+    f.write('\n'.join(lines) + '\n')
+    f.close()
+
+if __name__ == '__main__':
+    main()


More information about the z3-checkins mailing list