~ubuntu-branches/ubuntu/lucid/mew-beta/lucid

1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1
;;; mew-draft.el --- Draft mode for Mew
2
3
;; Author:  Kazu Yamamoto <Kazu@Mew.org>
4
;; Created: Oct  2, 1996
5
6
;;; Code:
7
8
(require 'mew)
9
10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
;;;
12
;;; Draft info
13
;;;
14
15
(defvar mew-tinfo-list
16
  '("header-keymap" "attach-keymap" "case" "encrypted-p" "privacy-err"
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
17
    "encode-err" "privacy-type" "hdr-file" "field-del" "other-frame"
18
    "preserved-header" "src-folder" "flowed" "use-flowed"))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
19
20
(mew-blinfo-defun 'mew-tinfo mew-tinfo-list)
21
22
23
(defvar mew-draft-mode-syntax-table nil
24
  "*Syntax table used while in Draft mode.")
25
26
(unless mew-draft-mode-syntax-table
27
  (setq mew-draft-mode-syntax-table (make-syntax-table text-mode-syntax-table))
28
  (modify-syntax-entry ?% "." mew-draft-mode-syntax-table))
29
30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31
;;;
32
;;; Draft mode
33
;;;
34
35
(defun mew-draft-set-local-variables ()
36
  (auto-save-mode mew-draft-mode-auto-save)
37
  (make-local-variable 'completion-ignore-case)
38
  (make-local-variable 'paragraph-start)
39
  (setq paragraph-start (concat mew-eoh "\\|[ \t]*$\\|" page-delimiter))
40
  (make-local-variable 'paragraph-separate)
41
  (setq paragraph-separate paragraph-start)
42
  (make-local-variable 'mail-header-separator)
43
  (setq mail-header-separator mew-header-separator)
44
  (make-local-variable 'comment-start)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
45
  (setq comment-start mew-comment-start)
46
  (make-local-variable 'comment-start-skip)
47
  (setq comment-start-skip mew-comment-start-skip)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
48
  (add-hook 'after-change-functions 'mew-draft-dynamic-highlight nil 'local)
49
  (if (boundp 'write-file-functions)
50
      (add-hook 'write-file-functions 'mew-encode-make-backup nil 'local)
51
    (add-hook 'local-write-file-hooks 'mew-encode-make-backup))
52
  (make-local-variable 'after-save-hook)
53
  (when mew-require-final-newline
54
    (make-local-variable 'require-final-newline)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
55
    (setq require-final-newline t))
56
  (when (featurep 'dnd)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
57
    (make-local-variable 'dnd-protocol-alist)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
58
    (setq dnd-protocol-alist
59
	  (append '(("^file:///" . mew-draft-dnd-handle-local-file)
60
		    ("^file://"  . mew-draft-dnd-handle-file)
61
		    ("^file:"    . mew-draft-dnd-handle-local-file))
62
		  dnd-protocol-alist))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
63
64
(defun mew-draft-mode (&optional encrypted)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
65
  "A major mode for composing a MIME message.
66
67
\\{mew-draft-mode-map}"
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
68
  (interactive)
69
  (setq major-mode 'mew-draft-mode)
1.2.4 by Tatsuya Kinoshita
Import upstream version 6.2.52
70
  (setq mode-line-buffer-identification (mew-mode-line-id))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
71
  (mew-draft-set-local-variables)
72
  (use-local-map mew-draft-mode-map)
73
  (set-syntax-table mew-draft-mode-syntax-table)
74
  (cd (expand-file-name mew-home))
75
  (mew-draft-setup-decoration)
76
  (mew-ainfo-set-icon (file-name-nondirectory (buffer-file-name)))
77
  (mew-tinfo-set-encrypted-p encrypted)
78
  (mew-tinfo-set-privacy-err nil)
79
  (mew-tinfo-set-privacy-type nil)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
80
  (mew-tinfo-set-use-flowed (mew-use-format-flowed (mew-tinfo-get-case)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
81
  (mew-draft-mode-name) ;; must be after (mew-tinfo-set-encrypted-p encrypted)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
82
  (run-hooks 'text-mode-hook 'mew-draft-mode-hook)
83
  ;; auto-fill-function is set by mew-draft-mode-hook
84
  (when auto-fill-function
85
    (make-local-variable 'auto-fill-function)
86
    (setq auto-fill-function 'mew-draft-auto-fill))
87
  (setq buffer-undo-list nil))
88
89
(defun mew-draft-mode-name (&optional header)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
90
  (let ((case (mew-tinfo-get-case))
91
	pcdb sub)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
92
    (cond
93
     ((or (mew-tinfo-get-privacy-type) (mew-tinfo-get-privacy-err))
94
      ;; If privacy err, don't display mew-protect-privacy-always-type etc.
95
      (setq pcdb (mew-pcdb-by-service (mew-tinfo-get-privacy-type)))
96
      (setq sub (mew-pcdb-mark pcdb)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
97
     ((and (mew-tinfo-get-encrypted-p) (mew-protect-privacy-encrypted case))
98
      (setq pcdb (mew-pcdb-by-service (mew-protect-privacy-encrypted-type case)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
99
      (setq sub (mew-pcdb-mark pcdb)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
100
     ((mew-protect-privacy-always case)
101
      (setq pcdb (mew-pcdb-by-service (mew-protect-privacy-always-type case)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
102
      (setq sub (mew-pcdb-mark pcdb))))
103
    (setq mode-name (if header mew-mode-name-header mew-mode-name-draft))
104
    (if sub (setq mode-name (concat mode-name " " sub)))
105
    (unless (mew-case-default-p (mew-tinfo-get-case))
106
      (setq mode-name (concat mode-name " " (mew-tinfo-get-case))))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
107
    (if (mew-tinfo-get-use-flowed)
108
	(setq mode-name (concat mode-name " F")))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
109
    (force-mode-line-update)))
110
111
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
112
;;;
113
;;; Draft subfunctions
114
;;;
115
116
(defun mew-draft-dynamic-highlight (beg end len)
117
  (when (mew-in-header-p)
118
    (save-match-data
119
      (mew-highlight-header)
120
      (when (mew-draft-p)
121
	(mew-draft-header-keymap)))))
122
123
(defun mew-draft-auto-fill ()
124
  (let ((ret1 (do-auto-fill)) ret2)
125
    (when (mew-in-header-p)
126
      (save-excursion
127
	(beginning-of-line)
128
	(while (not (or (looking-at "[^ \t\n]+:\\|[ \t]") (bobp)))
129
	  (setq ret2 t)
130
	  (insert "\t")
131
	  (forward-line -1)
132
	  (beginning-of-line))))
133
    (or ret1 ret2))) ;; if modifies, return t.
134
135
(defun mew-draft-find-and-switch (draft-path &optional switch-func)
136
  ;; switch-func = nil :: switch-to-buffer
137
  ;; switch-func = t   :: switch-to-buffer-other-window
138
  (let* ((special-display-buffer-names nil)
139
	 (special-display-regexps nil)
140
	 (same-window-buffer-names nil)
141
	 (same-window-regexps nil)
142
	 (draftname (mew-path-to-folder draft-path)))
143
    (when (get-buffer draftname)
1.2.5 by Tatsuya Kinoshita
Import upstream version 7.0.50~0.20100105
144
      (with-current-buffer draftname
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
145
	(clear-visited-file-modtime)
146
	(set-buffer-modified-p nil) ;; just in case
147
	(mew-delete-file buffer-auto-save-file-name)
148
	(mew-remove-buffer draftname)))
149
    (cond
150
     (mew-use-other-frame-for-draft
151
      (setq switch-func 'switch-to-buffer-other-frame))
152
     ((eq switch-func nil)
153
      (setq switch-func 'switch-to-buffer))
154
     ((eq switch-func t)
155
      (setq switch-func 'switch-to-buffer-other-window)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
156
    (mew-frwlet mew-cs-m17n mew-cs-dummy
157
      (funcall switch-func (mew-find-file-noselect draft-path)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
158
    ;; draft buffer
159
    (mew-set-buffer-cs mew-cs-m17n)
160
    ;; copy config, first
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
161
    (mew-tinfo-set-case mew-case)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
162
    (when mew-use-other-frame-for-draft
163
      (mew-tinfo-set-other-frame t)
164
      ;; to ensure to cite a message from summary frame.
165
      (mew-remove-buffer (mew-buffer-message)))
166
    (rename-buffer draftname)))
167
168
(defun mew-draft-to-attach (draft)
169
  "Converting draft to attach. E.g. +draft/1 -> +attach/1"
170
  (mew-concat-folder mew-attach-folder (file-name-nondirectory draft)))
171
172
(defun mew-attachdir (&optional draft)
173
  (mew-expand-folder (mew-draft-to-attach (or draft (buffer-name)))))
174
175
(defun mew-draft-header-insert-alist (halist)
176
  "Insert field-body: and field-value. Return the value of
177
the Body: field."
178
  (let ((case-fold-search t)
179
	key val ret)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
180
    (dolist (ent halist)
181
      (setq key (mew-alist-get-key ent))
182
      (setq val (mew-alist-get-value ent))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
183
      (unless (string-match ":$" key)
184
	(setq key (concat key ":")))
185
      (if (string-match mew-body: key)
186
	  (setq ret val)
187
	(mew-draft-header-insert key val)))
188
    ret))
189
190
(defun mew-insert-address-list (field adrs del force-insert)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
191
  (let ((cnt 0) (beg (point)) med)
192
    (dolist (adr adrs)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
193
      (unless (mew-is-my-address del adr)
194
	(if (= cnt 0)
195
	    (insert adr)
196
	  (insert ", " adr))
197
	(setq del (cons (concat "^" (regexp-quote adr) "$") del))
198
	(setq cnt (1+ cnt))))
199
    (when (or force-insert (> cnt 0))
200
      (beginning-of-line)
201
      (insert field " ")
202
      (setq med (point))
203
      (end-of-line)
204
      (insert "\n")
205
      (mew-header-fold-region beg (point) med 'use-tab))
206
    del))
207
208
(defun mew-insert-address-list2 (field adrs)
209
  (when adrs
210
    (let ((beg (point)) med)
211
      (insert field " ")
212
      (setq med (point))
213
      (insert (car adrs))
214
      (setq adrs (cdr adrs))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
215
      (dolist (adr adrs)
216
	(insert ", " adr))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
217
      (insert "\n")
218
      (mew-header-fold-region beg (point) med 'use-tab))))
219
220
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
221
;;;
222
;;; Draft header
223
;;;
224
225
(defun mew-draft-header (&optional subject nl to cc newsgroups in-reply-to references other-headers fromme)
226
;; to -- string or list
227
;; cc -- string or list
228
;; nl -- one empty line under "----", which is necessary if
229
;;      attachment is prepared
230
  (let ((del (unless fromme mew-regex-my-address-list)) ;; deleting list
231
	case body)
232
    (goto-char (point-min))
233
    (if newsgroups
234
	(cond
235
	 ((stringp newsgroups)
236
	  (mew-draft-header-insert mew-newsgroups: newsgroups))
237
	 ((listp newsgroups)
238
	  (mew-insert-address-list2 mew-newsgroups: newsgroups)))
239
      ;; Insert To: first.
240
      ;; All addresses inserted on To: are appended to del.
241
      (cond
242
       ((null to) (mew-draft-header-insert mew-to: ""))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
243
       ((stringp to) ;; To: specified from the mini-buffer.
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
244
	;; do not check to is mine. Cc: is also string
245
	;; We believe that user never specifies the same address of To: to Cc:.
246
	(mew-draft-header-insert mew-to: to))
247
       ;; To: collected by reply
248
       ((listp to)
249
	(setq del (mew-insert-address-list mew-to: to del t))))
250
      (cond
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
251
       ((null cc) ()) ;; do nothing
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
252
       ((stringp cc) ;; Cc: specified from the mini-buffer.
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
253
	(mew-draft-header-insert mew-cc: cc))
254
       ((listp cc) ;; Cc: collected by reply.
255
	(mew-insert-address-list mew-cc: cc del nil))))
256
    (if mew-case-guess-when-prepared
257
	(mew-draft-set-case-by-guess))
258
    (setq case (mew-tinfo-get-case))
259
    (unless newsgroups
260
      (mew-draft-header-insert mew-cc: (mew-cc case)))
261
    (mew-draft-header-insert mew-subj: (or subject ""))
262
    (mew-draft-header-insert mew-from: (mew-from case))
263
    (mew-draft-header-insert mew-fcc: (mew-fcc case))
264
    (unless newsgroups
1.1.2 by Tatsuya Kinoshita
Import upstream version 5.0.53
265
      (mew-draft-header-insert mew-bcc: (mew-bcc case))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
266
      (mew-draft-header-insert mew-dcc: (mew-dcc case)))
267
    (mew-draft-header-insert mew-reply-to: (mew-reply-to case))
268
    (unless newsgroups
269
      (mew-draft-header-insert mew-in-reply-to: in-reply-to))
270
    (mew-draft-header-insert mew-references: references)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
271
    (mew-draft-header-insert-xface)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
272
    (mew-draft-header-insert mew-organization: (mew-organization case))
273
    (setq body (mew-draft-header-insert-alist other-headers))
274
    ;; Deleting fields defined in mew-header-alist to replace them.
1.2.2 by Tatsuya Kinoshita
Import upstream version 6.0.51
275
    (mew-header-delete-lines (mapcar 'mew-alist-get-key (mew-header-alist case)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
276
    (mew-header-goto-end)
277
    (mew-draft-header-insert-alist (mew-header-alist case))
278
    ;; X-Mailer: must be the last
1.2.2 by Tatsuya Kinoshita
Import upstream version 6.0.51
279
    (if (mew-use-x-mailer case)
280
	(mew-draft-header-insert mew-x-mailer: mew-x-mailer))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
281
    ;; (mew-header-set "\n") is enough. But highlighting delayed.
282
    (mew-header-prepared)
283
    ;; on the body
284
    (if nl (insert "\n"))
285
    (if body (save-excursion (insert body)))
286
    ;; move the cursor after "To: "
287
    (goto-char (point-min))
288
    (search-forward ": " nil t)))
289
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
290
(defun mew-draft-header-insert-xface ()
291
  (if (and mew-x-face-file
292
	   (file-exists-p (expand-file-name mew-x-face-file)))
293
      (let (xface)
294
	(with-temp-buffer
295
	  (mew-insert-file-contents (expand-file-name mew-x-face-file))
296
	  (setq xface (mew-buffer-substring (point-min)
297
					    (max (buffer-size) 1))))
298
	(mew-draft-header-insert mew-x-face: xface))))
299
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
300
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
301
;;;
302
;;; Citation
303
;;;
304
305
(defun mew-draft-auto-set-input-method ()
306
  (if (and (fboundp 'activate-input-method)
307
	   mew-charset-input-method-alist)
308
      (let* ((charset (mew-charset-guess-region
309
		       (mew-header-end) (or (mew-attach-begin) (point-max))))
310
	     (method (mew-charset-to-input-method charset)))
311
	(when (stringp method)
312
	  (activate-input-method method)
313
	  (message "Set input method to %s" method)))))
314
315
(defun mew-draft-yank (&optional arg force)
316
  "Copy and paste a part of message from Message mode WITHOUT
317
citation prefix and label.
318
1. Roughly speaking, it copies the body in Message mode. For example,
319
   if text/plain is displayed, the entire Message mode is copied.
320
   If message/rfc822 is displayed, the body without the header is copied.
321
2. If called with '\\[universal-argument]', the header is also copied if exists.
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
322
3. If an Emacs mark exists, the target is the region between the mark and
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
323
   the cursor."
324
;; MUST take care of C-x C-x
325
;; MUST be able to cancel by C-x u
326
  (interactive "P")
327
  (if (and (not force) (or (mew-in-header-p) (mew-in-attach-p)))
328
      (message "Cannot cite a message here")
329
    (let (cite beg end)
330
      (save-excursion
331
	(cond
332
	 ((get-buffer (mew-buffer-message))
333
	  (set-buffer (mew-buffer-message)))
334
	 ((get-buffer mew-message-last-buffer)
335
	  (set-buffer mew-message-last-buffer)))
336
	(set-buffer (mew-buffer-message))
337
	(save-restriction
338
	  (widen)
339
	  (let ((mark-active t))
340
	    (cond
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
341
	     (arg
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
342
	      (setq beg (point-min) end (point-max)))
343
	     ((and (not mew-cite-ignore-region)
344
		   (mew-mark)
345
		   (/= (point) (mew-mark))
346
		   (not (and mew-cite-ignore-mouse-region
347
			     (mew-mouse-region-p))))
348
	      (setq beg (region-beginning) end (region-end)))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
349
	     ((mew-msghdr-p)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
350
	      ;; header exists in Message mode
351
	      (mew-header-goto-body)
352
	      (setq beg (point) end (point-max)))
353
	     (t
354
	      (setq beg (point-min) end (point-max)))))
355
	  (setq cite (mew-buffer-substring beg end))))
356
      (mew-push-mark)
357
      (insert cite)
358
      (mew-draft-auto-set-input-method))))
359
360
(defvar mew-message-citation-buffer nil
361
  "This value is used by mew-gnus.el to specify a buffer from where
362
you can cite.")
363
364
(defvar mew-message-citation-frame-id nil)
365
366
(defun mew-draft-cite (&optional arg force)
367
  "Copy and paste a part of message from Message mode with
368
citation prefix and label.
369
1. Roughly speaking, it copies the body in Message mode. For example,
370
   if text/plain is displayed, the entire Message mode is copied.
371
   If message/rfc822 is displayed, the body without the header is copied.
372
2. If called with '\\[universal-argument]', the header is also copied if exists.
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
373
3. If an Emacs mark exists, the target is the region between the mark and
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
374
   the cursor."
375
;; MUST take care of C-x C-x
376
;; MUST be able to cancel by C-x u
377
  (interactive "P")
378
  (if (and (not force) (or (mew-in-header-p) (mew-in-attach-p)))
379
      (message "Cannot cite a message here")
380
    (let* ((nonmewbuf mew-message-citation-buffer) ;; may be buffer local
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
381
	   (fid (or mew-message-citation-frame-id (mew-frame-id)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
382
	   (fld (mew-current-get-fld fid))
383
	   (msg (mew-current-get-msg fid))
384
	   (msg-buf (mew-buffer-message))
385
	   cite beg end tbuf irt-msgid)
386
      (unless (get-buffer msg-buf)
387
	(setq msg-buf mew-message-last-buffer))
388
      (save-excursion
389
	;;
390
	;; extract the body without header
391
	;;
392
	(setq tbuf (or nonmewbuf msg-buf))
393
	(if (get-buffer tbuf)
394
	    (set-buffer tbuf)
395
	  (error "No buffer to be cited"))
396
	(save-restriction
397
	  ;; first prepare "cite"
398
	  (widen)
399
	  (let ((mark-active t))
400
	    (cond
401
	     ;; arg will be effect in mew-cite-original
402
	     ((and (not mew-cite-ignore-region)
403
		   (mew-mark)
404
		   (/= (point) (mew-mark))
405
		   (not (and mew-cite-ignore-mouse-region
406
			     (mew-mouse-region-p))))
407
	      (setq beg (region-beginning) end (region-end)))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
408
	     ((mew-msghdr-p)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
409
	      ;; header exists in Message mode. Skip the header
410
	      ;; because we will concatenate it to cite later.
411
	      (mew-header-goto-body)
412
	      (setq beg (point) end (point-max)))
413
	     (t
414
	      (setq beg (point-min) end (point-max)))))
415
	  (setq cite (mew-buffer-substring beg end)))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
416
	;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
417
	;; concat the header
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
418
	;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
419
	(setq tbuf (or nonmewbuf
420
		       (save-excursion
421
			 (when (get-buffer msg-buf)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
422
			   (set-buffer msg-buf)
423
			   (if (mew-msghdr-p) (current-buffer))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
424
		       ;; header exists only in cache if multipart
425
		       (mew-cache-hit fld msg)))
426
	(if (get-buffer tbuf)
427
	    (set-buffer tbuf)
428
	  (error "No buffer to be cited"))
429
	(save-restriction
430
	  (widen)
431
	  (mew-header-goto-end)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
432
	  (setq cite (concat (mew-buffer-substring (point-min) (point))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
433
			     "\n" cite))
434
          (setq irt-msgid (mew-idstr-get-first-id
435
			   (mew-header-get-value mew-message-id:)))))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
436
      ;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
437
      ;; Draft mode, insert the header and the body.
438
      ;;
439
440
      ;; Append message-id to In-Reply-To:
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
441
      (if (and irt-msgid (mew-msghdr-p))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
442
          (save-excursion
443
            (let* ((mew-references-max-count nil)
444
		   (irt (mew-header-get-value mew-in-reply-to:))
445
		   (irtl (mew-idstr-to-id-list irt 'rev))
446
		   irtstr)
447
	      (mew-addq irtl irt-msgid)
448
	      (setq irtl (nreverse irtl))
449
	      (setq irtstr (mew-id-list-to-idstr irtl))
450
	      (mew-header-delete-lines (list mew-in-reply-to:))
451
	      (unless irt (goto-char (mew-header-end)))
452
	      (mew-draft-header-insert mew-in-reply-to: irtstr))))
453
      (save-restriction
454
	;; this gets complicated due to supercite, please do not care
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
455
	(narrow-to-region (point) (point)) ;; for (goto-char (point-min))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
456
	(insert cite)
457
	;; not for C-x C-x. Do not use mew-push-mark.
458
	(push-mark (point) t t)
459
	(goto-char (point-min)))
460
      (cond
461
       (mew-cite-hook
462
	(run-hooks 'mew-cite-hook))
463
       (t (mew-cite-original arg)))
464
      ;; (mark-marker) indicates the point after label.
465
      ;; Should we include the label too?
466
      (or force (mew-highlight-body-region (mark-marker) (point) 'draft))
467
      (mew-draft-auto-set-input-method))))
468
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
469
(defconst mew-cite-default-prefix "> ")
470
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
471
(defun mew-cite-original (&optional arg)
472
  (if (< (marker-position (mark-marker)) (point))
473
      (exchange-point-and-mark))
474
  (let ((beg (point)) (end (marker-position (mark-marker)))
475
        label prefix)
476
    (save-restriction
477
      (narrow-to-region beg end)
478
      (condition-case nil
479
          (setq label (funcall mew-cite-strings-function))
480
        (error
481
	 (error "Syntax of mew-cite-format was changed. Read explanation of mew-cite-fields")))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
482
      (cond
483
       (mew-cite-prefix-function
484
	(setq prefix (funcall mew-cite-prefix-function)))
485
       (mew-cite-prefix
486
	(setq prefix mew-cite-prefix))
487
       (t
488
	(setq prefix mew-cite-default-prefix)))
489
      (if (and mew-cite-prefix-confirmp (not mew-use-format-flowed))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
490
          (let ((ask (read-string
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
491
                      (format "Prefix (\"%s\"): " prefix) "")))
492
            (if (not (string= ask "")) (setq prefix ask))))
493
      ;; C-u C-c C-y cites body with header.
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
494
      (if (eq arg nil)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
495
	  ;; header has been already cited. So, delete it.
496
	  (delete-region beg (progn (mew-header-goto-body) (point))))
497
      (insert label)
498
      (mew-push-mark)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
499
      (if (or mew-cite-prefix-function mew-cite-prefix)
500
	  (progn
501
	    (and (bolp) (insert prefix))
502
	    (while (= 0 (forward-line))
503
	      (or (= (point) (point-max))
504
		  (insert prefix))))
505
	(if (bolp) (mew-cite-format-flowed))
506
	(while (= 0 (forward-line))
507
	  (unless (= (point) (point-max))
508
	    (mew-cite-format-flowed)))))))
509
510
(defun mew-cite-format-flowed ()
511
  (insert mew-flowed-quoted)
512
  (unless (char-equal (char-after) mew-flowed-quoted)
513
    (insert mew-flowed-stuffed)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
514
515
(defun mew-cite-get-value (field)
516
  (let ((value (mew-header-get-value field))
517
	repl func)
518
    (when (and (string= mew-from: field) value
519
	       (setq func (mew-addrbook-func mew-addrbook-for-cite-label)))
520
      (setq repl (funcall func (mew-addrstr-parse-address value)))
521
      (if repl (setq value repl)))
522
    (or value "")))
523
524
(defun mew-cite-strings ()
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
525
  "A function to create cite labels according to
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
526
'mew-cite-format' and 'mew-cite-fields'."
527
  (if (null mew-cite-fields)
528
      ""
529
    (let* ((vals (mapcar 'mew-cite-get-value mew-cite-fields))
530
	   (label (apply 'format mew-cite-format vals))
531
	   (ellipses (if (stringp mew-draft-cite-ellipses)
532
			 mew-draft-cite-ellipses ""))
533
	   beg eol)
534
      (if (not (or (eq mew-draft-cite-fill-mode 'truncate)
535
		   (eq mew-draft-cite-fill-mode 'wrap)))
536
	  label
537
	(with-temp-buffer
538
	  (let ((fill-column
539
		 (or mew-draft-cite-label-fill-column fill-column)))
540
	    (insert label)
541
	    (goto-char (point-min))
542
	    (while (not (eobp))
543
	      (cond
544
	       ((eq mew-draft-cite-fill-mode 'truncate)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
545
		(end-of-line)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
546
		(if (>= fill-column (current-column))
547
		    ()
548
		  (setq eol (point))
549
		  (insert ellipses)
550
		  (goto-char eol)
551
		  (while (< fill-column (current-column))
552
		    (delete-backward-char 1))))
553
	       ((eq mew-draft-cite-fill-mode 'wrap)
554
		(setq beg (point))
555
		(end-of-line)
556
		(if (= (current-column) 0)
557
		    ()
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
558
		  (fill-region beg (point)))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
559
	      (forward-line)))
560
	  (buffer-string))))))
561
562
(defun mew-cite-prefix-username ()
563
  "A good candidate for mew-cite-prefix-function.
564
The citation style is 'from_address> ', e.g. 'kazu> '"
565
  (let* ((from (mew-header-parse-address mew-from:))
566
	 (user (mew-addrstr-extract-user from))
567
	 (func (mew-addrbook-func mew-addrbook-for-cite-prefix))
568
	 nickname prefix)
569
    (if func (setq nickname (funcall func from)))
570
    (setq prefix (or nickname user))
571
    (if mew-ask-cite-prefix
572
	(setq prefix (read-string "Citation prefix: " prefix)))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
573
    (concat prefix mew-cite-default-prefix)))
574
575
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
576
;;;
577
;;; format=flowed
578
;;;
579
580
(defun mew-draft-encode-flowed (&optional arg)
581
  "Manually encode the body with format=flowed.
582
If called with '\\[universal-argument]', toggle whether or not
583
format=flowed is used on composing."
584
  (interactive "P")
585
  (if arg
586
      (progn
587
	(mew-tinfo-set-use-flowed (not (mew-tinfo-get-use-flowed)))
588
	(mew-draft-mode-name))
589
    (save-excursion
590
      (goto-char (mew-header-end))
591
      (forward-line)
592
      (if (mew-tinfo-get-flowed)
593
	  (progn
594
	    (mew-decode-flowed (point) (point-max)
595
			       (if (string= (mew-tinfo-get-flowed) "yes") t nil))
596
	    (mew-tinfo-set-flowed nil))
597
	(let* ((charset (mew-charset-guess-region (point) (point-max)))
598
	       (flowed-delsp (mew-encode-flowed (point) (point-max) charset))
599
	       flowed delsp)
600
	  (mew-set '(flowed delsp) flowed-delsp)
601
	  (if (not flowed)
602
	      (message "No line folded")
603
	    (mew-tinfo-set-flowed (if delsp "yes" "no")))))
604
      (mew-draft-rehighlight)
605
      (setq buffer-undo-list nil))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
606
607
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
608
;;;
609
;;; Misc
610
;;;
611
612
(defun mew-draft-save-buffer ()
613
  "Save this draft."
614
  (interactive)
615
  (let ((after-change-functions nil))
616
    (save-excursion
617
      (mew-header-clear 'keep-read-only)
618
      (insert-before-markers "\n") ;; for mew-summary-reply
619
      (save-buffer)
620
      (delete-region (1- (point)) (point))
621
      (mew-header-prepared)
622
      (set-buffer-modified-p nil))))
623
624
(defun mew-draft-kill ()
625
  "Kill this draft."
626
  (interactive)
627
  (if (not (y-or-n-p "Kill draft message? "))
628
      (message "Draft was not killed")
629
    (let* ((attachdir (mew-attachdir)) ;; attachdir must be here
630
	   (draft (buffer-file-name))
631
	   (buf (current-buffer))
632
	   (mdi (concat draft mew-draft-info-suffix)))
633
      (mew-elet
634
       (mew-overlay-delete-buffer))
635
      (save-buffer)
636
      (mew-delete-file draft)
637
      (mew-delete-file mdi)
638
      (if (and (mew-tinfo-get-other-frame) (> (length (frame-list)) 1))
639
	  (delete-frame)
640
	(mew-current-get-window-config))
641
      (mew-delete-directory-recursively attachdir)
642
      (mew-remove-buffer buf)
643
      (message "Draft was killed"))))
644
645
(defun mew-draft-insert-signature (&optional arg)
646
  "Insert the signature file specified by mew-signature-file.
647
If attachments exist and mew-signature-as-lastpart is *non-nil*,
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
648
the file is attached to the last part. Otherwise, the file is
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
649
inserted into the body. If mew-signature-insert-last is *non-nil*,
650
the file is inserted to the end of the body. Otherwise, inserted
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
651
the cursor position. If executed with '\\[universal-argument]',
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
652
you can set the case."
653
  (interactive "P")
654
  (let (case sigfile)
655
    (cond
656
     ((stringp arg)
657
      (setq case arg))
658
     (arg
659
      (setq case (mew-input-case (mew-tinfo-get-case) "Signature")))
660
     (t
661
      (setq case (mew-tinfo-get-case))))
662
    (setq sigfile (expand-file-name (mew-signature-file case)))
663
    (if (not (file-exists-p sigfile))
664
	(message "No signature file %s" sigfile)
665
      (if (and (mew-attach-p) mew-signature-as-lastpart)
666
	  (progn
667
	    (goto-char (point-max))
668
	    (forward-line -2)
669
	    (mew-attach-forward)
670
	    (mew-attach-copy sigfile "Signature")
671
	    (let* ((nums (mew-syntax-nums))
672
		   (syntax (mew-syntax-get-entry mew-encode-syntax nums)))
673
	      (mew-syntax-set-cdp syntax nil)
674
	      (mew-syntax-set-cd  syntax mew-signature-description))
675
	    (mew-encode-syntax-print mew-encode-syntax))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
676
	(when mew-signature-insert-last
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
677
	  (if (null (mew-attach-p))
678
	      (goto-char (point-max))
679
	    (goto-char (1- (mew-attach-begin))))
680
	  (end-of-line)
681
	  (unless (bolp) (insert "\n")))
682
	(mew-insert-file-contents sigfile)))))
683
684
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
685
;;;
686
;;; Re-highlight
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
687
;;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
688
689
(defun mew-draft-rehighlight-body ()
690
  (save-excursion
691
    (let ((beg (progn (goto-char (mew-header-end)) (forward-line) (point)))
692
	  (end (or (mew-attach-begin) (point-max))))
693
      (mew-highlight-body-region beg end 'draft 'rehighlight))))
694
695
(defun mew-draft-rehighlight ()
696
  "Highlight header and body again."
697
  (interactive)
698
  (let ((mod (buffer-modified-p)))
699
    (mew-highlight-header)
700
    (mew-draft-header-keymap)
701
    (mew-draft-rehighlight-body)
702
    (set-buffer-modified-p mod)))
703
704
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705
;;;
706
;;; Privacy
707
;;;
708
709
(defun mew-draft-toggle-privacy-always ()
710
  "Toggle whether or not all drafts are protected."
711
  (interactive)
712
  (setq mew-protect-privacy-always (not mew-protect-privacy-always))
713
  (message "Set mew-protect-privacy-always to %s"
714
	   mew-protect-privacy-always)
715
  (mew-draft-mode-name))
716
717
(defun mew-draft-toggle-privacy-encrypted ()
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
718
  "Toggle whether or not drafts replying to encrypted messages are
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
719
protected."
720
  (interactive)
721
  (setq mew-protect-privacy-encrypted (not mew-protect-privacy-encrypted))
722
  (message "Set mew-protect-privacy-encrypted to %s"
723
	   mew-protect-privacy-encrypted)
724
  (mew-draft-mode-name))
725
726
(defun mew-draft-set-privacy-type ()
727
  "\\<mew-draft-mode-map>
728
Set privacy service which will be effective when \\[mew-draft-make-message]."
729
  (interactive)
730
  (let* ((services (mew-pcdb-services))
731
	 (alist (mapcar (lambda (x) (cons (symbol-name x) x)) services))
732
	 str)
733
    (setq str (completing-read "Input privacy services: " alist nil t))
734
    (when (stringp str)
735
      (mew-tinfo-set-privacy-type (cdr (assoc str alist)))
736
      (mew-tinfo-set-privacy-err nil)))
737
  (mew-draft-mode-name))
738
739
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
740
;;;
741
;;; Sending and Queuing
742
;;;
743
744
(defun mew-draft-make-message (&optional privacy signer)
745
  "Compose a MIME message then put it into a queue folder."
746
  (interactive)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
747
  (if (string= mode-name "Edit")
748
      (mew-edit-make)
749
    (if (and (interactive-p) ;; prevent the loop
750
	     mew-use-old-pgp
751
	     mew-protect-privacy-with-old-pgp-signature)
752
	(mew-pgp-sign-message)
753
      (mew-draft-process-message 'queue privacy signer))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
754
755
(defun mew-draft-send-message ()
756
  "Compose a MIME message then send it."
757
  (interactive)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
758
  (if (string= mode-name "Edit")
759
      (mew-edit-make)
760
    (if (and (interactive-p) ;; just in case
761
	     mew-use-old-pgp
762
	     mew-protect-privacy-with-old-pgp-signature)
763
	(mew-pgp-sign-message)
764
      (mew-draft-process-message 'send))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
765
766
(defun mew-draft-process-message (action &optional privacy signer)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
767
  (if (and (boundp 'longlines-mode) longlines-mode) (longlines-mode -1))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
768
  (run-hooks 'mew-make-message-hook)
769
  (let* ((case (or (mew-tinfo-get-case) mew-case-default))
770
	 (old-case case)
771
	 guessed-case)
772
    (when mew-case-guess-when-composed
773
      (setq guessed-case (mew-draft-get-case-by-guess))
774
      (when guessed-case
775
	(if mew-case-guess-addition
776
	    (setq case (mew-draft-add-case case guessed-case))
777
	  (setq case guessed-case))))
778
    (unless (string= old-case case)
779
      (mew-tinfo-set-case case)
780
      (mew-draft-mode-name (mew-tinfo-get-hdr-file))
781
      (mew-draft-replace-fields old-case)
782
      (when (eq action 'send)
783
	(mew-highlight-header)
784
	(unless (mew-tinfo-get-hdr-file) (mew-draft-header-keymap)))
785
      (save-buffer))
786
    (if (mew-header-existp mew-newsgroups:)
787
	(mew-draft-nntp-process-message case action privacy signer)
788
      (mew-draft-smtp-process-message case action privacy signer))))
789
790
(defun mew-draft-resent-p (end)
791
  (let ((case-fold-search t))
792
    (save-excursion
793
      (re-search-forward mew-resent-regex end t))))
794
795
(defun mew-draft-smtp-process-message (case action &optional privacy signer)
796
  (run-hooks 'mew-send-hook)
797
  (let* ((buf (current-buffer))
798
	 (pnm (mew-smtp-info-name case))
799
	 (queue (mew-queue-folder case))
800
	 resentp fcc sendit msg err)
801
    (if (get-process pnm)
802
	(message "Another message is being sent. Try later")
803
      (mew-draft-remove-invalid-fields)
804
      ;; Check resentp
805
      (save-excursion
806
	(goto-char (point-min))
807
	(setq resentp (mew-draft-resent-p (mew-header-end))))
808
      ;; Ask Subject: before the query of "Really send".
809
      ;; Typing C-g here gets back to the draft.
810
      (mew-encode-ask-subject)
811
      (setq fcc (mew-encode-ask-fcc resentp))
812
      (if (eq action 'queue)
813
	  (setq sendit t)
814
	(if mew-ask-send
815
	    (setq sendit (y-or-n-p "Really send this message? "))
816
	  (setq sendit t)))
817
      (when sendit
818
	;; password should be asked in Summary mode.
819
	(if (and (mew-tinfo-get-other-frame) (> (length (frame-list)) 1))
820
	    (delete-frame)
821
	  (mew-current-get-window-config)
822
	  (delete-windows-on buf)) ;; just in case
823
	(save-excursion
824
	  (save-window-excursion
825
	    (set-buffer buf)
826
	    (if (mew-smtp-encode pnm case resentp fcc privacy signer)
827
		(let ((mdi (concat (buffer-file-name) mew-draft-info-suffix)))
828
		  (mew-delete-file mdi)
829
		  (setq msg (mew-smtp-queue case "from Draft mode"))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
830
		  (mew-remove-buffer buf)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
831
		  (if (eq action 'send)
832
		      (mew-smtp-send-message case queue (list msg))))
833
	      (setq err t))))
834
	;; now +queue/1 exists
835
	(if err
836
	    (progn
837
	      (mew-current-set-window-config)
838
	      (switch-to-buffer buf)
839
	      (delete-other-windows))
840
	  (if (and (eq action 'queue) mew-visit-queue-after-sending)
841
	      (mew-summary-visit-folder queue))
842
	  (run-hooks 'mew-real-send-hook))))))
843
844
(defun mew-draft-nntp-process-message (case action &optional privacy signer)
845
  (run-hooks 'mew-post-hook)
846
  (let* ((buf (current-buffer))
847
	 (pnm (mew-nntp2-info-name case))
848
	 (postq (mew-postq-folder case))
849
	 fcc sendit msg err)
850
    (if (get-process pnm)
851
	(message "Another message is being posted. Try later")
852
      (mew-draft-remove-invalid-fields)
853
      ;; Ask Subject: before the query of "Really post".
854
      ;; Typing C-g here gets back to the draft.
855
      (mew-encode-ask-subject)
856
      (setq fcc (mew-encode-ask-fcc nil))
857
      (if (eq action 'queue)
858
	  (setq sendit t)
859
	(if mew-ask-post
860
	    (setq sendit (y-or-n-p "Really post this message? "))
861
	  (setq sendit t)))
862
      (when sendit
863
	;; password should be asked in Summary mode.
864
	(if (and (mew-tinfo-get-other-frame) (> (length (frame-list)) 1))
865
	    (delete-frame)
866
	  (mew-current-get-window-config)
867
	  (delete-windows-on buf)) ;; just in case
868
	(save-excursion
869
	  (save-window-excursion
870
	    (set-buffer buf)
871
	    (if (mew-nntp2-encode pnm case fcc privacy signer)
872
		(let ((mdi (concat (buffer-file-name) mew-draft-info-suffix)))
873
		  (mew-delete-file mdi)
874
		  (setq msg (mew-nntp2-queue case "from Draft mode"))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
875
		  (mew-remove-buffer buf)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
876
		  (if (eq action 'send)
877
		      (mew-nntp2-send-message case postq (list msg))))
878
	      (setq err t))))
879
	(if err
880
	    (progn
881
	      (mew-current-set-window-config)
882
	      (switch-to-buffer buf)
883
	      (delete-other-windows))
884
	  (if (and (eq action 'queue) mew-visit-queue-after-sending)
885
	      (mew-summary-visit-folder postq))
886
	  (run-hooks 'mew-real-post-hook))))))
887
888
(defun mew-draft-remove-invalid-fields ()
889
  (when (mew-header-end)
890
    (save-excursion
891
      (save-restriction
892
	(goto-char (mew-header-end))
893
	(if (not (bolp)) (insert "\n"))
894
	(narrow-to-region (point-min) (mew-header-end))
895
	(let (beg med str)
896
	  (mew-elet
897
	   ;; removing null lines
898
	   (goto-char (point-min))
899
	   (while (and (re-search-forward "^$" nil t)
900
		       (not (eobp)))
901
	     (delete-char 1))
902
	   ;; removing fields which do not have value.
903
	   (goto-char (point-min))
904
	   (while (not (eobp))
905
	     (if (not (looking-at mew-keyval))
906
		 (forward-line)
907
	       (setq beg (match-beginning 0))
908
	       (setq med (match-end 0))
909
	       (forward-line)
910
	       (mew-header-goto-next)
911
	       (setq str (mew-buffer-substring med (1- (point))))
912
	       ;; str may consists of multiple lines
913
	       ;; So, "$" does not work. We need to use "[^ ]".
914
	       (unless (string-match "[^ \t\n]" str)
915
		 (delete-region beg (point)))))))))))
916
917
;; backward-compatibility
918
(defalias 'mew-draft-send-letter 'mew-draft-send-message)
919
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
920
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
921
;;;
922
;;; Privacy
923
;;;
924
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
925
(defvar mew-draft-privacy-method-alist '(("pgp" . pgp) ("smime" . smime)))
926
927
(defun mew-draft-set-privacy-method ()
928
  "Set mew-draft-privacy-method. 'pgp or 'smime."
929
  (interactive)
930
  (let ((method (completing-read "Privacy method: " mew-draft-privacy-method-alist nil t)))
931
    (setq mew-draft-privacy-method
932
	  (cdr (assoc method mew-draft-privacy-method-alist)))))
933
934
(defmacro mew-draft-privacy-switch (&rest form)
935
  `(let ((method (mew-draft-privacy-method (mew-tinfo-get-case))))
936
     (cond
937
      ,@(mapcar
938
	 (lambda (x)
939
	   (if (eq (car x) t)
940
	       x
941
	     `((eq method ',(car x)) ,(car (cdr x)))))
942
	 form)
943
      (t (message "'%s' is not supported" method)))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
944
945
(defun mew-draft-sign-message (&optional arg)
946
  "Sign the entire draft. Input your passphrase."
947
  (interactive "P")
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
948
  (mew-draft-privacy-switch
949
   (pgp   (mew-pgp-sign-message arg))
950
   (smime (mew-smime-sign-message arg))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
951
952
(defun mew-draft-encrypt-message ()
953
  "Encrypt the entire draft with PGP."
954
  (interactive)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
955
  (mew-draft-privacy-switch
956
   (pgp   (mew-pgp-encrypt-message))
957
   (smime (mew-smime-encrypt-message))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
958
959
(defun mew-draft-sign-encrypt-message (&optional arg)
960
  "Sign then encrypt the entire draft. Input your passphrase."
961
  (interactive "P")
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
962
  (mew-draft-privacy-switch
963
   (pgp   (mew-pgp-sign-encrypt-message arg))
964
   (smime (mew-smime-sign-encrypt-message arg))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
965
966
(defun mew-draft-encrypt-sign-message (&optional arg)
967
  "Encrypt then sign the entire draft. Input your passphrase."
968
  (interactive "P")
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
969
  (mew-draft-privacy-switch
970
   (pgp   (mew-pgp-encrypt-sign-message arg))
971
   (smime (mew-smime-encrypt-sign-message arg))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
972
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
973
(provide 'mew-draft)
974
975
;;; Copyright Notice:
976
1.2.5 by Tatsuya Kinoshita
Import upstream version 7.0.50~0.20100105
977
;; Copyright (C) 1996-2010 Mew developing team.
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
978
;; All rights reserved.
979
980
;; Redistribution and use in source and binary forms, with or without
981
;; modification, are permitted provided that the following conditions
982
;; are met:
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
983
;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
984
;; 1. Redistributions of source code must retain the above copyright
985
;;    notice, this list of conditions and the following disclaimer.
986
;; 2. Redistributions in binary form must reproduce the above copyright
987
;;    notice, this list of conditions and the following disclaimer in the
988
;;    documentation and/or other materials provided with the distribution.
989
;; 3. Neither the name of the team nor the names of its contributors
990
;;    may be used to endorse or promote products derived from this software
991
;;    without specific prior written permission.
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
992
;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
993
;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
994
;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
995
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
996
;; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
997
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
998
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
999
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1000
;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1001
;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1002
;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
1003
;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1004
1005
;;; mew-draft.el ends here