Logo Search packages:      
Sourcecode: zope-atseng version File versions  Download package

SchemaEditor.py

# -*- coding: iso-8859-1 -*-

"""
ATSchemaEditorNG

(C) 2003,2004, Andreas Jung, ZOPYX Software Development and Consulting
and Contributors
D-72070 T�bingen, Germany

Contact: andreas@andreas-jung.com

License: see LICENSE.txt

$Id: SchemaEditor.py 12085 2005-09-22 08:57:47Z rafrombrc $
"""

import re

from Globals import InitializeClass
from ExtensionClass import ExtensionClass
from AccessControl import ClassSecurityInfo
from Acquisition import ImplicitAcquisitionWrapper
from BTrees.OOBTree import OOBTree
from Products.CMFCore.PortalFolder import PortalFolder
from Products.CMFCore.CMFCorePermissions import *
from Products.CMFCore.utils import getToolByName
from Products.Archetypes.public import DisplayList, BaseFolderSchema
from Products.Archetypes.utils import OrderedDict, shasattr
from ManagedSchema import ManagedSchema

from interfaces import ISchemaEditor

import util
from config import *

id_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]$')
schemata_id_regex = re.compile('^[a-zA-Z][a-zA-Z0-9_ ]*[a-zA-Z0-9]$')
allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/ ().,:;#+*=&%$�!'

def remove_unallowed_chars(s):
    return ''.join([c  for c in s  if c in allowed])

field_registry = FIELD_INFO
widget_registry = OrderedDict()
storage_registry = OrderedDict()
for k, v in WIDGET_REGISTRY_INFO:
    widget_registry[k] = v

for k, v in STORAGE_REGISTRY_INFO:
    storage_registry[k] = v


# support for ATReferenceBrowserWidget
HAS_ATREF_WIDGET = False
try:
    from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget
    widget_registry.update({'ReferenceBrowserWidget':
                            {'widget':ReferenceBrowserWidget(), 'visible':True}})
    HAS_ATREF_WIDGET = True
except ImportError:
    pass

class SchemaEditorError(Exception): pass

00065 class SchemaEditor:
    """ a simple TTW editor for Archetypes schemas """

    security = ClassSecurityInfo()

    __implements__ = (ISchemaEditor,)

    security.declareProtected(ManageSchemaPermission, 'atse_init')
    def atse_init(self):
        pass

00076     def __setstate__(self, state):
        """ check for any initialization that hasn't happened, perform
            it if necessary """
        base_method = util._getBaseAttr(self, SchemaEditor, '__setstate__')
        if base_method is not None:
            base_method(self, state)
        if not getattr(self, '_atse_state_set', False):
            self._clear(safe=True)
            self._initRegistries()
            self._atse_state_set = True

    def _migrateObjPtype(self):
        if not type(self._obj_ptype) == type([]):
            return
        ttool = getToolByName(self, 'portal_types')
        oobtree = OOBTree()
        if len(self._obj_ptype):
            tempFolder = PortalFolder('temp').__of__(self)
            tempFolder.unindexObject()
            for ptype in self._obj_ptype:
                fti = getattr(ttool, ptype)
                fti.constructInstance(tempFolder, ptype)
                obj = getattr(tempFolder, ptype)
                oobtree[ptype] = obj.__class__
            del tempFolder
        self._obj_ptype = oobtree

    def _clear(self, safe=False):
        if not safe:
            self._schemas = OOBTree()   # schema_id -> ManagedSchema instance
            self._obj_ptype = OOBTree() # portal type -> object class

        # safe update
        else:
            if not shasattr(self, '_schemas'):
                self._schemas = OOBTree()
            if not shasattr(self, '_obj_ptype'):
                self._obj_ptype = OOBTree()
            elif type(self._obj_ptype) == type([]): # migrate to OOBTree
                self._migrateObjPtype()

    def _initRegistries(self):
        if not shasattr(self, '_widget_registry'):
            self._widget_registry = widget_registry.copy()
        if not shasattr(self, '_storage_registry'):
            self._storage_registry = storage_registry.copy()
        if not shasattr(self, '_field_registry'):
            self._field_registry = field_registry
        

    security.declareProtected(ManageSchemaPermission, 'atse_registerSchema')
    def atse_registerSchema(self, 
                            schema_id,
                            schema,     
                            filtered_schemas=(), 
                            undeleteable_fields=(), 
                            undeleteable_schematas=('default', 'metadata'), 
                            domain='plone'):

        # staying in sync
        self._clear(safe=True)
        self._initRegistries()
        
        if self._schemas.has_key(id):
            raise SchemaEditorError('Schema with id "%s" already exists' % id)
    
        S = ManagedSchema(schema.copy().fields())
        S._filtered_schemas = filtered_schemas
        S._undeleteable_fields = dict([[f, 0] for f in undeleteable_fields])
        S._undeleteable_schematas = dict([[s, 0] for s in undeleteable_schematas])
        S._i18n_domain = domain
        self._schemas[schema_id] = S
        self._p_changed = 1

00150     def atse_registerObject(self, obj,
                            filtered_schemas=(), 
                            undeleteable_fields=(), 
                            undeleteable_schematas=('default', 'metadata'), 
                            domain='plone'):
        """
        Using that method you can register an object.
        Information needed are extracted from it. The Schema id
        is set to the portal type of the object.
        """
        if not hasattr(obj, 'portal_type'):
            raise Exception, 'Object %s is not an valid input' % str(obj)

        # avoiding update problems
        self._clear(safe=True)

        schema = getattr(obj, 'schema')
        ptype = getattr(obj, 'portal_type')

        if obj.__class__ == ExtensionClass:
            obj_klass = obj
        else:
            obj_klass = obj.__class__

        if not (self._obj_ptype.has_key(ptype)):
            self._obj_ptype[ptype] = obj_klass
        # do nothing if object is already there
        # XXX refresh schema
        else:
            return

        self.atse_registerSchema(ptype, schema,
                                 filtered_schemas,
                                 undeleteable_fields,
                                 undeleteable_schematas,
                                 domain)

    security.declareProtected(ManageSchemaPermission, 'atse_unregisterSchema')
00188     def atse_unregisterSchema(self, schema_id):
        """ unregister schema """
        if not self._schemas.has_key(schema_id):
            raise SchemaEditorError('No such schema: %s' % schema_id)
        del self._schemas[schema_id]
        self._p_changed = 1

    security.declareProtected(ManageSchemaPermission, 'atse_reRegisterSchema')
00196     def atse_reRegisterSchema(self, schema_id, schema):
        """ re-registering schema """

        self.atse_unregisterSchema(schema_id)
        self.atse_registerSchema(schema_id, schema)
        self._p_changed = 1
        
    security.declareProtected(ManageSchemaPermission, 'atse_reRegisterObject')
00204     def atse_reRegisterObject(self, object):
        """ re-registering object """
        self.atse_unregisterSchema(object.portal_type)
        del self._obj_ptype[object.portal_type]
        self.atse_registerObject(object)
        self._p_changed = 1

    security.declareProtected(View, 'atse_getSchemaById')
00212     def atse_getSchemaById(self, schema_id):
        """ return a schema by its schema_id """
        if not self._schemas.has_key(schema_id):
            raise SchemaEditorError('No such schema: %s' % schema_id)
        return self._schemas[schema_id]

    security.declareProtected(View, 'atse_getSchemaById')
00219     def atse_getRegisteredSchemata(self):
        """
        Returns all registered schemata
        """
        return self._schemas.keys()

    security.declareProtected(View, 'atse_getSchemaById')
00226     def atse_selectRegisteredSchema(self, schema_template, REQUEST=None):
        """
        Redirection
        """
        req = REQUEST or self.REQUEST
        sel = req.form['selection']
        return util.redirect(req.RESPONSE, schema_template,
                             self.translate('atse_editing_schema_for_type',
                                            {'portal_type':sel}, 
                                            default='Now editing schema for ${portal_type}', 
                                            domain='ATSchemaEditorNG'),
                             schema_id=sel)

    security.declareProtected(View, 'atse_isSchemaRegistered')
00240     def atse_isSchemaRegistered(self, schema_id):
        """ returns True if schema exists """
        return self._schemas.has_key(schema_id) > 0

    security.declareProtected(View, 'atse_getDefaultSchema')
00245     def atse_getDefaultSchema(self):
        """ returns the first schema in list """
        if self._schemas.items():
            return self._schemas.items()[0][1]

        # XXX urgh
        # change this to use an attr
        return BaseFolderSchema()

    security.declareProtected(View, 'atse_getDefaultSchemaId')
00255     def atse_getDefaultSchemaId(self):
        """ returns default schema id """

        if self._schemas.items():
            return self._schemas.items()[0][0]

        return ''

    security.declareProtected(View, 'atse_getSchemataNames')
00264     def atse_getSchemataNames(self, schema_id, filter=True):
        """ return names of all schematas """
        S = self.atse_getSchemaById(schema_id)
        if filter:
            ret = []
            for n in S.getSchemataNames():
                if n in S._filtered_schemas or \
                   len(S.filterFields(schemata=n)) == \
                   len(S.filterFields(schemata=n, atse_managed=ATSE_MANAGED_NONE)):
                    pass
                else:
                    ret.append(n)
            return ret
        else:
            return [n for n in S.getSchemataNames()]

    security.declareProtected(View, 'atse_getSchemata')
00281     def atse_getSchemata(self, schema_id, name, filtered=True):
        """ return a schemata given by its name """
        S = self.atse_getSchemaById(schema_id)
        s = ManagedSchema()
        for f in S.getSchemataFields(name):
            if filtered and getattr(f,
                                    'atse_managed',
                                    ATSE_MANAGED_FULL) == ATSE_MANAGED_NONE:
                continue
            s.addField(f)
        return ImplicitAcquisitionWrapper(s, self)

    security.declareProtected(ManageSchemaPermission,
                              'atse_getUnmanagedFields')
00295     def atse_getUnmanagedFieldNames(self, schema_id):
        """ returns names of all fields that are not managed by
        the schema editor"""
        S = self.atse_getSchemaById(schema_id)
        pred = S._fieldIsUnmanaged
        return [f.getName() for f in S.filterFields(pred)]

    security.declareProtected(ManageSchemaPermission,
                              'atse_syncUnmanagedFields')
00304     def atse_syncUnmanagedAndNewFields(self, schema_id, schema_template=None,
                                       RESPONSE=None):
        """ synchronizes all unmanaged fields with the field
        definitions specified in the file system source code """
        unmanaged_fnames = self.atse_getUnmanagedFieldNames(schema_id)
        klass = self._obj_ptype[schema_id]
        src_schema = klass.schema
        atse_schema = self._schemas[schema_id]
        for field in src_schema.fields():
            fname = field.getName()
            if not atse_schema.has_key(fname):
                atse_schema.addFieldAfterFieldName(last_fname, field)
            elif fname in unmanaged_fnames:
                atse_schema.replaceField(fname, src_schema[fname].copy())
            last_fname = fname
        self._schemas._p_changed = 1
        if schema_template is not None and RESPONSE is not None:
            util.redirect(RESPONSE, schema_template,
                          self.translate('atse_fields_synced',
                                         default='Unmanaged and missing fields have been synchronized',
                                         domain='ATSchemaEditorNG'), 
                          schema_id=schema_id)

    ######################################################################
    # Add/remove schematas
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_addSchemata')
00332     def atse_addSchemata(self, schema_id, schema_template, name, RESPONSE=None):
        """ add a new schemata """

        S = self.atse_getSchemaById(schema_id)

        if not name:
            raise SchemaEditorError(self.translate('atse_empty_name', 
                                                   default='Empty ID given', 
                                                   domain='ATSchemaEditorNG'))

        if name in S.getSchemataNames():
            raise SchemaEditorError(self.translate('atse_exists', 
                                                   {'schemata':name},
                                                   default='Schemata \"$schemata\" already exists', 
                                                   domain='ATSchemaEditorNG'))
        if not schemata_id_regex.match(name):
            raise SchemaEditorError(self.translate('atse_invalid_id_for_schemata', 
                                                  {'schemata':name},
                                                  default='\"$schemata\" is an invalid ID for a schemata',
                                                  domain='ATSchemaEditorNG'))

        S.addSchemata(name)
        self._schemas[schema_id] = S

        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_added', default='Schemata added',domain='ATSchemaEditorNG'),
                      schemata=name,
                      schema_id=schema_id)

    security.declareProtected(ManageSchemaPermission, 'atse_delSchemata')
00362     def atse_delSchemata(self, schema_id, schema_template, name, RESPONSE=None):
        """ delete a schemata """
        S = self.atse_getSchemaById(schema_id)

        if S._undeleteable_schematas.has_key(name): 
            raise SchemaEditorError(self.translate('atse_can_not_remove_schema', 
                                                   default='Can not remove this schema because it is protected from deletion',
                                                   domain='ATSchemaEditorNG'))
   
        if len(self.atse_getSchemataNames(schema_id, True)) == 1: 
            raise SchemaEditorError(self.translate('atse_can_not_remove_last_schema', 
                                                   default='Can not remove the last schema',
                                                   domain='ATSchemaEditorNG'))

        for field in S.getSchemataFields(name): 
            if S._undeleteable_fields.has_key(field.getName()):
                raise SchemaEditorError(self.translate('atse_schemata_contains_undeleteable_fields', 
                                        default='The schemata contains fields that can not be deleted',
                                        domain='ATSchemaEditorNG'))

        
        S.delSchemata(name)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, 
                      schema_template,
                      self.translate('atse_deleted', 
                                     default='Schemata deleted',
                                     domain='ATSchemaEditorNG'),
                      schemata=self.atse_getSchemataNames(schema_id, True)[0],
                      schema_id=schema_id)

    ######################################################################
    # Field manipulation
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_delField')
00398     def atse_delField(self, schema_id, schema_template, name, RESPONSE=None):
        """ remove a field from the  schema"""

        S = self.atse_getSchemaById(schema_id)

        if S._undeleteable_fields.has_key(name):
            raise SchemaEditorError(self.translate('atse_field_not_deleteable',
                                            {'name' : name},
                                            default='field \"$name\" can not be deleted because it is protected from deletion',
                                            domain='ATSchemaEditorNG'))

        old_schemata = S.get(name).schemata
        S.delField(name)    

        if old_schemata in S.getSchemataNames(): # Schematas disappear if they are empty
            return_schemata = old_schemata
        else:
            return_schemata = self.atse_getSchemataNames(schema_id, True)[0]
    
        self._schemas[schema_id] = S
        
        if RESPONSE:
            util.redirect(RESPONSE, 
                          schema_template,
                          self.translate('atse_field_deleted',
                                         default='Field deleted',
                                         domain='ATSchemaEditorNG'), 
                          schema_id=schema_id,
                          schemata=return_schemata)

    security.declareProtected(ManageSchemaPermission, 'atse_addField')
00429     def atse_addField(self, schema_id, schemata, schema_template,
                      name, RESPONSE=None):
        """create a new field"""
        S = self.atse_getSchemaById(schema_id)

        if not name:
            raise SchemaEditorError(self.translate('atse_empty_field_name', 
                                            default='Field name is empty',
                                            domain='ATSchemaEditorNG'))

        if not id_regex.match( name ):
            raise SchemaEditorError(self.translate('atse_not_a_valid_id', 
                                            {'id' : name},
                                            default='\"$id\" is not a valid ID',
                                            domain='ATSchemaEditorNG'))

        if name in [f.getName() for f in S.fields()]:
            raise SchemaEditorError(self.translate('atse_field_already_exists', 
                                           {'id' : name},
                                           default='\"$id\" already exists',
                                           domain='ATSchemaEditorNG'))

        fieldset = schemata    
        field = StringField(name, schemata=fieldset, widget=StringWidget)
        S.addField(field)
        self._schemas[schema_id] = S
        if RESPONSE:        
            util.redirect(RESPONSE, schema_template,
                          self.translate('atse_field_added', 
                                         default='Field added',
                                         domain='ATSchemaEditorNG'), 
                          schema_id=schema_id,
                          schemata=fieldset, 
                          field=name)
        return            
        
    security.declareProtected(ManageSchemaPermission, 'atse_update')
00466     def atse_update(self, schema_id, schema_template, fielddata,
                    REQUEST, RESPONSE=None):
        """ update a single field"""
        S = self.atse_getSchemaById(schema_id)
        R = REQUEST.form
        FD = fielddata

        if R.has_key('add_field'):
            self.atse_addField(schema_id, FD.schemata, schema_template,
                               R['name'], RESPONSE)
            return            
            
        field = TYPE_MAP.get(FD.type, None)
        if not field:
            raise SchemaEditorError(self.translate('atse_unknown_field', 
                                              {'field' : FD.type},
                                             default='unknown field type: $field',
                                             domain='ATSchemaEditorNG')) 

        D = {}    # dict to be passed to the field constructor
        D['default'] = FD.get('default', '')
        D['schemata'] = FD.schemata
        D['createindex'] = FD.get('createindex', 0)
        storageInfo = self.atse_getStorageMap()[FD.get('storage')]
        D['storage'] = storageInfo['storage']
        
        # call storage data processing method
        if storageInfo.has_key('post_method') and R.get('storage_data'):
            post_method = getattr(storageInfo['storage'], storageInfo['post_method'] )
            post_method(context=self, 
                        public_name = FD.name, 
                        storage_data = R.get('storage_data'))
   
        # build widget
        widget_data = self.atse_getWidgetMap().get(FD.widget, None)
        if not widget_data:
            raise SchemaEditorError(self.translate('atse_unknown_widget', 
                                                  {'widget' : FD.widget},
                                                  default='unknown widget type: $widget',
                                                  domain='ATSchemaEditorNG'))
        widget = widget_data['widget'].copy()

        # support for relations
        D['relationship'] = FD.get('relationship', 'defaultRelation')

        widget.size = FD.get('widgetsize', 60)
        widget.rows = FD.get('widgetrows', 5)
        widget.cols = FD.get('widgetcols', 60)
        maxlength =  FD.get('widgetmaxlength')
        if maxlength:
            widget.maxlength = maxlength

        # setting visibility of field
        widget.visible = {'edit' : 'visible', 'view' : 'visible'}
        if not FD.has_key('visible_edit'):
            widget.visible['edit'] = 'invisible'

        if not FD.has_key('visible_view'):
            widget.visible['view'] = 'invisible'

        if FD.has_key('description'):
            widget.description = FD['description']

        # Validators
        if FD.has_key('validators'):
            validators = tuple([v.strip() for v in FD['validators'].split(',')])
            if validators:
                D['validators'] = validators
                
        widget.label = FD.label
        widget.label_msgid = 'label_' + FD.label
        widget.i18n_domain = S._i18n_domain

        D['widget'] = widget

        # build DisplayList instance for SelectionWidgets
        widget_map = self.atse_getWidgetMap()
        if widget_map[FD.widget].get('useVocab'):
            vocab = FD.get('vocabulary', [])

            # The vocabulary can either be a list of string of 'values'
            # or a list of strings 'key|value' or a list with *one*
            # string 'method:<methodname>'. 'method:<methodname>' is used
            # specify a method that is called to retrieve a DisplayList
            # instance

            if len(vocab) == 1 and vocab[0].startswith('method:'):
                dummy,method = vocab[0].split(':')
                D['vocabulary'] = method.strip()
            else:
                l = []
                for line in vocab:
                    line = line.strip()
                    if not line: continue
                    if '|' in line:
                        k,v = line.split('|', 1)
                    else:
                        k = v = line

                    k = remove_unallowed_chars(k)
                    l.append( (k,v))

                D['vocabulary'] = DisplayList(l)

        D['required'] = FD.get('required', 0)

        newfield = field(FD.name, **D)

        # call custom data processing method
        if hasattr(self, '_post_method_name'):
            post_method = getattr(self, self._post_method_name)
            post_method(context=self,
                        field=newfield,
                        custom_data=R.get('custom_data'))

        S.replaceField(FD.name, newfield)
        self._schemas[schema_id] = S

        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_field_changed', default='Field changed', domain='ATSchemaEditorNG'), 
                      schema_id=schema_id,
                      schemata=FD.schemata, 
                      field=FD.name)


    ######################################################################
    # Field / Widget / Storage registration handling
    ######################################################################

    # XXX integrate w/ AT's centralized field/widget registry in
    # Products.Archetypes.Registry
    security.declareProtected(ManageSchemaPermission, 'atse_getFieldTypes')
00598     def atse_getFieldTypes(self):
        """get this instance's registered field info"""
        return self._field_registry

    security.declareProtected(ManageSchemaPermission, 'atse_registerFieldType')
00603     def atse_registerFieldType(self, field_type):
        """add a new field type to the set of registered field types"""
        self._initRegistries()
        if not field_type in self._field_registry:
            self._field_registry += (field_type,)
        else:
            raise SchemaEditorError('Field Type %s already registered' \
                                    % field_type)            

    security.declareProtected(ManageSchemaPermission, 'atse_getWidgetInfo')
00613     def atse_getWidgetInfo(self):
        """get the instance's registered widget info or the default"""
        return self._widget_registry.items()

    security.declareProtected(ManageSchemaPermission, 'atse_getWidgetMap')
00618     def atse_getWidgetMap(self):
        """get the instance's registered widget map or the default"""
        return self._widget_registry
    
    security.declareProtected(ManageSchemaPermission, 'atse_registerWidget')
00623     def atse_registerWidget(self, widget_id, widget, **kw):
        """add a new widget to the set of registered widgets; supported
        keyword arguments:

        - visible: whether or not to include the widget in the schema editor

        - useVocab: whether or not to include the key|value vocabulary box

        - size_macro: path to a macro that will accept the widget size data

        - post_macro: path to a macro that will be injected at the end of the
                      field edit form"""
        self._initRegistries()
        kw['widget'] = widget
        self._widget_registry[widget_id] = kw
        self._p_changed = 1 # mutation might not trigger db write

    security.declareProtected(ManageSchemaPermission, 'atse_getStorageInfo')
00641     def atse_getStorageInfo(self):
        """get the instance's registered storage info or the default"""
        if not hasattr(self, '_storage_info'):
            self._initRegistries()
        return self._storage_registry.items()

    security.declareProtected(ManageSchemaPermission, 'atse_getStorageMap')
00648     def atse_getStorageMap(self):
        """get the instance's registered storage map or the default"""
        return self._storage_registry
        
    security.declareProtected(ManageSchemaPermission, 'atse_registerStorage')
00653     def atse_registerStorage(self, storage_id, storage, **kw):
        """add a new storage to the set of registered storages; supported
        keyword arguments:

        - visible: whether or not to include the storage in the schema editor

        - post_macro: path to a macro that will be injected at the end of the
                      field edit form
                      
        - post_method: method to call method(fieldName , storage_data) 
                       storage_data contains all storage_data.* fields."""
                      
        self._initRegistries()
        kw['storage'] = storage
        self._storage_registry[storage_id] = kw
        self._p_changed = 1 # mutation might not trigger db write
            
    ######################################################################
    # Editor-wide fieldeditor customization hooks
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_setPostMacro')
00675     def atse_setPostMacro(self, post_macro_path, post_method_name):
        """specify a post_macro to use when rendering the fieldeditor
        interface for every field, regardless of field, widget, or storage
        type:

        - post_macro_path: full path to the macro, starting with 'here',
                           e.g. '/here/your_template/macros/your_macro'

        - post_method_name: method to call method(context, field, custom_data)
                            custom_data contains all custom_data.* fields"""
        
        self._post_macro_path = post_macro_path
        self._post_method_name = post_method_name

    security.declareProtected(ManageSchemaPermission, 'atse_getPostMacro')
00690     def atse_getPostMacro(self):
        """return the editor-wide post macro path as a string"""
        return getattr(self, '_post_macro_path', '')

    security.declareProtected(ManageSchemaPermission, 'atse_setWidgetPostMacro')
00695     def atse_setWidgetPostMacro(self, widget_post_macro_path):
        """specify a post_macro to use when rendering the fieldeditor
        interface for every field, regardless of field, widget, or storage
        type; this macro will be rendered within the 'Widget settings'
        box in the field editor.  widget_post_macro_path should be a full
        path to the macro, starting with 'here', e.g.
        '/here/your_template/macros/your_macro'"""
        self._widget_post_macro_path = widet_post_macro_path

    security.declareProtected(ManageSchemaPermission, 'atse_getWidgetPostMacro')
00705     def atse_getWidgetPostMacro(self):
        """return the editor-wide widget post macro path as a string"""
        return getattr(self, '_widget_post_macro_path', '')

    ######################################################################
    # Moving schematas and fields
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_schemataMoveLeft')
00714     def atse_schemataMoveLeft(self, schema_id, schema_template, name, RESPONSE=None):
        """ move a schemata to the left"""
        S = self.atse_getSchemaById(schema_id)
        S.moveSchemata(name, -1)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_moved_left', default='Schemata moved to left', domain='ATSchemaEditorNG'), 
                      schema_id=schema_id,
                      schemata=name)

    security.declareProtected(ManageSchemaPermission, 'atse_schemataMoveRight')
00725     def atse_schemataMoveRight(self, schema_id, schema_template, name, RESPONSE=None):
        """ move a schemata to the right"""
        S = self.atse_getSchemaById(schema_id)
        S.moveSchemata(name, 1)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_moved_right', 
                                     default='Schemata moved to right',
                                     domain='ATSchemaEditorNG'), 
                      schema_id=schema_id,
                      schemata=name)

    security.declareProtected(ManageSchemaPermission, 'atse_fieldMoveLeft')
00738     def atse_fieldMoveLeft(self, schema_id, schema_template, name, RESPONSE=None):
        """ move a field of a schemata to the left"""
        S = self.atse_getSchemaById(schema_id)
        S.moveField(name, -1)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_field_moved_up', 
                                     default='Field moved up', 
                                     domain='ATSchemaEditorNG'),
                      schemata=S[name].schemata, 
                      schema_id=schema_id,
                      field=name)

    security.declareProtected(ManageSchemaPermission, 'atse_fieldMoveRight')
00752     def atse_fieldMoveRight(self, schema_id, schema_template, name, RESPONSE=None):
        """ move a field of a schemata to the right"""
        S = self.atse_getSchemaById(schema_id)
        S.moveField(name, 1)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, schema_template, 
                      self.translate('atse_field_moved_down', 
                                     default='Field moved down',
                                     domain='ATSchemaEditorNG'), 
                      schemata=S[name].schemata, 
                      schema_id=schema_id,
                      field=name)

    security.declareProtected(ManageSchemaPermission, 'atse_changeSchemataForField')
00766     def atse_changeSchemataForField(self, schema_id, schema_template, name, schemata_name, RESPONSE=None):
        """ move a field from the current fieldset to another one """
        S = self.atse_getSchemaById(schema_id)
        S.changeSchemataForField(name, schemata_name)
        self._schemas[schema_id] = S
        util.redirect(RESPONSE, schema_template,
                      self.translate('atse_field_moved', 
                                     default='Field moved to other fieldset',
                                     domain='ATSchemaEditorNG'), 
                      schemata=schemata_name, 
                      schema_id=schema_id,
                      field=name)

    ######################################################################
    # Hook for UI
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_getField')
00784     def atse_getField(self, schema_id, name):
        """ return a field by its name """
        S = self.atse_getSchemaById(schema_id)
        return S[name]

    security.declareProtected(ManageSchemaPermission, 'atse_getFieldType')
00790     def atse_getFieldType(self, field):
        """ return the type of a field """
        return field.__class__.__name__

    security.declareProtected(ManageSchemaPermission, 'atse_getFieldValidators')
00795     def atse_getFieldValidators(self, field):
        """ return a list of the pertinent validators for a field """
        validators = getattr(field, 'validators', ())
        # filtering out 'isEmpty..' validators since they get injected
        # into the validation chain automatically
        return tuple([v.name for v,q in validators if
                      not v.name.startswith('isEmpty')])

    security.declareProtected(ManageSchemaPermission, 'atse_formatVocabulary')
00804     def atse_formatVocabulary(self, field):
        """ format the DisplayList of a field to be displayed
            within a textarea.
        """
        if isinstance(field.vocabulary, str):
            return 'method:' + field.vocabulary

        l = []
        for k in field.vocabulary:
            v = field.vocabulary.getValue(k)
            if k == v: l.append(k)
            else: l.append('%s|%s' % (k,v))
        return '\n'.join(l)

    security.declareProtected(ManageSchemaPermission, 'atse_schema_baseclass')
00819     def atse_schema_baseclass(self, schema_id):
        """ return name of baseclass """
        S = self.atse_getSchemaById(schema_id)
        return S.__class__.__name__

    ######################################################################
    # [spamies] Helper methods for maintenance and widget access
    ######################################################################

    security.declareProtected(ManageSchemaPermission, 'atse_isFieldVisible')
00829     def atse_isFieldVisible(self, fieldname, mode='view', schema_id=None):
        """
        Returns True if the given field is visible
        in the given mode. Default is view.
        """
        
        if not schema_id:
            schema_id = self.atse_getDefaultSchemaId()
            
        field = self.atse_getField(schema_id, fieldname)
        if hasattr(field.widget, 'visible'):
            visible = field.widget.visible
            if isinstance(visible, int):
                return visible
            if field.widget.visible.get(mode) == 'invisible':
                return False
            else: return True

        # always True if we've found nothing
        return True

    security.declareProtected(ManageSchemaPermission, 'atse_editorCanUpdate')
00851     def atse_editorCanUpdate(self, portal_type):
        """
        Returns True if an object was registered and
        its portal_type could be saved.
        """
        if hasattr(self, '_obj_ptype'):
            if portal_type and self._obj_ptype.has_key(portal_type):
                return True
        return False

    security.declareProtected(ManageSchemaPermission, 'atse_updateManagedSchemas')
00862     def atse_updateManagedSchema(self,
                                 portal_type,
                                 schema_template,
                                 REQUEST=None, RESPONSE=None):        
        """
        Update stored issue schema for all managed schemas.
        That can only done, if an complete object was registered.
        """
        # we absolutely need to have portal_type
        if not self.atse_editorCanUpdate(portal_type):
            return util.redirect(RESPONSE, schema_template,
                                 self.translate('atse_unknown_portal_type',
                                                {'portal_type':portal_type},
                                                default='Can not determine portal_type of managed objects (${portal_type})...', 
                                                domain='ATSchemaEditorNG'))

        # we assume that the schema name is the same as the portal_type
        schema = self.atse_getSchemaById(portal_type)

        # gettin' objects and updating them
        objects = [ o.getObject() for o in \
                    self.portal_catalog.searchResults(portal_type=portal_type)]

        # ParentManagedSchema is refreshing the schema,
        # if the _v_ variable is None...
        for obj in objects:
            if hasattr(obj, '_v_schema'):
                delattr(obj, '_v_schema')
                obj._p_changed = 1

        # XXX do translation
        if RESPONSE:
            return util.redirect(RESPONSE, schema_template,
                          self.translate('atse_objects_updated',
                                         {'portal_type':portal_type},
                                         default='Objects of type ${portal_type} updated successfully',
                                         domain='ATSchemaEditorNG'))

InitializeClass(SchemaEditor)

Generated by  Doxygen 1.6.0   Back to index