X-Git-Url: https://git.hcoop.net/clinton/lisp-on-lines.git/blobdiff_plain/19531fbd947da15a17f8e5557a1a1492eab2bca3..4e2ecf695f074d4ed79c1099fa56b1d6fce08bfb:/src/mewa/slot-presentations.lisp diff --git a/src/mewa/slot-presentations.lisp b/src/mewa/slot-presentations.lisp index 4d89895..f501b71 100644 --- a/src/mewa/slot-presentations.lisp +++ b/src/mewa/slot-presentations.lisp @@ -1,7 +1,53 @@ (in-package :it.bese.ucw) +(defun multiple-value-funcall->list (function &rest args) + "The function to be called by m-v-bf" + (multiple-value-call #'list (apply function args))) -(defslot-presentation clsql-wall-time-slot-presentation () +(defmacro multiple-value-bindf (vars form &body body) + "Like M-V-B, only it works in actions. form must be a function call" + `(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)) @@ -11,7 +57,13 @@ (format nil "~a/~a/~a" m d y))))) (defmethod (setf presentation-slot-value) ((value string) (slot clsql-wall-time-slot-presentation) instance) - (setf (presentation-slot-value slot instance) (clsql:parse-date-time (remove #\Space value)))) + (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)")) @@ -30,12 +82,38 @@ ifFormat : \"%m/%d/%Y\", });" input-id)))))) -(defslot-presentation mewa-relation-slot-presentation () - ((slot-name :accessor slot-name :initarg :slot-name) - (foreign-instance :accessor foreign-instance) +(defslot-presentation mewa-relation-slot-presentation (mewa-slot-presentation slot-presentation) + ((foreign-instance :accessor foreign-instance) (linkedp :accessor linkedp :initarg :linkedp :initform t)) (:type-name relation)) +(defaction search-records ((slot mewa-relation-slot-presentation) instance) + (multiple-value-bindf (finstance foreign-slot-name) + (meta-model:explode-foreign-key instance (slot-name slot)) + (let ((new-instance + (call-component + (parent slot) + (make-instance (or (cadr (mewa:find-attribute finstance :presentation-search)) + 'mewa::mewa-presentation-search) + :search-presentation + (mewa:make-presentation finstance + :type :search-presentation) + :list-presentation + (mewa:make-presentation finstance + :type :listing))))) + (setf (slot-value instance (slot-name slot)) (slot-value new-instance foreign-slot-name)) + (meta-model:sync-instance instance :fill-gaps-only-p (fill-gaps-only-p self))))) + +(defaction create-record ((slot mewa-relation-slot-presentation) instance) + (multiple-value-bindf (finstance foreign-slot-name) + (meta-model:explode-foreign-key instance (slot-name slot)) + (let ((new-instance + (call-component + (parent slot) + (mewa:make-presentation finstance :type :editor)))) + (setf (slot-value instance (slot-name slot)) (slot-value new-instance foreign-slot-name)) + (meta-model:sync-instance instance :fill-gaps-only-p (fill-gaps-only-p self))))) + (defmethod present-relation ((slot mewa-relation-slot-presentation) instance) ;;;;(<:as-html (slot-name slot) "=> " (foreign-instance slot) " from " instance ) (let* ((i (foreign-instance slot)) @@ -45,18 +123,11 @@ :initargs (list :global-properties (list :editablep nil :linkedp nil))))) - (when (ucw::parent slot) (setf (component.place pres) (component.place (ucw::parent slot)))) - (flet ((render () (when i (>")) - (call-next-method) - (<:as-html "total :" (len slot))) + (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))) @@ -150,4 +261,4 @@ (progn (setf (instance (presentation slot)) (presentation-slot-value slot instance)) (present (presentation slot))) - (<:as-html "--")))) \ No newline at end of file + (<:as-html "--"))))