352 rows, cols = 10, 80 |
352 rows, cols = 10, 80 |
353 kwargs.setdefault('rows', rows) |
353 kwargs.setdefault('rows', rows) |
354 kwargs.setdefault('cols', cols) |
354 kwargs.setdefault('cols', cols) |
355 |
355 |
356 |
356 |
357 def guess_field(eclass, rschema, role='subject', **kwargs): |
357 def guess_field(eclass, rschema, role='subject', skip_meta_attr=True, **kwargs): |
358 """return the most adapated widget to edit the relation |
358 """return the most adapated widget to edit the relation |
359 'subjschema rschema objschema' according to information found in the schema |
359 'subjschema rschema objschema' according to information found in the schema |
360 """ |
360 """ |
361 fieldclass = None |
361 fieldclass = None |
362 eschema = eclass.e_schema |
362 eschema = eclass.e_schema |
367 targetschema = rschema.subjects(eschema)[0] |
367 targetschema = rschema.subjects(eschema)[0] |
368 card = rschema.rproperty(targetschema, eschema, 'cardinality')[1] |
368 card = rschema.rproperty(targetschema, eschema, 'cardinality')[1] |
369 kwargs['required'] = card in '1+' |
369 kwargs['required'] = card in '1+' |
370 kwargs['name'] = rschema.type |
370 kwargs['name'] = rschema.type |
371 if rschema.is_final(): |
371 if rschema.is_final(): |
372 if rschema in eschema.format_fields: |
372 if skip_meta_attr and rschema in eschema.meta_attributes(): |
373 return None |
373 return None |
374 if targetschema == 'Password': |
|
375 return StringField(widget=PasswordInput(), **kwargs) |
|
376 if eschema.has_metadata(rschema, 'format'): |
|
377 constraints = rschema.rproperty(eschema, targetschema, 'constraints') |
|
378 for cstr in constraints: |
|
379 if isinstance(cstr, StaticVocabularyConstraint): |
|
380 raise Exception('rich text field with static vocabulary') |
|
381 if isinstance(cstr, SizeConstraint) and cstr.max is not None: |
|
382 rows_cols_from_constraint(cstr, kwargs) |
|
383 return RichTextField(**kwargs) |
|
384 fieldclass = FIELDS[targetschema] |
374 fieldclass = FIELDS[targetschema] |
385 if fieldclass is StringField: |
375 if fieldclass is StringField: |
|
376 if targetschema == 'Password': |
|
377 # special case for Password field: specific PasswordInput widget |
|
378 return StringField(widget=PasswordInput(), **kwargs) |
|
379 if eschema.has_metadata(rschema, 'format'): |
|
380 # use RichTextField instead of StringField if the attribute has |
|
381 # a "format" metadata. But getting information from constraints |
|
382 # may be useful anyway... |
|
383 constraints = rschema.rproperty(eschema, targetschema, 'constraints') |
|
384 for cstr in constraints: |
|
385 if isinstance(cstr, StaticVocabularyConstraint): |
|
386 raise Exception('rich text field with static vocabulary') |
|
387 if isinstance(cstr, SizeConstraint) and cstr.max is not None: |
|
388 rows_cols_from_constraint(cstr, kwargs) |
|
389 return RichTextField(**kwargs) |
|
390 # return StringField or TextField according to constraints |
386 constraints = rschema.rproperty(eschema, targetschema, 'constraints') |
391 constraints = rschema.rproperty(eschema, targetschema, 'constraints') |
387 return stringfield_from_constraints(constraints, **kwargs) |
392 return stringfield_from_constraints(constraints, **kwargs) |
|
393 if fieldclass is FileField: |
|
394 for metadata in ('format', 'encoding'): |
|
395 metaschema = eschema.has_metadata(rschema, metadata) |
|
396 if metaschema is not None: |
|
397 kwargs['%s_field' % metadata] = guess_field(eclass, metaschema, |
|
398 skip_meta_attr=False) |
388 return fieldclass(**kwargs) |
399 return fieldclass(**kwargs) |
389 kwargs['role'] = role |
400 kwargs['role'] = role |
390 return RelationField.fromcardinality(card, **kwargs) |
401 return RelationField.fromcardinality(card, **kwargs) |
391 |
402 |
392 FIELDS = { |
403 FIELDS = { |