home *** CD-ROM | disk | FTP | other *** search
- ;;; ------------------------------------------------------------
- ;;; Menus for Scheme (tm)
- ;;; AN EXPERIMENTAL MENU-DRIVEN USER INTERFACE FOR PC SCHEME
- ;;; DOS MENU
- ;;; $Revision: 1.0 $ $Date: 14 Dec 1987 0:38:12 $
- ;;; ------------------------------------------------------------
- ;;; Copyright (c) 1987 by Morton Goldberg.
- ;;;
- ;;; Permission is granted to make copies of this program text
- ;;; for personal, non-commercial use provided this notice of
- ;;; copyright appears in all copies and derived works. All
- ;;; other rights reserved. In particular, you may not publish
- ;;; or otherwise distribute any copies of this text or any
- ;;; derived works without permission from the copyright holder.
- ;;; ------------------------------------------------------------
- ;;; Implementation Language: Texas Instruments' PC Scheme
- ;;; (Version 3.0)
- ;;; ------------------------------------------------------------
-
- (writeln "Menu-Driven User Interface -- DOS Menu")
- (writeln "Copyright (c) 1987 by Morton Goldberg")
- (let ((rev-number "$Revision: 1.0 $"))
- ;; Write the revision number string without the leading
- ;; and trailing dollar-signs (which are needed by the
- ;; version control system).
- (writeln (substring rev-number
- 1
- (sub1 (string-length rev-number)))))
-
- ;;; ------------------------------------------------------------
- ;;; DOS COMMAND WITH FILE SPECIFICATION ARGUMENTS
-
- ;;; Activate the file specification popup query window once for
- ;;; each file argument needed, test the file argument(s), and if
- ;;; OK, call the `cmd' argument, a `dos-...' procedure (e.g.,
- ;;; `dos-delete'), with the string(s) typed-in by the user. The
- ;;; procedure can be called with either three or five arguments,
- ;;; depending on whether the `dos-...' procedure takes one or
- ;;; two arguments:
- ;;;
- ;;; (cmd-with-file-args cmd test-1 text-1)
- ;;;
- ;;; (cmd-with-file-args cmd test-1 text-1 test-2 text-2)
- ;;;
- ;;; The `test-' arguments should be one of the symbols NEW-FILE,
- ;;; OLD-FILE, or NO-TEST and the `text-' arguments are strings
- ;;; to be displayed in the query windows. The procedure returns
- ;;; whatever `cmd' returns.
- (define (cmd-with-file-args cmd test-1 text-1 . file-2-args)
- (define (file-test test file-spec)
- (case test
- (OLD-FILE
- (if (not (file-exists? file-spec))
- (begin
- (window-clear pcs-status-window)
- (display "No such file" pcs-status-window)
- #f)
- #t))
- (NEW-FILE
- (if (file-exists? file-spec)
- (begin
- (window-clear pcs-status-window)
- (display "File already exists" pcs-status-window)
- #f)
- #t))
- (else
- #t)))
- (let ((spec-1 (get-response-to-query text-1)))
- (if (and spec-1 (file-test test-1 spec-1))
- (if file-2-args
- (let* ((test-2 (car file-2-args))
- (text-2 (cadr file-2-args))
- (spec-2 (get-response-to-query text-2)))
- (if (and spec-2 (file-test test-2 spec-2))
- (cmd spec-1 spec-2)))
- (cmd spec-1)))))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-dir ?) CHOICE
-
- ;;; Chop a list in equal length sublists (except maybe for the
- ;;; last sublist). This is a non-destructive function. It
- ;;; returns a list comprised of the sublists.
- (define (chop-list the-list sublist-length)
- (define (copy-n the-list sublist-length)
- (if (and the-list (> sublist-length 0))
- (cons (car the-list)
- (copy-n (cdr the-list) (sub1 sublist-length)))
- ()))
- (and
- (positive? sublist-length)
- (if the-list
- (cons (copy-n the-list sublist-length)
- (chop-list (list-tail the-list sublist-length)
- sublist-length))
- '())))
-
- ;;; Make a table from a list of lists. Returns a vector of
- ;;; strings representing a table where the strings represent one
- ;;; row of table data.
- ;;;
- ;;; height is the length of vector; i.e., the number of rows in
- ;;; the table.
- ;;;
- ;;; width is the length of the row strings.
- ;;;
- ;;; tabs is a list of the form: (tab-1 tab-2 ... ) where tab-j
- ;;; is such that (string-ref row-i tab-j) returns the first
- ;;; character in the j-th data column of the i-th table row.
- ;;;
- ;;; data is a list of the form (col-1 col-2 ... ) where col-j is
- ;;; a list comprised of the strings which will form the j-th
- ;;; column of the table.
- (define (make-table height width tabs data)
- (define (first-str list-of-strings)
- (if list-of-strings
- (car list-of-strings)
- ""))
- (let ((table (make-vector height))
- (cols (min (length tabs) (length data))))
- ;; Do loop for the rows.
- (do ((ii 0 (add1 ii))
- (dd data (map cdr dd)))
- ((>= ii height) table)
- (let ((row-strings (map first-str dd)))
- (set! (vector-ref table ii) (make-string width #\space))
- ;; Do loop for the columns.
- (do ((jj 0 (add1 jj))
- (tt tabs (cdr tt))
- (rr row-strings (cdr rr)))
- ((>= jj cols))
- (let ((item (car rr))
- (pos (car tt)))
- (substring-move-left! item
- 0
- (string-length item)
- (vector-ref table ii)
- pos)))))))
-
- ;;; This is the init-list for the *files-display-rpt* popup text
- ;;; window.
- (define *files-rpt-init*
- `('w-top 1
- 'w-left 1
- 'n-attr ,*popup-norm*
- 'border? #t))
-
- ;;; Create the popup text window which will display the file
- ;;; name strings returned by `dos-dir'.
- (define *files-rpt*
- (make-popup-text-window *files-rpt-init* '#(" ")))
-
- (define (dos-dir-cmd)
- (define range-error
- "Can't show files -- no such files or too many")
- (define tabs '(0 15 30 45 60))
- (define items (cmd-with-file-args dos-dir
- 'NO-TEST
- (vector *wild-spec-msg* "")))
- (if (and items (<= (length items) (* 5 22)))
- (let* ((item-cols (chop-list items 22))
- (dir-table (make-table 22
- (- (* 15 (length item-cols)) 3)
- tabs
- item-cols)))
- (send *files-rpt* set-text dir-table)
- (window-clear pcs-status-window)
- (display "Press [Esc] to Proceed" pcs-status-window)
- (send *files-rpt* popup)
- (window-clear pcs-status-window))
- (begin
- (window-clear pcs-status-window)
- (display range-error pcs-status-window))))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-chdir ?) CHOICE
-
- ;;; Activate the directory path popup query window. Call
- ;;; #<procedure dos-chdir> with the string typed-in by the user.
- (define (dos-cd-cmd)
- (cmd-with-file-args dos-chdir
- 'NO-TEST
- (vector *file-path-msg* "")))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-file-copy ? ?) CHOICE
-
- (define (dos-copy-cmd)
- (cmd-with-file-args dos-file-copy
- 'OLD-FILE
- (vector *file-spec-msg* "Copy: ")
- 'NO-TEST
- (vector *file-spec-msg* "To: ")))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-delete ?) CHOICE
-
- (define (dos-del-cmd)
- (cmd-with-file-args dos-delete
- 'OLD-FILE
- (vector *file-spec-msg* "Delete: ")))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-rename ? ?) CHOICE
-
- (define (dos-ren-cmd)
- (cmd-with-file-args dos-rename
- 'OLD-FILE
- (vector *file-spec-msg* "Rename: ")
- 'NEW-FILE
- (vector *file-spec-msg* "To: ")))
-
- ;;; ------------------------------------------------------------
- ;;; (dos-call ? 16384) CHOICE
-
- ;;; Query for a DOS command. Call DOS with the string typed-in
- ;;; by the user.
- (define (any-dos-cmd)
- (let ((cmd (get-response-to-query
- (vector "Enter any DOS Command" ""))))
- (if cmd
- (dos-call "" cmd 16384))))
-
- ;;; ------------------------------------------------------------
-
- ;;; This is the item list for the DOS menu.
- (define *dos-menu-items*
- `(("a (dos-dir ?)" #\a ,dos-dir-cmd)
- ("b (dos-chdir ?)" #\b ,dos-cd-cmd)
- ("c (dos-file-copy ? ?)" #\c ,dos-copy-cmd)
- ("d (dos-delete ?)" #\d ,dos-del-cmd)
- ("e (dos-rename ? ?)" #\e ,dos-ren-cmd)
- ("f (dos-call ? 16384)" #\f ,any-dos-cmd)))
-
- ;;; Create the dos menu, which is a vertical menu.
- (define *dos-menu*
- (let ((menu (make-vertical-menu *vertical-menu-init*
- *dos-menu-items*)))
- (h-justify 'CENTER menu)
- (v-justify 'TOP menu)
- menu))
-
- ;;; Link to the top-level menu.
- (define (dos-menu)
- (send *dos-menu* popup)
- *the-non-printing-object*)
-
- ;;; ------------------------------------------------------------
-