#lang racket
(require racket/gui/base
"mreddesigner-misc.ss"
"mred-id.ss"
"mred-plugin.ss"
"code-generation.ss"
"template-load.ss"
)
(module+ test
(require rackunit))
(define template-dir (build-path "templates"))
(define/provide template-dict #f)
(define/provide (template-file f) (build-path template-dir f))
(define/provide (get-template-name file)
(and (file-exists? file)
(with-input-from-file file
(λ()(let* ([name (read)])
(and (string? name)
name))))
))
(define template-name-pattern
"med-template-~a.med")
(define template-name-regexp
(format (regexp-quote template-name-pattern) ".*"))
(define/provide (make-template-dict)
(set! template-dict
(append-map (λ(f)
(let ([f (build-path template-dir f)])
(if (and (file-exists? f) (regexp-match template-name-regexp (path->string f)))
(list (cons f (get-template-name f)))
'()
)))
(directory-list template-dir))))
(define (print-template mid name)
(write name) (newline)
(parameterize ([print-as-expression #f])
(pretty-print
`(list
(cons 'name
,name)
(cons 'parent-class
,(send (send mid get-plugin) get-parent-widget-class-symbol))
(cons 'med-version
,(list 'list application-version-maj application-version-min))
(cons 'code
,(write-mred-id-code mid))))))
(define/provide (save-template mid name [file #f])
(debug-printf "save-template: ~a\n" name)
(when name
(let ([file (or file
(make-temporary-file template-name-pattern #f
template-dir))])
(with-output-to-file file
(λ() (print-template mid name))
#:exists 'replace)
))
(debug-printf "save-template: exit\n")
)
(define/provide (load-template file parent-mid)
(debug-printf "load-template: ~a\n" file)
(and file
(let ([dico (template-load-file file)])
(debug-printf "load-template: load done\n")
(when dico
(let ([name (dict-ref dico 'name)]
[parent-class (dict-ref dico 'parent-class)]
[med-version (dict-ref dico 'med-version #f)] [proc (dict-ref dico 'code)])
(if med-version
(printf "MED template version: ~a\n" med-version)
(printf "No MED template version found\n"))
(and (check-template-version med-version)
(procedure? proc)
(equal? (procedure-arity proc) 1)
(or (can-instantiate-under? parent-mid parent-class)
(begin
(printf "Cannot insert template at this node\n")
#f))
(proc parent-mid)
)
)))
)
)
(define/provide (delete-template file)
(when file
(delete-file file)))
(define (newer-version-than-current? vers)
(and vers
(or (> (first vers) application-version-maj)
(and (= (first vers) application-version-maj)
(> (second vers) application-version-min)))))
(define (check-template-version vers)
(or (not (newer-version-than-current? vers))
(eq?
'yes
(message-box "Object created with newer version"
(format "The object you are loading was made with version ~a.~a of ~a which is newer than you current version ~a.~a. There may be problems loading it. Do you still want to proceed?"
(first vers) (second vers)
application-name
application-version-maj application-version-min)
#f '(yes-no)))))