async.el 34.4 KB
Newer Older
Linus Tolke's avatar
Linus Tolke committed
1
2
;;;;;
;;;;; $Id$
3
;;;;; Copyright (C) 1991-2002  Lysator Academic Computer Association.
Linus Tolke's avatar
Linus Tolke committed
4
;;;;;
5
;;;;; This file is part of the LysKOM Emacs LISP client.
Linus Tolke's avatar
Linus Tolke committed
6
7
8
;;;;; 
;;;;; LysKOM is free software; you can redistribute it and/or modify it
;;;;; under the terms of the GNU General Public License as published by 
9
;;;;; the Free Software Foundation; either version 2, or (at your option) 
Linus Tolke's avatar
Linus Tolke committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
;;;;; any later version.
;;;;; 
;;;;; LysKOM 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 LysKOM; see the file COPYING.  If not, write to
;;;;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
;;;;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
;;;;; MA 02139, USA.
;;;;;
;;;;; Please mail bug reports to bug-lyskom@lysator.liu.se. 
;;;;;
Per Cederqvist's avatar
.  
Per Cederqvist committed
25
26
27
28
29
30
31
32
33
34
35
36
37
;;;; ================================================================
;;;; ================================================================
;;;;
;;;; File: async.el
;;;;
;;;; These functions implement a nice service that give the user
;;;; continuous messages about what other users are doing and what
;;;; is happening inside the lyskom server.
;;;;
;;;; Author: Linus Tolke
;;;; Entry:  Inge Wallin
;;;;

38
39
40
41
(setq lyskom-clientversion-long 
      (concat lyskom-clientversion-long
	      "$Id$\n"))

Per Cederqvist's avatar
.  
Per Cederqvist committed
42

David Byers's avatar
David Byers committed
43
44
45
46
47
(defun lyskom-is-ignoring-async (buffer message &rest args)
  (save-excursion 
    (set-buffer buffer)
    (let ((tmp (assq message lyskom-ignoring-async-list)))
      (and tmp (equal args (cdr tmp))))))
David Byers's avatar
David Byers committed
48

Per Cederqvist's avatar
.  
Per Cederqvist committed
49
50
51
52
53
(defun lyskom-parse-async (tokens buffer)
  "Parse an asynchronous message from the server.
The message consists of TOKENS tokens. Unknown messages are skipped.
Actions are taken to perform the various tasks that is required on reciept of
an asynchronous message.
David Byers's avatar
David Byers committed
54
55
56
57
58
59

If variable `kom-presence-messages-in-echo-area' is non-nil or some
minibuffer editing is going on then nothing is printed on the message
area. This function is called with the lyskom-unparsed-buffer as
current-buffer. All calls using the lyskom-variables have to be made
using the buffer BUFFER.
Per Cederqvist's avatar
.  
Per Cederqvist committed
60
61
62
63
64
65

Be careful when editing this. All parsing is done with the buffer this
function is called with as the current-buffer, while all calls from
this function shall be with current-buffer the BUFFER."
  (let ((msg-no (lyskom-parse-num)))
    (cond
David Byers's avatar
David Byers committed
66
67
     ((or (eq msg-no 0)
          (eq msg-no 15)) ; New text
Per Cederqvist's avatar
.  
Per Cederqvist committed
68
      (let* ((text-no (lyskom-parse-num))
David Byers's avatar
David Byers committed
69
70
71
	     (text-stat (if (eq msg-no 0)
                            (lyskom-parse-text-stat-old text-no)
                          (lyskom-parse-text-stat text-no))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
72
	(lyskom-save-excursion
73
74
	 (set-buffer buffer)
	 (lyskom-async-new-text text-stat)))) ;
Per Cederqvist's avatar
.  
Per Cederqvist committed
75
76

     ((eq msg-no 1)			; Logout (obsolete)
77
      (lyskom-skip-tokens tokens))
Per Cederqvist's avatar
.  
Per Cederqvist committed
78
79
80
81
82
83
84
85
86
87

     ((eq msg-no 2)			; Login, obsolete.
      (lyskom-skip-tokens tokens))

     ((eq msg-no 3)			; Conference deleted
      (lyskom-skip-tokens tokens))

     ((eq msg-no 4)			; Conference created
      (lyskom-skip-tokens tokens))

88
89
     ((eq msg-no 5)			; A person or conference has
					; changed name.
Per Cederqvist's avatar
.  
Per Cederqvist committed
90
91
92
93
      (let ((conf-no (lyskom-parse-num))
	    (old-name (lyskom-parse-string))
	    (new-name (lyskom-parse-string)))
	(lyskom-save-excursion
94
95
96
97
	 (set-buffer buffer)
	 (if (and lyskom-pers-no (= conf-no lyskom-pers-no))
	     (lyskom-format-insert-before-prompt 
	      'you-changed-name-to
98
	      new-name
99
	      (lyskom-default-button 'conf conf-no)))
100
101
102
103
104
105
	 (let ((cached-stat (cache-get-conf-stat conf-no))
               (cached-ustat (cache-get-uconf-stat conf-no)))
	   (when cached-stat
             (set-conf-stat->name cached-stat new-name))
	   (when cached-ustat
             (set-uconf-stat->name cached-ustat new-name)))
106
107
	 (cond
	  ((lyskom-is-in-minibuffer))
David Byers's avatar
David Byers committed
108
          ((lyskom-show-presence conf-no kom-presence-messages-in-echo-area)
109
110
111
	   (lyskom-message "%s" (lyskom-format 'name-has-changed-to-name
					       old-name new-name))))
	 (cond
David Byers's avatar
David Byers committed
112
	  ((lyskom-show-presence conf-no kom-presence-messages-in-buffer)
113
114
115
116
	   (lyskom-format-insert-before-prompt
	    'name-has-changed-to-name-r 
	    old-name 
	    new-name
117
118
119
	    (lyskom-default-button 'conf conf-no)
	    (and kom-text-properties
		 (list 'face kom-presence-face)))))
120
121
122
123

         ;; Update in the mship-edit buffer

         (lp--maybe-update-entry-for-conf conf-no))))
David Byers's avatar
David Byers committed
124

Per Cederqvist's avatar
.  
Per Cederqvist committed
125
     ((eq msg-no 6)			;i_am_on - something is moving
David Byers's avatar
David Byers committed
126
127
      (lyskom-parse-who-info))

Per Cederqvist's avatar
.  
Per Cederqvist committed
128
129
     ((eq msg-no 7)			; Database is syncing.
      (lyskom-save-excursion
130
131
       (set-buffer buffer)
       ;; I removed the test for kom-presence-messages /david
132
133
       (if (and (not (lyskom-is-in-minibuffer))
                kom-show-sync-messages)
134
135
136
137
138
139
140
141
142
143
	   (lyskom-message "%s" (lyskom-get-string 'database-sync)))
       (setq mode-line-process (lyskom-get-string 'mode-line-saving))
       (setq lyskom-is-saving t)
       ;; I guess the following two lines could be replaced by
       ;; force-mode-line-update in a modern emacs.
       (set-buffer-modified-p (buffer-modified-p))
       (sit-for 0)
       (if (not lyskom-pending-calls)
	   (initiate-get-time 'async nil))))
     
Per Cederqvist's avatar
.  
Per Cederqvist committed
144
     ((eq msg-no 8)			; Forced leave conference
David Byers's avatar
David Byers committed
145
      (let ((conf-no (lyskom-parse-num)))
David Byers's avatar
David Byers committed
146
        (unless (lyskom-is-ignoring-async buffer 8 conf-no)
David Byers's avatar
David Byers committed
147
148
149
150
151
152
          (lyskom-save-excursion
              (set-buffer buffer)
              (initiate-get-conf-stat 'follow
                                      'lyskom-async-forced-leave-conf
                                      conf-no
                                      conf-no)))))
153
     
Per Cederqvist's avatar
.  
Per Cederqvist committed
154
155
     ((eq msg-no 9)			; A person has logged in
      (let ((pers-no (lyskom-parse-num))
156
	    (session-no (lyskom-parse-num)))
Per Cederqvist's avatar
.  
Per Cederqvist committed
157
	(lyskom-save-excursion
158
159
160
161
162
163
164
165
166
167
168
169
	  (set-buffer buffer)
	  (if (and lyskom-pers-no
		   (not (zerop lyskom-pers-no)))
	      (let ((c (make-collector)))
		(initiate-get-conf-stat 'follow 'collector-push pers-no c)
		(initiate-get-static-session-info 'follow 'collector-push 
						  session-no c)
		(lyskom-run 'follow (lambda (c)
				      (lyskom-show-logged-in-person 
				       (elt (collector->value c) 1)
				       (elt (collector->value c) 0)))
			    c))))))
170
171
172

     ;; msg-no 10 is the old broadcast message. No longer used.
     
Per Cederqvist's avatar
.  
Per Cederqvist committed
173
174
175
     ((eq msg-no 11)
      (lyskom-save-excursion
       (set-buffer buffer)
176
       (lyskom-insert-before-prompt (lyskom-get-string-sol 'lyskom-is-full))
177
178
179
       ))
     
     
Per Cederqvist's avatar
.  
Per Cederqvist committed
180
181
182
183
184
185
     ((eq msg-no 12)			; Message to the user (or everybody)
      (let ((recipient (lyskom-parse-num))
	    (sender (lyskom-parse-num))
	    (message (lyskom-parse-string)))
	(lyskom-save-excursion
	 (set-buffer buffer)
186
187
188
189
190
191
192
193
194
195
196
	 (if (zerop recipient)
	     (initiate-get-conf-stat 'async
				     'lyskom-handle-personal-message
				     sender
				     0
				     message)
	   (lyskom-collect 'async)
	   (initiate-get-conf-stat 'async nil sender)
	   (initiate-get-conf-stat 'async nil recipient)
	   (lyskom-use 'async 'lyskom-handle-personal-message message)))))
     
Per Cederqvist's avatar
.  
Per Cederqvist committed
197
198
199
200
     ((eq msg-no 13)			; New logout
      (let ((pers-no (lyskom-parse-num))
	    (session-no (lyskom-parse-num)))
	(lyskom-save-excursion
201
202
203
	 (set-buffer buffer)
	 (if (and lyskom-pers-no
		  (not (zerop lyskom-pers-no))
David Byers's avatar
David Byers committed
204
		  (or (lyskom-show-presence pers-no kom-presence-messages-in-echo-area)
David Byers's avatar
David Byers committed
205
		      (lyskom-show-presence pers-no kom-presence-messages-in-buffer)))
206
207
	     (initiate-get-conf-stat 'follow
				     'lyskom-show-logged-out-person
David Byers's avatar
David Byers committed
208
				     pers-no session-no)))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
209

David Byers's avatar
David Byers committed
210
     ((eq msg-no 14)                    ; Deleted text
211
      (let* ((text-no (lyskom-parse-num))
David Byers's avatar
David Byers committed
212
213
214
215
216
217
218
219
220
            (text-stat (lyskom-parse-text-stat text-no)))
        (lyskom-save-excursion
         (set-buffer buffer)
         (lyskom-async-deleted-text text-stat))))

     ((eq msg-no 16)                    ; New recipient
      (let ((text-no (lyskom-parse-num))
            (conf-no (lyskom-parse-num))
            (misc-type (lyskom-parse-num)))
221
222
223
224
225
226
227
228
229
230
231
232
233
        (cond ((eq misc-type 0) (setq misc-type 'RECPT))
              ((eq misc-type 1) (setq misc-type 'CC-RECPT))
              ((eq misc-type 15) (setq misc-type 'BCC-RECPT)))
        (when (symbolp misc-type)
          (lyskom-save-excursion
            (set-buffer buffer)
            (cache-del-text-stat text-no)
            (cache-del-conf-stat conf-no)
            (initiate-get-text-stat 'follow
                                    'lyskom-async-new-recipient
                                    text-no
                                    text-no conf-no misc-type)
            ))))
David Byers's avatar
David Byers committed
234
235
236
237
238
239
240
241
242

     ((eq msg-no 17)                    ; Deleted recipient
      (let ((text-no (lyskom-parse-num))
            (conf-no (lyskom-parse-num))
            (misc-type (lyskom-parse-num)))
        (lyskom-save-excursion
         (set-buffer buffer)
          (cache-del-conf-stat conf-no)
          (cache-del-text-stat text-no)
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
          ;; FIXME: Code here.
          ;; FIXME: This implementation sucks. There is no need to
          ;; FIXME:   remove the text from the cache. Just modify it.
          ;; FIXME: If we cache maps somewhere, we'll want to remove
          ;; FIXME:   the text from the appropriate map.
          ;; FIXME: If we want to get *really* picky, and the user is
          ;; FIXME:   doing a review texts to conference, and this text
          ;; FIXME:   has been found, remove this text from those
          ;; FIXME:   lists too (probably not worth the effort).
          ;; FIXME: The text should be removed from the reading lists
          ;; FIXME:   if it is there because we are reading the conf
          ;; FIXME:   that is being removed. Take care not to lose
          ;; FIXME:   any comments to it though...
          ;; FIXME: The unread counter for the conference should be
          ;; FIXME:   decreased like it is in async-deleted-text (i hope).
258
          (lyskom-ignore misc-type)
David Byers's avatar
David Byers committed
259
260
261
262
263
         )))

     ((eq msg-no 18)                    ; New membership
      (let ((pers-no (lyskom-parse-num))
            (conf-no (lyskom-parse-num)))
David Byers's avatar
David Byers committed
264
        (unless (lyskom-is-ignoring-async buffer 18 pers-no conf-no)
David Byers's avatar
David Byers committed
265
266
267
268
          (lyskom-save-excursion
              (set-buffer buffer)
              (cache-del-pers-stat pers-no)
              (cache-del-conf-stat conf-no)
David Byers's avatar
David Byers committed
269
              (when (eq pers-no lyskom-pers-no)
David Byers's avatar
David Byers committed
270
271
                (lyskom-collect 'follow)
                (initiate-get-conf-stat 'follow nil conf-no)
272
                (initiate-query-read-texts 'follow nil pers-no conf-no t 0)
David Byers's avatar
David Byers committed
273
274
275
                (lyskom-use 'follow 'lyskom-async-new-membership pers-no conf-no))
            ))))

276
277
278
279
280
281
     ((eq msg-no 19)                    ; async-new-user-area
      (let* ((pers-no (lyskom-parse-num))
             (old-user-area (lyskom-parse-num))
             (new-user-area (lyskom-parse-num)))
        (lyskom-save-excursion
          (set-buffer buffer)
282
283
          (when (and (eq pers-no lyskom-pers-no)
                     (not (eq lyskom-current-user-area new-user-area)))
284
285
286
287
288
            (initiate-get-pers-stat 'follow 
                                    'lyskom-async-new-user-area
                                    pers-no
                                    old-user-area
                                    new-user-area)))))
289
290
291
292
293
294

     ((eq msg-no 20)                    ; async-new-presentation
      (let* ((conf-no (lyskom-parse-num))
             (old-pres (lyskom-parse-num))
             (new-pres (lyskom-parse-num)))
        (lyskom-ignore old-pres)
295
296
297
298
299
300
        (lyskom-save-excursion
          (set-buffer buffer)
          (when (cache-get-conf-stat conf-no)
            (set-conf-stat->presentation (cache-get-conf-stat conf-no)
                                         new-pres)
            (lp--maybe-update-entry-for-conf conf-no)))))
301
302
303
304
305

     ((eq msg-no 21)                    ; async-new-motd
      (let* ((conf-no (lyskom-parse-num))
             (old-motd (lyskom-parse-num))
             (new-motd (lyskom-parse-num)))
306
307
308
309
310
311
        (lyskom-save-excursion
          (set-buffer buffer)
          (lyskom-ignore old-motd)
          (when (cache-get-conf-stat conf-no)
            (set-conf-stat->msg-of-day (cache-get-conf-stat conf-no)
                                       new-motd)))))
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
     ((eq msg-no 22)                    ; async-text-aux-changes
      (let* ((text-no (lyskom-parse-num))
             (deleted-aux (lyskom-parse-aux-item-list))
             (added-aux (lyskom-parse-aux-item-list))
             (text-stat nil))
        (lyskom-save-excursion
          (set-buffer buffer)
          (setq text-stat (cache-get-text-stat text-no))
          (when text-stat
            (set-text-stat->aux-items text-stat
                                      (lyskom-aux-item-modify-list
                                       (text-stat->aux-items text-stat)
                                       deleted-aux
                                       added-aux))))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
327
328
329
     (t
      (lyskom-skip-tokens tokens)))))

330
331
332
333
334
335
336
337
338
339
(defun lyskom-async-new-user-area (pers-stat old-user-area new-user-area)
  (when pers-stat
    (let ((need-reread (and (eq lyskom-pers-no (pers-stat->pers-no pers-stat))
                            (not (eq lyskom-current-user-area new-user-area)))))
  ;; Update the cache
  (set-pers-stat->user-area pers-stat new-user-area)
  ;; Re-read
  (when (and need-reread
             new-user-area
             (not (zerop new-user-area)))
340
341
342
343
344
345
    (initiate-get-text 'follow (lambda (text)
                                 (when text
                                   (lyskom-format-insert-before-prompt 'reading-settings-from-server)
                                   (setq lyskom-saved-unknown-variables
                                    (lyskom-read-options-eval text))))
                       new-user-area)))))
346

Per Cederqvist's avatar
.  
Per Cederqvist committed
347

David Byers's avatar
David Byers committed
348
349
350
351
(defun lyskom-async-forced-leave-conf (conf-stat conf-no)
  (if conf-stat
      (lyskom-format-insert-before-prompt 'no-longer-member conf-stat)
    (lyskom-format-insert-before-prompt 'no-longer-member-n conf-no))
David Byers's avatar
David Byers committed
352
  (lyskom-remove-membership conf-no)
David Byers's avatar
David Byers committed
353
  (when (eq conf-no lyskom-current-conf)
354
    (lyskom-leave-current-conf))
David Byers's avatar
David Byers committed
355
356
357
358
359
360
361
  (read-list-delete-read-info conf-no lyskom-to-do-list)
  (lyskom-update-prompt))

(defun lyskom-async-new-membership (conf-conf-stat
                                    membership
                                    pers-no 
                                    conf-no)
David Byers's avatar
David Byers committed
362
363
364
  ;; Are we already members?

  (when membership
David Byers's avatar
David Byers committed
365
366
    (let ((cur-mship (lyskom-try-get-membership conf-no t))
          (mship-type (membership->type membership)))
David Byers's avatar
David Byers committed
367
368
      (unless cur-mship
        (lyskom-format-insert-before-prompt 
David Byers's avatar
David Byers committed
369
370
371
372
373
         (cond ((membership-type->invitation mship-type)
                'have-become-invited-member)
               ((membership-type->passive mship-type)
                'have-become-passive-member)
               (t 'have-become-member))
David Byers's avatar
David Byers committed
374
375
376
         conf-conf-stat))

    (cond ((membership-type->passive (membership->type membership))
David Byers's avatar
David Byers committed
377
           (lyskom-replace-membership membership)
David Byers's avatar
David Byers committed
378
           (when (eq conf-no lyskom-current-conf)
379
             (lyskom-leave-current-conf))
David Byers's avatar
David Byers committed
380
381
382
383
384
385
386
387
           (read-list-delete-read-info conf-no lyskom-to-do-list)
           (lyskom-update-prompt))

          ;; Already a member. Perhaps the priority changed.
          ;; Update the cache. The reading list is probably also
          ;; not quite correct since the priority might have changed

          (cur-mship
388
389
           (lyskom-replace-membership membership)
           (lyskom-sort-to-do-list))
David Byers's avatar
David Byers committed
390
391
392

          ;; Not a member. Completely new. Deal with it.
          (t (lyskom-add-membership membership conf-no))))))
David Byers's avatar
David Byers committed
393
394
    

David Byers's avatar
David Byers committed
395
(defun lyskom-show-presence (num flag)
396
397
398
  "Returns non-nil if presence messages for NUM should be displayed
according to the value of FLAG."
  (cond ((null flag) nil)
David Byers's avatar
David Byers committed
399
        ((eq flag 'friends) (memq num kom-friends))
400
401
402
        ((eq flag 'morons) (memq num kom-morons))
        ((eq flag 'friends-and-morons) (or (memq num kom-friends)
                                           (memq num kom-morons)))
403
        ((listp flag) (lyskom-indirect-assq num flag))
David Byers's avatar
David Byers committed
404
        (t t)))
405
406


407
(defun lyskom-show-logged-in-person (conf-stat session-info)
Per Cederqvist's avatar
.  
Per Cederqvist committed
408
  "Visa p} kommandoraden vem som loggat in."
David Byers's avatar
David Byers committed
409
410
411
412
413
  (let ((server (lyskom-session-nickname))
	(login-when-date (let ((kom-print-relative-dates nil))
			   (lyskom-format-time 'date)))
	(login-when-time (let ((kom-print-relative-dates nil))
			   (lyskom-format-time 'time))))
414
415
416
    (cond
     ((lyskom-is-in-minibuffer))
     ((lyskom-show-presence (conf-stat->conf-no conf-stat)
David Byers's avatar
David Byers committed
417
                            kom-presence-messages-in-echo-area)
418
419
420
421
      (lyskom-message
       "%s"
       (lyskom-format 'has-entered
                      (or conf-stat
422
                          (lyskom-get-string 'unknown-person))
423
424
                      server
                      ))))
425

426
427
428
    (cond
     ((lyskom-show-presence (conf-stat->conf-no conf-stat)
                            kom-presence-messages-in-buffer)
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
      (lyskom-format-insert-before-prompt 
       'has-entered-r
       (or conf-stat 
	   (lyskom-get-string
	    'unknown-person))
       (and kom-text-properties
	    (list 'face kom-presence-face))
       server
       login-when-date
       login-when-time
       (and session-info
	    nil
	    (lyskom-combine-username 
	     (static-session-info->username session-info)
	     (static-session-info->ident-user session-info)
	     (static-session-info->hostname session-info))))))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
445
446
447
448


(defun lyskom-show-logged-out-person (conf-stat session-no)
  "Visa p} kommandoraden vem som loggat ut."
David Byers's avatar
David Byers committed
449
450
451
452
453
  (let ((server (lyskom-session-nickname))
	(logout-when-date (let ((kom-print-relative-dates nil))
			    (lyskom-format-time 'date)))
	(logout-when-time (let ((kom-print-relative-dates nil))
			    (lyskom-format-time 'time))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
454
455
  (cond
   ((lyskom-is-in-minibuffer))
456
   ((lyskom-show-presence (conf-stat->conf-no conf-stat) 
David Byers's avatar
David Byers committed
457
                          kom-presence-messages-in-echo-area)
David Kågedal's avatar
David Kågedal committed
458
459
460
    (lyskom-message
     "%s"
     (lyskom-format 'has-left (or conf-stat
461
				  (lyskom-get-string 'unknown-person))
462
                    server))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
463
  (cond
464
465
   ((lyskom-show-presence (conf-stat->conf-no conf-stat)
                          kom-presence-messages-in-buffer)
David Byers's avatar
David Byers committed
466
467
468
469
470
471
472
473
474
    (lyskom-format-insert-before-prompt 'has-left-r 
					(or conf-stat
					    (lyskom-get-string
					     'unknown-person))
					(and kom-text-properties
					     (list 'face kom-presence-face))
					server
					logout-when-date
					logout-when-time)))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
475
476


477

Per Cederqvist's avatar
.  
Per Cederqvist committed
478
479
(defun lyskom-is-in-minibuffer ()
  "Returns non-nil if I am using the minibuffer for some reading."
David Kågedal's avatar
David Kågedal committed
480
  (or lyskom-inhibit-minibuffer-messages
481
      cursor-in-echo-area
David Kågedal's avatar
David Kågedal committed
482
      (not (zerop (minibuffer-depth)))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
483
484


485
 (defun lyskom-show-personal-message (sender recipient message 
486
                                            &optional when nobeep)
Per Cederqvist's avatar
.  
Per Cederqvist committed
487
  "Insert a personal message into the lyskom buffer.
Joel Rosdahl's avatar
Joel Rosdahl committed
488
Args: SENDER: conf-stat for the person sending the message.
489
490
      RECIPIENT: 0 if this message is for everybody, otherwise the conf-stat
                 of the recipient.
491
      MESSAGE: A string containing the message.
492
      WHEN: Optional time of arrival. A lyskom time structure.
493
494
495
      NOBEEP: True means don't beep. No matter what."
  (lyskom-insert-personal-message sender recipient message when nobeep)
  (setq lyskom-last-personal-message-sender 
496
        (if (stringp sender) sender (conf-stat->conf-no sender)))
497
498
499
  (setq lyskom-last-group-message-recipient 
        (if (and recipient
                 (not (eq 0 recipient))
500
501
                 (not (eq (conf-stat->conf-no recipient) lyskom-pers-no)))
            (conf-stat->conf-no recipient)
502
          nil))
David Byers's avatar
David Byers committed
503
504
  (run-hooks 'lyskom-personal-message-hook)
  (run-hooks 'kom-personal-message-hook))
505

506

507
508
(defun lyskom-insert-personal-message (sender recipient message
                                              &optional when nobeep)
509
  "Insert a personal message in the current buffer.
510
Arguments: SENDER RECIPIENT MESSAGE.
Joel Rosdahl's avatar
Joel Rosdahl committed
511
512
513
SENDER is a conf-stat (possibly nil).
RECIPIENT is 0 if the message is public, otherwise the conf-stat of the
recipient.
514
MESSAGE is a string containing the message.
515
516
WHEN, if given, is the time when the message arrived. It must be a lyskom
time structure.
517
Non-nil NOBEEP means don't beep."
518
  (lyskom-handle-as-personal-message
519
520
521
522
523
524
525
526
527
528
   (lyskom-format-as-personal-message sender recipient message when nobeep)
   (conf-stat->conf-no sender) 
   nil))

(defun lyskom-format-as-personal-message (sender 
                                          recipient
                                          message
                                          &optional when nobeep)
  "Formats a personal message, returning it as a string.
Arguments: SENDER RECIPIENT MESSAGE.
Joel Rosdahl's avatar
Joel Rosdahl committed
529
530
531
SENDER is a conf-stat (possibly nil).
RECIPIENT is 0 if the message is public, otherwise the conf-stat of the
recipient.
532
MESSAGE is a string containing the message.
533
534
WHEN, if given, is the time when the message arrived. It must be a lyskom
time structure.
535
Non-nil NOBEEP means don't beep."
536
  (let ((lyskom-last-text-format-flags nil)
537
538
        (now (lyskom-current-client-time)))
    (when (null when) (setq when (lyskom-current-client-time)))
539
    (if (or kom-show-personal-message-date
540
541
542
            (not (eq (time->mday when) (time->mday now)))
            (not (eq (time->mon when) (time->mon now)))
            (not (eq (time->year when) (time->year now))))
543
544
545
        (setq when (let ((kom-print-relative-dates nil))
                     (lyskom-format-time 'date-and-time when)))
      (setq when (lyskom-format-time 'time when)))
546

547
548
549
    (setq nobeep (or nobeep (and kom-ansaphone-on
                                 kom-silent-ansaphone)))

David Kågedal's avatar
David Kågedal committed
550
551
552
553
554
    (cond ((or (null recipient)		; Have been seen to be nil when
                                        ; listing recorded
                                        ; messages. Should it be?
                                        ; /davidk
	       (eq recipient 0))	; Public message
555
           (if (not nobeep) (lyskom-beep kom-ding-on-common-messages sender))
556
           (lyskom-format (lyskom-get-string-sol 'message-broadcast)
557
558
559
560
561
                          (cond
                           ((stringp sender) sender)
                           (sender sender)
                           (t (lyskom-get-string 'unknown)))
                          message
David Byers's avatar
David Byers committed
562
                          when
563
                          (when kom-async-highlight-dashed-lines
564
565
                            `(face ,(or kom-async-dashed-lines-face
                                        lyskom-default-async-dashed-lines-face)))
566
                          (when kom-async-highlight-text-body
567
568
                            `(face ,(or kom-async-text-body-face
                                        lyskom-default-async-text-body-face)))))
569
          ((= (conf-stat->conf-no recipient) lyskom-pers-no) ; Private
570
           (if (not nobeep) (lyskom-beep kom-ding-on-personal-messages sender))
571
           (lyskom-format (lyskom-get-string-sol 'message-from)
572
573
574
575
576
                          (cond
                           ((stringp sender) sender)
                           (sender sender)
                           (t (lyskom-get-string 'unknown)))
                          message
David Byers's avatar
David Byers committed
577
                          when
578
                          (when kom-async-highlight-dashed-lines
579
580
                            `(face ,(or kom-async-dashed-lines-face
                                        lyskom-default-async-dashed-lines-face)))
581
                          (when kom-async-highlight-text-body
582
583
                            `(face ,(or kom-async-text-body-face
                                        lyskom-default-async-text-body-face)))))
584
          (t                            ; Group message
585
           (if (not nobeep) (lyskom-beep kom-ding-on-group-messages recipient))
586
           (lyskom-format (lyskom-get-string-sol 'message-from-to)
587
588
589
                          message
                          (cond
                           ((stringp sender) sender)
David Byers's avatar
David Byers committed
590
                           (sender  sender)
591
592
593
                           (t (lyskom-get-string 'unknown)))
                          (cond
                           ((stringp recipient) recipient)
David Byers's avatar
David Byers committed
594
                           (recipient recipient)
595
                           (t (lyskom-get-string 'unknown)))
David Byers's avatar
David Byers committed
596
                          when
597
                          (when kom-async-highlight-dashed-lines
598
599
                            `(face ,(or kom-async-dashed-lines-face
                                        lyskom-default-async-dashed-lines-face)))
600
                          (when kom-async-highlight-text-body
601
602
                            `(face ,(or kom-async-text-body-face
                                        lyskom-default-async-text-body-face))))))))
603

604
605

  
606
607
608
609
(defun lyskom-handle-as-personal-message (string from &optional filter)
  "Insert STRING as a personal message and beep if not from me and
supposed to. The buffer, is chosen according to the
kom-show-personal-messages-in-buffer variable value. The text is
610
converted, before insertion."
611
612
613
614
615
  (if (and filter
           (or
            (eq 0 (string-match "^Remote-command: [0-9]+ [0-9]+\n" string))
            (eq 0 (string-match "^Auto-reply:\n" string))))
      nil
616
617
618
619
620
621
622
623
    (let ((pop kom-pop-personal-messages))
      (lyskom-save-excursion
       (cond
	((eq kom-show-personal-messages-in-buffer t)
	 (lyskom-insert-before-prompt string)
	 (if pop (display-buffer (current-buffer))))
	((null kom-show-personal-messages-in-buffer))
	(t
624
625
626
627
628
629
630
631
632
633
634
635
636
637
         (let ((inhibit-read-only t))
           (let ((message-buffer
                  (car (lyskom-buffers-of-category 'personal-messages))))
             (if message-buffer
                 (set-buffer message-buffer)
               (set-buffer (lyskom-get-buffer-create 
                            'personal-messages 
                            kom-show-personal-messages-in-buffer t))
               (lyskom-view-mode)
               (setq buffer-read-only t)))
           (goto-char (point-max))
           (lyskom-insert string )
           (if pop
               (save-selected-window
David Byers's avatar
David Byers committed
638
639
                 (select-window (lyskom-display-buffer (current-buffer)
                                                       (not (eq pop t))))
640
641
                 (goto-char (point-max))
                 (recenter -1))))))))))
642
  
Per Cederqvist's avatar
.  
Per Cederqvist committed
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661

;;; ================================================================
;;; New recipient

;;; The text stat and might have been cached and thus invalid. Check
;;; for this. The conf-stat for the conf-no is almost certainly 
;;; invalid.

(defun lyskom-async-new-recipient (text-stat text-no conf-no misc-type)
  "Handle a new recipient message"

  ;; Check if we are added. A new letter!
  (when (and (eq  conf-no lyskom-pers-no)
             (not (eq (text-stat->author text-stat) lyskom-pers-no)))
    (lyskom-beep kom-ding-on-new-letter))

  ;; If the text is read in another conference, mark it as read here too
  ;; unless the new recipient is the mailbox
662
663
  (if (and kom-mark-read-texts-as-read-in-new-recipient
           (lyskom-text-read-at-least-once-p text-stat t)
664
           (not (eq conf-no lyskom-pers-no)))
665
666
667
668
669
670
671
      (lyskom-traverse misc-info (text-stat->misc-info-list text-stat)
        (when (and (memq (misc-info->type misc-info) lyskom-recpt-types-list)
                   (eq conf-no (misc-info->recipient-no misc-info)))
          (initiate-mark-as-read 'follow
                                 nil
                                 conf-no 
                                 (list (misc-info->local-no misc-info)))))
672
673
674
675
676
677
678

    ;; Text is previously unread or in the mailbox
    (let ((local-no nil))
      (lyskom-traverse misc-info (text-stat->misc-info-list text-stat)
        (when (and (eq (misc-info->type misc-info) misc-type)
                   (eq (misc-info->recipient-no misc-info) conf-no))
          (setq local-no (misc-info->local-no misc-info))))
David Byers's avatar
David Byers committed
679
680
681
682
683
684
685
686
      (when local-no
        (initiate-get-conf-stat 'async 'lyskom-add-new-text
                                conf-no
                                text-no
                                local-no)
        (lyskom-prefetch-text-all text-no)
        (lyskom-run 'async 'lyskom-default-new-recipient-hook text-stat)
        (lyskom-run 'async 'lyskom-prefetch-and-print-prompt)))))
687
688
689
690
691

(defun lyskom-default-new-recipient-hook (text-stat)
  (when (and (not lyskom-dont-change-prompt) ;We shall change it
             (not lyskom-executing-command)) ;We have time to do it.
    (lyskom-update-prompt))
David Byers's avatar
David Byers committed
692
693
  (run-hooks 'lyskom-new-recipient-hook)
  (run-hooks 'kom-new-recipient-hook))
694
695
696



Per Cederqvist's avatar
.  
Per Cederqvist committed
697
;;; ================================================================
David Byers's avatar
David Byers committed
698
;;;            Functions for dealing with a new or deleted text
Per Cederqvist's avatar
.  
Per Cederqvist committed
699
700
701
702


(defun lyskom-default-new-text-hook (text-stat)
  "Print a message if the user was waiting. Change the prompt. run hooks."
703
704
  (if (and (not lyskom-dont-change-prompt) ;We shall change it
	   (not lyskom-executing-command)) ;We have time to do it.
705
      (lyskom-update-prompt))
706

Per Cederqvist's avatar
.  
Per Cederqvist committed
707
708
  (let ((no-message nil))
    (run-hooks 'lyskom-new-text-hook)
David Byers's avatar
David Byers committed
709
    (run-hooks 'kom-new-text-hook)
Per Cederqvist's avatar
.  
Per Cederqvist committed
710
711
712
713
  
    (if (and (not no-message)
	     lyskom-is-waiting
	     (not (lyskom-is-in-minibuffer)))
714
715
	(lyskom-message "%s" (lyskom-format 'text-is-created
					    (text-stat->text-no text-stat))))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
716

David Byers's avatar
David Byers committed
717
718
719
720
721
(defun lyskom-default-deleted-text-hook (text-stat)
  "Update the prompt. Run hooks"
  (if (and (not lyskom-dont-change-prompt) ;We shall change it
	   (not lyskom-executing-command)) ;We have time to do it.
      (lyskom-update-prompt))
David Byers's avatar
David Byers committed
722
723
  (run-hooks 'lyskom-deleted-text-hook)
  (run-hooks 'kom-deleted-text-hook))
David Byers's avatar
David Byers committed
724

Per Cederqvist's avatar
.  
Per Cederqvist committed
725
726
727
728
729
(defun lyskom-async-new-text (text-stat)
  "Take care of a message that a new text has been created."
  (cache-del-pers-stat (text-stat->author text-stat)) ;+++Borde {ndra i cachen i st{llet.
  
  (lyskom-traverse
730
731
732
      misc-info (text-stat->misc-info-list text-stat)
    (let ((type (misc-info->type misc-info)))
      (cond
733
       ((memq type lyskom-recpt-types-list)
734
735
	;; add on lyskom-reading-list and lyskom-to-do-list if
	;; this recipient is a recipient that has been checked.
736
737
738
739
740
741
	(if (and (eq  (misc-info->recipient-no misc-info)
                      lyskom-pers-no)
                 (not (eq (text-stat->author text-stat)
                          lyskom-pers-no)))
            (lyskom-beep kom-ding-on-new-letter))
        (initiate-get-conf-stat 'async 'lyskom-add-new-text
742
743
744
745
746
747
748
749
750
751
752
753
				(misc-info->recipient-no misc-info)
				(text-stat->text-no text-stat)
				(misc-info->local-no misc-info)))
       ((eq type 'COMM-TO)
	(cache-del-text-stat (misc-info->comm-to misc-info)))
       ((eq type 'FOOTN-TO)
	(cache-del-text-stat (misc-info->footn-to misc-info)))
       (t
	(signal 'lyskom-internal-error
		(list 'lyskom-async-new-text
		      "Unexpected misc-info in new text "
		      type))))))
Per Cederqvist's avatar
.  
Per Cederqvist committed
754

755
  (lyskom-prefetch-text-stat-all text-stat)
756

757
  ;; Give a message if the user is waiting. Update the prompt.
758
759
760
  (lyskom-run 'async 'lyskom-default-new-text-hook text-stat)

  (lyskom-run 'async 'lyskom-prefetch-and-print-prompt))
761
762


David Byers's avatar
David Byers committed
763
764
765
766
767
768
(defun lyskom-async-deleted-text (text-stat)
  "Take care of a message that a text has been deleted."
      (cache-del-pers-stat (text-stat->author text-stat))
      (lyskom-traverse
          misc-info (text-stat->misc-info-list text-stat)
        (let ((type (misc-info->type misc-info)))
769
          (cond ((memq type lyskom-recpt-types-list)
David Byers's avatar
David Byers committed
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
                 (initiate-get-conf-stat 'async 'lyskom-delete-old-text
                                         (misc-info->recipient-no misc-info)
                                         text-stat
                                         (misc-info->local-no misc-info)))
                ((eq type 'COMM-TO)
                 (cache-del-text-stat (misc-info->comm-to misc-info)))
                ((eq type 'FOOTN-TO)
                 (cache-del-text-stat (misc-info->footn-to misc-info))))))
      (lyskom-run 'async 'lyskom-default-deleted-text-hook text-stat)
      (lyskom-run 'async 'lyskom-prefetch-and-print-prompt))

(defun lyskom-delete-old-text (recipient text-stat local-no)
  "RECIPIENT is a conf-stat and previous recipient of TEXT-STAT.
This call is used in response to a deleted text message"
  (when recipient

    ;; Update the cache

    (cache-del-text-stat (text-stat->text-no text-stat))
    (cache-del-text (text-stat->text-no text-stat))
    (set-conf-stat->no-of-texts 
     recipient
     (min (conf-stat->no-of-texts recipient)
          (min (conf-stat->no-of-texts recipient)
               (1- (conf-stat->no-of-texts recipient)))))

    ;; Update the read lists

    (let ((membership (lyskom-try-get-membership
                       (conf-stat->conf-no recipient))))
      (when (and membership
                 (lyskom-visible-membership membership))
802
        (read-list-delete-text (text-stat->text-no text-stat) 
David Byers's avatar
David Byers committed
803
804
805
                               lyskom-to-do-list)
        (read-list-delete-text (text-stat->text-no text-stat) 
                               lyskom-reading-list)))
David Byers's avatar
David Byers committed
806
807
808
809
810

    (lyskom-set-mode-line)))
                 

    
Per Cederqvist's avatar
.  
Per Cederqvist committed
811
812
813
814
815
816
817
818
819

(defun lyskom-add-new-text (recipient text-no local-no)
  "RECIPIENT is a conf-stat and recipient of TEXT-NO.
Args: RECIPIENT TEXT-NO LOCAL-NO.
LOCAL-NO is the texts local number in RECIPIENT. This info is used
to update the no-of-texts field in the cache.

Also add this info in lyskom-to-do-list if info about RECIPIENT as been
fetched. Does not try to print prompt or do any prefetch. That will be
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
done after all the confs has been handled.

If recipient is nil this means we are crossposting to a protected conference.
In that case, just discard this call."

  (cond
   (recipient				;+++ Annan felhantering.
    ;; Update the cache.

    (set-conf-stat->no-of-texts
     recipient
     (max (conf-stat->no-of-texts recipient)
	  (+ local-no -1
	     (- (conf-stat->first-local-no recipient)))))

    ;; Update the read-lists.

837
838
839
840
    ;; Prefetch thoughts:
    ;; We need a way to check if a conferences is fetched.
    ;; davidk /960924
    
841
842
843
    (let ((membership (lyskom-try-get-membership
		       (conf-stat->conf-no recipient))))
      (if (and membership
844
	       ;; (lyskom-conf-fetched-p (conf-stat->conf-no recipient))
845
	       (lyskom-visible-membership membership)
846
847
848
849
850
851
852
	       (not (read-list-enter-text text-no recipient
					  lyskom-to-do-list)))
	  ;; If we have already read all texts in the conference or the
	  ;; text has not been prefetched
	  (let ((info (lyskom-create-read-info
		       'CONF
		       recipient
853
		       (membership->priority membership)
854
855
856
		       (lyskom-create-text-list (list text-no)))))
	    (read-list-enter-read-info info lyskom-to-do-list)
	    (if (= lyskom-current-conf (conf-stat->conf-no recipient))
857
		(read-list-enter-read-info info lyskom-reading-list)))
David Byers's avatar
David Byers committed
858
859
860
861
862
863
864
865

        ;; We don't have the membership yet. Treat it as an unread conf
        ;; and prefetch it. This might result in two prefetches of the
        ;; same conference, but the prefetch should be able to deal with
        ;; that.
        (unless membership
          (lyskom-prefetch-one-membership (conf-stat->conf-no recipient)
                                          lyskom-pers-no))))
866
867

    (lyskom-set-mode-line))))
868
869
870
871
872


;;; Local Variables: 
;;; eval: (put 'lyskom-traverse 'lisp-indent-hook 2)
;;; end: