def diff(source, target, *interfaces): """Get a list of (field, changed, result) 3-tuples, for "diff-able" fields. """ if not len(interfaces): interfaces = interface.providedBy(source) results = [] for iface in interfaces: # the order is locked on the order returned by of interface.names() for name in iface.names(): #!+VERSIONS(miano, 2 may 2012) something changed in the last couple # of weeks that makes removeSecurityPolicy below required yet # it wasn't before. field = removeSecurityProxy(iface[name]) # only consider for diffing fields of this type #!+VERSIONS(miano, 2 May 2012) This was an isinstance check before. # switched it to check on interfaces. if set((schema.interfaces.IText, schema.interfaces.ITextLine, schema.interfaces.ISet)).isdisjoint( set(interface.providedBy(field))): continue bound = field.bind(source) source_value = bound.query(source, field.default) target_value = bound.query(target, field.default) if source_value is None or target_value is None: continue hresult = htmldiff(source_value, target_value) results.append((field, bool(hresult!=source_value), hresult)) return results
def update(self): """ Checks if we have Modified errors and renders split view with display widgets for db values and normal for input """ super(DiffEditForm, self).update() for error in self.errors: if error.__class__ == Modified: # Set flag that form is in diff mode if not self.diff: self.diff=True if self.diff: # Set last timestamp which we store in hidden field because # document may be modified during diff and from.timestamp field # contains old value self.last_timestamp = self.context.timestamp for widget in self.widgets: try: value = widget.getInputValue() except: value = "" # Get widget's field form_field = self.form_fields.get(widget.context.__name__) field = form_field.field.bind(self.context) # Form display widget for our field if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) # If field is Text or TextLine we display HTML diff if IText.providedBy(field) or ITextLine.providedBy(field): if value: diff_val = htmldiff(field.get(self.context), value) else: diff_val = "" display_widget = component.getMultiAdapter( (field, self.request), IDiffDisplayWidget) display_widget.setRenderedValue(diff_val) else: display_widget.setRenderedValue(field.get(self.context)) display_widget.name = widget.name + ".diff.display" # Add display - input widgets pair to list of diff widgets self.diff_widgets.append((widget, display_widget))
def update(self): """ Checks if we have Modified errors and renders split view with display widgets for db values and normal for input """ super(DiffEditForm, self).update() for error in self.errors: if error.__class__ == Modified: # Set flag that form is in diff mode if not self.diff: self.diff = True if self.diff: # Set last timestamp which we store in hidden field because # document may be modified during diff and from.timestamp field # contains old value self.last_timestamp = self.context.timestamp for widget in self.widgets: try: value = widget.getInputValue() except: value = "" # Get widget's field form_field = self.form_fields.get(widget.context.__name__) field = form_field.field.bind(self.context) # Form display widget for our field if form_field.custom_widget is not None: display_widget = form_field.custom_widget( field, self.request) else: display_widget = component.getMultiAdapter( (field, self.request), IDisplayWidget) # If field is Text or TextLine we display HTML diff if IText.providedBy(field) or ITextLine.providedBy(field): if value: diff_val = htmldiff(field.get(self.context), value) else: diff_val = "" display_widget = component.getMultiAdapter( (field, self.request), IDiffDisplayWidget) display_widget.setRenderedValue(diff_val) else: display_widget.setRenderedValue(field.get(self.context)) display_widget.name = widget.name + ".diff.display" # Add display - input widgets pair to list of diff widgets self.diff_widgets.append((widget, display_widget))