--- a/devtools/fill.py Mon Oct 19 20:26:22 2009 +0200
+++ b/devtools/fill.py Mon Oct 19 20:33:30 2009 +0200
@@ -308,13 +308,16 @@
-def select(constraints, cursor, selectvar='O'):
+def select(constraints, cursor, selectvar='O', objtype=None):
"""returns list of eids matching <constraints>
<selectvar> should be either 'O' or 'S' to match schema definitions
"""
try:
- rset = cursor.execute('Any %s WHERE %s' % (selectvar, constraints))
+ rql = 'Any %s WHERE %s' % (selectvar, constraints)
+ if objtype:
+ rql += ', %s is %s' % (selectvar, objtype)
+ rset = cursor.execute(rql)
except:
print "could restrict eid_list with given constraints (%r)" % constraints
return []
@@ -335,6 +338,14 @@
gen = RelationsQueriesGenerator(schema, cursor, existingrels)
return gen.compute_queries(edict, ignored_relations)
+def composite_relation(rschema):
+ for obj in rschema.objects():
+ if obj.objrproperty(rschema, 'composite') == 'subject':
+ return True
+ for obj in rschema.subjects():
+ if obj.subjrproperty(rschema, 'composite') == 'object':
+ return True
+ return False
class RelationsQueriesGenerator(object):
rql_tmpl = 'SET S %s O WHERE S eid %%(subjeid)s, O eid %%(objeid)s'
@@ -346,8 +357,9 @@
def compute_queries(self, edict, ignored_relations):
queries = []
# 1/ skip final relations and explictly ignored relations
- rels = [rschema for rschema in self.schema.relations()
- if not (rschema.final or rschema in ignored_relations)]
+ rels = sorted([rschema for rschema in self.schema.relations()
+ if not (rschema.final or rschema in ignored_relations)],
+ key=lambda x:not composite_relation(x))
# for each relation
# 2/ take each possible couple (subj, obj)
# 3/ analyze cardinality of relation
@@ -355,6 +367,7 @@
# b/ else insert N relations where N is the mininum
# of 20 and the number of existing targetable entities
for rschema in rels:
+ print rschema
sym = set()
sedict = deepcopy(edict)
oedict = deepcopy(edict)
@@ -366,7 +379,7 @@
continue
subjcard, objcard = rschema.rproperty(subj, obj, 'cardinality')
# process mandatory relations first
- if subjcard in '1+' or objcard in '1+':
+ if subjcard in '1+' or objcard in '1+' or composite_relation(rschema):
queries += self.make_relation_queries(sedict, oedict,
rschema, subj, obj)
else:
@@ -399,10 +412,9 @@
# restrict object eids if possible
# XXX the attempt to restrict below in completely wrong
# disabling it for now
- objeids = select(restrictions, self.cursor)
+ objeids = select(restrictions, self.cursor, objtype=obj)
else:
objeids = oedict.get(obj, frozenset())
-## objeids = oedict.get(obj, frozenset())
if subjcard in '?1' or objcard in '?1':
for subjeid, objeid in used:
if subjcard in '?1' and subjeid in subjeids:
@@ -461,8 +473,8 @@
def check_card_satisfied(card, remaining, subj, rschema, obj):
if card in '1+' and remaining:
- raise Exception("can't satisfy cardinality %s for relation %s %s %s"
- % (card, subj, rschema, obj))
+ print "can't satisfy cardinality %s for relation %s %s %s" % (card, subj, rschema, obj)
+
def choose_eid(values, avoid):
values = tuple(values)
--- a/web/data/cubicweb.edition.js Mon Oct 19 20:26:22 2009 +0200
+++ b/web/data/cubicweb.edition.js Mon Oct 19 20:33:30 2009 +0200
@@ -465,44 +465,6 @@
* @param default_value : value if the field is empty
* @param lzone : html fragment (string) for a clic-zone triggering actual edition
*/
-function inlineValidateAttributeForm(rtype, eid, divid, reload, default_value) {
- try {
- var form = getNode(divid+'-form');
- if (typeof FCKeditorAPI != "undefined") {
- for ( var name in FCKeditorAPI.__Instances ) {
- var oEditor = FCKeditorAPI.__Instances[name] ;
- if ( oEditor.GetParentForm() == form ) {
- oEditor.UpdateLinkedField();
- }
- }
- }
- var zipped = formContents(form);
- var d = asyncRemoteExec('edit_field', 'apply', zipped[0], zipped[1],
- rtype, eid, default_value);
- } catch (ex) {
- log('got exception', ex);
- return false;
- }
- d.addCallback(function (result, req) {
- if (handleFormValidationResponse(divid+'-form', noop, noop, result)) {
- if (reload) {
- document.location.href = result[1].split('?')[0];
- } else {
- var fieldview = getNode('value-' + divid);
- // XXX using innerHTML is very fragile and won't work if
- // we mix XHTML and HTML
- fieldview.innerHTML = result[2];
- // switch inline form off only if no error
- if (result[0]) {
- // hide global error messages
- hideInlineEdit(eid, rtype, divid);
- }
- }
- }
- return false;
- });
- return false;
-}
function inlineValidateRelationForm(rtype, role, eid, divid, reload, vid,
default_value, lzone) {
@@ -518,13 +480,12 @@
d.addCallback(function (result, req) {
if (handleFormValidationResponse(divid+'-form', noop, noop, result)) {
if (reload) {
- document.location.href = result[1].split('?')[0];
+ document.location.reload();
} else {
- var d = asyncRemoteExec('reledit_form', eid, rtype, role, default_value, lzone);
- d.addCallback(function (result) {
- // XXX brittle ... replace with loadxhtml
- jQuery('#'+divid+'-reledit').replaceWith(result);
- });
+ var args = {fname: 'reledit_form', rtype: rtype, role: role, eid: eid, divid: divid,
+ reload: reload, vid: vid, default_value: default_value, landing_zone: lzone};
+ log('DONE');
+ jQuery('#'+divid+'-reledit').parent().loadxhtml(JSON_BASE_URL, args, 'post');
}
}
return false;
--- a/web/views/basecontrollers.py Mon Oct 19 20:26:22 2009 +0200
+++ b/web/views/basecontrollers.py Mon Oct 19 20:33:30 2009 +0200
@@ -397,26 +397,15 @@
self.req.form = self._rebuild_posted_form(names, values, action)
return _validate_form(self.req, self.vreg)
- @jsonize
- def js_edit_field(self, action, names, values, rtype, eid, default):
- success, args, _ = self.validate_form(action, names, values)
- if success:
- # Any X,N where we don't seem to use N is an optimisation
- # printable_value won't need to query N again
- rset = self.req.execute('Any X,N WHERE X eid %%(x)s, X %s N' % rtype,
- {'x': eid}, 'x')
- entity = rset.get_entity(0, 0)
- value = entity.printable_value(rtype) or default
- return (success, args, value)
- else:
- return (success, args, None)
-
- @jsonize
- def js_reledit_form(self, eid, rtype, role, default, lzone):
- """XXX we should get rid of this and use loadxhtml"""
- entity = self.req.entity_from_eid(eid)
- return entity.view('reledit', rtype=rtype, role=role,
- default=default, landing_zone=lzone)
+ @xhtmlize
+ def js_reledit_form(self):
+ args = dict((x,self.req.form[x])
+ for x in frozenset(('rtype', 'role', 'reload', 'landing_zone')))
+ entity = self.req.entity_from_eid(int(self.req.form['eid']))
+ # note: default is reserved in js land
+ args['default'] = self.req.form['default_value']
+ args['reload'] = simplejson.loads(args['reload'])
+ return entity.view('reledit', **args)
@jsonize
def js_i18n(self, msgids):
--- a/web/views/editforms.py Mon Oct 19 20:26:22 2009 +0200
+++ b/web/views/editforms.py Mon Oct 19 20:33:30 2009 +0200
@@ -112,6 +112,9 @@
attrcategories = ('primary', 'secondary', 'metadata')
_onclick = u"showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')"
+ _onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', "
+ "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');")
+ _cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')"
_defaultlandingzone = (u'<img title="%(msg)s" '
'src="data/accessories-text-editor.png" '
'alt="%(msg)s"/>')
@@ -134,16 +137,16 @@
display_help=False, display_fields=[(rtype, role)], table_class='',
button_bar_class='buttonbar', display_progress_div=False)
- def _build_form(self, entity, rtype, role, formid, default, onsubmit, reload,
+ def _build_form(self, entity, rtype, role, formid, default, reload,
extradata=None, **formargs):
- divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid))
+ divid = '%s-%s-%s' % (entity.eid, rtype, role)
event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype,
- 'reload' : dumps(reload), 'default' : default}
+ 'reload' : dumps(reload), 'default' : default, 'role' : role, 'vid' : u'',
+ 'lzone' : self._build_landing_zone(None)}
if extradata:
event_data.update(extradata)
- onsubmit %= event_data
- cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" % (entity.eid, rtype,
- divid)
+ onsubmit = self._onsubmit % event_data
+ cancelclick = self._cancelclick % (entity.eid, rtype, divid)
form = self.vreg['forms'].select(
formid, self.req, entity=entity, domid='%s-form' % divid,
cssstyle='display: none', onsubmit=onsubmit, action='#',
@@ -162,7 +165,7 @@
):
"""display field to edit entity's `rtype` relation on click"""
assert rtype
- assert role in ('subject', 'object')
+ assert role in ('subject', 'object'), '%s is not an acceptable role value' % role
if default is None:
default = xml_escape(self.req._('<no value>'))
entity = self.entity(row, col)
@@ -170,17 +173,14 @@
lzone = self._build_landing_zone(landing_zone)
# compute value, checking perms, build form
if rschema.final:
- onsubmit = ("return inlineValidateAttributeForm('%(rtype)s', '%(eid)s', '%(divid)s', "
- "%(reload)s, '%(default)s');")
- form = self._build_form(
- entity, rtype, role, 'edition', default, onsubmit, reload,
- attrcategories=self.attrcategories)
+ form = self._build_form(entity, rtype, role, 'edition', default, reload,
+ attrcategories=self.attrcategories)
if not self.should_edit_attribute(entity, rschema, role, form):
self.w(entity.printable_value(rtype))
return
value = entity.printable_value(rtype) or default
- self.attribute_form(lzone, value, form,
- self._build_renderer(entity, rtype, role))
+ self.relation_form(lzone, value, form,
+ self._build_renderer(entity, rtype, role))
else:
if rvid is None:
rvid = self._compute_best_vid(entity.e_schema, rschema, role)
@@ -193,11 +193,8 @@
if rset:
self.w(value)
return
- onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', "
- "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');")
- form = self._build_form(
- entity, rtype, role, 'base', default, onsubmit, reload,
- dict(vid=rvid, role=role, lzone=lzone))
+ form = self._build_form(entity, rtype, role, 'base', default, reload,
+ dict(vid=rvid, lzone=lzone))
field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role)
form.append_field(field)
self.relation_form(lzone, value, form,
@@ -227,26 +224,6 @@
return False
return True
- def attribute_form(self, lzone, value, form, renderer):
- """div (class=field)
- +-xxx div
- | +-xxx div (class=editableField)
- | | +-landing zone
- | +-value-xxx div
- | +-value
- +-form-xxx div
- """
- w = self.w
- w(u'<div class="field">')
- w(u'<div id="%s" style="display: inline">' % form.event_data['divid'])
- w(tags.div(lzone, klass='editableField',
- onclick=self._onclick % form.event_data))
- w(u'<div id="value-%s" style="display: inline">%s</div>' %
- (form.event_data['divid'], value))
- w(u'</div>')
- w(form.form_render(renderer=renderer))
- w(u'</div>')
-
def relation_form(self, lzone, value, form, renderer):
"""xxx-reledit div (class=field)
+-xxx div (class="editableField")