def __init__(self, **kwargs): self._fieldindex = OrderedDict() # mapping tussen ids en veldnamen self._fltr = None # voor elke instantie van ViewModel krijgen de # veldnamen een uniek id for fieldname, classfield in self._fieldattrs.items(): idx = counter.inc() field = classfield.__class__(name=fieldname, config=classfield) field._idx = idx field.set_model(self) object.__setattr__(self, fieldname, field) self._fieldindex[idx] = fieldname
def __init__(self, impl, presenter): self._impl = impl self._title = "" self._presenter = presenter self._model = self._presenter.get_viewmodel() self._fields = OrderedDict() self._groups = OrderedDict() self._presenter.set_view(self) self._groupcounter = { } # veldnaam => counter, t.b.v. geneste groepen met herhalende records self._receiving = False # voorkom deadlocks; geef geen events door aan presenter als _receiving True is. self._main_group = ViewGroup("main", ViewLayout.VERTICAL) if impl: impl.set_base(self)
def __new__(cls, clsname, bases, dct): new_cls = type.__new__(cls, clsname, bases, dct) # Veldattributen moeten worden afgebeeld in volgorde van declaratie. new_cls._fieldattrs = OrderedDict() for fieldname, field in sorted( inspect.getmembers( new_cls, lambda member: isinstance(member, ViewField)), key=lambda name_and_field: name_and_field[1]._sequence): new_cls._fieldattrs[fieldname] = field return new_cls
def __init__(self, *args, **kwargs): super(RelationField, self).__init__(*args[1:], **kwargs) if kwargs.get("config"): return assert args, "Geen relatie opgegeven" assert issubclass( args[0], ViewModel ), "Argument is geen subklasse van ViewModel: %r" % args[0] self._relation = args[0] if self._group: self._group.fieldcount = self.fieldcount headers = OrderedDict() for fieldname, field in self._relation._fieldattrs.items(): headers[fieldname] = HeaderField(name=fieldname, value=fieldname.capitalize()) HeaderCls = type("%sHeader" % self._relation.__name__, (ViewModel, ), headers) self._group.header = HeaderCls()
def clear_groups(self): self._groups = OrderedDict()
def clear_fields(self): if self._impl: self._impl.clear_fields() self._fields = OrderedDict()
class View(object): DLG_OK = "DLG_OK" DLG_OK_CANCEL = "DLG_OK_CANCEL" DLG_YES_NO = "DLG_YES_NO" CMD_OK = "CMD_OK" CMD_CANCEL = "CMD_CANCEL" CMD_YES = "CMD_YES" CMD_NO = "CMD_NO" def __init__(self, impl, presenter): self._impl = impl self._title = "" self._presenter = presenter self._model = self._presenter.get_viewmodel() self._fields = OrderedDict() self._groups = OrderedDict() self._presenter.set_view(self) self._groupcounter = { } # veldnaam => counter, t.b.v. geneste groepen met herhalende records self._receiving = False # voorkom deadlocks; geef geen events door aan presenter als _receiving True is. self._main_group = ViewGroup("main", ViewLayout.VERTICAL) if impl: impl.set_base(self) def get_impl(self): return self._impl def set_impl(self, impl): self._impl = impl if impl: impl.set_base(self) def get_title(self): return self._title def set_title(self, title): self._title = title if self._impl: self._impl.set_title(title) def clear_fields(self): if self._impl: self._impl.clear_fields() self._fields = OrderedDict() def clear_groups(self): self._groups = OrderedDict() def add_to_group(self, *args): """ Maak veldgroepen aan. De volgende methods zijn toolkit-afhankelijk en zitten daarom in een toolkit-specifieke implementatie (bijv. desktop/wx_view): - create_container() - add_to_container() - create_field add_to_group() wordt aangeroepen vanuit Presenter.load_data(). """ if not self._impl: return container = None thing = None if len(args) == 1: thing = args[0] elif len(args) > 1: container = args[0] thing = args[1] containers = {} if container is None: assert isinstance( thing, ViewModel), "%r is not an instance of ViewModel" % thing main_container = self._groups.get("main") if not main_container: self._groups["main"] = self._impl.create_container( self._main_group) containers["main"] = self._groups["main"] viewgroup = getattr(thing, "__group__", None) if viewgroup is None: container = containers["main"] else: container = self._impl.create_container(viewgroup) containers[viewgroup.name] = container self._impl.add_to_container(containers["main"], container) if isinstance(thing, ViewModel): model = thing # voor de leesbaarheid for fieldname in model.get_field_attributes().keys(): modelfield = model.get_field(fieldname) if modelfield.__fieldtype__ == "title": self.set_title(modelfield.get_value()) continue if modelfield.group is None: if modelfield.__fieldtype__ in ("one_to_one", "one_to_many"): fieldcontainer = self._impl.create_container( self._main_group) self._impl.add_to_container(container, fieldcontainer) else: fieldcontainer = container else: fieldcontainer = containers.get(modelfield.group.name) if fieldcontainer is None: containers[ modelfield.group. name] = fieldcontainer = self._impl.create_container( modelfield.group) self._impl.add_to_container(container, fieldcontainer) self.add_to_group(fieldcontainer, modelfield) elif isinstance(thing, ViewField): viewfield = thing # voor de leesbaarheid if viewfield.__fieldtype__ in ("one_to_one", "one_to_many"): collectiongroup = viewfield.group or self._main_group if collectiongroup.layout in [ViewLayout.FLEXGRID]: if collectiongroup.header: self.add_to_group(container, collectiongroup.header) rows = viewfield.get_value() for row in rows: self.add_to_group(container, row) else: item_count = len(viewfield.get_value()) for model in viewfield.get_value(): modelcontainer = self._impl.create_container( getattr(model, "__group__", None) or self._main_group) self._impl.add_to_container(container, modelcontainer) self.add_to_group(modelcontainer, model) if item_count == 0: self._impl.add_to_container(container, None) else: self._impl.add_to_container( container, self._impl.create_field(viewfield, viewfield.get_value())) def update_view(self): if not self._impl: return self._impl.update_view() def on(self, event): if not self._impl: return self._impl.on(event) def set_field_attr(self, field, attr, value): if type(field) in (str, unicode, int): field = self._model.get_field(field) if not field: return field.set(attr, value) self.on(ViewEvent(attr, field.get_id(), value=value)) def open_dossier(self, patient_key): if not self._impl: return self._impl.open_dossier(patient_key) def messagebox(self, title, message, dialog_type=None): if not self._impl: return if dialog_type is None: dialog_type = self.DLG_OK return self._impl.messagebox(title, message, dialog_type)
class ViewModel(object): __metaclass__ = ViewModelMeta def __init__(self, **kwargs): self._fieldindex = OrderedDict() # mapping tussen ids en veldnamen self._fltr = None # voor elke instantie van ViewModel krijgen de # veldnamen een uniek id for fieldname, classfield in self._fieldattrs.items(): idx = counter.inc() field = classfield.__class__(name=fieldname, config=classfield) field._idx = idx field.set_model(self) object.__setattr__(self, fieldname, field) self._fieldindex[idx] = fieldname def __getattribute__(self, name): if name.startswith("__"): return object.__getattribute__(self, name) attr = object.__getattribute__(self, name) if attr: if isinstance(attr, ViewField): return attr.get_value() else: return attr return object.__getattribute__(self, name) def __setattr__(self, name, value): attr = self.__dict__.get(name) if attr and isinstance(attr, ViewField): attr.set_value(value) else: object.__setattr__(self, name, value) def get_field(self, id_or_name): if str(id_or_name).isdigit(): field_id = int(id_or_name) if field_id in self._fieldindex.keys(): return object.__getattribute__(self, self._fieldindex[field_id]) for fieldname, fieldtype in self.get_field_attributes().items(): item = getattr(self, fieldname, None) if item: if isinstance(fieldtype, OneToOne): field = item.get_field(id_or_name) if field: return field elif isinstance(fieldtype, OneToMany): for subitem in item: field = subitem.get_field(id_or_name) if field: return field else: field = self.__dict__.get(id_or_name) if field: return field def __del__(self): pass def save(self): """ Wijzigingen doorvoeren in de database """ def get_value_by_id(self, field_id): if field_id in self._fieldindex.keys(): return getattr(self, self._fieldindex[field_id], None) for fieldname, fieldtype in self.get_field_attributes().items(): item = getattr(self, fieldname, None) if item: if isinstance(fieldtype, OneToOne): value = item.get_value_by_id(field_id) if value: return value elif isinstance(fieldtype, OneToMany): for subitem in item: value = subitem.get_value_by_id(field_id) if value: return value def set_value_by_id(self, field_id, value): if field_id in self._fieldindex.keys(): setattr(self, self._fieldindex[field_id], value) return True for fieldname, fieldtype in self.get_field_attributes().items(): item = getattr(self, fieldname, None) if item: if isinstance(fieldtype, OneToOne): result = item.set_value_by_id(field_id, value) if result: return result elif isinstance(fieldtype, OneToMany): for subitem in item: result = subitem.set_value_by_id(field_id, value) if result: return result return False def get_field_attributes(self): """ Geeft veldattributen terug in de juiste volgorde: de volgorde waarin ze zijn gedeclareerd. """ return self._fieldattrs def undo(self): self.select(fltr=self._fltr)