Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / gnus-xmas.el
index 6ecfd94..cee9ee9 100644 (file)
@@ -1,9 +1,10 @@
 ;;; gnus-xmas.el --- Gnus functions for XEmacs
 
-;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
-;;      Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
+;;     Katsumi Yamaoka <yamaoka@jpl.org>
 ;; Keywords: news
 
 ;; This file is part of GNU Emacs.
@@ -44,6 +45,12 @@ automatically."
                 directory)
   :group 'gnus-xmas)
 
+(unless gnus-xmas-glyph-directory
+  (unless (setq gnus-xmas-glyph-directory
+               (message-xmas-find-glyph-directory "gnus"))
+    (error "Can't find glyph directory. \
+Possibly the `etc' directory has not been installed.")))
+
 ;;(format "%02x%02x%02x" 114 66 20) "724214"
 
 (defvar gnus-xmas-logo-color-alist
@@ -75,24 +82,10 @@ automatically."
   (cdr (assq gnus-xmas-logo-color-style gnus-xmas-logo-color-alist))
   "Colors used for the Gnus logo.")
 
-(defcustom gnus-article-x-face-command
-  (if (or (featurep 'xface)
-         (featurep 'xpm))
-      'gnus-xmas-article-display-xface
-    "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | ee -")
-  "*String or function to be executed to display an X-Face header.
-If it is a string, the command will be executed in a sub-shell
-asynchronously.         The compressed face will be piped to this command."
-  :type '(choice string function))
-
 ;;; Internal variables.
 
 ;; Don't warn about these undefined variables.
 
-(defvar gnus-group-mode-hook)
-(defvar gnus-summary-mode-hook)
-(defvar gnus-article-mode-hook)
-
 ;;defined in gnus.el
 (defvar gnus-active-hashtb)
 (defvar gnus-article-buffer)
@@ -140,12 +133,12 @@ It is provided only to ease porting of broken FSF Emacs programs."
   (if (stringp buffer)
       nil
     (map-extents (lambda (extent ignored)
-                   (remove-text-properties
-                    start end
-                    (list (extent-property extent 'text-prop) nil)
-                    buffer)
+                  (remove-text-properties
+                   start end
+                   (list (extent-property extent 'text-prop) nil)
+                   buffer)
                   nil)
-                 buffer start end nil nil 'text-prop)
+                buffer start end nil nil 'text-prop)
     (gnus-add-text-properties start end props buffer)))
 
 (defun gnus-xmas-highlight-selected-summary ()
@@ -197,7 +190,7 @@ displayed, no centering will be performed."
        ;; whichever is the least.
        ;; NOFORCE parameter suggested by Daniel Pittman <daniel@danann.net>.
        (set-window-start
-        window (min bottom (save-excursion (forward-line (- top)) (point))) 
+        window (min bottom (save-excursion (forward-line (- top)) (point)))
         t))
       ;; Do horizontal recentering while we're at it.
       (when (and (get-buffer-window (current-buffer) t)
@@ -290,19 +283,19 @@ call it with the value of the `gnus-data' text property."
 (defun gnus-xmas-appt-select-lowest-window ()
   (let* ((lowest-window (selected-window))
         (bottom-edge (car (cdr (cdr (cdr (window-pixel-edges))))))
-         (last-window (previous-window))
-         (window-search t))
+        (last-window (previous-window))
+        (window-search t))
     (while window-search
       (let* ((this-window (next-window))
-             (next-bottom-edge (car (cdr (cdr (cdr
-                                               (window-pixel-edges
+            (next-bottom-edge (car (cdr (cdr (cdr
+                                              (window-pixel-edges
                                                this-window)))))))
-        (when (< bottom-edge next-bottom-edge)
+       (when (< bottom-edge next-bottom-edge)
          (setq bottom-edge next-bottom-edge)
          (setq lowest-window this-window))
 
-        (select-window this-window)
-        (when (eq last-window this-window)
+       (select-window this-window)
+       (when (eq last-window this-window)
          (select-window lowest-window)
          (setq window-search nil))))))
 
@@ -328,7 +321,8 @@ call it with the value of the `gnus-data' text property."
 
 (defun gnus-xmas-article-menu-add ()
   (gnus-xmas-menu-add article
-    gnus-article-article-menu gnus-article-treatment-menu))
+    gnus-article-article-menu gnus-article-treatment-menu
+    gnus-article-post-menu gnus-article-commands-menu))
 
 (defun gnus-xmas-score-menu-add ()
   (gnus-xmas-menu-add score
@@ -428,12 +422,9 @@ call it with the value of the `gnus-data' text property."
   (defalias 'gnus-window-edges 'window-pixel-edges)
 
   (if (and (<= emacs-major-version 19)
-          (< emacs-minor-version 14))
+          (< emacs-minor-version 14))
       (defalias 'gnus-set-text-properties 'gnus-xmas-set-text-properties))
 
-  (when (fboundp 'turn-off-scroll-in-place)
-    (add-hook 'gnus-article-mode-hook 'turn-off-scroll-in-place))
-
   (unless (boundp 'standard-display-table)
     (setq standard-display-table nil))
 
@@ -446,15 +437,12 @@ call it with the value of the `gnus-data' text property."
          (list 'funcall fval)
        (cons 'progn (cdr (cdr fval))))))
 
-  (unless (fboundp 'match-string-no-properties)
-    (defalias 'match-string-no-properties 'match-string))
-
   (defalias 'gnus-x-color-values
-       (if (fboundp 'x-color-values)
-           'x-color-values
-         (lambda (color)
-           (color-instance-rgb-components
-            (make-color-instance color))))))
+    (if (fboundp 'x-color-values)
+       'x-color-values
+      (lambda (color)
+       (color-instance-rgb-components
+        (make-color-instance color))))))
 
 (defun gnus-xmas-redefine ()
   "Redefine lots of Gnus functions for XEmacs."
@@ -468,48 +456,88 @@ call it with the value of the `gnus-data' text property."
   (defalias 'gnus-group-startup-message 'gnus-xmas-group-startup-message)
   (defalias 'gnus-tree-minimize 'gnus-xmas-tree-minimize)
   (defalias 'gnus-appt-select-lowest-window
-       'gnus-xmas-appt-select-lowest-window)
+    'gnus-xmas-appt-select-lowest-window)
   (defalias 'gnus-mail-strip-quoted-names 'gnus-xmas-mail-strip-quoted-names)
   (defalias 'gnus-character-to-event 'character-to-event)
   (defalias 'gnus-mode-line-buffer-identification
-       'gnus-xmas-mode-line-buffer-identification)
+    'gnus-xmas-mode-line-buffer-identification)
   (defalias 'gnus-key-press-event-p 'key-press-event-p)
   (defalias 'gnus-region-active-p 'region-active-p)
   (defalias 'gnus-annotation-in-region-p 'gnus-xmas-annotation-in-region-p)
   (defalias 'gnus-mime-button-menu 'gnus-xmas-mime-button-menu)
 
-  (add-hook 'gnus-group-mode-hook 'gnus-xmas-group-menu-add)
-  (add-hook 'gnus-summary-mode-hook 'gnus-xmas-summary-menu-add)
-  (add-hook 'gnus-article-mode-hook 'gnus-xmas-article-menu-add)
+  ;; These ones are not defcutom'ed, sometimes not even defvar'ed. They
+  ;; probably should. If that is done, the code below should then be moved
+  ;; where each variable is defined, in order not to mess with user settings.
+  ;; -- didier
   (add-hook 'gnus-score-mode-hook 'gnus-xmas-score-menu-add)
-
-  (add-hook 'gnus-pick-mode-hook 'gnus-xmas-pick-menu-add)
-  (add-hook 'gnus-topic-mode-hook 'gnus-xmas-topic-menu-add)
-  (add-hook 'gnus-tree-mode-hook 'gnus-xmas-tree-menu-add)
   (add-hook 'gnus-binary-mode-hook 'gnus-xmas-binary-menu-add)
   (add-hook 'gnus-grouplens-mode-hook 'gnus-xmas-grouplens-menu-add)
   (add-hook 'gnus-server-mode-hook 'gnus-xmas-server-menu-add)
   (add-hook 'gnus-browse-mode-hook 'gnus-xmas-browse-menu-add)
-
-  (add-hook 'gnus-group-mode-hook 'gnus-xmas-setup-group-toolbar)
-  (add-hook 'gnus-summary-mode-hook 'gnus-xmas-setup-summary-toolbar)
-
-  (add-hook 'gnus-agent-summary-mode-hook 'gnus-xmas-agent-summary-menu-add)
-  (add-hook 'gnus-agent-group-mode-hook 'gnus-xmas-agent-group-menu-add)
-  (add-hook 'gnus-agent-server-mode-hook 'gnus-xmas-agent-server-menu-add)
-
   (add-hook 'gnus-draft-mode-hook 'gnus-xmas-draft-menu-add)
-  (add-hook 'gnus-summary-mode-hook
-           'gnus-xmas-switch-horizontal-scrollbar-off)
-  (add-hook 'gnus-tree-mode-hook 'gnus-xmas-switch-horizontal-scrollbar-off))
-
+  (add-hook 'gnus-mailing-list-mode-hook 'gnus-xmas-mailing-list-menu-add)
+
+  (when (featurep 'mule)
+    (defun gnus-truncate-string (str end-column &optional start-column padding)
+      "Truncate string STR to end at column END-COLUMN.
+The optional 2nd arg START-COLUMN, if non-nil, specifies
+the starting column; that means to return the characters occupying
+columns START-COLUMN ... END-COLUMN of STR.
+
+The optional 3rd arg PADDING, if non-nil, specifies a padding character
+to add at the end of the result if STR doesn't reach column END-COLUMN,
+or if END-COLUMN comes in the middle of a character in STR.
+PADDING is also added at the beginning of the result
+if column START-COLUMN appears in the middle of a character in STR.
+
+If PADDING is nil, no padding is added in these cases, so
+the resulting string may be narrower than END-COLUMN.
+\[Emacs 20.3 emulating function]"
+      (or start-column
+         (setq start-column 0))
+      (let ((len (length str))
+           (idx 0)
+           (column 0)
+           (head-padding "") (tail-padding "")
+           ch last-column last-idx from-idx)
+       (condition-case nil
+           (while (< column start-column)
+             (setq ch (aref str idx)
+                   column (+ column (char-width ch))
+                   idx (1+ idx)))
+         (args-out-of-range (setq idx len)))
+       (if (< column start-column)
+           (if padding (make-string end-column padding) "")
+         (if (and padding (> column start-column))
+             (setq head-padding
+                   (make-string (- column start-column) padding)))
+         (setq from-idx idx)
+         (if (< end-column column)
+             (setq idx from-idx)
+           (condition-case nil
+               (while (< column end-column)
+                 (setq last-column column
+                       last-idx idx
+                       ch (aref str idx)
+                       column (+ column (char-width ch))
+                       idx (1+ idx)))
+             (args-out-of-range (setq idx len)))
+           (if (> column end-column)
+               (setq column last-column idx last-idx))
+           (if (and padding (< column end-column))
+               (setq tail-padding
+                     (make-string (- end-column column) padding))))
+         (setq str (substring str from-idx idx))
+         (if padding
+             (concat head-padding str tail-padding)
+           str))))))
 
 ;;; XEmacs logo and toolbar.
 
 (defun gnus-xmas-group-startup-message (&optional x y)
   "Insert startup message in current buffer."
   ;; Insert the message.
-  (setq gnus-xmas-glyph-directory (message-xmas-find-glyph-directory "gnus"))
   (erase-buffer)
   (cond
    ((and (console-on-window-system-p)
@@ -527,7 +555,11 @@ call it with the value of the `gnus-data' text property."
                             ("background" . ,(face-background 'default)))])
                         ((featurep 'xbm)
                          `[xbm :file ,logo-xbm])
-                        (t [nothing])))))
+                        (t [nothing]))))
+          (wpheight (window-pixel-height))
+          (rest (max 0 (1- (/ (* (- wpheight (glyph-height glyph))
+                                 (window-height))
+                              wpheight 2)))))
       (insert " ")
       (set-extent-begin-glyph (make-extent (point) (point)) glyph)
       (goto-char (point-min))
@@ -535,37 +567,57 @@ call it with the value of the `gnus-data' text property."
        (insert (make-string (/ (max (- (window-width) (or x 35)) 0) 2)
                             ?\ ))
        (forward-line 1))
-      (setq gnus-simple-splash nil))
-    (goto-char (point-min))
-    (let* ((pheight (+ 20 (count-lines (point-min) (point-max))))
-          (wheight (window-height))
-          (rest (- wheight pheight)))
-      (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n))))
+      (setq gnus-simple-splash nil)
+      (goto-char (point-min))
+      (insert gnus-product-name " " gnus-version-number
+             (if (zerop (string-to-number gnus-revision-number))
+                 ""
+               (concat " (r" gnus-revision-number ")"))
+             " based on " gnus-original-product-name " v"
+             gnus-original-version-number "\n")
+      (end-of-line 0)
+      (put-text-property (point-min) (point) 'face 'gnus-splash-face)
+      (insert-char ?\  (prog1
+                          (max 0 (/ (- (window-width) (point)) 2))
+                        (goto-char (point-min))))
+      (forward-line 1)
+      (insert-char ?\n rest)
+      (set-window-start (selected-window) (point-min))))
    (t
-    (insert
-     (format "              %s
-          _    ___ _             _
-          _ ___ __ ___  __    _ ___
-          __   _     ___    __  ___
-              _           ___     _
-             _  _ __             _
-             ___   __            _
-                   __           _
-                    _      _   _
-                   _      _    _
-                      _  _    _
-                  __  ___
-                 _   _ _     _
-                _   _
-              _    _
-             _    _
-            _
-          __
+    (insert "
+         _    ___ _             _
+         _ ___ __ ___  __    _ ___
+         __   _     ___    __  ___
+             _           ___     _
+            _  _ __             _
+            ___   __            _
+                  __           _
+                   _      _   _
+                  _      _    _
+                     _  _    _
+                 __  ___
+                _   _ _     _
+               _   _
+             _    _
+            _    _
+           _
+         __
 
 "
-            ""))
+           )
+    (goto-char (point-min))
+    (insert gnus-product-name " " gnus-version-number
+           (if (zerop (string-to-number gnus-revision-number))
+               ""
+             (concat " (r" gnus-revision-number ")"))
+           " based on " gnus-original-product-name " v"
+           gnus-original-version-number)
+    (insert-char ?\  (prog1
+                        (max 0 (/ (- (window-width) (point)) 2))
+                      (goto-char (point-min))))
+    (forward-line 1)
     ;; And then hack it.
-    (gnus-indent-rigidly (point-min) (point-max)
+    (gnus-indent-rigidly (point) (point-max)
                         (/ (max (- (window-width) (or x 46)) 0) 2))
     (goto-char (point-min))
     (forward-line 1)
@@ -700,27 +752,32 @@ XEmacs compatibility workaround."
   "Face to show X face"
   :group 'gnus-xmas)
 
-(defun gnus-xmas-article-display-xface (beg end)
-  "Display any XFace headers in the current article."
+(defun gnus-xmas-article-display-xface (beg end &optional buffer)
+  "Display any XFace headers in BUFFER."
   (save-excursion
     (let ((xface-glyph
           (cond
            ((featurep 'xface)
             (make-glyph (vector 'xface :data
                                 (concat "X-Face: "
-                                        (buffer-substring beg end)))))
+                                        (if buffer
+                                            (with-current-buffer buffer
+                                              (buffer-substring beg end))
+                                          (buffer-substring beg end))))))
            ((featurep 'xpm)
-            (let ((cur (current-buffer)))
+            (let ((cur (or buffer (current-buffer))))
               (save-excursion
                 (gnus-set-work-buffer)
                 (insert-buffer-substring cur beg end)
-                (gnus-xmas-call-region "uncompface")
-                (goto-char (point-min))
-                (insert "/* Width=48, Height=48 */\n")
-                (gnus-xmas-call-region "icontopbm")
-                (gnus-xmas-call-region "ppmtoxpm")
-                (make-glyph
-                 (vector 'xpm :data (buffer-string))))))
+                (let ((coding-system-for-read 'binary)
+                      (coding-system-for-write 'binary))
+                  (gnus-xmas-call-region "uncompface")
+                  (goto-char (point-min))
+                  (insert "/* Width=48, Height=48 */\n")
+                  (gnus-xmas-call-region "icontopbm")
+                  (gnus-xmas-call-region "ppmtoxpm")
+                  (make-glyph
+                   (vector 'xpm :data (buffer-string)))))))
            (t
             (make-glyph [nothing]))))
          (ext (make-extent (progn
@@ -742,7 +799,6 @@ XEmacs compatibility workaround."
 
 (defvar gnus-xmas-modeline-glyph
   (progn
-    (setq gnus-xmas-glyph-directory (message-xmas-find-glyph-directory "gnus"))
     (let* ((file-xpm (expand-file-name "gnus-pointer.xpm"
                                       gnus-xmas-glyph-directory))
           (file-xbm (expand-file-name "gnus-pointer.xbm"
@@ -870,9 +926,7 @@ XEmacs compatibility workaround."
 
 (defun gnus-xmas-mailing-list-menu-add ()
   (gnus-xmas-menu-add mailing-list
-                     gnus-mailing-list-menu))
-
-(add-hook 'gnus-mailing-list-mode-hook 'gnus-xmas-mailing-list-menu-add)
+    gnus-mailing-list-menu))
 
 (provide 'gnus-xmas)