*** empty log message ***
[gnus] / lisp / gnus-win.el
index 1f662b3..d66d0c5 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-win.el --- window configuration functions for Gnus
-;; Copyright (C) 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
 ;; Keywords: news
 
 ;;; Code:
 
-(require 'gnus-load)
+(eval-when-compile (require 'cl))
 
-(defvar gnus-use-full-window t
-  "*If non-nil, use the entire Emacs screen.")
+(require 'gnus)
+
+(defgroup gnus-windows nil
+  "Window configuration."
+  :group 'gnus)
+
+(defcustom gnus-use-full-window t
+  "*If non-nil, use the entire Emacs screen."
+  :group 'gnus-windows
+  :type 'boolean)
 
 (defvar gnus-window-configuration nil
   "Obsolete variable.  See `gnus-buffer-configuration'.")
 
-(defvar gnus-window-min-width 2
-  "*Minimum width of Gnus buffers.")
+(defcustom gnus-window-min-width 2
+  "*Minimum width of Gnus buffers."
+  :group 'gnus-windows
+  :type 'integer)
+
+(defcustom gnus-window-min-height 1
+  "*Minimum height of Gnus buffers."
+  :group 'gnus-windows
+  :type 'integer)
 
-(defvar gnus-window-min-height 1
-  "*Minimum height of Gnus buffers.")
+(defcustom gnus-always-force-window-configuration nil
+  "*If non-nil, always force the Gnus window configurations."
+  :group 'gnus-windows
+  :type 'boolean)
 
 (defvar gnus-buffer-configuration
   '((group
@@ -49,8 +66,9 @@
               (summary 1.0 point)
               (if gnus-carpal '(summary-carpal 4))))
     (article
-     (cond 
-      (gnus-use-picons
+     (cond
+      ((and gnus-use-picons
+           (eq gnus-picons-display-where 'picons))
        '(frame 1.0
               (vertical 1.0
                         (summary 0.25 point)
      (vertical 1.0
               (summary 0.25)
               (faq 1.0 point)))
+    (edit-article
+     (vertical 1.0
+              (article 1.0 point)))
     (edit-form
      (vertical 1.0
               (group 0.5)
      (vertical 1.0
               (article 0.5)
               (message 1.0 point)))
-    (draft
-     (vertical 1.0
-              (draft 1.0 point)))
     (pipe
      (vertical 1.0
               (summary 0.25 point)
      (vertical 1.0
               ("*Gnus Help Bug*" 0.5)
               ("*Gnus Bug*" 1.0 point)))
+    (score-trace
+     (vertical 1.0
+              (summary 0.5 point)
+              ("*Score Trace*" 1.0)))
+    (score-words
+     (vertical 1.0
+              (summary 0.5 point)
+              ("*Score Words*" 1.0)))
+    (category
+     (vertical 1.0
+              (category 1.0)))
     (compose-bounce
      (vertical 1.0
               (article 0.5)
               (message 1.0 point))))
   "Window configuration for all possible Gnus buffers.
-This variable is a list of lists.  Each of these lists has a NAME and
-a RULE.         The NAMEs are commonsense names like `group', which names a
-rule used when displaying the group buffer; `summary', which names a
-rule for what happens when you enter a group and do not display an
-article buffer; and so on.  See the value of this variable for a
-complete list of NAMEs.
-
-Each RULE is a list of vectors.         The first element in this vector is
-the name of the buffer to be displayed; the second element is the
-percentage of the screen this buffer is to occupy (a number in the
-0.0-0.99 range); the optional third element is `point', which should
-be present to denote which buffer point is to go to after making this
-buffer configuration.")
+See the Gnus manual for an explanation of the syntax used.")
 
 (defvar gnus-window-to-buffer
   '((group . gnus-group-buffer)
@@ -154,7 +171,7 @@ buffer configuration.")
     (server . gnus-server-buffer)
     (browse . "*Gnus Browse Server*")
     (edit-group . gnus-group-edit-buffer)
-    (edit-group . gnus-edit-form-buffer)
+    (edit-form . gnus-edit-form-buffer)
     (edit-server . gnus-server-edit-buffer)
     (group-carpal . gnus-carpal-group-buffer)
     (summary-carpal . gnus-carpal-summary-buffer)
@@ -167,60 +184,78 @@ buffer configuration.")
     (faq . gnus-faq-buffer)
     (picons . "*Picons*")
     (tree . gnus-tree-buffer)
+    (score-trace . "*Score Trace*")
     (info . gnus-info-buffer)
+    (category . gnus-category-buffer)
     (article-copy . gnus-article-copy)
     (draft . gnus-draft-buffer))
   "Mapping from short symbols to buffer names or buffer variables.")
 
+;;; Internal variables.
+
+(defvar gnus-current-window-configuration nil
+  "The most recently set window configuration.")
+
 (defvar gnus-created-frames nil)
 
 (defun gnus-kill-gnus-frames ()
   "Kill all frames Gnus has created."
   (while gnus-created-frames
     (when (frame-live-p (car gnus-created-frames))
-      ;; We slap a condition-case around this `delete-frame' to ensure 
+      ;; We slap a condition-case around this `delete-frame' to ensure
       ;; against errors if we try do delete the single frame that's left.
-      (condition-case ()
-         (delete-frame (car gnus-created-frames))
-       (error nil)))
+      (ignore-errors
+       (delete-frame (car gnus-created-frames))))
     (pop gnus-created-frames)))
 
+(defun gnus-window-configuration-element (list)
+  (while (and list
+             (not (assq (car list) gnus-window-configuration)))
+    (pop list))
+  (cadr (assq (car list) gnus-window-configuration)))
+
 (defun gnus-windows-old-to-new (setting)
   ;; First we take care of the really, really old Gnus 3 actions.
   (when (symbolp setting)
     (setq setting
          ;; Take care of ooold GNUS 3.x values.
          (cond ((eq setting 'SelectArticle) 'article)
-               ((memq setting '(SelectSubject ExpandSubject)) 'summary)
-               ((memq setting '(SelectNewsgroup ExitNewsgroup)) 'group)
+               ((memq setting '(SelectNewsgroup SelectSubject ExpandSubject))
+                'summary)
+               ((memq setting '(ExitNewsgroup)) 'group)
                (t setting))))
   (if (or (listp setting)
          (not (and gnus-window-configuration
                    (memq setting '(group summary article)))))
       setting
-    (let* ((setting (if (eq setting 'group)
-                       (if (assq 'newsgroup gnus-window-configuration)
-                           'newsgroup
-                         'newsgroups) setting))
-          (elem (cadr (assq setting gnus-window-configuration)))
+    (let* ((elem
+           (cond
+            ((eq setting 'group)
+             (gnus-window-configuration-element
+              '(group newsgroups ExitNewsgroup)))
+            ((eq setting 'summary)
+             (gnus-window-configuration-element
+              '(summary SelectNewsgroup SelectSubject ExpandSubject)))
+            ((eq setting 'article)
+             (gnus-window-configuration-element
+              '(article SelectArticle)))))
           (total (apply '+ elem))
           (types '(group summary article))
           (pbuf (if (eq setting 'newsgroups) 'group 'summary))
           (i 0)
-          perc
-          out)
+          perc out)
       (while (< i 3)
        (or (not (numberp (nth i elem)))
            (zerop (nth i elem))
            (progn
              (setq perc (if (= i 2)
                             1.0
-                          (/ (float (nth 0 elem)) total)))
-             (setq out (cons (if (eq pbuf (nth i types))
-                                 (list (nth i types) perc 'point)
-                               (list (nth i types) perc))
-                             out))))
-       (setq i (1+ i)))
+                          (/ (float (nth i elem)) total)))
+             (push (if (eq pbuf (nth i types))
+                       (list (nth i types) perc 'point)
+                     (list (nth i types) perc))
+                   out)))
+       (incf i))
       `(vertical 1.0 ,@(nreverse out)))))
 
 ;;;###autoload
@@ -347,7 +382,8 @@ buffer configuration.")
                  (split-window window (cadar comp-subs)
                                (eq type 'horizontal))))
          (setq result (or (gnus-configure-frame
-                           (car comp-subs) window) result))
+                           (car comp-subs) window)
+                          result))
          (select-window new-win)
          (setq window new-win)
          (setq comp-subs (cdr comp-subs))))
@@ -358,6 +394,8 @@ buffer configuration.")
 (defvar gnus-frame-split-p nil)
 
 (defun gnus-configure-windows (setting &optional force)
+  (setq gnus-current-window-configuration setting)
+  (setq force (or force gnus-always-force-window-configuration))
   (setq setting (gnus-windows-old-to-new setting))
   (let ((split (if (symbolp setting)
                   (cadr (assq setting gnus-buffer-configuration))
@@ -383,18 +421,11 @@ buffer configuration.")
                ;; We want to remove all other windows.
                (if (not gnus-frame-split-p)
                    ;; This is not a `frame' split, so we ignore the
-                   ;; other frames.  
+                   ;; other frames.
                    (delete-other-windows)
                  ;; This is a `frame' split, so we delete all windows
                  ;; on all frames.
-                 (mapcar 
-                  (lambda (frame)
-                    (unless (eq (cdr (assq 'minibuffer
-                                           (frame-parameters frame)))
-                                'only)
-                      (select-frame frame)
-                      (delete-other-windows)))
-                  (frame-list)))
+                 (gnus-delete-windows-in-gnusey-frames))
              ;; Just remove some windows.
              (gnus-remove-some-windows)
              (switch-to-buffer nntp-server-buffer))
@@ -403,6 +434,33 @@ buffer configuration.")
       (switch-to-buffer nntp-server-buffer)
       (gnus-configure-frame split (get-buffer-window (current-buffer))))))
 
+(defun gnus-delete-windows-in-gnusey-frames ()
+  "Do a `delete-other-windows' in all frames that have Gnus windows."
+  (let ((buffers
+        (mapcar
+         (lambda (elem)
+           (if (symbolp (cdr elem))
+               (when (and (boundp (cdr elem))
+                          (symbol-value (cdr elem)))
+                 (get-buffer (symbol-value (cdr elem))))
+             (when (cdr elem)
+               (get-buffer (cdr elem)))))
+         gnus-window-to-buffer)))
+    (mapcar
+     (lambda (frame)
+       (unless (eq (cdr (assq 'minibuffer
+                             (frame-parameters frame)))
+                  'only)
+        (select-frame frame)
+        (let (do-delete)
+          (walk-windows
+           (lambda (window)
+             (when (memq (window-buffer window) buffers)
+               (setq do-delete t))))
+          (when do-delete
+            (delete-other-windows)))))
+     (frame-list))))
+
 (defun gnus-all-windows-visible-p (split)
   "Say whether all buffers in SPLIT are currently visible.
 In particular, the value returned will be the window that
@@ -441,7 +499,7 @@ should have point."
          (setq win (get-buffer-window buf t)))
        (if win
            (when (memq 'point split)
-               (setq all-visible win))
+             (setq all-visible win))
          (setq all-visible nil)))
        (t
        (when (eq type 'frame)
@@ -460,39 +518,35 @@ should have point."
       ;; Remove windows on all known Gnus buffers.
       (while buffers
        (setq buf (cdar buffers))
-       (if (symbolp buf)
-           (setq buf (and (boundp buf) (symbol-value buf))))
+       (when (symbolp buf)
+         (setq buf (and (boundp buf) (symbol-value buf))))
        (and buf
             (get-buffer-window buf)
             (progn
-              (setq bufs (cons buf bufs))
+              (push buf bufs)
               (pop-to-buffer buf)
-              (if (or (not lowest)
-                      (< (gnus-window-top-edge) lowest))
-                  (progn
-                    (setq lowest (gnus-window-top-edge))
-                    (setq lowest-buf buf)))))
+              (when (or (not lowest)
+                        (< (gnus-window-top-edge) lowest))
+                (setq lowest (gnus-window-top-edge))
+                (setq lowest-buf buf))))
        (setq buffers (cdr buffers)))
       ;; Remove windows on *all* summary buffers.
       (walk-windows
        (lambda (win)
         (let ((buf (window-buffer win)))
-          (if (string-match    "^\\*Summary" (buffer-name buf))
-              (progn
-                (setq bufs (cons buf bufs))
-                (pop-to-buffer buf)
-                (if (or (not lowest)
-                        (< (gnus-window-top-edge) lowest))
-                    (progn
-                      (setq lowest-buf buf)
-                      (setq lowest (gnus-window-top-edge)))))))))
-      (and lowest-buf
-          (progn
-            (pop-to-buffer lowest-buf)
-            (switch-to-buffer nntp-server-buffer)))
+          (when (string-match  "^\\*Summary" (buffer-name buf))
+            (push buf bufs)
+            (pop-to-buffer buf)
+            (when (or (not lowest)
+                      (< (gnus-window-top-edge) lowest))
+              (setq lowest-buf buf)
+              (setq lowest (gnus-window-top-edge)))))))
+      (when lowest-buf
+       (pop-to-buffer lowest-buf)
+       (switch-to-buffer nntp-server-buffer))
       (while bufs
-       (and (not (eq (car bufs) lowest-buf))
-            (delete-windows-on (car bufs)))
+       (when (not (eq (car bufs) lowest-buf))
+         (delete-windows-on (car bufs)))
        (setq bufs (cdr bufs))))))
 
 (provide 'gnus-win)