(require-library "browser.ss" "browser")
(define collecting-thread #f)
(define results-editor% (class hyper-text% ()
(inherit set-title)
(sequence
(super-init #f)
(set-title "Search Results"))))
(define f (make-object (class frame% args
(rename [super-on-subwindow-char on-subwindow-char])
(override
[on-close exit]
[on-subwindow-char
(lambda (w e)
(case (send e get-key-code)
[(prior) (send (send results get-editor) move-position 'up #f 'page) #t]
[(next) (send (send results get-editor) move-position 'down #f 'page) #t]
[else (if (and (eq? #\tab (send e get-key-code))
(eq? w results))
; Override normal behavior, which is to pass the tab on to
; the edit
(if (send e get-shift-down)
(send before-results focus)
(send search-text focus))
(super-on-subwindow-char w e))]))])
(sequence (apply super-init args)))
"PLT Help Desk" #f 600 440))
(define html-panel (make-object (class hyper-panel% ()
(rename [super-leaving-page leaving-page])
(public
[stop-search
(lambda ()
(when collecting-thread
(semaphore-wait break-sema)
(break-thread collecting-thread)
(semaphore-post break-sema)))])
(override
[leaving-page
(lambda (page new-page)
(unless (is-a? (page->editor new-page) results-editor%)
(stop-search))
(super-leaving-page page new-page))]
[on-navigate stop-search])
(sequence (super-init f)))))
(define results (send html-panel get-canvas))
(define before-results
(let loop ([l (send html-panel get-children)])
(cond
[(null? (cdr l)) results]
[(eq? (cadr l) results) (let loop ([v (car l)])
(if (is-a? v area-container<%>)
(loop (car (last-pair (send v get-children))))
v))]
[else (loop (cdr l))])))
(define top (make-object vertical-pane% f))
(define search-text (make-object text-field% "Find docs for:" top
(lambda (t e)
(send search enable (positive? (send (send t get-editor) last-position))))))
(define search-pane (make-object horizontal-pane% top))
(define search (make-object button% "Search" search-pane
(lambda (b e)
(semaphore-wait break-sema) ; protects from too-early break
(set! collecting-thread (thread start-search)))
'(border)))
(define where (make-object choice% #f '("for Keyword"
"for Keyword or Index Entry"
"for Keyword, Index Entry, or Text")
search-pane void))
(define exact (make-object choice% #f '("exact match"
"containing match"
"regexp match")
search-pane void))
(define stop (make-object button% "Stop" search-pane
(lambda (b e)
(break-thread collecting-thread))))
(send where set-selection 1)
(send exact set-selection 1)
(send search enable #f)
(send stop show #f)
(send top stretchable-height #f)
(send search-text focus)
(let* ([mb (make-object menu-bar% f)]
[file (make-object menu% "&File" mb)]
[edit (make-object menu% "&Edit" mb)])
(append-editor-operation-menu-items edit)
(make-object menu-item% "Open URL..." file
(lambda (i e)
(letrec ([d (make-object dialog% "Open URL" f 500)]
[t (make-object text-field% "URL:" d
(lambda (t e)
(send ok enable
(positive? (send (send t get-editor)
last-position)))))]
[p (make-object horizontal-panel% d)]
[browse (make-object button% "Browse..." p
(lambda (b e)
(let ([f (get-file)])
(send t set-value (string-append "file:" f)))))]
[spacer (make-object vertical-pane% p)]
[ok (make-object button% "Open" p
(lambda (b e)
(let ([s (send t get-value)])
(with-handlers ([void
(lambda (x)
(message-box "Bad URL"
(format "Bad URL: ~a" (exn-message x))
d))])
(let ([url (string->url s)])
(send results goto-url url #f)
(send d show #f)))))
'(border))]
[cancel (make-object button% "Cancel" p
(lambda (b e) (send d show #f)))])
(send p set-alignment 'right 'center)
(send ok enable #f)
(send d center)
(send t focus)
(send d show #t)))
#\O)
(make-object menu-item% "Quit" file (lambda (i e) (exit)) #\Q))
(send f show #t)
(send results goto-url
(string-append "file:" (build-path (collection-path "doc") "index.htm"))
#f)
(define cycle-key #f)
(define break-sema (make-semaphore 1))
(define choices-sema (make-semaphore 1))
(define choices null)
(define (add-choice type name title page label ckey)
(semaphore-wait choices-sema)
(set! choices (cons (list type name title page label) choices))
(semaphore-post choices-sema)
(queue-callback
(lambda ()
(when (eq? cycle-key ckey)
(semaphore-wait choices-sema)
(let ([l choices]
[editor (send results get-editor)])
(set! choices null)
(semaphore-post choices-sema)
(send editor begin-edit-sequence)
(for-each
(lambda (i)
(let-values ([(type name title page label) (apply values i)])
(if type
(begin
(send editor insert " " (send editor last-position) 'same #f)
(let ([start (send editor last-position)])
(send editor insert name start 'same #f)
(let ([end (send editor last-position)])
(send editor insert (format " in ~s~n" title) end 'same #f)
(send editor make-link-style start end)
(send editor set-clickback start end
(lambda (edit start end)
(send results goto-url
(make-url
"file"
#f ; host
#f ; port
page
#f ; params
#f ; query
label)
#f))))))
(begin
(send editor insert (format "In ~a:~n" name) (send editor last-position) 'same #f)))))
(reverse l))
(send editor end-edit-sequence))))
#f))
(define (add-section name ckey)
(add-choice #f name #f #f #f ckey))
(define not-break? (lambda (x) (not (exn:misc:user-break? x))))
; Locate standard HTML documentation
(define-values (std-docs std-doc-names)
(let* ([path (collection-path "doc")]
[doc-names (directory-list path)]
[docs (map (lambda (x) (build-path path x)) doc-names)])
(values docs doc-names)))
; Check collections for doc.txt files:
(define-values (txt-docs txt-doc-names)
(let loop ([collection-paths (current-library-collection-paths)]
[docs null]
[names null])
(cond
[(null? collection-paths)
(values docs names)]
[else (let ([path (car collection-paths)])
(let cloop ([l (with-handlers ([void (lambda (x) null)]) (directory-list path))]
[docs docs]
[names names])
(cond
[(null? l) (loop (cdr collection-paths) docs names)]
[(and (directory-exists? (build-path path (car l)))
(not (member (car l) names))
(file-exists? (build-path path (car l) "doc.txt")))
(cloop (cdr l) (cons (build-path path (car l)) docs)
(cons (car l) names))]
[else (cloop (cdr l) docs names)])))])))
(define docs (append std-docs txt-docs))
(define doc-names (append std-doc-names (map (lambda (s) (format "~a collection" s)) txt-doc-names)))
(define doc-kinds (append (map (lambda (x) 'html) std-docs) (map (lambda (x) 'text) txt-docs)))
(define re:iname (regexp "A HREF=\"(node[0-9]*[.]htm)\">(.*)