#lang scheme/base
(require drscheme/tool
mred
mrlib/switchable-button
mrlib/path-dialog
mzlib/unit
scheme/path
scheme/class)
(provide tool@)
(define tool@
(unit
(import drscheme:tool^)
(export drscheme:tool-exports^)
(define (phase1) (void))
(define (phase2) (void))
(define project-icon "project.png")
(define project-icon-sm "project-sm.png")
(define home-dir (find-system-path 'home-dir))
(define saved-tabs-file (string->path "saved-tabs-file.sp"))
(define saved-tabs-file-path (build-path home-dir saved-tabs-file))
(define (projects-unit-frame-mixin super%)
(class super%
(inherit get-button-panel)
(define (resolve-save-rel list-of-tab-file-abs-paths save-location-file-abs-path)
(let ((base (get-base-path save-location-file-abs-path)))
(map (lambda (tab-file-abs-path)
(path->string (find-relative-path base (simple-form-path tab-file-abs-path))))
list-of-tab-file-abs-paths)))
(define (resolve-load-rel save-location-file list-of-relative-tab-file-str)
(let ((base (get-base-path save-location-file)))
(map (lambda (relative-tab-file-str)
(build-path base (string->path relative-tab-file-str)))
list-of-relative-tab-file-str)))
(define (get-save-location suggested-starting-path)
(send (new path-dialog% [directory suggested-starting-path]
[put? #t]
[filename "saved-tabs-file.sp"]
[label "Save current tabs to.."]
[message "Save a tabs file"]
[filters (list (list "Scheme Project Files" "*.sp")
(list "Any" "*.*"))]
)
run))
(define (get-load-location suggested-starting-path)
(send (new path-dialog% [directory suggested-starting-path]
[existing? #t]
[label "Load Tabs file"]
[message "Choose a tabs set file to load..."]
[filename "saved-tabs-file.sp"]
[filters (list (list "Scheme Project Files" "*.sp;*.scm;*.ss")
(list "Any" "*.*"))]
)
run))
(define (save-tabs-to-file out-file)
(call-with-output-file out-file (lambda (i) (write (resolve-save-rel (get-tab-files) out-file) i))
#:exists 'replace
))
(define (reload-tab-from-file in-file)
(for-each (lambda (filename)
(drscheme:unit:open-drscheme-window (path->string filename)))
(let* ((rel-pathstr-list (call-with-input-file in-file (lambda (i) (read i))))
(abs-file-path-list (resolve-load-rel in-file rel-pathstr-list))
(normlized-abs-file-str-list (map simple-form-path abs-file-path-list)))
(remove* (get-tab-files) normlized-abs-file-str-list))))
(define (get-tab-files)
(filter (lambda (filename) filename)
(map (lambda (tab) (get-tab-filename tab))
(send this get-tabs))))
(define (get-base-path file) (let-values (((base-path name dir?) (split-path file)))
base-path))
(define (get-tab-filename tab)
(send (send tab get-defs) get-filename))
(define save-tabs
(lambda args
(let* ((this-tab (send this get-current-tab))
(file (get-tab-filename this-tab))
(save-location (if file (get-save-location (get-base-path file))
(get-save-location home-dir))))
(when save-location (save-tabs-to-file save-location)))))
(define reload-tabs
(lambda args
(let* ((this-tab (send this get-current-tab))
(file (get-tab-filename this-tab))
(load-location (if file (get-load-location (get-base-path file))
(get-load-location home-dir)
)))
(when load-location (reload-tab-from-file load-location)))))
(define/override (file-menu:between-save-as-and-print file-menu)
(make-object separator-menu-item% file-menu)
(new menu-item%
[label "Save Tabs"]
[parent file-menu]
[callback save-tabs])
(new menu-item%
[label "Reload Tabs"]
[parent file-menu]
[callback reload-tabs])
(make-object separator-menu-item% file-menu)
(super file-menu:between-save-as-and-print file-menu)
)
(super-new)
(send this update-shown)
(inherit register-toolbar-button)
(define project-icon-bitmap (make-object bitmap% project-icon-sm 'png/mask))
(define save-project-button
(new switchable-button%
(label "Save Tabs")
(parent (make-object vertical-pane% (get-button-panel)))
(callback save-tabs)
[bitmap project-icon-bitmap]
))
(register-toolbar-button save-project-button)
(send (get-button-panel) change-children
(lambda (_)
(cons (send save-project-button get-parent)
(remq (send save-project-button get-parent) _))))
(define load-project-button
(new switchable-button%
(label "Reload Tabs")
(parent (make-object vertical-pane% (get-button-panel)))
(callback reload-tabs)
[bitmap project-icon-bitmap]
))
(register-toolbar-button load-project-button)
(send (get-button-panel) change-children
(lambda (_)
(cons (send load-project-button get-parent)
(remq (send load-project-button get-parent) _))))
))
(drscheme:get/extend:extend-unit-frame projects-unit-frame-mixin)
))