Commit 8a7aa1ae authored by David Byers's avatar David Byers
Browse files

Edit mode fixes:

Try not to add same recipient twice
Better default placement of recipients
Don't allow texts with duplilcate recipients or no recipients

Other fixes:
New implementation of kom-next-kom and friends
parent 49d78612
1999-08-22 David Byers <davby@ida.liu.se>
* edit-text.el (lyskom-edit-send-check-recipients): Check for
duplicate recipients and no recipients.
* swedish-strings.el (lyskom-sv-edit-mode-map): Add binding for kom-edit-add-bcc.
* edit-text.el (lyskom-edit-find-misc): New function.
(lyskom-edit-move-recipients): Only add recipients when necessary.
Convert existing ones if possible. Add recipients after comment-to
headers.
* utilities.el (lyskom-insert-in-list): New function.
* edit-text.el (lyskom-edit-do-add-recipient/copy): New function.
(lyskom-edit-add-recipient/copy): Removed string argument. Use
lyskom-edit-do-add-recipient/copy.
* english-strings.el: Change "note on the door" to "notice"
everywhere.
* edit-text.el (lyskom-edit-move-recipients): Use only
lyskom-edit-replace-headers to replace the headers.
* commands2.el (kom-next-unread-kom): New implementation.
(kom-previous-kom): New implementation.
(kom-next-kom): New implementation.
(lyskom-next-kom): New implementation replaces lyskom-next-kom and
lyskom-previous-kom.
* komtypes.el (lyskom-member-list-find-member): Fixed bug in
lyskom-member-list-find-member when member list is empty.
* commands1.el (kom-send-letter): Remove string from quit
signalling.
(lyskom-comment-recipients): Same here.
* lyskom-rest.el (silent-read): Use read-char-exclusive.
(j-or-n-p): Same here.
(lyskom-ja-or-nej-p): Remove string from quit signalling.
(lyskom-j-or-n-p): Same here.
1999-08-21 David Byers <davby@ida.liu.se>
* commands2.el (kom-add-private-answer): New function.
......
......@@ -7,9 +7,8 @@ Att g
listan, glöm inte att ta bort det från listan!
Kommandon: begär bekräftelse, endast personliga kommentarer, inga
kommentarer. Se inlägg 4089678.
Man borde använda next-command-event med vänner i silent-read och
j-or-n-p.
lyskom-get-texts-to är buggig. Om man återser senaste N av vem som
helst till ett möte och det inte finns N texter så buggar den ur. Den
......@@ -71,9 +70,6 @@ bilder f
** OSORTERADE
Creating-software sätts även vid anonyma inlägg, vilket är lite
för avslöjande. /davidk
Om förbindelsen bryts så får man args out of range ibland.
FIX BY: 0.46
......@@ -87,7 +83,7 @@ bilder f
KOM-sessioner. Funktionen verkar vara lite för känslig för hur
lyskom-buffer-list ser ut. Den borde nog göra något lite
intelligentare när listan ser ut att ha tagit slut.
FIX BY: 0.46
FIX BY: 0.46 KLART
Peter Enderborg hade en 118 tecken bred XEmacs 20.3 med scrollbar,
och vilkalistan blev precis 1 tecken för bred. I Gnu Emacs 19.30
......@@ -333,16 +329,16 @@ bilder f
** EDIT-BUFFERTEN
Defaultplaceringen av nya mottagare i editbufferten är fånig.
FIX BY: 0.46
FIX BY: 0.46 FIXAT. Sist istf först.
Det borde gå att ändra mottagare till cc-mottagare genom att bara
lägga till mottagaren igen som cc-mottagare. Motsvarande för bcc
och så vidare.
FIX BY: 0.46
FIX BY: 0.46 FIXAT
Borde kolla efter dublettmottagare innan man skickar in inlägget.
Annars så får man ett tråkigt felmeddelande från servern.
FIX BY: 0.46
FIX BY: 0.46 FIXAT
Kolla hur misslyckad inskickning hanteras. Vi borde ajtomagiskt
ploppa upp edit-bufferten, alternativt ha ett kommando för att
......
......@@ -306,7 +306,7 @@ as TYPE. If no such misc-info, return NIL"
'recpt tono
'recpt lyskom-pers-no))
"" "")))))
(quit (signal 'quit "Quitting in letter"))))
(quit (signal 'quit nil))))
;;; ================================================================
......@@ -934,7 +934,7 @@ BCCREP is a list of all recipient that are going to be bcc-recipients."
recver
subject "")))
(quit (signal 'quit "quit in lyskom-comment-recipients"))))
(quit (signal 'quit nil))))
;;; ================================================================
......
......@@ -1623,145 +1623,127 @@ is alive."
(defun lyskom-next-kom ()
"Internal version of kom-next-kom"
(if lyskom-buffer-list
(progn
(if (lyskom-buffer-p (car lyskom-buffer-list))
;; If there is an "active" lyskom buffer, send it to the
;; back of the list.
(progn
;; If the "active" lyskom buffer is the current buffer,
;; and kom-bury-buffers is non-nil, bury it.
(if (and kom-bury-buffers
(eq (car lyskom-buffer-list)
(current-buffer)))
(kom-bury))
(setq lyskom-buffer-list
(nconc (cdr lyskom-buffer-list)
(list (car lyskom-buffer-list)))))
;; The "active" lyskom buffer is dead, so we remove it from
;; some lists.
(setq lyskom-sessions-with-unread
(delq (car lyskom-buffer-list)
lyskom-sessions-with-unread))
(setq lyskom-sessions-with-unread-letters
(delq (car lyskom-buffer-list)
lyskom-sessions-with-unread-letters))
(setq lyskom-buffer-list (cdr lyskom-buffer-list)))
;; Don't switch to dead sessions.
(if (lyskom-buffer-p (car lyskom-buffer-list))
(switch-to-buffer (car lyskom-buffer-list))
(lyskom-next-kom)))
(error "No active LysKOM buffers")))
;; (defun lyskom-next-kom ()
"Internal version of kom-next-kom"
;; Find the lyskom-buffer to go from, to the next
;; If we are in a lyskom buffer that is in lyskom-buffer-list
;; switch from the current buffer.
;; If we are in a lyskom buffer that is unlisted,
;; put this buffer in the list and switch from it
;; If we are in another buffer, switch from the last listed buffer
;; If we are switching from nil, then the target buffer is
;; the first buffer in lyskom-buffer-list.
;; If we are switching from a buffer, then the target buffer is the
;; first in the rest of the list, or the first buffer
;; if we are at the end of the list
;; Splice the list as follows:
;; Put the rest of the list, after the current buffer in front of the
;; buffer list, and remove it from the back. Now the
;; buffer we switched from is at the back and the one
;; we want to switch to is at the front.
;; Iterate over the buffer list and switch to the first buffer that
;; is active. Remove any buffers that are inactive.
;; If the new target buffer after this is the one we were switching
;; from, then signal an error
;;)
(defun lyskom-previous-kom ()
"Internal version of kom-previous-kom"
(if (> (length lyskom-buffer-list) 1)
(let (lastbuf
(last-but-one lyskom-buffer-list))
(while (cdr (cdr last-but-one))
(setq last-but-one (cdr last-but-one)))
(setq lastbuf (car (cdr last-but-one)))
(if (lyskom-buffer-p (car lyskom-buffer-list))
;; If there is an "active" lyskom buffer, send it to the
;; back of the list.
(progn
;; If the "active" lyskom buffer is the current buffer,
;; and kom-bury-buffers is non-nil, bury it.
(if (and kom-bury-buffers
(eq (car lyskom-buffer-list)
(current-buffer)))
(kom-bury))
(setq lyskom-buffer-list (cons lastbuf lyskom-buffer-list))
(rplacd last-but-one nil))
;; The "active" lyskom buffer is dead, so we remove it from
;; some lists.
(setq lyskom-sessions-with-unread
(delq (cdr last-but-one)
lyskom-sessions-with-unread))
(setq lyskom-sessions-with-unread-letters
(delq (cdr last-but-one)
lyskom-sessions-with-unread-letters))
(rplacd last-but-one nil))
(if (lyskom-buffer-p (car last-but-one))
(switch-to-buffer lastbuf)
(lyskom-previous-kom)))
(if (null lyskom-buffer-list)
(error
(lyskom-get-string 'no-lyskom-session)))))
(defun lyskom-clean-buffer-list (buffers)
"Remove all dead buffers from BUFFERS"
(let ((result nil))
(while buffers
(when (lyskom-buffer-p (car buffers))
(setq result (cons (car buffers) result)))
(setq buffers (cdr buffers)))
(nreverse result)))
(defun lyskom-next-kom (buffer-list-name direction)
"Internal version of kom-next-kom
BUFFER-LIST-NAME is the list of buffers to rotate through. It must be a
name since this function may modify the list.
DIRECTION should be one of 'forward or 'backward and is the direction to
rotate through the buffer list.
Return-value: 'no-session if there is no suitable session to switch to
'same-session if the current buffer is the only suitable one
nil if everything went well"
;; Clean the buffer lists
(setq lyskom-sessions-with-unread
(lyskom-clean-buffer-list lyskom-sessions-with-unread)
lyskom-sessions-with-unread-letters
(lyskom-clean-buffer-list lyskom-sessions-with-unread-letters)
lyskom-buffer-list
(lyskom-clean-buffer-list lyskom-buffer-list))
(let ((current (lyskom-buffer-root-ancestor (current-buffer)))
(buffer-list (symbol-value buffer-list-name))
(result nil))
;; Figure out the start buffer. The target buffer will be the
;; following buffer in lyskom-buffer-list
(cond
((null buffer-list) (setq result 'no-session
current nil))
;; If we are in a lyskom buffer that is in lyskom-buffer-list
;; switch from the current buffer. If unlisted, list it.
((lyskom-buffer-p current)
(unless (memq current buffer-list)
(setq lyskom-buffer-list (cons current lyskom-buffer-list))))
;; If we are in a non-LysKOM buffer, the start buffer is the
;; last one in the list
(t (setq current (car lyskom-buffer-list))))
;; Rotate the buffer list so the target buffer is first
(when current
(cond ((eq direction 'forward)
(setq buffer-list
(lyskom-rotate-list buffer-list
(car (cdr (memq current lyskom-buffer-list))))))
(t
(setq buffer-list
(lyskom-rotate-list buffer-list
(or (car (lyskom-preceding-cons
buffer-list
current))
(car (last buffer-list)))))))
(set buffer-list-name buffer-list)
;; If the current buffer and the target buffer are the same
;; do nothing. Otherwise, flip around the buffers
(if (eq (current-buffer) (car buffer-list))
(setq result 'same-session)
;; Possibly bury the current buffer
(when (and kom-bury-buffers (eq current (current-buffer)))
(kom-bury))
;; Switch to the new buffer
(switch-to-buffer (car buffer-list))
(setq result nil)))
result))
(def-kom-emacs-command kom-next-kom ()
"Pop up the next lyskom-session."
(interactive)
(let ((start-buffer (current-buffer)))
(if (lyskom-buffer-p (current-buffer))
(lyskom-tell-internat 'kom-tell-next-lyskom))
(lyskom-next-kom)
(when (eq (current-buffer) start-buffer)
(if kom-next-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string 'no-other-lyskom-r))
(error (lyskom-get-string 'no-lyskom-session))))))
(let ((result (lyskom-next-kom 'lyskom-buffer-list 'forward)))
(cond ((eq result 'no-session)
(error (lyskom-get-string 'no-lyskom-session)))
((eq result 'same-session)
(if kom-next-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string
'no-other-lyskom-r))
(error (lyskom-get-string 'no-lyskom-session))))
(t nil))))
(def-kom-emacs-command kom-previous-kom ()
"Pop up the previous lyskom-session."
(interactive)
(let ((start-buffer (current-buffer)))
(if (lyskom-buffer-p (current-buffer))
(lyskom-tell-internat 'kom-tell-next-lyskom))
(lyskom-previous-kom)
(when (eq (current-buffer) start-buffer)
(if kom-previous-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string 'no-other-lyskom-r))
(error 'no-lyskom-session)))))
(let ((result (lyskom-next-kom 'lyskom-buffer-list 'backward)))
(cond ((eq result 'no-session)
(error (lyskom-get-string 'no-lyskom-session)))
((eq result 'same-session)
(if kom-previous-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string
'no-other-lyskom-r))
(error (lyskom-get-string 'no-lyskom-session))))
(t nil))))
(def-kom-emacs-command kom-next-unread-kom ()
"Pop up the next LysKOM session with unread texts in."
"Pop up the previous lyskom-session."
(interactive)
(let ((start-buffer (current-buffer)))
(if (not (lyskom-buffer-p (current-buffer)))
(lyskom-next-kom))
(let ((thisbuf (current-buffer)))
(lyskom-next-kom)
(while (and (not (eq thisbuf (current-buffer)))
(not (memq lyskom-buffer lyskom-sessions-with-unread)))
(lyskom-next-kom)))
(when (eq start-buffer (current-buffer))
(if kom-next-unread-kom-running-as-kom-command
(lyskom-insert-before-prompt
(lyskom-get-string 'no-unread-lyskom-r))
(error (lyskom-get-string 'no-unread-lyskom))))))
(let ((result (lyskom-next-kom 'lyskom-sessions-with-unread 'forward)))
(cond ((eq result 'no-session)
(if kom-next-unread-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string
'no-unread-lyskom-r))
(error (lyskom-get-string 'no-unread-lyskom))))
((eq result 'same-session)
(if kom-next-unread-kom-running-as-kom-command
(lyskom-insert-before-prompt (lyskom-get-string
'no-other-unread-lyskom-r))
(error (lyskom-get-string 'no-lyskom-session))))
(t nil))))
;;; ============================================================
......
......@@ -752,13 +752,30 @@ text is a member of some recipient of this text."
(setq comm-to-list (cons (cdr misc)
comm-to-list)))
((or (eq (car misc) 'recpt)
(eq (car misc) 'cc-recpt))
(eq (car misc) 'bcc-recpt)
(eq (car misc) 'cc-recpt)
(eq (car misc) 'bcc-recpt))
(when (eq (car misc) 'recpt)
(setq num-real-recpt (1+ num-real-recpt))
(when (eq (cdr misc) me) (setq num-me (1+ num-me))))
(setq recipient-list (cons (cdr misc) recipient-list)))))
;;
;; Check that there are recipients
;;
(when (null recipient-list)
(lyskom-error "%s" (lyskom-format 'no-recipients)))
;;
;; Check for duplicate recipients
;;
(let ((tmp recipient-list))
(while tmp
(when (memq (car tmp) (cdr tmp))
(lyskom-error "%s" (lyskom-format 'duplicate-recipients (car tmp))))
(setq tmp (cdr tmp))))
;;
;; Check for new comments
;;
......@@ -1040,56 +1057,87 @@ text is a member of some recipient of this text."
"Adds a conference as recipient to the text being edited."
(interactive)
(lyskom-edit-add-recipient/copy (lyskom-get-string 'added-recipient)
(lyskom-get-string 'recipient)))
nil
'recpt))
(defun kom-edit-add-bcc ()
"Adds a conference as bcc recipient to the text being edited."
(interactive)
(lyskom-edit-add-recipient/copy (lyskom-get-string 'added-blank-carbon-copy)
(lyskom-get-string 'blank-carbon-copy)))
nil
'bcc-recpt))
(defun kom-edit-add-copy ()
"Adds a conference to which a copy of the edited text will be sent."
(interactive)
(lyskom-edit-add-recipient/copy (lyskom-get-string 'added-carbon-copy)
(lyskom-get-string 'carbon-copy)))
nil
'cc-recpt))
(defun kom-edit-move-text ()
"Adds a conference as a recipient, and changes all other recipients to
CC recipients."
(interactive)
(lyskom-edit-add-recipient/copy (lyskom-get-string 'who-to-move-to-q)
(lyskom-get-string 'recipient)
'lyskom-edit-move-recipients))
(defun lyskom-edit-move-recipients (conf-stat insert-at edit-buffer)
(save-excursion
(set-buffer edit-buffer)
(let* ((tmp (lyskom-edit-parse-headers))
(subject (car tmp))
(miscs (cons 'MISC-LIST
(mapcar
(function
(lambda (x)
(if (eq (car x) 'recpt)
(cons 'cc-recpt (cdr x))
x)))
(cdr (lyskom-edit-translate-headers (elt tmp 1))))))
(aux-list (elt tmp 2)))
(lyskom-edit-replace-headers subject miscs aux-list)
(lyskom-edit-insert-misc-conf conf-stat
(lyskom-get-string 'recipient)
(point-min-marker)
nil))))
(miscs (mapcar (lambda (x) (if (eq (car x) 'recpt)
(cons 'cc-recpt (cdr x)) x))
(cdr (lyskom-edit-translate-headers (elt tmp 1)))))
(aux-list (elt tmp 2))
(elem nil))
;; If the new target is already a recipient, convert it to the right
;; kind. Otherwise insert the new target after the last comm-to
(setq elem (lyskom-edit-find-misc miscs '(recpt cc-recpt bcc-recpt)
(conf-stat->conf-no conf-stat)))
(if elem
(setcar elem 'recpt)
(lyskom-insert-in-list
(cons 'recpt (conf-stat->conf-no conf-stat))
miscs
(car (cdr (memq (lyskom-edit-find-misc miscs '(footn-to comm-to)
nil t)
miscs)))))
(lyskom-edit-replace-headers subject (cons 'MISC-LIST miscs) aux-list))))
(defun lyskom-edit-do-add-recipient/copy (recpt-type recpt-no edit-buffer)
(lyskom-save-excursion
(set-buffer edit-buffer)
(let* ((headers (lyskom-edit-parse-headers))
(miscs (lyskom-edit-translate-headers (elt headers 1)))
(elem (lyskom-edit-find-misc miscs '(cc-recpt bcc-recpt recpt)
recpt-no)))
(cond (elem (setcar elem recpt-type))
(t (setq miscs
(append miscs (list (cons recpt-type recpt-no))))))
(lyskom-edit-replace-headers (elt headers 0)
miscs
(elt headers 2)))))
(defun lyskom-edit-add-recipient/copy (prompt string &optional what-to-do)
"Adds a new recipient or a cc-recipient to the text which is being edited."
(defun lyskom-edit-add-recipient/copy (prompt
&optional what-to-do recpt-type)
"Adds a new recipient or a cc-recipient to the text which is being edited.
PROMPT is the prompt to use to ask the user for a recipient.
WHAT-TO-DO is a function to call to do the insertion.
RECPT-TYPE is the type of recipient to add."
(let ((edit-buffer (current-buffer))
(insert-at (point-min-marker))
(conf-stat (lyskom-read-conf-stat prompt '(all) nil "" t)))
......@@ -1099,10 +1147,20 @@ CC recipients."
;; +++ The information about msg-of-day might be old. We should
;; make sure it is up-to-date.
(let ((text-no (conf-stat->msg-of-day conf-stat)))
(if (zerop text-no)
;; If we have no notice on the recipient, just go ahead
(if what-to-do
(funcall what-to-do conf-stat insert-at edit-buffer)
(lyskom-edit-insert-misc-conf conf-stat string insert-at nil))
(lyskom-edit-do-add-recipient/copy recpt-type
(conf-stat->conf-no conf-stat)
edit-buffer))
;; Otherwise, show the notive and keep on going
(let ((text (blocking-do 'get-text text-no)))
(if (and text (get-buffer-window edit-buffer))
(let ((win-config (current-window-configuration)))
......@@ -1114,13 +1172,15 @@ CC recipients."
(and (j-or-n-p (lyskom-get-string 'still-want-to-add))
(if what-to-do
(funcall what-to-do conf-stat insert-at edit-buffer)
(lyskom-edit-insert-misc-conf conf-stat string
insert-at nil)))
(lyskom-edit-do-add-recipient/copy recpt-type
(conf-stat->conf-no conf-stat)
edit-buffer)))
(set-window-configuration win-config))
(if what-to-do
(funcall what-to-do conf-stat insert-at edit-buffer)
(lyskom-edit-insert-misc-conf conf-stat string
insert-at nil))))))))))
(lyskom-edit-do-add-recipient/copy recpt-type
(conf-stat->conf-no conf-stat)
edit-buffer))))))))))
(defun kom-edit-add-cross-reference ()
(interactive)
......@@ -1295,6 +1355,25 @@ CC recipients."
;;; in lyskom-edit-mode.
(defun lyskom-edit-find-misc (misc-list type data &optional last)
"Return the first misc-info pair in MISC-LIST of type TYPE containing DATA.
If TYPE is a list, then any type in TYPE is considered to match. If DATA
is nil, then any DATA is considered to match.
If optional LAST is non-nil, then return the last match instead of the first."
(when (eq (car misc-list) 'MISC-LIST) (setq misc-list (cdr misc-list)))
(let ((result nil)
(elem nil))
(while (and misc-list (or last (null result)))
(setq elem (car misc-list))
(setq misc-list (cdr misc-list))
(when (cond ((listp type) (and (memq (car elem) type)
(or (null data) (eq data (cdr elem)))))
((symbolp type) (and (eq type (car elem))
(or (null data) (eq data (cdr elem)))))
(t (or (null data) (eq data (cdr elem)))))
(setq result elem)))
result))
(defun lyskom-edit-translate-headers (misc-list)
"Translate result of lyskom-edit-parse-header to something we can send
to lyskom-edit-replace-headers"
......
......@@ -145,7 +145,7 @@
(password . "Your Password? ")
(wrong-password . "Incorrect password.\n")
(are-logged-in . "You have entered LysKOM. Please wait...\n")
(you-have-motd . "\nYou have a note on your door:\n\n")
(you-have-motd . "\nYou have a notice on your mailbox:\n\n")
(lyskom-motd-was-garbed . "\nThe login message does not exist!
The message that was supposed to be shown after login has disappeared.
Please contact the LysKOM administrator.\n")
......@@ -245,7 +245,7 @@ Be ashamed of being You! You have a very good reason.\n\n")
(who-letter-to . "Send a letter to whom? ")
(who-send-text-to . "Send article to which conference? ")
(has-motd . "%#1P has a note on the door:\n\n")
(has-motd . "%#1P has a notice on his/her mailbox:\n\n")
(motd-persist-q . "Send the letter? ")
(who-to-add . "Whom do you want to add? ")
......@@ -310,14 +310,14 @@ and you have finished reading. Please come back later.
===============================================================================
\n")
(what-to-change-pres-you . "Change presentation of who/what (yourself): ")
(who-to-put-motd-for . "Post note on the door of who/what (yourself): ")
(who-to-put-motd-for . "Post notice on who/what (yourself): ")
(cant-get-conf-stat . "Cannot get the status of that conference.\n")
(go-to-conf-p . "Go to conference: ")
(want-become-member . "Do you want to join? ")
(no-ok . "Okiedokie, whatever you say.\n")
(who-to-remove-motd-for . "Remove note from the door of who/what: ")
(who-to-remove-motd-for . "Remove notice from who/what: ")
(conf-all-read . "%#1M - no unread articles.\n")
(no-in-conf . "You are not present in any conference.\n")
......@@ -493,12 +493,12 @@ Read all about it at http://www.lysator.liu.se/history/")
(highest-local-no . "Highest local number: %20#1d\n")
(last-text-time .
"Time of last article: %20#1s (accordning to your cache)\n")
(no-of-motd . "Note on the door in article: %13#1n\n")
(no-of-motd . "Notice in article: %13#1n\n")
(superconf-is-no-name . "Superconference: %25#1m %#3s(%#2M)\n")
(permitted-submitters-no-name . "Allowed authors: %25#1m %#3s(%#2M)\n")
(supervisor-is-no-name . "Supervisor: %30#1p %#3s(%#2P)\n")
(presentation-no . "Presentation: %25#1n\n")
(conf-has-motd . "\n%#1M has a note on the door:\n")
(conf-has-motd . "\n%#1M has a notice on his/her mailbox:\n")
(status-conf-generic . "%-40#1s %#2s\n")
(Everybody . "Everyone")
......@@ -746,7 +746,7 @@ Help: \\[describe-mode] ---")
(added-carbon-copy . "Carbon copy to conference: ")
(added-blank-carbon-copy . "Blind carbon copy to conference: ")
(text-to-comment-q . "Which article to you want to comment? ")
(conf-has-motd-no . "The conference has a note on the door. (%#1d)\n\n%#2s")
(conf-has-motd-no . "The conference has a notice. (%#1d)\n\n%#2s")