(in-package :it.bese.ucw) (defun multiple-value-funcall->list (function &rest args) (multiple-value-call #'list (apply function args))) (defmacro multiple-value-bindf (vars form &body body) `(destructuring-bind ,vars (multiple-value-funcall->list #',(car form) ,@(cdr form)) ,@body)) (defcomponent mewa-slot-presentation () ((slot-name :accessor slot-name :initarg :slot-name :documentation "The name of the slot being accessed") (fill-gaps-only-p :accessor fill-gaps-only-p :initarg :fill-gaps-only-p :initform nil :documentation "When nil, the instance is syncronised with the database. When T, only the default value for primary keys and the joins are updated.")) (:documentation "The superclass of all Mewa slot presentations")) ;;;; this has to be in the eval when i would think (eval-when (:compile-toplevel :load-toplevel :execute) (defun generate-slot-presentation-definition-for-type (type) (let* ((u-name (intern (format nil "~A-SLOT-PRESENTATION" type))) (sp-name (intern (format nil "MEWA-~A" u-name))) (t-name (intern (format nil "MEWA-~A" type)))) `(defslot-presentation ,sp-name (,u-name mewa-slot-presentation) () (:type-name ,t-name))))) (defmacro define-base-mewa-presentations (&body types) "Define the mewa-slot-presentations by subclassing the base UCW ones" `(progn ,@(mapcar #'generate-slot-presentation-definition-for-type types))) ;;;then actually define the base presentations : (define-base-mewa-presentations boolean string number integer currency) (defslot-presentation clsql-wall-time-slot-presentation (mewa-relation-slot-presentation) () (:type-name clsql-sys:wall-time)) (defmethod presentation-slot-value ((slot clsql-wall-time-slot-presentation) instance) (let ((date (call-next-method))) (when date (multiple-value-bind (y m d) (clsql:time-ymd date) (format nil "~a/~a/~a" m d y))))) (defmethod (setf presentation-slot-value) ((value string) (slot clsql-wall-time-slot-presentation) instance) (let ((new-time (clsql:parse-date-time (remove #\Space value))) (old-time (when (slot-boundp instance (slot-name slot)) (slot-value instance (slot-name slot))))) (unless (or (eql old-time new-time) (when (and new-time old-time) (equal :equal (clsql:time-compare new-time old-time)))) (setf (presentation-slot-value slot instance) new-time )))) (defmethod label :around ((slot clsql-wall-time-slot-presentation)) (concatenate 'string (call-next-method) " (mm/dd/yyyy)")) (defmethod present-slot ((slot clsql-wall-time-slot-presentation) instance) (let ((date (presentation-slot-value slot instance)) (input-id (string (gensym)))) (if (and date (not (editablep slot))) (<:span (<:as-html date))) (when (editablep slot) ( " (foreign-instance slot) " from " instance ) (let* ((i (foreign-instance slot)) (pres (mewa::make-presentation i :type :one-line :initargs (list :global-properties (list :editablep nil :linkedp nil))))) (when (and (ucw::parent slot) (slot-boundp slot 'ucw::place)) (setf (component.place pres) (component.place (ucw::parent slot)))) (when i ( 0 (current slot)) ;;what to do here is open to debate (setf (current slot) (- (len slot)(number-to-display slot) )))) (defmethod present-slot ((slot has-very-many-slot-presentation) instance) ;;(<:as-html "isance: " instance) (if (slot-boundp slot 'place) (progn (>")) (call-next-method) (<:as-html "total :" (len slot))) (call-next-method))) (defmethod get-foreign-instances :around ((slot has-very-many-slot-presentation) instance) (let ((f (call-next-method))) (setf (len slot) (length f)) (setf (instances slot) f) (loop for cons on (nthcdr (current slot) f) for i from 0 upto (number-to-display slot) collect (car cons)))) (defslot-presentation has-a-slot-presentation (one-of-presentation) ((key :initarg :key :accessor key)) (:type-name has-a)) (defmethod get-foreign-slot-value ((slot has-a-slot-presentation) (object t) (slot-name t)) (slot-value object slot-name)) (defmethod present-slot ((slot has-a-slot-presentation) instance) (<:as-html (presentation-slot-value slot instance)) (if (editablep slot) (