')
+
+ @cached
+ def filter_box_context_info(self):
+ entity = self.entity(0, 0)
+ role, eid, rtype, etype = self.req.search_state[1]
+ assert entity.eid == typed_eid(eid)
+ # the default behaviour is to fetch all unrelated entities and display
+ # them. Use fetch_order and not fetch_unrelated_order as sort method
+ # since the latter is mainly there to select relevant items in the combo
+ # box, it doesn't give interesting result in this context
+ rql = entity.unrelated_rql(rtype, etype, role,
+ ordermethod='fetch_order',
+ vocabconstraints=False)
+ rset = self.req.execute(rql, {'x' : entity.eid}, 'x')
+ return rset, 'list', "search-associate-content", True
+
+
+class OutOfContextSearch(EntityView):
+ id = 'outofcontext-search'
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ erset = entity.as_rset()
+ if self.req.match_search_state(erset):
+ self.w(u'%s[...]' % (
+ html_escape(linksearch_select_url(self.req, erset)),
+ self.req._('select this entity'),
+ html_escape(entity.view('textoutofcontext')),
+ html_escape(entity.absolute_url(vid='primary')),
+ self.req._('view detail for this entity')))
+ else:
+ entity.view('outofcontext', w=self.w)
+
+
+class UnrelatedDivs(EntityView):
+ id = 'unrelateddivs'
+ __select__ = match_form_params('relation')
+
+ @property
+ def limit(self):
+ if self.req.form.get('__force_display'):
+ return None
+ return self.req.property_value('navigation.related-limit') + 1
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ relname, target = self.req.form.get('relation').rsplit('_', 1)
+ rschema = self.schema.rschema(relname)
+ hidden = 'hidden' in self.req.form
+ is_cell = 'is_cell' in self.req.form
+ self.w(self.build_unrelated_select_div(entity, rschema, target,
+ is_cell=is_cell, hidden=hidden))
+
+ def build_unrelated_select_div(self, entity, rschema, target,
+ is_cell=False, hidden=True):
+ options = []
+ divid = 'div%s_%s_%s' % (rschema.type, target, entity.eid)
+ selectid = 'select%s_%s_%s' % (rschema.type, target, entity.eid)
+ if rschema.symetric or target == 'subject':
+ targettypes = rschema.objects(entity.e_schema)
+ etypes = '/'.join(sorted(etype.display_name(self.req) for etype in targettypes))
+ else:
+ targettypes = rschema.subjects(entity.e_schema)
+ etypes = '/'.join(sorted(etype.display_name(self.req) for etype in targettypes))
+ etypes = cut(etypes, self.req.property_value('navigation.short-line-size'))
+ options.append('' % (self.req._('select a'), etypes))
+ options += self._get_select_options(entity, rschema, target)
+ options += self._get_search_options(entity, rschema, target, targettypes)
+ if 'Basket' in self.schema: # XXX
+ options += self._get_basket_options(entity, rschema, target, targettypes)
+ relname, target = self.req.form.get('relation').rsplit('_', 1)
+ return u"""\
+
+
+
+""" % (hidden and 'hidden' or '', divid, selectid, html_escape(dumps(entity.eid)),
+ is_cell and 'true' or 'null', relname, '\n'.join(options))
+
+ def _get_select_options(self, entity, rschema, target):
+ """add options to search among all entities of each possible type"""
+ options = []
+ eid = entity.eid
+ pending_inserts = self.req.get_pending_inserts(eid)
+ rtype = rschema.type
+ for eview, reid in entity.vocabulary(rschema, target, self.limit):
+ if reid is None:
+ options.append('' % html_escape(eview))
+ else:
+ optionid = relation_id(eid, rtype, target, reid)
+ if optionid not in pending_inserts:
+ # prefix option's id with letters to make valid XHTML wise
+ options.append('' %
+ (optionid, reid, html_escape(eview)))
+ return options
+
+ def _get_search_options(self, entity, rschema, target, targettypes):
+ """add options to search among all entities of each possible type"""
+ options = []
+ _ = self.req._
+ for eschema in targettypes:
+ mode = '%s:%s:%s:%s' % (target, entity.eid, rschema.type, eschema)
+ url = self.build_url(entity.rest_path(), vid='search-associate',
+ __mode=mode)
+ options.append((eschema.display_name(self.req),
+ '' % (
+ html_escape(url), _('Search for'), eschema.display_name(self.req))))
+ return [o for l, o in sorted(options)]
+
+ def _get_basket_options(self, entity, rschema, target, targettypes):
+ options = []
+ rtype = rschema.type
+ _ = self.req._
+ for basketeid, basketname in self._get_basket_links(self.req.user.eid,
+ target, targettypes):
+ optionid = relation_id(entity.eid, rtype, target, basketeid)
+ options.append('' % (
+ optionid, basketeid, _('link to each item in'), html_escape(basketname)))
+ return options
+
+ def _get_basket_links(self, ueid, target, targettypes):
+ targettypes = set(targettypes)
+ for basketeid, basketname, elements in self._get_basket_info(ueid):
+ baskettypes = elements.column_types(0)
+ # if every elements in the basket can be attached to the
+ # edited entity
+ if baskettypes & targettypes:
+ yield basketeid, basketname
+
+ def _get_basket_info(self, ueid):
+ basketref = []
+ basketrql = 'Any B,N WHERE B is Basket, B owned_by U, U eid %(x)s, B name N'
+ basketresultset = self.req.execute(basketrql, {'x': ueid}, 'x')
+ for result in basketresultset:
+ basketitemsrql = 'Any X WHERE X in_basket B, B eid %(x)s'
+ rset = self.req.execute(basketitemsrql, {'x': result[0]}, 'x')
+ basketref.append((result[0], result[1], rset))
+ return basketref
+
+
+class ComboboxView(EntityView):
+ """the view used in combobox (unrelated entities)
+
+ THIS IS A TEXT VIEW. DO NOT HTML_ESCAPE
+ """
+ id = 'combobox'
+ title = None
+
+ def cell_call(self, row, col):
+ """the combo-box view for an entity: same as text out of context view
+ by default
+ """
+ self.wview('textoutofcontext', self.rset, row=row, col=col)
+
+
+# class EditRelationView(EntityView):
+# """Note: This is work in progress
+
+# This view is part of the edition view refactoring.
+# It is still too big and cluttered with strange logic, but it's a start
+
+# The main idea is to be able to call an edition view for a specific
+# relation. For example :
+# self.wview('editrelation', person_rset, rtype='firstname')
+# self.wview('editrelation', person_rset, rtype='works_for')
+# """
+# id = 'editrelation'
+
+# __select__ = match_form_params('rtype')
+
+# # TODO: inlineview, multiple edit, (widget view ?)
+# def cell_call(self, row, col, rtype=None, role='subject', targettype=None,
+# showlabel=True):
+# self.req.add_js( ('cubicweb.ajax.js', 'cubicweb.edition.js') )
+# entity = self.entity(row, col)
+# rtype = self.req.form.get('rtype', rtype)
+# showlabel = self.req.form.get('showlabel', showlabel)
+# assert rtype is not None, "rtype is mandatory for 'edirelation' view"
+# targettype = self.req.form.get('targettype', targettype)
+# role = self.req.form.get('role', role)
+# category = entity.rtags.get_category(rtype, targettype, role)
+# if category in ('primary', 'secondary') or self.schema.rschema(rtype).is_final():
+# if hasattr(entity, '%s_format' % rtype):
+# formatwdg = entity.get_widget('%s_format' % rtype, role)
+# self.w(formatwdg.edit_render(entity))
+# self.w(u' ')
+# wdg = entity.get_widget(rtype, role)
+# if showlabel:
+# self.w(u'%s' % wdg.render_label(entity))
+# self.w(u'%s %s %s' %
+# (wdg.render_error(entity), wdg.edit_render(entity),
+# wdg.render_help(entity),))
+# else:
+# self._render_generic_relation(entity, rtype, role)
+
+# def _render_generic_relation(self, entity, relname, role):
+# text = self.req.__('add %s %s %s' % (entity.e_schema, relname, role))
+# # pending operations
+# operations = self.req.get_pending_operations(entity, relname, role)
+# if operations['insert'] or operations['delete'] or 'unfold' in self.req.form:
+# self.w(u'