Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/MANIFEST.in
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/MANIFEST.in	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/MANIFEST.in	(revision 839)
@@ -0,0 +1,6 @@
+global-include *.zcml
+global-include *.pot
+global-include *.po
+global-include *.xml
+global-include *.pt
+global-include *.txt
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/README.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/README.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/README.txt	(revision 839)
@@ -0,0 +1,35 @@
+Introduction
+============
+
+Readonly FormGen String Field (quintagroup.ploneformgen.readonlystringfield) is
+a Plone product that allows to add Readonly String Field to the form, created
+with PloneFormGen product.
+
+Usage 
+-----
+
+* Add Readonly String Field as a usual String Field to PloneFormGen form.
+
+* Insert 'Default Value' or 'Default Expression' expression, that will be
+  evaluated when the form is displayed to get the field default value.
+
+* That value will be displayed on every form submission as a default value,
+  but will not be editable.
+
+* If under some circumstances you need to make readonly field editable, then
+  set appropriate condition in Edit Mode field.
+
+Supported Plone versions
+------------------------
+
+* 3.x
+
+Dependencies
+------------
+
+* PloneFormGen
+
+Authors
+-------
+
+* Vitaliy Podoba - piv@quintagroup.com
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/HISTORY.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/HISTORY.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/HISTORY.txt	(revision 839)
@@ -0,0 +1,32 @@
+Changelog
+=========
+
+0.2 - March 24, 2009
+--------------------
+
+* Updated documentation accordingly to changes in readonly field functionality.
+  [piv]
+
+* Added tests.
+  [piv]
+
+* Added uninstall procedure.
+  [piv]
+
+* Removed editable mode from read only field for anonymous user, made this
+  functionality as optional feature by means of edit mode tal expression field.
+  [piv]
+
+* Added Products.PloneFormGen as egg requirement and as installation
+  dependency.
+  [piv]
+
+* Formatted documentation as reStructuredText.
+  [piv]
+
+
+0.1 - October 31, 2008
+----------------------
+
+* Initial release.
+  [piv]
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/INSTALL.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/INSTALL.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/INSTALL.txt	(revision 839)
@@ -0,0 +1,47 @@
+quintagroup.ploneformgen.readonlystringfield Installation
+=======================
+
+ * When you're reading this you have probably already run
+   ``easy_install quintagroup.ploneformgen.readonlystringfield``. Find out how to install setuptools
+   (and EasyInstall) here:
+   http://peak.telecommunity.com/DevCenter/EasyInstall
+
+ * Get `pythonproducts`_ and install it via::
+
+       python setup.py install --home /path/to/instance
+
+   into your Zope instance.
+
+ * Create a file called ``quintagroup.ploneformgen.readonlystringfield-configure.zcml`` in the
+   ``/path/to/instance/etc/package-includes`` directory.  The file
+   should only contain this::
+
+       <include package="quintagroup.ploneformgen.readonlystringfield" />
+
+.. _pythonproducts: http://plone.org/products/pythonproducts
+
+Alternatively, if you are using zc.buildout and the plone.recipe.zope2instance
+recipe to manage your project, you can do this:
+
+ * Add ``quintagroup.ploneformgen.readonlystringfield`` to the list of eggs to install, e.g.:
+
+    [buildout]
+    ...
+    eggs =
+        ...
+        quintagroup.ploneformgen.readonlystringfield
+
+  * Tell the plone.recipe.zope2instance recipe to install a ZCML slug:
+
+    [instance]
+    recipe = plone.recipe.zope2instance
+    ...
+    zcml =
+        quintagroup.ploneformgen.readonlystringfield
+
+  * Re-run buildout, e.g. with:
+
+    $ ./bin/buildout
+
+You can skip the ZCML slug if you are going to explicitly include the package
+from another package's configure.zcml file.
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.GPL
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.GPL	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.GPL	(revision 839)
@@ -0,0 +1,225 @@
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/docs/LICENSE.txt	(revision 839)
@@ -0,0 +1,16 @@
+  quintagroup.ploneformgen.readonlystringfield is copyright Vitaliy Podoba
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program 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 General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA 02111-1307 USA.
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/__init__.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/__init__.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/__init__.py	(revision 839)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/__init__.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/__init__.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/__init__.py	(revision 839)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/Install.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/Install.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/Install.py	(revision 839)
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+import transaction
+from Products.CMFCore.utils import getToolByName
+
+PRODUCT_DEPENDENCIES = (
+    'PloneFormGen',
+)
+
+EXTENSION_PROFILES = (
+    'quintagroup.ploneformgen.readonlystringfield:default',
+)
+
+UNINSTALL_PROFILES = (
+    'quintagroup.ploneformgen.readonlystringfield:uninstall',
+)
+
+def install(self, reinstall=False):
+    """Install a set of products (which themselves may either use Install.py
+    or GenericSetup extension profiles for their configuration) and then
+    install a set of extension profiles.
+    
+    One of the extension profiles we install is that of this product. This
+    works because an Install.py installation script (such as this one) takes
+    precedence over extension profiles for the same product in 
+    portal_quickinstaller. 
+    
+    We do this because it is not possible to install other products during
+    the execution of an extension profile (i.e. we cannot do this during
+    the importVarious step for this profile).
+    """
+    
+    portal_quickinstaller = getToolByName(self, 'portal_quickinstaller')
+    portal_setup = getToolByName(self, 'portal_setup')
+
+    for product in PRODUCT_DEPENDENCIES:
+        if reinstall and portal_quickinstaller.isProductInstalled(product):
+            portal_quickinstaller.reinstallProducts([product])
+            transaction.savepoint()
+        if not portal_quickinstaller.isProductInstalled(product):
+            portal_quickinstaller.installProduct(product)
+            transaction.savepoint()
+    
+    for extension_id in EXTENSION_PROFILES:
+        portal_setup.runAllImportStepsFromProfile('profile-%s' % extension_id, purge_old=False)
+        product_name = extension_id.split(':')[0]
+        portal_quickinstaller.notifyInstalled(product_name)
+        transaction.savepoint()
+
+def uninstall(self):
+    portal_setup = getToolByName(self, 'portal_setup')
+    for extension_id in UNINSTALL_PROFILES:
+        portal_setup.runAllImportStepsFromProfile('profile-%s' % extension_id, purge_old=False)
+        product_name = extension_id.split(':')[0]
+        transaction.savepoint()
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/__init__.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/__init__.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/Extensions/__init__.py	(revision 839)
@@ -0,0 +1,1 @@
+#
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/__init__.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/__init__.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/__init__.py	(revision 839)
@@ -0,0 +1,24 @@
+from zope.i18nmessageid import MessageFactory
+
+from Products.Archetypes import atapi
+from Products.CMFCore import utils
+
+import config
+
+readonlyStringFieldMessageFactory = MessageFactory('quintagroup.ploneformgen.readonlystringfield')
+
+def initialize(context):
+    """Initializer called when used as a Zope 2 product."""
+
+    import field
+
+    content_types, constructors, ftis = atapi.process_types(
+        atapi.listTypes(config.PROJECTNAME),
+        config.PROJECTNAME)
+
+    for atype, constructor in zip(content_types, constructors):
+        utils.ContentInit('%s: %s' % (config.PROJECTNAME, atype.portal_type),
+            content_types      = (atype,),
+            permission         = config.ADD_PERMISSIONS[atype.portal_type],
+            extra_constructors = (constructor,),
+            ).initialize(context)
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/config.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/config.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/config.py	(revision 839)
@@ -0,0 +1,9 @@
+from Products.CMFCore import permissions
+
+PROJECTNAME = 'quintagroup.ploneformgen.readonlystringfield'
+
+
+ADD_PERMISSIONS = {
+    'FormReadonlyStringField' : permissions.AddPortalContent,
+    # -*- extra stuff goes here -*-
+}
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/configure.zcml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/configure.zcml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/configure.zcml	(revision 839)
@@ -0,0 +1,28 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
+    xmlns:cmf="http://namespaces.zope.org/cmf"
+    i18n_domain="quintagroup.ploneformgen.readonlystringfield">
+
+  <five:registerPackage package="." initialize=".initialize" />
+
+  <genericsetup:registerProfile
+      name="default"
+      title="Readonly FormGen String Field"
+      directory="profiles/default"
+      description="Readonly String Field for PloneFormGen product"
+      provides="Products.GenericSetup.interfaces.EXTENSION"
+      />
+
+  <genericsetup:registerProfile
+      name="uninstall"
+      title="Uninstall Readonly FormGen String Field"
+      directory="profiles/uninstall"
+      description="Uninstall Readonly String Field for PloneFormGen product"
+      provides="Products.GenericSetup.interfaces.EXTENSION"
+      />
+
+  <cmf:registerDirectory name="readonlystringfield"/>
+
+</configure>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/field.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/field.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/field.py	(revision 839)
@@ -0,0 +1,85 @@
+from AccessControl import ClassSecurityInfo
+
+from Products.CMFCore.permissions import View
+from Products.CMFCore.Expression import getExprContext
+from Products.Archetypes.atapi import Schema
+from Products.Archetypes.Field import StringField
+from Products.Archetypes.Widget import StringWidget
+from Products.ATContentTypes.content.base import registerATCT
+
+from Products.TALESField import TALESString
+from Products.PloneFormGen.content.fields import FGStringField
+from Products.PloneFormGen.content.fieldsBase import finalizeFieldSchema
+
+from quintagroup.ploneformgen.readonlystringfield.widget import ReadonlyStringWidget
+from quintagroup.ploneformgen.readonlystringfield.config import PROJECTNAME
+
+class FGReadonlyStringField(FGStringField):
+    """ A string entry field """
+
+    security  = ClassSecurityInfo()
+
+    schema = FGStringField.schema.copy() + Schema((
+        TALESString('editMode',
+            searchable=0,
+            required=0,
+            validators=('talesvalidator',),
+            default='',
+            widget=StringWidget(label="Edit Mode Expression",
+                description="""
+                    A TALES expression that will be evaluated when the form is displayed
+                    to know whether or not to make field editable.
+                    Leave empty if you need read only field in any case. Your expression
+                    should evaluate as a string.
+                    PLEASE NOTE: errors in the evaluation of this expression will cause
+                    an error on form display.
+                """,
+                size=70,
+                i18n_domain = "quintagroup.ploneformgen.readonlystringfield",
+                label_msgid = "label_editmode_text",
+                description_msgid = "help_editmode_text",
+                ),
+            ),
+    ))
+
+    # hide references & discussion
+    finalizeFieldSchema(schema, folderish=True, moveDiscussion=False)
+
+    # Standard content type setup
+    portal_type = meta_type = 'FormReadonlyStringField'
+    archetype_name = 'Readonly String Field'
+    content_icon = 'StringField.gif'
+    typeDescription= 'A readonly string field'
+
+    def __init__(self, oid, **kwargs):
+        """ initialize class """
+
+        super(FGReadonlyStringField, self).__init__(oid, **kwargs)
+
+        # set a preconfigured field as an instance attribute
+        self.fgField = StringField('fg_string_field',
+            searchable=0,
+            required=0,
+            write_permission = View,
+            validators=('isNotTooLong',),
+            widget=ReadonlyStringWidget(),
+            )
+
+    def fgPrimeDefaults(self, request, contextObject=None):
+        super(FGReadonlyStringField, self).fgPrimeDefaults(request,
+            contextObject=contextObject)
+        editable = self.isEditable(contextObject)
+        if editable:
+            request.set('%s_editable' % self.fgField.__name__, '1')
+
+    def isEditable(self, context=None):
+        if self.getRawEditMode():
+            if context:
+                value = self.getEditMode(
+                    expression_context=getExprContext(self, context))
+            else:
+                value = self.getEditMode()
+            return value
+        return False
+
+registerATCT(FGReadonlyStringField, PROJECTNAME)
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/factorytool.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/factorytool.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/factorytool.xml	(revision 839)
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<object name="portal_factory" meta_type="Plone Factory Tool">
+ <factorytypes>
+  <type portal_type="FormReadonlyStringField"/>
+ </factorytypes>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/metadata.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/metadata.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/metadata.xml	(revision 839)
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<metadata>
+  <version>0.2</version>
+</metadata>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/propertiestool.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/propertiestool.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/propertiestool.xml	(revision 839)
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<object name="portal_properties" meta_type="Plone Properties Tool">
+ <object name="navtree_properties" meta_type="Plone Property Sheet">
+  <property name="metaTypesNotToList" type="lines" purge="False">
+   <element value="FormReadonlyStringField"/>
+  </property>
+ </object>
+ <object name="site_properties" meta_type="Plone Property Sheet">
+  <property name="types_not_searched" type="lines" purge="False">
+   <element value="FormReadonlyStringField"/>
+  </property>
+ </object>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/skins.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/skins.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/skins.xml	(revision 839)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<object name="portal_skins" meta_type="Plone Skins Tool">
+ <object name="readonlystringfield" meta_type="Filesystem Directory View"
+    directory="quintagroup.ploneformgen.readonlystringfield:skins/readonlystringfield"/>
+ <skin-path name="*">
+  <layer name="readonlystringfield" insert-after="custom"/>
+ </skin-path>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types.xml	(revision 839)
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="Plone Types Tool">
+ <property
+    name="title">Controls the available content types in your portal</property>
+ <object name="FormReadonlyStringField"
+    meta_type="Factory-based Type Information with dynamic views"/>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormFolder.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormFolder.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormFolder.xml	(revision 839)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<object name="FormFolder"
+   meta_type="Factory-based Type Information with dynamic views"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="allowed_content_types" purge="False">
+  <element value="FormReadonlyStringField"/>
+ </property>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormReadonlyStringField.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormReadonlyStringField.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/types/FormReadonlyStringField.xml	(revision 839)
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<object name="FormReadonlyStringField"
+   meta_type="Factory-based Type Information with dynamic views"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title">Readonly String Field</property>
+ <property name="description">A readonly string entry field</property>
+ <property name="content_icon">StringField.gif</property>
+ <property name="content_meta_type">FormReadonlyStringField</property>
+ <property name="product">quintagroup.ploneformgen.readonlystringfield</property>
+ <property name="factory">addFGReadonlyStringField</property>
+ <property name="immediate_view">fg_base_view_p3</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types"/>
+ <property name="allow_discussion">False</property>
+ <property name="default_view">fg_base_view_p3</property>
+ <property name="view_methods">
+  <element value="fg_base_view_p3"/>
+ </property>
+ <property name="default_view_fallback">False</property>
+ <alias from="(Default)" to="(dynamic view)"/>
+ <alias from="edit" to="atct_edit"/>
+ <alias from="index.html" to="(dynamic view)"/>
+ <alias from="properties" to="base_metadata"/>
+ <alias from="sharing" to="folder_localrole_form"/>
+ <alias from="view" to="(selected layout)"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    url_expr="string:${object_url}" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    url_expr="string:${object_url}/edit" visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/workflows.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/workflows.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/default/workflows.xml	(revision 839)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<object name="portal_workflow" meta_type="Plone Workflow Tool">
+ <bindings>
+  <type type_id="FormReadonlyStringField">
+   <bound-workflow workflow_id=""/>
+  </type>
+ </bindings>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/import_steps.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/import_steps.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/import_steps.xml	(revision 839)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<import-steps>
+ <import-step id="readonlystringfield-uninstall" version="20090323-01"
+              handler="quintagroup.ploneformgen.readonlystringfield.setuphandlers.uninstall"
+              title="Uninstall step for PloneFormGen ReadonlyStringField">
+    Uninstall PloneFormGen ReadonlyStringField things.
+ </import-step>
+</import-steps>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/propertiestool.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/propertiestool.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/propertiestool.xml	(revision 839)
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<object name="portal_properties" meta_type="Plone Properties Tool">
+ <object name="navtree_properties" meta_type="Plone Property Sheet">
+  <property name="metaTypesNotToList" type="lines" purge="False">
+   <element value="FormReadonlyStringField" remove="True" />
+  </property>
+ </object>
+ <object name="site_properties" meta_type="Plone Property Sheet">
+  <property name="types_not_searched" type="lines" purge="False">
+   <element value="FormReadonlyStringField" remove="True" />
+  </property>
+ </object>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/quintagroup.ploneformgen.readonlystringfield_uninstall.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/quintagroup.ploneformgen.readonlystringfield_uninstall.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/quintagroup.ploneformgen.readonlystringfield_uninstall.txt	(revision 839)
@@ -0,0 +1,1 @@
+#
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/skins.xml
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/skins.xml	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/profiles/uninstall/skins.xml	(revision 839)
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<object name="portal_skins" meta_type="Plone Skins Tool">
+ <skin-path name="*">
+  <layer name="readonlystringfield" remove="True" />
+ </skin-path>
+</object>
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/setuphandlers.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/setuphandlers.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/setuphandlers.py	(revision 839)
@@ -0,0 +1,15 @@
+from Products.CMFCore.utils import getToolByName
+
+def cleanUpFactoryTool(portal):
+    tool = getToolByName(portal, 'portal_factory')
+    if 'FormReadonlyStringField' in tool._factory_types.keys():
+        del tool._factory_types['FormReadonlyStringField']
+
+def uninstall(context):
+    # Only run step if a flag file is present (e.g. not an extension profile)
+    if context.readDataFile(
+        'quintagroup.ploneformgen.readonlystringfield_uninstall.txt') is None:
+        return
+    out = []
+    site = context.getSite()
+    cleanUpFactoryTool(site)
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/skins/readonlystringfield/readonlystring.pt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/skins/readonlystringfield/readonlystring.pt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/skins/readonlystringfield/readonlystring.pt	(revision 839)
@@ -0,0 +1,52 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      i18n:domain="plone">
+  <head><title></title></head>
+  <body>
+
+    <!-- Readonly String Widgets -->
+    <metal:view_macro define-macro="view"
+            tal:define="kssClassesView context/@@kss_field_decorator_view;
+                        getKssClasses nocall:kssClassesView/getKssClassesInlineEditable;">
+        <span metal:define-macro="string-field-view"
+            tal:define="kss_class python:getKssClasses(fieldName,
+                              templateId='readonlystring', macro='string-field-view');"
+            tal:attributes="class kss_class;
+                            id string:parent-fieldname-$fieldName">
+            <span metal:define-slot="inside" 
+                  tal:replace="accessor">string</span>
+        </span>
+    </metal:view_macro>
+
+    <metal:define define-macro="edit">
+      <metal:use use-macro="field_macro | here/widgets/field/macros/edit">
+        <input metal:fill-slot="widget_body"
+               type="text"
+               name=""
+               class="blurrable firstToFocus"
+               id=""
+               value=""
+               size="30"
+               readonly="1"
+               tal:define="editable python:path('request/%s_editable|nothing' % fieldName)"
+               tal:attributes="name fieldName;
+                               id fieldName;
+                               value value;
+                               size widget/size;
+                               maxlength widget/maxlength;
+                               readonly python:not editable and '1' or None"
+               />
+      </metal:use>
+    </metal:define>
+
+    <div metal:define-macro="search">
+      <div metal:use-macro="here/readonlystring/macros/edit">
+      </div>
+    </div>
+
+  </body>
+
+</html>
+
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/__init__.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/__init__.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/__init__.py	(revision 839)
@@ -0,0 +1,1 @@
+#
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/base.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/base.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/base.py	(revision 839)
@@ -0,0 +1,32 @@
+from Testing import ZopeTestCase as ztc
+from Products.Five import zcml
+from Products.Five import fiveconfigure
+from Products.PloneTestCase import PloneTestCase as ptc
+from Products.PloneTestCase.layer import onsetup
+
+ztc.installProduct('PloneFormGen')
+
+@onsetup
+def setup_package():
+    # roadrunner is not working without these 2 lines
+    import Products.PloneFormGen
+    zcml.load_config('configure.zcml', Products.PloneFormGen)
+
+    fiveconfigure.debug_mode = True
+    import quintagroup.ploneformgen.readonlystringfield
+    zcml.load_config('configure.zcml',
+        quintagroup.ploneformgen.readonlystringfield)
+    fiveconfigure.debug_mode = False
+
+    ztc.installPackage('quintagroup.ploneformgen.readonlystringfield')
+
+setup_package()
+ptc.setupPloneSite(products=['quintagroup.ploneformgen.readonlystringfield',])
+
+
+class ReadOnlyStringFieldTestCase(ptc.PloneTestCase):
+    """Common test base class"""
+
+
+class ReadOnlyStringFieldFunctionalTestCase(ptc.FunctionalTestCase):
+    """Common functional test base class"""
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/readonlystringfield.txt
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/readonlystringfield.txt	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/readonlystringfield.txt	(revision 839)
@@ -0,0 +1,49 @@
+Read only String Field
+----------------------
+
+Get our test browser::
+
+    >>> from Products.Five.testbrowser import Browser
+    >>> browser = Browser()
+    >>> portal_url = 'http://nohost/plone'
+    >>> self.app.acl_users.userFolderAddUser('root', 'secret', ['Manager'], [])
+    >>> browser.addHeader('Authorization', 'Basic root:secret')
+
+Add a new form folder and remove all the initial fields::
+
+    >>> self.setRoles(['Manager'])
+    >>> self.portal.invokeFactory('FormFolder', 'testform')
+    'testform'
+    >>> self.portal.testform.manage_delObjects(ids=['replyto','topic','comments'])
+
+And add a user_name readonly string field::
+
+    >>> self.portal.testform.invokeFactory('FormReadonlyStringField', 'user_name')
+    'user_name'
+
+Confirm that the user name field is on the rendered form and is read only::
+
+    >>> browser.open(portal_url + '/testform')
+    >>> 'id="user_name"' in browser.contents
+    True
+    >>> 'readonly="readonly"' in browser.contents
+    True
+
+Now check how EditMode TALES expression field is working. Firstly set it to
+true::
+
+    >>> self.portal.testform.user_name.update(editMode='python:True')
+    >>> browser.open(portal_url + '/testform')
+    >>> 'id="user_name"' in browser.contents
+    True
+    >>> 'readonly="readonly"' in browser.contents
+    False
+
+Eventually set EditMode to be evaluated to False::
+
+    >>> self.portal.testform.user_name.update(editMode='python:False')
+    >>> browser.open(portal_url + '/testform')
+    >>> 'id="user_name"' in browser.contents
+    True
+    >>> 'readonly="readonly"' in browser.contents
+    True
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_docs.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_docs.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_docs.py	(revision 839)
@@ -0,0 +1,17 @@
+import unittest
+import doctest
+
+from Testing import ZopeTestCase as ztc
+
+from quintagroup.ploneformgen.readonlystringfield.tests.base import \
+    ReadOnlyStringFieldFunctionalTestCase
+
+def test_suite():
+    return unittest.TestSuite([
+        ztc.FunctionalDocFileSuite(
+            'readonlystringfield.txt',
+            package='quintagroup.ploneformgen.readonlystringfield.tests',
+            test_class=ReadOnlyStringFieldFunctionalTestCase,
+            optionflags= doctest.REPORT_ONLY_FIRST_FAILURE | \
+                doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS),
+    ])
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_erase.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_erase.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_erase.py	(revision 839)
@@ -0,0 +1,73 @@
+import unittest
+import transaction
+from AccessControl.SecurityManagement import newSecurityManager, \
+    noSecurityManager
+from Testing import ZopeTestCase as ztc
+from Products.CMFCore.utils import getToolByName
+from  Products.PloneTestCase.layer import PloneSiteLayer
+
+from quintagroup.ploneformgen.readonlystringfield.tests.base import \
+    ReadOnlyStringFieldTestCase
+
+
+class TestErase(ReadOnlyStringFieldTestCase):
+    # we use here nested layer for not to make an impact on
+    # the rest test cases, this test case check uninstall procedure
+    # thus it has to uninstall package which will be required to
+    # be installed for other test cases
+    class layer(PloneSiteLayer):
+        @classmethod
+        def setUp(cls):
+            app = ztc.app()
+            portal = app.plone
+            
+            # elevate permissions
+            user = portal.getWrappedOwner()
+            newSecurityManager(None, user)
+
+            tool = getToolByName(portal, 'portal_quickinstaller')
+            product_name = 'quintagroup.ploneformgen.readonlystringfield'
+            if tool.isProductInstalled(product_name):
+                tool.uninstallProducts([product_name,])
+            
+            # drop elevated perms
+            noSecurityManager()
+            
+            transaction.commit()
+            ztc.close(app)
+    
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+    
+    def test_factoryTool(self):
+        tool = getToolByName(self.portal, 'portal_factory')
+        self.failIf('FormReadonlyStringField' in tool._factory_types.keys(),
+            'FormReadonlyStringField type is still in portal_factory tool.')
+    
+    def test_typesTool(self):
+        tool = getToolByName(self.portal, 'portal_types')
+        self.failIf('FormReadonlyStringField' in tool.objectIds(),
+            'FormReadonlyStringField type is still in portal_types tool.')
+    
+    def test_propertiesTool(self):
+        tool = getToolByName(self.portal, 'portal_properties')
+        navtree = tool.navtree_properties
+        self.failIf('FormReadonlyStringField' in navtree.metaTypesNotToList,
+            'FormReadonlyStringField is still in metaTypesNotToList property.')
+        site = tool.site_properties
+        self.failIf('FormReadonlyStringField' in site.types_not_searched,
+            'FormReadonlyStringField is still in types_not_searched property.')
+    
+    def test_skinsTool(self):
+        tool = getToolByName(self.portal, 'portal_skins')
+        self.failIf('readonlystringfield' in tool.objectIds(),
+            'There is still readonlystringfield folder in portal_skins.')
+        for path_id, path in tool._getSelections().items():
+            layers = [l.strip() for l in path.split(',')]
+            self.failIf('readonlystringfield' in layers,
+                'readonlystringfield layer is still in %s.' % path_id)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestErase))
+    return suite
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_setup.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_setup.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/tests/test_setup.py	(revision 839)
@@ -0,0 +1,49 @@
+import unittest
+from Products.CMFCore.utils import getToolByName
+
+from quintagroup.ploneformgen.readonlystringfield.tests.base import \
+    ReadOnlyStringFieldTestCase
+
+
+class TestSetup(ReadOnlyStringFieldTestCase):
+    
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+    
+    def test_installerTool(self):
+        tool = getToolByName(self.portal, 'portal_quickinstaller')
+        self.failUnless(tool.isProductInstalled('PloneFormGen'),
+            'PloneFormGen product is not installed.')
+    
+    def test_factoryTool(self):
+        tool = getToolByName(self.portal, 'portal_factory')
+        self.failUnless('FormReadonlyStringField' in tool._factory_types.keys(),
+            'FormReadonlyStringField type is not in portal_factory tool.')
+    
+    def test_typesTool(self):
+        tool = getToolByName(self.portal, 'portal_types')
+        self.failUnless('FormReadonlyStringField' in tool.objectIds(),
+            'FormReadonlyStringField type is not in portal_types tool.')
+    
+    def test_propertiesTool(self):
+        tool = getToolByName(self.portal, 'portal_properties')
+        navtree = tool.navtree_properties
+        self.failUnless('FormReadonlyStringField' in navtree.metaTypesNotToList,
+            'FormReadonlyStringField is not in metaTypesNotToList property.')
+        site = tool.site_properties
+        self.failUnless('FormReadonlyStringField' in site.types_not_searched,
+            'FormReadonlyStringField is not in types_not_searched property.')
+    
+    def test_skinsTool(self):
+        tool = getToolByName(self.portal, 'portal_skins')
+        self.failUnless('readonlystringfield' in tool.objectIds(),
+            'There is no readonlystringfield folder in portal_skins.')
+        for path_id, path in tool._getSelections().items():
+            layers = [l.strip() for l in path.split(',')]
+            self.failUnless('readonlystringfield' in layers,
+                'readonlystringfield layer is not registered for %s.' % path_id)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestSetup))
+    return suite
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/widget.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/widget.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/quintagroup/ploneformgen/readonlystringfield/widget.py	(revision 839)
@@ -0,0 +1,16 @@
+from Products.Archetypes.Widget import StringWidget
+from Products.Archetypes.Registry import registerWidget
+
+
+class ReadonlyStringWidget(StringWidget):
+    _properties = StringWidget._properties.copy()
+    _properties.update({
+        'macro' : "readonlystring",
+        })
+
+registerWidget(ReadonlyStringWidget,
+               title='ReadonlyString',
+               description=('Renders a HTML readonly text input box which '
+                            'accepts a single line of text'),
+               used_for=('Products.Archetypes.Field.StringField',)
+               )
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.cfg
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.cfg	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.cfg	(revision 839)
@@ -0,0 +1,3 @@
+[egg_info]
+tag_build = dev
+tag_svn_revision = true
Index: /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.py
===================================================================
--- /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.py	(revision 839)
+++ /quintagroup.ploneformgen.readonlystringfield/tags/0.2/setup.py	(revision 839)
@@ -0,0 +1,33 @@
+from setuptools import setup, find_packages
+import os
+
+version = '0.2'
+
+setup(name='quintagroup.ploneformgen.readonlystringfield',
+      version=version,
+      description="Readonly String Field for PloneFormGen product",
+      long_description=open("README.txt").read() + "\n" +
+                       open(os.path.join("docs", "HISTORY.txt")).read(),
+      # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[
+        "Framework :: Plone",
+        "Programming Language :: Python",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        ],
+      keywords='plone form generator readonly field',
+      author='Vitaliy Podoba',
+      author_email='piv@quintagroup.com',
+      url='http://quintagroup.com/services/plone-development/products/',
+      license='GPL',
+      packages=find_packages(exclude=['ez_setup']),
+      namespace_packages=['quintagroup', 'quintagroup.ploneformgen'],
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          'setuptools',
+          'Products.PloneFormGen',
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      """,
+      )
