web/views/cwproperties.py
branchstable
changeset 1865 62d3726ad8cb
parent 1739 78b0819162a8
child 1870 015dfeaf1d89
equal deleted inserted replaced
1864:4ceaf8f2709b 1865:62d3726ad8cb
    15 from cubicweb.selectors import (one_line_rset, none_rset, implements,
    15 from cubicweb.selectors import (one_line_rset, none_rset, implements,
    16                                 match_user_groups)
    16                                 match_user_groups)
    17 from cubicweb.view import StartupView
    17 from cubicweb.view import StartupView
    18 from cubicweb.web import uicfg, stdmsgs
    18 from cubicweb.web import uicfg, stdmsgs
    19 from cubicweb.web.form import CompositeForm, EntityFieldsForm, FormViewMixIn
    19 from cubicweb.web.form import CompositeForm, EntityFieldsForm, FormViewMixIn
       
    20 from cubicweb.web.formrenderers import FormRenderer
    20 from cubicweb.web.formfields import FIELDS, StringField
    21 from cubicweb.web.formfields import FIELDS, StringField
    21 from cubicweb.web.formwidgets import Select, Button, SubmitButton
    22 from cubicweb.web.formwidgets import Select, Button, SubmitButton
    22 from cubicweb.web.views import primary
    23 from cubicweb.web.views import primary
    23 
    24 
    24 
    25 
    46 _('ui.site-title')
    47 _('ui.site-title')
    47 _('ui.encoding')
    48 _('ui.encoding')
    48 _('category')
    49 _('category')
    49 
    50 
    50 
    51 
    51 def make_togglable_link(nodeid, label, cookiename):
    52 def make_togglable_link(nodeid, label):
    52     """builds a HTML link that switches the visibility & remembers it"""
    53     """builds a HTML link that switches the visibility & remembers it"""
    53     action = u"javascript: toggleVisibility('%s', '%s')" % \
    54     action = u"javascript: togglePrefVisibility('%s')" % nodeid
    54         (nodeid, cookiename)
       
    55     return u'<a href="%s">%s</a>' % (action, label)
    55     return u'<a href="%s">%s</a>' % (action, label)
    56 
    56 
    57 def css_class(someclass):
    57 def css_class(someclass):
    58     return someclass and 'class="%s"' % someclass or ''
    58     return someclass and 'class="%s"' % someclass or ''
    59 
    59 
    93             status = cookie.value
    93             status = cookie.value
    94         return status
    94         return status
    95 
    95 
    96     def call(self, **kwargs):
    96     def call(self, **kwargs):
    97         """The default view representing the application's index"""
    97         """The default view representing the application's index"""
    98         self.req.add_js('cubicweb.preferences.js')
    98         self.req.add_js(('cubicweb.edition.js', 'cubicweb.preferences.js', 'cubicweb.ajax.js'))
    99         self.req.add_css('cubicweb.preferences.css')
    99         self.req.add_css('cubicweb.preferences.css')
   100         vreg = self.vreg
   100         vreg = self.vreg
   101         values = self.defined_keys
   101         values = self.defined_keys
   102         groupedopts = {}
   102         groupedopts = {}
   103         mainopts = {}
   103         mainopts = {}
   111                 groupedopts.setdefault(reg, {}).setdefault(oid, []).append(key)
   111                 groupedopts.setdefault(reg, {}).setdefault(oid, []).append(key)
   112             else:
   112             else:
   113                 mainopts.setdefault(parts[0], []).append(key)
   113                 mainopts.setdefault(parts[0], []).append(key)
   114         # precompute form to consume error message
   114         # precompute form to consume error message
   115         for group, keys in mainopts.items():
   115         for group, keys in mainopts.items():
   116             mainopts[group] = self.form(keys, True)
   116             mainopts[group] = self.form(group, keys, False)
       
   117 
   117         for group, objects in groupedopts.items():
   118         for group, objects in groupedopts.items():
   118             for oid, keys in objects.items():
   119             for oid, keys in objects.items():
   119                 groupedopts[group][oid] = self.form(keys, True)
   120                 groupedopts[group][oid] = self.form(group + '-' + oid, keys, True)
       
   121 
   120         w = self.w
   122         w = self.w
   121         req = self.req
   123         req = self.req
   122         _ = req._
   124         _ = req._
   123         w(u'<h1>%s</h1>\n' % _(self.title))
   125         w(u'<h1>%s</h1>\n' % _(self.title))
   124         # we don't want this in each sub-forms
   126         # we don't want this in each sub-forms XXX
   125         w(u'<div id="progress">%s</div>' % self.req._('validating...'))
   127         w(u'<div id="progress">%s</div>' % self.req._('validating...'))
   126         for label, group, form in sorted((_(g), g, f)
   128         for label, group, form in sorted((_(g), g, f)
   127                                          for g, f in mainopts.iteritems()):
   129                                          for g, f in mainopts.iteritems()):
   128             status = css_class(self._group_status(group))
   130             status = css_class(self._group_status(group))
   129             w(u'<h2 class="propertiesform">%s</h2>\n' %
   131             w(u'<h2 class="propertiesform">%s</h2>\n' %
   130               (make_togglable_link('fieldset_' + group, label,
   132             (make_togglable_link('fieldset_' + group, label.capitalize())))
   131                                    self._cookie_name(group))))
       
   132             w(u'<div id="fieldset_%s" %s>' % (group, status))
   133             w(u'<div id="fieldset_%s" %s>' % (group, status))
       
   134             w(u'<fieldset class="preferences">')
   133             w(form)
   135             w(form)
   134             w(u'</div>')
   136             w(u'</fieldset></div>')
       
   137 
   135         for label, group, objects in sorted((_(g), g, o)
   138         for label, group, objects in sorted((_(g), g, o)
   136                                             for g, o in groupedopts.iteritems()):
   139                                             for g, o in groupedopts.iteritems()):
   137             status = css_class(self._group_status(group))
   140             status = css_class(self._group_status(group))
   138             w(u'<h2 class="propertiesform">%s</h2>\n' %
   141             w(u'<h2 class="propertiesform">%s</h2>\n' %
   139               (make_togglable_link('fieldset_' + group, label,
   142               (make_togglable_link('fieldset_' + group, label.capitalize())))
   140                                    self._cookie_name(group))))
       
   141             w(u'<div id="fieldset_%s" %s>' % (group, status))
   143             w(u'<div id="fieldset_%s" %s>' % (group, status))
   142             for label, oid, form in sorted((self.req.__('%s_%s' % (group, o)), o, f)
   144 	    
   143                                            for o, f in objects.iteritems()):
   145 	    # create selection
   144                 w(u'<fieldset class="subentity">')
   146 	    sorted_objects =  sorted((self.req.__('%s_%s' % (group, o)), o, f)
   145                 w(u'<legend class="componentTitle">%s</legend>\n' % label)
   147                                            for o, f in objects.iteritems())
       
   148 	    for label, oid, form in sorted_objects:
       
   149                 w(u'''<div class="componentLink"><a href="javascript:noop();" onclick="javascript:toggleVisibility('field_%(oid)s_%(group)s')" class="componentTitle">%(label)s</a>''' % {'label':label, 'oid':oid, 'group':group})
       
   150                 w(u''' (<div class="openlink"><a href="javascript:noop();" onclick="javascript:closeFieldset('fieldset_%(group)s')">%(label)s</a></div>)'''
       
   151                   % {'label':_('close all'), 'group':group})
       
   152                 w(u'</div>')
   146                 docmsgid = '%s_%s_description' % (group, oid)
   153                 docmsgid = '%s_%s_description' % (group, oid)
   147                 doc = _(docmsgid)
   154                 doc = _(docmsgid)
   148                 if doc != docmsgid:
   155                 if doc != docmsgid:
   149                     w(u'<p class="description">%s</p>' % html_escape(doc))
   156                     w(u'<div class="helper">%s</div>' % html_escape(doc).capitalize())
   150                 w(form)
   157 		    
       
   158 		w(u'<fieldset id="field_%(oid)s_%(group)s" class="%(group)s preferences">'
       
   159                   % {'oid':oid, 'group':group})
       
   160 		w(form)
   151                 w(u'</fieldset>')
   161                 w(u'</fieldset>')
   152             w(u'</div>')
   162             w(u'</div>')
   153 
   163 
   154     @property
   164     @property
   155     @cached
   165     @cached
   173             entity.eid = self.req.varmaker.next()
   183             entity.eid = self.req.varmaker.next()
   174             entity['pkey'] = key
   184             entity['pkey'] = key
   175             entity['value'] = self.vreg.property_value(key)
   185             entity['value'] = self.vreg.property_value(key)
   176         return entity
   186         return entity
   177 
   187 
   178     def form(self, keys, splitlabel=False):
   188     def form(self, formid, keys, splitlabel=False):
   179         buttons = [SubmitButton(),
   189         buttons = [SubmitButton()]
   180                    Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
   190         form = CompositeForm(self.req, domid=formid, action=self.build_url(),
   181         form = CompositeForm(self.req, domid=None, action=self.build_url(),
   191                              form_buttons=buttons, 
   182                              form_buttons=buttons,
   192 			     onsubmit="return validatePrefsForm('%s')" % formid,
   183                              submitmsg=self.req._('changes applied'))
   193                              submitmsg=self.req._('changes applied'))
   184         path = self.req.relative_path()
   194 	path = self.req.relative_path()
   185         if '?' in path:
   195         if '?' in path:
   186             path, params = path.split('?', 1)
   196             path, params = path.split('?', 1)
   187             form.form_add_hidden('__redirectparams', params)
   197             form.form_add_hidden('__redirectparams', params)
   188         form.form_add_hidden('__redirectpath', path)
   198         form.form_add_hidden('__redirectpath', path)
   189         for key in keys:
   199         for key in keys:
   190             self.form_row(form, key, splitlabel)
   200             self.form_row(form, key, splitlabel)
   191         return form.form_render(display_progress_div=False)
   201 	renderer = EPropertiesFormRenderer()
       
   202         return form.form_render(display_progress_div=False,
       
   203 				renderer=renderer)
   192 
   204 
   193     def form_row(self, form, key, splitlabel):
   205     def form_row(self, form, key, splitlabel):
   194         entity = self.entity_for_key(key)
   206         entity = self.entity_for_key(key)
   195         if splitlabel:
   207         if splitlabel:
   196             label = key.split('.')[-1]
   208             label = key.split('.')[-1]
   197         else:
   209         else:
   198             label = key
   210             label = key
   199         subform = EntityFieldsForm(self.req, entity=entity, set_error_url=False)
   211 	subform = EntityFieldsForm(self.req, entity=entity, set_error_url=False)
       
   212 	
   200         subform.append_field(PropertyValueField(name='value', label=label,
   213         subform.append_field(PropertyValueField(name='value', label=label,
   201                                                 eidparam=True))
   214                                                 eidparam=True))
   202         subform.vreg = self.vreg
   215         subform.vreg = self.vreg
   203         subform.form_add_hidden('pkey', key, eidparam=True)
   216         subform.form_add_hidden('pkey', key, eidparam=True)
       
   217  	subform.form_add_hidden("current-value:%s" % entity.eid,)
   204         form.form_add_subform(subform)
   218         form.form_add_subform(subform)
   205         return subform
   219         return subform
   206 
   220     
   207 
       
   208 def is_user_prefs(cls, req, rset, row=None, col=0, **kwargs):
   221 def is_user_prefs(cls, req, rset, row=None, col=0, **kwargs):
   209     return req.user.eid == rset[row or 0][col]
   222     return req.user.eid == rset[row or 0][col]
   210 
   223 
   211 
   224 
   212 class EPropertiesForm(SystemEPropertiesForm):
   225 class EPropertiesForm(SystemEPropertiesForm):
   324         self.help = pdef['help']
   337         self.help = pdef['help']
   325         vocab = pdef['vocabulary']
   338         vocab = pdef['vocabulary']
   326         if vocab is not None:
   339         if vocab is not None:
   327             if callable(vocab):
   340             if callable(vocab):
   328                 # list() just in case its a generator function
   341                 # list() just in case its a generator function
   329                 self.choices = list(vocab(form.req))
   342                 self.choices = list(vocab(form.req)) 
   330             else:
   343             else:
   331                 self.choices = vocab
   344                 self.choices = vocab
   332             wdg = Select()
   345             wdg = Select()
   333         else:
   346         else:
   334             wdg = FIELDS[pdef['type']].widget()
   347             wdg = FIELDS[pdef['type']].widget()
   336                 self.choices = [(form.req._('yes'), '1'), (form.req._('no'), '')]
   349                 self.choices = [(form.req._('yes'), '1'), (form.req._('no'), '')]
   337             elif pdef['type'] in ('Float', 'Int'):
   350             elif pdef['type'] in ('Float', 'Int'):
   338                 wdg.attrs.setdefault('size', 3)
   351                 wdg.attrs.setdefault('size', 3)
   339         self.widget = wdg
   352         self.widget = wdg
   340 
   353 
       
   354 class EPropertiesFormRenderer(FormRenderer):
       
   355     """specific renderer for cwproperties"""
       
   356 
       
   357     def open_form(self, form, values):
       
   358 	err = '<div class="formsg"></div>'
       
   359 	return super(EPropertiesFormRenderer, self).open_form(form, values) + err
       
   360     
       
   361     def _render_fields(self, fields, w, form):
       
   362 	for field in fields:
       
   363 	    w(u'<div class="preffield">\n')
       
   364 	    if self.display_label:
       
   365 		w(u'%s' % self.render_label(form, field))
       
   366             error = form.form_field_error(field)
       
   367 	    w(u'%s' % self.render_help(form, field))
       
   368 	    w(u'<div class="prefinput">')
       
   369       	    w(field.render(form, self))
       
   370 	    w(u'</div>')
       
   371 	    w(u'</div>')
       
   372 
       
   373     def render_buttons(self, w, form):
       
   374         w(u'<div>\n')
       
   375         for button in form.form_buttons:
       
   376             w(u'%s\n' % button.render(form))
       
   377         w(u'</div>')
   341 
   378 
   342 uicfg.autoform_field.tag_attribute(('CWProperty', 'pkey'), PropertyKeyField)
   379 uicfg.autoform_field.tag_attribute(('CWProperty', 'pkey'), PropertyKeyField)
   343 uicfg.autoform_field.tag_attribute(('CWProperty', 'value'), PropertyValueField)
   380 uicfg.autoform_field.tag_attribute(('CWProperty', 'value'), PropertyValueField)