X-Git-Url: https://git.hcoop.net/clinton/lisp-on-lines.git/blobdiff_plain/7d87c1d23f23c4aa5632712191ee989240afe80a..2cb4247de9700f350d146a65c4156d7959d0bb8d:/src/mewa/slot-presentations.lisp?ds=sidebyside diff --git a/src/mewa/slot-presentations.lisp b/src/mewa/slot-presentations.lisp index 131d01c..2ed5b32 100644 --- a/src/mewa/slot-presentations.lisp +++ b/src/mewa/slot-presentations.lisp @@ -1,5 +1,50 @@ (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))) + +(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) () @@ -15,9 +60,9 @@ (old-time (when (slot-boundp instance (slot-name slot)) (slot-value instance (slot-name slot))))) (unless (or (eql old-time new-time) - (and (null old-time) new-time) - (equal :equal (clsql:time-compare new-time old-time))) - (setf (presentation-slot-value slot instance) 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)")) @@ -36,36 +81,52 @@ 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) - (linkedp :accessor linkedp :initarg :linkedp :initform t)) +(defslot-presentation mewa-relation-slot-presentation (mewa-slot-presentation slot-presentation) + ((foreign-instance :accessor foreign-instance) + (linkedp :accessor linkedp :initarg :linkedp :initform t) + (creator :accessor creator :initarg :creator :initform :editor)) (:type-name relation)) -(defun get-fkey-data (instance slot-name) - "ugly workaround b/c UCW does not like M-V-B" - (multiple-value-bind (finstance foreign-slot-name) - (meta-model:explode-foreign-key instance slot-name) - (cons finstance foreign-slot-name))) - (defaction search-records ((slot mewa-relation-slot-presentation) instance) - (let* ((d (get-fkey-data instance (slot-name slot))) - (finstance (car d)) - (foreign-slot-name (cdr d)) - (new-instance - (call-component - (parent slot) - (make-instance '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) - (clsql:update-objects-joins (list 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-on-foreign-key ((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 (creator self))))) + + ;;;; TODO: this next bit is due to a bad design decision. + ;;;; Components should always have (ok) return self, but somewhere + ;;;; i've made in return (instance self) sometimes, and this + ;;;; bahaviour is totatlly fucked. + + (when (typep new-instance 'mewa::mewa) + (setf new-instance (instance new-instance))) + + ;;;; sorry about that, and now back t our regular program. + + (meta-model:sync-instance new-instance) + (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)) @@ -75,18 +136,9 @@ :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))) @@ -182,4 +282,11 @@ (progn (setf (instance (presentation slot)) (presentation-slot-value slot instance)) (present (presentation slot))) - (<:as-html "--")))) \ No newline at end of file + (<:as-html "--")))) + + + + + + +