11 from datetime import datetime |
11 from datetime import datetime |
12 |
12 |
13 from logilab.mtconverter import xml_escape |
13 from logilab.mtconverter import xml_escape |
14 from logilab.common.decorators import cached |
14 from logilab.common.decorators import cached |
15 |
15 |
|
16 from yams.schema import KNOWN_METAATTRIBUTES |
16 from yams.constraints import (SizeConstraint, StaticVocabularyConstraint, |
17 from yams.constraints import (SizeConstraint, StaticVocabularyConstraint, |
17 FormatConstraint) |
18 FormatConstraint) |
18 |
19 |
19 from cubicweb.utils import ustrftime |
20 from cubicweb.utils import ustrftime |
20 from cubicweb import tags, uilib |
21 from cubicweb import tags, uilib |
568 self.widget.attrs.setdefault('maxlength', 15) |
569 self.widget.attrs.setdefault('maxlength', 15) |
569 |
570 |
570 def process_form_value(self, form): |
571 def process_form_value(self, form): |
571 return int(Field.process_form_value(self, form)) |
572 return int(Field.process_form_value(self, form)) |
572 |
573 |
|
574 |
573 class BooleanField(Field): |
575 class BooleanField(Field): |
574 widget = Radio |
576 widget = Radio |
575 |
577 |
576 def vocabulary(self, form): |
578 def vocabulary(self, form): |
577 if self.choices: |
579 if self.choices: |
578 return self.choices |
580 return self.choices |
579 return [(form._cw._('yes'), '1'), (form._cw._('no'), '')] |
581 return [(form._cw._('yes'), '1'), (form._cw._('no'), '')] |
580 |
582 |
581 def process_form_value(self, form): |
583 def process_form_value(self, form): |
582 return bool(Field.process_form_value(self, form)) |
584 return bool(Field.process_form_value(self, form)) |
|
585 |
583 |
586 |
584 class FloatField(IntField): |
587 class FloatField(IntField): |
585 def format_single_value(self, req, value): |
588 def format_single_value(self, req, value): |
586 formatstr = req.property_value('ui.float-format') |
589 formatstr = req.property_value('ui.float-format') |
587 if value is None: |
590 if value is None: |
591 def render_example(self, req): |
594 def render_example(self, req): |
592 return self.format_single_value(req, 1.234) |
595 return self.format_single_value(req, 1.234) |
593 |
596 |
594 def process_form_value(self, form): |
597 def process_form_value(self, form): |
595 return float(Field.process_form_value(self, form)) |
598 return float(Field.process_form_value(self, form)) |
|
599 |
596 |
600 |
597 class DateField(StringField): |
601 class DateField(StringField): |
598 format_prop = 'ui.date-format' |
602 format_prop = 'ui.date-format' |
599 widget = DateTimePicker |
603 widget = DateTimePicker |
600 |
604 |
611 # directly, so handle that case : |
615 # directly, so handle that case : |
612 if isinstance(date, basestring): |
616 if isinstance(date, basestring): |
613 date = form.parse_date(wdgdate, 'Date') |
617 date = form.parse_date(wdgdate, 'Date') |
614 return date |
618 return date |
615 |
619 |
|
620 |
616 class DateTimeField(DateField): |
621 class DateTimeField(DateField): |
617 format_prop = 'ui.datetime-format' |
622 format_prop = 'ui.datetime-format' |
618 |
623 |
619 def process_form_value(self, form): |
624 def process_form_value(self, form): |
620 # widget is supposed to return a date as a correctly formatted string |
625 # widget is supposed to return a date as a correctly formatted string |
623 # directly, so handle that case : |
628 # directly, so handle that case : |
624 if isinstance(date, basestring): |
629 if isinstance(date, basestring): |
625 date = form.parse_datetime(date, 'Datetime') |
630 date = form.parse_datetime(date, 'Datetime') |
626 return date |
631 return date |
627 |
632 |
|
633 |
628 class TimeField(DateField): |
634 class TimeField(DateField): |
629 format_prop = 'ui.time-format' |
635 format_prop = 'ui.time-format' |
630 widget = TextInput |
636 widget = TextInput |
631 |
637 |
632 def process_form_value(self, form): |
638 def process_form_value(self, form): |
637 if isinstance(time, basestring): |
643 if isinstance(time, basestring): |
638 time = form.parse_time(wdgdate, 'Time') |
644 time = form.parse_time(wdgdate, 'Time') |
639 return time |
645 return time |
640 |
646 |
641 class RelationField(Field): |
647 class RelationField(Field): |
642 # XXX (syt): iirc, we originaly don't sort relation vocabulary since we want |
|
643 # to let entity.unrelated_rql control this, usually to get most recently |
|
644 # modified entities in the select box instead of by alphabetical order. Now, |
|
645 # we first use unrelated_rql to get the vocabulary, which may be limited |
|
646 # (hence we get the latest modified entities) and we can sort here for |
|
647 # better readability |
|
648 # |
|
649 # def __init__(self, **kwargs): |
|
650 # kwargs.setdefault('sort', False) |
|
651 # super(RelationField, self).__init__(**kwargs) |
|
652 |
648 |
653 @staticmethod |
649 @staticmethod |
654 def fromcardinality(card, **kwargs): |
650 def fromcardinality(card, **kwargs): |
655 kwargs.setdefault('widget', Select(multiple=card in '*+')) |
651 kwargs.setdefault('widget', Select(multiple=card in '*+')) |
656 return RelationField(**kwargs) |
652 return RelationField(**kwargs) |
657 |
653 |
658 def vocabulary(self, form): |
654 def vocabulary(self, form): |
659 entity = form.edited_entity |
655 entity = form.edited_entity |
660 req = entity._cw |
|
661 # first see if its specified by __linkto form parameters |
656 # first see if its specified by __linkto form parameters |
662 linkedto = entity.linked_to(self.name, self.role) |
657 linkedto = entity.linked_to(self.name, self.role) |
663 if linkedto: |
658 if linkedto: |
664 entities = (req.entity_from_eid(eid) for eid in linkedto) |
659 entities = (req.entity_from_eid(eid) for eid in linkedto) |
665 return [(entity.view('combobox'), entity.eid) for entity in entities] |
660 return [(entity.view('combobox'), entity.eid) for entity in entities] |
765 for cstr in rdef.constraints: |
760 for cstr in rdef.constraints: |
766 if isinstance(cstr, SizeConstraint) and cstr.max is not None: |
761 if isinstance(cstr, SizeConstraint) and cstr.max is not None: |
767 kwargs['max_length'] = cstr.max |
762 kwargs['max_length'] = cstr.max |
768 return StringField(**kwargs) |
763 return StringField(**kwargs) |
769 if fieldclass is FileField: |
764 if fieldclass is FileField: |
770 for metadata in ('format', 'encoding', 'name'): |
765 for metadata in KNOWN_METAATTRIBUTES: |
771 metaschema = eschema.has_metadata(rschema, metadata) |
766 metaschema = eschema.has_metadata(rschema, metadata) |
772 if metaschema is not None: |
767 if metaschema is not None: |
773 kwargs['%s_field' % metadata] = guess_field(eschema, metaschema, |
768 kwargs['%s_field' % metadata] = guess_field(eschema, metaschema, |
774 skip_meta_attr=False) |
769 skip_meta_attr=False) |
775 return fieldclass(**kwargs) |
770 return fieldclass(**kwargs) |