From 79a2ede8f80b2ecf2961125cd30fc36a626f77ca Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Sat, 26 May 2001 03:01:00 +0000 Subject: [PATCH] Add first working draft of folder browser. --- v7/src/imail/compile.scm | 10 +- v7/src/imail/ed-ffi.scm | 11 +- v7/src/imail/imail-browser.scm | 482 +++++++++++++++++++++++++++++++++ v7/src/imail/imail.pkg | 24 +- v7/src/imail/print.sh | 10 +- 5 files changed, 521 insertions(+), 16 deletions(-) create mode 100644 v7/src/imail/imail-browser.scm diff --git a/v7/src/imail/compile.scm b/v7/src/imail/compile.scm index c592cbe04..317fc13b2 100644 --- a/v7/src/imail/compile.scm +++ b/v7/src/imail/compile.scm @@ -1,8 +1,8 @@ ;;; -*-Scheme-*- ;;; -;;; $Id: compile.scm,v 1.10 2000/06/08 18:08:25 cph Exp $ +;;; $Id: compile.scm,v 1.11 2001/05/26 02:58:25 cph Exp $ ;;; -;;; Copyright (c) 2000 Massachusetts Institute of Technology +;;; Copyright (c) 2000-2001 Massachusetts Institute of Technology ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as @@ -16,7 +16,8 @@ ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;;; 02111-1307, USA. ;;;; IMAIL mail reader: compilation @@ -40,7 +41,8 @@ (access edwin-syntax-table (->environment '(EDWIN))))) (lambda (filename) (compile-file filename '() syntax-table))) - '("imail-summary" + '("imail-browser" + "imail-summary" "imail-top")) (cref/generate-constructors "imail") (sf "imail.con") diff --git a/v7/src/imail/ed-ffi.scm b/v7/src/imail/ed-ffi.scm index 1c695253d..12bf6d6b6 100644 --- a/v7/src/imail/ed-ffi.scm +++ b/v7/src/imail/ed-ffi.scm @@ -1,8 +1,8 @@ ;;; -*-Scheme-*- ;;; -;;; $Id: ed-ffi.scm,v 1.13 2000/07/05 00:13:18 cph Exp $ +;;; $Id: ed-ffi.scm,v 1.14 2001/05/26 02:58:27 cph Exp $ ;;; -;;; Copyright (c) 2000 Massachusetts Institute of Technology +;;; Copyright (c) 2000-2001 Massachusetts Institute of Technology ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as @@ -16,12 +16,15 @@ ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;;; 02111-1307, USA. ;;;; IMAIL mail reader: Edwin buffer packaging info (standard-scheme-find-file-initialization - '#(("imail-core" (edwin imail) + '#(("imail-browser" (edwin imail front-end folder-browser) + edwin-syntax-table) + ("imail-core" (edwin imail) system-global-syntax-table) ("imail-file" (edwin imail file-folder) system-global-syntax-table) diff --git a/v7/src/imail/imail-browser.scm b/v7/src/imail/imail-browser.scm new file mode 100644 index 000000000..d39b6ab16 --- /dev/null +++ b/v7/src/imail/imail-browser.scm @@ -0,0 +1,482 @@ +;;; -*-Scheme-*- +;;; +;;; $Id: imail-browser.scm,v 1.1 2001/05/26 03:00:53 cph Exp $ +;;; +;;; Copyright (c) 2001 Massachusetts Institute of Technology +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 2 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program; if not, write to the Free Software +;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;;; 02111-1307, USA. + +;;;; IMAIL mail reader: folder browser + +#| + +To do: + +* Change revert command to preserve the position of point as well as + possible. + +* Change revert command to preserve which folders are expanded and + collapsed. + +* Change commands to operate on marked folders if any are marked: + + imail-create-folder + imail-copy-folder + imail-rename-folder + +|# + +(declare (usual-integrations)) + +(define-command imail-browse-container + "Visit a buffer showing the contents of an IMAIL container." + (lambda () + (list (prompt-for-container "Browse container" #f + 'HISTORY 'IMAIL-BROWSE-CONTAINER + 'HISTORY-INDEX 0 + 'REQUIRE-MATCH? #t))) + (lambda (url-string) + (let* ((url (imail-parse-partial-url url-string)) + (container (open-resource url)) + (buffer + (new-buffer + (string-append (url-presentation-name url) + "-browser")))) + (set-buffer-imail-container! buffer container) + (set-buffer-imail-url-selector! buffer browser-selected-url) + (receive-modification-events container notice-container-events) + (rebuild-imail-browser-buffer buffer) + (select-buffer buffer)))) + +(define (browser-selected-url mark) + (let ((info (browser-line-info #f mark))) + (and info + (browser-line-info-url info)))) + +(define (rebuild-imail-browser-buffer buffer) + (let ((container (selected-container #t buffer))) + (buffer-widen! buffer) + (with-read-only-defeated (buffer-start buffer) + (lambda () + (region-delete! (buffer-region buffer)) + (let ((container-url (resource-locator container)) + (mark (mark-left-inserting-copy (buffer-start buffer)))) + (let ((title (url->string container-url))) + (insert-string title mark) + (insert-newline mark) + (insert-chars #\- (string-length title) mark) + (insert-newline mark)) + (insert-browser-lines container-url container-url mark)))) + (set-buffer-major-mode! buffer (ref-mode-object imail-browser)) + (buffer-not-modified! buffer) + (set-buffer-read-only! buffer) + (set-buffer-point! buffer (buffer-start buffer)))) + +(define (insert-browser-lines container-1 container-2 mark) + (for-each (lambda (subfolder-url) + (insert-browser-line subfolder-url container-2 mark)) + (sort (container-url-contents container-1) browser-urlstring url1) (url->string url2))) + +(define (url-contained? url1 url2) + (let loop ((url url1)) + (or (eq? url url2) + (let ((url* (container-url url))) + (and (not (eq? url* url)) + (loop url*)))))) + +(define (with-buffer-open buffer thunk) + (without-text-clipped buffer + (lambda () + (with-read-only-defeated buffer + (lambda () + (let ((value (thunk))) + (buffer-not-modified! buffer) + value)))))) + +(define (with-region-marked mark marker thunk) + (let ((start (mark-right-inserting-copy mark))) + (let ((value (thunk))) + (marker start mark) + (mark-temporary! start) + value))) + +(define (mouse-command-mark) + (let ((button-event (current-button-event))) + (let ((window (button-event/window button-event))) + (or (window-coordinates->mark window + (button-event/x button-event) + (button-event/y button-event)) + (buffer-end (window-buffer window)))))) + +(define (replace-right-char mark char) + (group-replace-char! (mark-group mark) + (mark-index mark) + char)) + +(define-major-mode imail-browser read-only "IMAIL Browser" + "Major mode in effect in IMAIL folder browser. +Each line summarizes a single mail folder. + +\\{imail-browser}" + (lambda (buffer) + (local-set-variable! truncate-lines #t buffer) + (buffer-put! buffer 'REVERT-BUFFER-METHOD imail-browser-revert-buffer) + (event-distributor/invoke! (ref-variable imail-browser-mode-hook buffer) + buffer))) + +(define-variable imail-browser-mode-hook + "An event distributor that is invoked when entering IMAIL Browser mode." + (make-event-distributor)) + +(define (imail-browser-revert-buffer buffer dont-use-auto-save? dont-confirm?) + dont-use-auto-save? + (if (or dont-confirm? (prompt-for-yes-or-no? "Revert IMAIL browser buffer")) + (rebuild-imail-browser-buffer buffer))) + +(define-key 'imail-browser #\+ 'imail-create-folder) +(define-key 'imail-browser #\C 'imail-copy-folder) +(define-key 'imail-browser #\R 'imail-rename-folder) + +(define-key 'imail-browser #\? 'describe-mode) +(define-key 'imail-browser #\c 'imail-browser-view-container) +(define-key 'imail-browser #\d 'imail-browser-flag-folder-deletion) +(define-key 'imail-browser #\f 'imail-browser-view-folder) +(define-key 'imail-browser #\g 'imail-browser-revert) +(define-key 'imail-browser #\h 'describe-mode) +(define-key 'imail-browser #\m 'imail-browser-mark-folder) +(define-key 'imail-browser #\q 'imail-browser-quit) +(define-key 'imail-browser #\t 'imail-browser-toggle-container) +(define-key 'imail-browser #\u 'imail-browser-unmark) +(define-key 'imail-browser #\x 'imail-browser-do-deletions) + +(define-key 'imail-browser #\rubout 'imail-browser-backup-unmark) +(define-key 'imail-browser #\M-rubout 'imail-browser-unmark-all-folders) + +(define-command imail-browser-view-folder + "" + () + (lambda () + (let ((url (selected-url))) + (if (folder-url? url) + ((ref-command imail) (url->string url)) + (editor-error "Not a selectable folder."))))) + +(define-command imail-browser-view-container + "" + () + (lambda () + (let ((url (selected-url))) + (let ((container (url-is-container? url))) + (if container + ((ref-command imail-browse-container) (url->string container)) + (editor-error "Not a selectable container.")))))) + +(define-command imail-browser-mouse-toggle-container + "" + () + (lambda () + ((ref-command imail-browser-toggle-container) (mouse-command-mark)))) + +(define-command imail-browser-toggle-container + "" + "d" + (lambda (mark) + (let ((buffer (mark-buffer mark)) + (info (browser-line-info #t mark))) + (let ((container (browser-line-info-container-url info))) + (if (not container) + (editor-error "Not on a container line.")) + (with-buffer-open buffer + (lambda () + (if (browser-line-info-container-expanded? info) + (let ((start (line-start mark 1 'LIMIT))) + (let loop ((end start)) + (if (and (not (group-end? end)) + (let ((url (selected-url #f end))) + (and url + (url-contained? url container)))) + (loop (line-start end 1 'LIMIT)) + (delete-string start end))) + (update-container-line-marker mark #\+) + (let ((container (get-memoized-resource container #f))) + (if container + (remove-browser-expanded-container! buffer container))) + (browser-line-info-container-collapsed! info)) + (begin + (let ((mark + (mark-left-inserting-copy + (line-start mark 1 'LIMIT)))) + (insert-browser-lines container + (selected-container-url #t buffer) + mark) + (mark-temporary! mark)) + (update-container-line-marker mark #\-) + (let ((container (open-resource container))) + (receive-modification-events container + notice-container-events) + (add-browser-expanded-container! buffer container)) + (browser-line-info-container-expanded! info))))))))) + +(define-command imail-browser-revert + "Re-read the contents of the buffer." + () + (lambda () (revert-buffer (selected-buffer) #t #t))) + +(define-command imail-browser-quit + "Kill the selected buffer. +Discards any pending changes." + () + (lambda () (kill-buffer-interactive (selected-buffer)))) + +(define-command imail-browser-flag-folder-deletion + "Mark the folder under point to be deleted. +With prefix argument, mark the next N folders for deletion." + "p" + (lambda (n) (imail-browser-mark-lines n #\D))) + +(define-command imail-browser-mark-folder + "" + "p" + (lambda (n) (imail-browser-mark-lines n #\*))) + +(define-command imail-browser-unmark + "" + "p" + (lambda (n) (imail-browser-mark-lines n #\space))) + +(define-command imail-browser-backup-unmark + "" + "p" + (lambda (n) ((ref-command imail-browser-unmark) (- n)))) + +(define-command imail-browser-unmark-all-folders + "" + "cRemove marks (RET means all)" + (lambda (mark-char) + (let ((buffer (selected-buffer))) + (with-buffer-open buffer + (lambda () + (let loop ((mark (line-start (buffer-start buffer) 0))) + (if (not (group-end? mark)) + (begin + (if (and (or (char=? mark-char #\return) + (char=? (extract-right-char mark) mark-char)) + (selected-url #f mark)) + (replace-right-char mark #\space)) + (let ((mark (line-start mark 1 #f))) + (if mark + (loop mark))))))))))) + +(define (imail-browser-mark-lines n mark-char) + (with-buffer-open (selected-buffer) + (lambda () + (cond ((> n 0) + (let loop ((n n) (mark (line-start (current-point) 0))) + (if (selected-url #f mark) + (begin + (replace-right-char mark mark-char) + (let ((mark (line-start mark 1 'ERROR))) + (set-current-point! mark) + (if (> n 1) + (loop (- n 1) mark)))) + (editor-failure)))) + ((< n 0) + (let loop ((n n) (mark (line-start (current-point) -1 'ERROR))) + (set-current-point! mark) + (if (selected-url #f mark) + (begin + (replace-right-char mark mark-char) + (if (< n -1) + (loop (+ n 1) (line-start mark -1 'ERROR)))) + (editor-failure)))))))) + +(define-command imail-browser-do-deletions + "Delete each folder that is marked for deletion." + () + (lambda () + (let ((buffer (selected-buffer))) + (with-buffer-open buffer + (lambda () + (let ((urls (browser-marked-urls buffer #\D))) + (if (and (pair? urls) + (cleanup-pop-up-buffers + (lambda () + (browser-pop-up-urls-window urls) + (prompt-for-yes-or-no? "Delete these folders")))) + (for-each delete-resource urls)))))))) + +(define (browser-pop-up-urls-window urls) + (pop-up-temporary-buffer " *imail-browser-folders*" + '(READ-ONLY SHRINK-WINDOW) + (lambda (buffer window) + (local-set-variable! truncate-partial-width-windows #f buffer) + (write-strings-densely + (map url->string urls) + (mark->output-port (buffer-point buffer)) + (window-x-size (or window (car (buffer-windows buffer)))))))) + +(define (browser-marked-urls buffer mark-char) + (let loop ((mark (buffer-start buffer)) (result '())) + (let ((char (extract-right-char mark))) + (if char + (loop (line-start mark 1 'ERROR) + (let ((url + (and (eq? char mark-char) + (selected-url #f mark)))) + (if url + (cons url result) + result))) + (reverse! result))))) \ No newline at end of file diff --git a/v7/src/imail/imail.pkg b/v7/src/imail/imail.pkg index 744084f8a..34551f24b 100644 --- a/v7/src/imail/imail.pkg +++ b/v7/src/imail/imail.pkg @@ -1,6 +1,6 @@ ;;; -*-Scheme-*- ;;; -;;; $Id: imail.pkg,v 1.82 2001/05/18 19:21:12 cph Exp $ +;;; $Id: imail.pkg,v 1.83 2001/05/26 02:58:30 cph Exp $ ;;; ;;; Copyright (c) 2000-2001 Massachusetts Institute of Technology ;;; @@ -16,7 +16,8 @@ ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software -;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;;; 02111-1307, USA. ;;;; IMAIL mail reader: packaging @@ -355,6 +356,21 @@ write-imail-summary-line!)) (define-package (edwin imail front-end folder-browser) - ;;(files "imail-browser") + (files "imail-browser") (parent (edwin imail front-end)) - (export (edwin))) \ No newline at end of file + (export (edwin) + edwin-command$imail-browse-container + edwin-command$imail-browser-backup-unmark + edwin-command$imail-browser-do-deletions + edwin-command$imail-browser-flag-folder-deletion + edwin-command$imail-browser-mark-folder + edwin-command$imail-browser-mouse-toggle-container + edwin-command$imail-browser-quit + edwin-command$imail-browser-revert + edwin-command$imail-browser-toggle-container + edwin-command$imail-browser-unmark + edwin-command$imail-browser-unmark-all-folders + edwin-command$imail-browser-view-container + edwin-command$imail-browser-view-folder + edwin-mode$imail-browser + edwin-variable$imail-browser-mode-hook)) \ No newline at end of file diff --git a/v7/src/imail/print.sh b/v7/src/imail/print.sh index 1064477b9..88f30297b 100755 --- a/v7/src/imail/print.sh +++ b/v7/src/imail/print.sh @@ -1,8 +1,8 @@ #!/bin/sh # -# $Id: print.sh,v 1.8 2000/06/29 22:06:11 cph Exp $ +# $Id: print.sh,v 1.9 2001/05/26 03:01:00 cph Exp $ # -# Copyright (c) 1999-2000 Massachusetts Institute of Technology +# Copyright (c) 1999-2001 Massachusetts Institute of Technology # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -16,9 +16,11 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. -prlist todo.txt imail-top.scm imail-summary.scm imail-core.scm \ +prlist todo.txt imail-top.scm imail-summary.scm imail-browser.scm \ + imail-core.scm \ imail-imap.scm imap-response.scm imap-syntax.scm \ imail-file.scm imail-rmail.scm imail-umail.scm \ imail-util.scm url.scm parser.scm rexp.scm -- 2.25.1