88 id = 'reledit' |
88 id = 'reledit' |
89 __select__ = non_final_entity() & match_kwargs('rtype') |
89 __select__ = non_final_entity() & match_kwargs('rtype') |
90 |
90 |
91 # FIXME editableField class could be toggleable from userprefs |
91 # FIXME editableField class could be toggleable from userprefs |
92 |
92 |
93 onsubmit = ("return inlineValidateAttributeForm('%(divid)s-form', '%(rtype)s', " |
93 _onclick = u"showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')" |
94 "'%(eid)s', '%(divid)s', %(reload)s, '%(default)s');") |
94 _defaultlandingzone = u'<img title="%(msg)s" src="data/file.gif" alt="%(msg)s"/>' |
95 ondblclick = "showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')" |
95 _landingzonemsg = _('click to edit this field') |
96 |
96 # default relation vids according to cardinality |
97 def cell_call(self, row, col, rtype=None, role='subject', reload=False, |
97 _one_rvid = 'incontext' |
98 vid='textoutofcontext', default=None): |
98 _many_rvid = 'csv' |
99 """display field to edit entity's `rtype` relation on double-click""" |
99 |
100 rschema = self.schema.rschema(rtype) |
100 def _compute_best_vid(self, entity, rtype, role): |
|
101 if compute_cardinality(entity.e_schema, |
|
102 entity.schema.rschema(rtype), |
|
103 role) in '+*': |
|
104 return self._many_rvid |
|
105 return self._one_rvid |
|
106 |
|
107 def _build_landing_zone(self, lzone): |
|
108 return lzone or self._defaultlandingzone % {'msg' : self.req._(self._landingzonemsg)} |
|
109 |
|
110 def _build_renderer(self, entity, rtype, role): |
|
111 return self.vreg.select_object('formrenderers', 'base', self.req, |
|
112 entity=entity, |
|
113 display_label=False, display_help=False, |
|
114 display_fields=[(rtype, role)], |
|
115 table_class='', button_bar_class='buttonbar', |
|
116 display_progress_div=False) |
|
117 |
|
118 def cell_call(self, row, col, rtype=None, role='subject', |
|
119 reload=False, # controls reloading the whole page after change |
|
120 rvid=None, # vid to be applied to other side of rtype |
|
121 default=None, # default value |
|
122 landing_zone=None # prepend value with a separate html element to click onto |
|
123 # (esp. needed when values are links) |
|
124 ): |
|
125 """display field to edit entity's `rtype` relation on click""" |
|
126 assert rtype |
|
127 assert role in ('subject', 'object') |
|
128 if default is None: |
|
129 default = xml_escape(self.req._('<no value>')) |
101 entity = self.entity(row, col) |
130 entity = self.entity(row, col) |
102 if not default: |
131 rschema = entity.schema.rschema(rtype) |
103 default = self.req._('not specified') |
132 # compute value, checking perms, build form |
104 if rschema.is_final(): |
133 if rschema.is_final(): |
105 value = entity.printable_value(rtype) |
134 value = entity.printable_value(rtype) or default |
106 if not entity.has_perm('update'): |
135 if not entity.has_perm('update'): |
107 self.w(value) |
136 self.w(value) |
108 return |
137 return |
|
138 self._attribute_form(entity, value, rtype, role, reload, |
|
139 row, col, default, landing_zone) |
109 else: |
140 else: |
|
141 dispctrl = uicfg.primaryview_display_ctrl.etype_get(entity.e_schema, |
|
142 rtype, role) |
|
143 vid = dispctrl.get('vid', 'reledit') |
|
144 if vid != 'reledit': # reledit explicitly disabled |
|
145 self.wview(vid, entity.related(rtype, role)) |
|
146 return |
|
147 if rvid is None: |
|
148 rvid = self._compute_best_vid(entity, rtype, role) |
110 rset = entity.related(rtype, role) |
149 rset = entity.related(rtype, role) |
111 # XXX html_escape but that depends of the actual vid |
150 candidate = self.view(rvid, rset, 'null') |
112 value = html_escape(self.view(vid, rset, 'null') or default) |
151 value = candidate or default |
113 # XXX consider local roles ? |
152 if role == 'subject' and not rschema.has_perm(self.req, 'add', |
114 if role == 'subject'and not rschema.has_perm(self.req, 'add', |
153 fromeid=entity.eid): |
115 fromeid=entity.eid): |
154 return self.w(value) |
116 self.w(value) |
155 elif role == 'object' and not rschema.has_perm(self.req, 'add', |
117 return |
156 toeid=entity.eid): |
118 elif role == 'object'and not rschema.has_perm(self.req, 'add', |
157 return self.w(value) |
119 toeid=entity.eid): |
158 elif get_schema_property(entity.e_schema, rschema, |
120 self.w(value) |
159 role, 'composite') == role: |
121 return |
160 self.warning('reledit cannot be applied : (... %s %s [composite])' |
122 if not value.strip(): |
161 % (rtype, entity.e_schema)) |
123 value = default |
162 return self.w(value) |
124 if rschema.is_final(): |
163 self._relation_form(entity, value, rtype, role, reload, row, col, |
125 form = self._build_attribute_form(entity, value, rtype, role, |
164 rvid, default, landing_zone) |
126 reload, row, col, default) |
165 |
127 else: |
166 |
128 form = self._build_relation_form(entity, value, rtype, role, |
167 def _relation_form(self, entity, value, rtype, role, row, col, reload, rvid, default, lzone): |
129 row, col, vid, default) |
168 lzone = self._build_landing_zone(lzone) |
130 renderer = self.vreg.select('formrenderers', 'base', self.req, |
169 value = lzone + value |
131 entity=entity, |
170 divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid)) |
132 display_label=False, display_help=False, |
171 event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, 'vid' : rvid, |
133 display_fields=[(rtype, role)], |
172 'reload' : reload, 'default' : default, 'role' : role, |
134 table_class='', button_bar_class='buttonbar', |
173 'lzone' : lzone} |
135 display_progress_div=False) |
174 onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', " |
|
175 "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');" |
|
176 % event_data) |
|
177 cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" % ( |
|
178 entity.eid, rtype, divid) |
|
179 form = self.vreg.select_object('forms', 'base', self.req, entity=entity, |
|
180 domid='%s-form' % divid, cssstyle='display: none', |
|
181 onsubmit=onsubmit, action='#', |
|
182 form_buttons=[SubmitButton(), |
|
183 Button(stdmsgs.BUTTON_CANCEL, |
|
184 onclick=cancelclick)]) |
|
185 field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role) |
|
186 form.append_field(field) |
|
187 self.w(u'<div id="%s-reledit" class="field">' % divid) |
|
188 self.w(tags.div(value, klass='editableField', id=divid, |
|
189 onclick=self._onclick % event_data)) |
|
190 renderer = self._build_renderer(entity, rtype, role) |
136 self.w(form.form_render(renderer=renderer)) |
191 self.w(form.form_render(renderer=renderer)) |
137 |
192 self.w(u'</div>') |
138 def _build_relation_form(self, entity, value, rtype, role, row, col, vid, default): |
193 |
139 entity = self.entity(row, col) |
194 def _attribute_form(self, entity, value, rtype, role, reload, row, col, default, lzone): |
140 divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid)) |
|
141 event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, 'vid' : vid, |
|
142 'default' : default, 'role' : role} |
|
143 onsubmit = ("return inlineValidateRelationForm('%(divid)s-form', '%(rtype)s', " |
|
144 "'%(role)s', '%(eid)s', '%(divid)s', '%(vid)s', '%(default)s');" |
|
145 % event_data) |
|
146 cancelclick = "cancelInlineEdit(%s,\'%s\',\'%s\')" % ( |
|
147 entity.eid, rtype, divid) |
|
148 form = self.vreg.select('forms', 'base', self.req, entity=entity, |
|
149 domid='%s-form' % divid, cssstyle='display: none', |
|
150 onsubmit=onsubmit, action='#', |
|
151 form_buttons=[SubmitButton(), |
|
152 Button(stdmsgs.BUTTON_CANCEL, |
|
153 onclick=cancelclick)]) |
|
154 form.append_field(RelationField(name=rtype, role=role, sort=True, |
|
155 widget=Select(), |
|
156 label=u' ')) |
|
157 self.w(tags.div(value, klass='editableField', id=divid, |
|
158 ondblclick=self.ondblclick % event_data)) |
|
159 return form |
|
160 |
|
161 def _build_attribute_form(self, entity, value, rtype, role, reload, row, col, default): |
|
162 eid = entity.eid |
195 eid = entity.eid |
163 divid = 'd%s' % make_uid('%s-%s' % (rtype, eid)) |
196 divid = 'd%s' % make_uid('%s-%s' % (rtype, eid)) |
164 event_data = {'divid' : divid, 'eid' : eid, 'rtype' : rtype, |
197 event_data = {'divid' : divid, 'eid' : eid, 'rtype' : rtype, |
165 'reload' : dumps(reload), 'default' : default} |
198 'reload' : dumps(reload), 'default' : default, 'lzone' : lzone} |
|
199 onsubmit = ("return inlineValidateAttributeForm('%(rtype)s', '%(eid)s', '%(divid)s', " |
|
200 "%(reload)s, '%(default)s', '%(lzone)s');") |
166 buttons = [SubmitButton(stdmsgs.BUTTON_OK), |
201 buttons = [SubmitButton(stdmsgs.BUTTON_OK), |
167 Button(stdmsgs.BUTTON_CANCEL, |
202 Button(stdmsgs.BUTTON_CANCEL, |
168 onclick="cancelInlineEdit(%s,\'%s\',\'%s\')" % ( |
203 onclick="hideInlineEdit(%s,\'%s\',\'%s\')" % ( |
169 eid, rtype, divid))] |
204 eid, rtype, divid))] |
170 form = self.vreg.select('forms', 'edition', self.req, rset=self.rset, |
205 form = self.vreg.select_object('forms', 'edition', self.req, self.rset, |
171 row=row, col=col, form_buttons=buttons, |
206 row=row, col=col, form_buttons=buttons, |
172 domid='%s-form' % divid, action='#', |
207 domid='%s-form' % divid, action='#', |
173 cssstyle='display: none', |
208 cssstyle='display: none', |
174 onsubmit=self.onsubmit % event_data) |
209 onsubmit=onsubmit % event_data) |
175 self.w(tags.div(value, klass='editableField', id=divid, |
210 self.w(tags.div(value, klass='editableField', id=divid, |
176 ondblclick=self.ondblclick % event_data)) |
211 onclick=self._onclick % event_data)) |
177 return form |
212 renderer = self._build_renderer(entity, rtype, role) |
|
213 self.w(form.form_render(renderer=renderer)) |
178 |
214 |
179 |
215 |
180 class EditionFormView(FormViewMixIn, EntityView): |
216 class EditionFormView(FormViewMixIn, EntityView): |
181 """display primary entity edition form""" |
217 """display primary entity edition form""" |
182 id = 'edition' |
218 id = 'edition' |