Coverage for lino/core/layouts.py : 73%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Copyright 2009-2015 Luc Saffre # License: BSD (see file COPYING for details)
"""
# import six # str = six.text_type
#~ if lo._table.__name__ == 'Users': #~ return True
"""A layout panel which does not exist in the current configuration but might exist as a real panel in some other configuration.
"""
"""This is available in :mod:`lino.api.dd`. To be used when a panel is more complex than what can be expressed using a simple template string.
The `options` parameter can be:
- label - required_roles
Unlike a :class:`FormLayout` it cannot have any child panels and cannot become a tabbed panel.
"""
""" Calls the standard :meth:`string.replace` method on this Panel's template. """ self.desc = self.desc.replace(*args, **kw)
#~ def remove_element(self,*args): #~ """ #~ Removes specified element names from this Panel's `main` template. #~ """ #~ for name in args: #~ if not name in self.desc: #~ raise Exception("Panel has no element '%s'" % name) #~ self.desc = self.desc.replace(name,'')
""" A `LayoutHandle` analyzes some subclass of :class:`BaseLayout` and stores the resulting layout elements provided by the renderer.
The same class is used for all kinds of BaseLayout instances. """
raise Exception( "Failed to create main element %r for %s." % ( layout.main, layout))
if not k in self._names: raise Exception( "%s has no attribute %r (layout.main is %r)" % (self, k, layout.main)) self._names[k].label = v
return "%s for %s" % (self.__class__.__name__, self.layout)
return self.layout.get_title(ar)
return self.main.walk()
return self.main.ext_lines(request)
# logger.debug("desc2elem(panelclass,%r,%r)",elemname,desc)
return None
newkw = dict(desc.options) newkw.update(kwargs) kwargs = newkw else:
# flatten continued lines:
# if len(explicit_specs) > 0: # self.hidden_elements |= set(wildcard_names) and mk not in self.hidden_elements: desc += ' ' + mk self.hidden_elements.add(mk)
# it's a vertical box """To get a hbox, the template string may not contain any newline. """ else: # it's a horizontal box # 20100214 pcsw.PersonDetail hatte 2 MainPanels, # weil PageLayout kein einzeiliges (horizontales) # `main` vertrug elems += e else: return None self, elemname, vertical, elems, **kwargs)
return raise Exception( 'Duplicate element definition %s = %r in %s' % (name, desc, self.layout)) return
#~ logger.debug("create_element(%r)", desc_name) raise Exception( 'Duplicate element usage %s = %r in %s' % (name, desc_name, self.layout)) # 20150216 hidden formpanel fields # if isinstance(self.layout, FormLayout): # return None for be in e: be.hidden = True else:
"""Parse the given element descriptor and return a tuple `(name, options)` where `name` is the element name and `options` is a `dict` with keyword arguments to be forwarded to the widget constructor (:class:`LayoutElement`).
""" elif len(a) == 2: options.update(width=int(a[0]), height=int(a[1])) else: raise Exception("Invalid picture '%s'" % picture) else: raise Exception("Invalid picture '%s'" % picture)
return False # if isinstance(de, VirtualField): # return False return False
# 20150610 : data elements defined on the layout panel have # precedence over those defined in the datasource.
# if not name in ('__str__', '__unicode__', 'name', 'label'): # if name == 'ledger': # logger.info("20150610 'ledger' in instance of %s is %r", # self.layout.__class__, value) return value
return self.layout.get_choices_url( settings.SITE.kernel.default_renderer.plugin, *args, **kw)
""" Base class for all Layouts (:class:`FormLayout`, :class:`ColumnsLayout` and :class:`ParamsLayout`).
A Layout instance just holds the string templates. It is designed to be subclassed by applications programmers.
In some cases we still use the (reprecated) methods :meth:`set_detail_layout <lino.core.actors.Actor.set_detail_layout>`, :meth:`set_insert_layout <lino.core.actors.Actor.set_insert_layout>`, :meth:`add_detail_panel <lino.core.actors.Actor.add_detail_panel>` and :meth:`add_detail_tab <lino.core.actors.Actor.add_detail_tab>` on the :class:`Actor <lino.core.actors.Actor>`.
"""
"""A tuple `(width, height)` that specifies the size of the window to be used for this layout.
For example, specifying `window_size=(50, 30)` means "50 characters wide and 30 lines high". The `height` value can also be the string ``'auto'``.
"""
hidden_elements=None, **kw): """ datasource is either an actor or an action. """ #~ self._window_size = window_size #~ elif not hasattr(self,'main'): raise Exception( "Cannot instantiate %s without `main`." % self.__class__) #~ if not hasattr(self,k): #~ raise Exception("Got unexpected keyword %s=%r" % (k,v))
self.hidden_elements = set(fields_list( ds, self.hidden_elements)) #~ if str(ds).endswith('Partners'): #~ print "20130124 set_datasource ", self,self.hidden_elements
""" Removes specified element names from this layout's `main` template. """ for name in args: self.main = self.main.replace(name, '')
"""Update the template of one or more panels.
""" msg = """\ In %s, updating attribute %r: --- before: %s --- after: %s ---""" % (self, k, getattr(self, k, '(undefined)'), v) logger.info(msg)
""" Adds a new panel to this layout.
Arguments:
- `name` is the internal name of the panel - `tpl` the template string - `label` an optional label - any further keyword are passed as options to the new panel """ #~ if hasattr(self,'_extjs3_handle'): #~ raise Exception("Cannot update for layout after UI has been set up.") if '\n' in name: raise Exception("name may not contain any newline") if ' ' in name: raise Exception("name may not contain any whitespace") #~ if getattr(self,name,None) is not None: #~ raise Exception("name %r already defined in %s" % (name,self)) self._add_panel(name, tpl, label, options)
if tpl is None: return # when does this occur? if hasattr(self, name): raise Exception("Oops, %s has already a name %r" % (self, name)) if DEBUG_LAYOUTS(self): msg = """\ Adding panel %r to %s ---: %s ---""" % (name, self, tpl) logger.info(msg) setattr(self, name, tpl) self._added_panels[name] = tpl # 20120914c if label is not None: self._labels[name] = label if options: self._element_options[name] = options
""" Add a tab panel to an existing layout. Arguments: see :meth:`BaseLayout.add_panel`. The difference with :meth:`BaseLayout.add_panel` is that this potentially turns the existing `main` panel to a tabbed panel.
Arguments:
- `name` is the internal name of the panel - `tpl` the template string - `label` an optional label """ #~ print "20120526 add_detail_tab", self, name #~ if hasattr(self,'_extjs3_handle'): #~ raise Exception("Cannot update form layout after UI has been set up.") if '\n' in name: raise Exception("name may not contain any newline") if ' ' in name: raise Exception("name may not contain any whitespace") if '\n' in self.main: if hasattr(self, 'general'): raise NotImplementedError("""\ %s has both a vertical `main` and a panel called `general`.""" % self) self.general = self.main self.main = "general " + name self._labels['general'] = _("General") if DEBUG_LAYOUTS(self): msg = """\ add_tabpanel() on %s moving content of vertical 'main' panel to 'general'. New 'main' panel is %r""" logger.info(msg, self, self.main) else: self.main += " " + name if DEBUG_LAYOUTS(self): msg = """\ add_tabpanel() on %s horizontal 'main' panel %r.""" logger.info(msg, self, self.main) #~ if tpl is not None: self._add_panel(name, tpl, label, options) #~ self._add_panel(name,tpl) #~ setattr(self,name,tpl) # ~ self._added_panels[name] = tpl # 20120914c #~ if label is not None: #~ self._labels[name] = label #~ self._element_options[name] = options #~ if kw: #~ print 20120525, self, self.detail_layout._element_options
""" `ui` is a :class:`Plugin` instance. """ raise Exception( "{0} has no `ui_handle_attr_name`!".format(ui))
# we do not want any inherited handle
return "%s on %s" % (self.__class__.__name__, self._datasource)
# 20140101 # return settings.SITE.build_admin_url( # "choices", # self._datasource.app_label, # self._datasource.__name__, # field.name, **kw)
return ui.build_plain_url( "choices", self._datasource.app_label, self._datasource.__name__, field.name, **kw)
lh = self.get_layout_handle(settings.SITE.kernel.default_ui) # if profile is None: # profile = UserProfiles.admin if name is None: e = lh.main else: e = lh.main.find_by_name(name) return e.to_rst(profile)
"""Base class for layout descriptions of detail and insert windows.
Lino instantiates this for every :attr:`detail_layout <lino.core.actors.Actor.detail_layout>` and for every :attr:`insert_layout <lino.core.actors.Actor.insert_layout>`.
"""
""" A layout for describing the columns of a table.
Lino automatically creates one instance of this for every table using the string specified in that table's :attr:`column_names <lino.core.tables.AbstractTable.column_names>` attribute.
"""
raise Exception("20130327 No datasource for %r" % self)
""" A Layout description for a table parameter panel.
Lino instantiates this for every actor with :attr:`parameters <lino.core.actors.Actor.parameters>`, based on that actor's :attr:`params_layout <lino.core.actors.Actor.params_layout>`. """
""" A Layout description for an action parameter panel.
Lino instantiates this for every :attr:`params_layout <lino.core.actions.Action.params_layout>` of a custom action.
A subclass of :class:`ParamsLayout`. """
return settings.SITE.kernel.default_ui.build_plain_url( "apchoices", self._datasource.defining_actor.app_label, self._datasource.defining_actor.__name__, self._datasource.action_name, field.name, **kw)
|