(elmo-flatten): Use `append' and `listp' instead of
[elisp/wanderlust.git] / elmo / modb-standard.el
1 ;;; modb-standard.el --- Standartd Implement of MODB.
2
3 ;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;;      Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
7 ;; Keywords: mail, net news
8
9 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
10
11 ;; This program is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15 ;;
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25 ;;
26
27 ;;; Commentary:
28 ;;
29
30 ;;; Code:
31 ;;
32 (eval-when-compile (require 'cl))
33
34 (require 'elmo-util)
35 (require 'modb)
36
37 (defcustom modb-standard-divide-number 500
38   "*Standard modb divide entity number."
39   :type '(choice (const :tag "Not divide" nil)
40                  number)
41   :group 'elmo)
42
43 (defvar modb-standard-entity-filename "entity"
44   "Message entity database.")
45
46 (defvar modb-standard-flag-filename "flag"
47   "Message number <=> Flag status database.")
48
49 (defvar modb-standard-msgid-filename "msgid"
50   "Message number <=> Message-Id database.")
51
52 (eval-and-compile
53   (luna-define-class modb-standard (modb-generic)
54                      (number-list       ; sorted list of message numbers.
55                       entity-map        ; number, msg-id -> entity mapping.
56                       flag-map          ; number -> flag-list mapping
57                       flag-count        ; list of (FLAG . COUNT)
58                       overview-handler  ; instance of modb-entity-handler.
59                       ))
60   (luna-define-internal-accessors 'modb-standard))
61
62 ;; for internal use only
63 (defsubst modb-standard-key (number)
64   (concat "#" (number-to-string number)))
65
66 (defsubst modb-standard-entity-id (entity)
67   (if (eq 'autoload (car-safe entity))
68       (cddr entity)
69     (elmo-msgdb-message-entity-field
70      (elmo-message-entity-handler entity)
71      entity 'message-id)))
72
73 (defsubst modb-standard-entity-map (modb)
74   (or (modb-standard-entity-map-internal modb)
75       (modb-standard-set-entity-map-internal
76        modb
77        (elmo-make-hash (elmo-msgdb-length modb)))))
78
79 (defsubst modb-standard-flag-map (modb)
80   (or (modb-standard-flag-map-internal modb)
81       (modb-standard-set-flag-map-internal
82        modb
83        (elmo-make-hash (elmo-msgdb-length modb)))))
84
85 (defsubst modb-standard-set-message-modified (modb number)
86   (if modb-standard-divide-number
87       (let ((section (/ number modb-standard-divide-number))
88             (modified (modb-generic-message-modified-internal modb)))
89         (unless (memq section modified)
90           (modb-generic-set-message-modified-internal
91            modb (cons section modified))))
92     (modb-generic-set-message-modified-internal modb t)))
93
94 (defsubst modb-standard-set-flag-modified (modb number)
95   (modb-generic-set-flag-modified-internal modb t))
96
97 (defsubst modb-standard-message-flags (modb number)
98   (cdr (elmo-get-hash-val (modb-standard-key number)
99                           (modb-standard-flag-map-internal modb))))
100
101 (defsubst modb-standard-match-flags (check-flags flags)
102   (catch 'done
103     (while check-flags
104       (when (memq (car check-flags) flags)
105         (throw 'done t))
106       (setq check-flags (cdr check-flags)))))
107
108 (defsubst modb-standard-countup-flags (modb flags &optional delta)
109   (let ((flag-count (modb-standard-flag-count-internal modb))
110         (delta (or delta 1))
111         elem)
112     (dolist (flag flags)
113       (if (setq elem (assq flag flag-count))
114           (setcdr elem (+ (cdr elem) delta))
115         (setq flag-count (cons (cons flag delta) flag-count))))
116     (modb-standard-set-flag-count-internal modb flag-count)))
117
118 ;; save and load functions
119 (defun modb-standard-load-msgid (modb path)
120   (let* ((alist (elmo-object-load
121                  (expand-file-name modb-standard-msgid-filename path)))
122          (table (or (modb-standard-entity-map-internal modb)
123                     (elmo-make-hash (length alist))))
124          numbers info)
125     (dolist (pair alist)
126       (setq info (cons 'autoload pair))
127       (elmo-set-hash-val (modb-standard-key (car pair)) info table)
128       (elmo-set-hash-val (cdr pair) info table)
129       (setq numbers (cons (car pair) numbers)))
130     (modb-standard-set-number-list-internal modb (nreverse numbers))
131     (modb-standard-set-entity-map-internal modb table)))
132
133 (defun modb-standard-save-msgid (modb path)
134   (let ((table (modb-standard-entity-map-internal modb))
135         entity alist)
136     (dolist (number (modb-standard-number-list-internal modb))
137       (setq entity (elmo-get-hash-val (modb-standard-key number) table))
138       (setq alist (cons (cons number (modb-standard-entity-id entity))
139                         alist)))
140     (elmo-object-save
141      (expand-file-name modb-standard-msgid-filename path)
142      (nreverse alist))))
143
144 (defun modb-standard-load-flag (modb path)
145   (let ((table (or (modb-standard-flag-map-internal modb)
146                    (elmo-make-hash (elmo-msgdb-length modb)))))
147     (dolist (info (elmo-object-load
148                    (expand-file-name modb-standard-flag-filename path)))
149       (modb-standard-countup-flags modb (cdr info))
150       (elmo-set-hash-val (modb-standard-key (car info)) info table))
151     (modb-standard-set-flag-map-internal modb table)))
152
153 (defun modb-standard-save-flag (modb path)
154   (let (table flist info)
155     (when (setq table (modb-standard-flag-map-internal modb))
156       (mapatoms
157        (lambda (atom)
158          (setq info (symbol-value atom))
159          (when (cdr info)
160            (setq flist (cons info flist))))
161        table))
162     (elmo-object-save
163      (expand-file-name modb-standard-flag-filename path)
164      flist)))
165
166 (defsubst modb-standard-entity-filename (section)
167   (if section
168       (concat modb-standard-entity-filename
169               "-"
170               (number-to-string section))
171     modb-standard-entity-filename))
172
173 (defsubst modb-standard-loaded-message-id (msgdb number)
174   "Get message-id for autoloaded entity."
175   (let ((ret (elmo-get-hash-val
176               (modb-standard-key number)
177               (modb-standard-entity-map-internal msgdb))))
178     (cond
179      ((null ret)
180       ;; Garbage entity.
181       (elmo-clear-hash-val (modb-standard-key number)
182                            (modb-standard-entity-map-internal msgdb))
183       nil)                              ; return nil.
184      ((eq (car-safe ret) 'autoload)
185       (cdr (cdr ret)))                  ; message-id.
186      ((elmo-msgdb-message-entity-field (elmo-message-entity-handler ret)
187                                        ret 'message-id)) ; Already loaded.
188      (t (error "Internal error: invalid msgdb status")))))
189
190 (defun modb-standard-load-entity (modb path &optional section)
191   (let ((table (or (modb-standard-entity-map-internal modb)
192                    (elmo-make-hash (elmo-msgdb-length modb))))
193         (objects (elmo-object-load
194                   (expand-file-name
195                    (modb-standard-entity-filename section)
196                    path)))
197         number msgid)
198     (cond ((eq (car objects) 'modb-standard-entity-handler)
199            ;; (standard PARAMETERS ENTITY*)
200            (let ((handler (apply #'luna-make-entity
201                                  (car objects)
202                                  (car (cdr objects))))
203                  entity)
204              (dolist (element (cdr (cdr objects)))
205                (setq entity (cons handler (cons nil element))
206                      number (elmo-msgdb-message-entity-number handler entity)
207                      msgid  (modb-standard-loaded-message-id modb number))
208                (when msgid
209                  (elmo-msgdb-message-entity-set-field
210                   handler entity 'message-id msgid)
211                  (elmo-set-hash-val (modb-standard-key number) entity table)
212                  (elmo-set-hash-val msgid entity table)))))
213           (t
214            ;; legacy format
215            (dolist (entity objects)
216              (setq number (elmo-msgdb-message-entity-number
217                            (elmo-message-entity-handler entity)
218                            entity)
219                    msgid (modb-standard-loaded-message-id modb number))
220              (when msgid
221                (setcar entity msgid)
222                (elmo-set-hash-val (modb-standard-key number) entity table)
223                (elmo-set-hash-val msgid entity table)))))
224     (modb-standard-set-entity-map-internal modb table)))
225
226 (defsubst modb-standard-save-entity-1 (modb path &optional section)
227   (let ((table (modb-standard-entity-map-internal modb))
228         (filename (expand-file-name
229                    (modb-standard-entity-filename (car section)) path))
230         (handler (elmo-msgdb-message-entity-handler modb))
231         entity entities)
232     (dolist (number (or (cdr section)
233                         (modb-standard-number-list-internal modb)))
234       (when (setq entity (elmo-msgdb-message-entity modb number))
235         (unless (modb-entity-handler-equal-p
236                  handler
237                  (elmo-message-entity-handler entity))
238           (setq entity (elmo-msgdb-copy-message-entity
239                         (elmo-message-entity-handler entity)
240                         entity handler)))
241         (setq entities (cons (cdr (cdr entity)) entities))))
242     (if entities
243         (elmo-object-save filename
244                           (nconc
245                            (list (luna-class-name handler)
246                                  (modb-entity-handler-dump-parameters handler))
247                            entities))
248       (ignore-errors (delete-file filename)))))
249
250 (defun modb-standard-save-entity (modb path)
251   (let ((modified (modb-generic-message-modified-internal modb)))
252     (cond ((listp modified)
253            (let ((sections (mapcar 'list modified))
254                  section)
255              (dolist (number (modb-standard-number-list-internal modb))
256                (when (setq section (assq (/ number modb-standard-divide-number)
257                                          sections))
258                  (nconc section (list number))))
259              (dolist (section sections)
260                (modb-standard-save-entity-1 modb path section))))
261           (modified
262            (modb-standard-save-entity-1 modb path)))))
263
264 ;;; Implement
265 ;;
266 (luna-define-method elmo-msgdb-load ((msgdb modb-standard))
267   (let ((inhibit-quit t)
268         (path (elmo-msgdb-location msgdb)))
269     (when (file-exists-p (expand-file-name modb-standard-flag-filename path))
270       (modb-standard-load-msgid msgdb path)
271       (modb-standard-load-flag msgdb path)
272       (unless modb-standard-divide-number
273         (modb-standard-load-entity msgdb path))
274       t)))
275
276 (luna-define-method elmo-msgdb-save ((msgdb modb-standard))
277   (let ((path (elmo-msgdb-location msgdb))
278         (inhibit-quit t))
279     (when (elmo-msgdb-message-modified-p msgdb)
280       (modb-standard-save-msgid  msgdb path)
281       (modb-standard-save-entity msgdb path)
282       (modb-generic-set-message-modified-internal msgdb nil))
283     (when (elmo-msgdb-flag-modified-p msgdb)
284       (modb-standard-save-flag msgdb path)
285       (modb-generic-set-flag-modified-internal msgdb nil))))
286
287 (luna-define-method elmo-msgdb-append :around ((msgdb modb-standard)
288                                                msgdb-append)
289   (when (> (elmo-msgdb-length msgdb-append) 0)
290     (if (eq (luna-class-name msgdb-append) 'modb-standard)
291         (let ((numbers (modb-standard-number-list-internal msgdb-append))
292               duplicates)
293           ;; number-list
294           (modb-standard-set-number-list-internal
295            msgdb
296            (nconc (modb-standard-number-list-internal msgdb)
297                   numbers))
298           ;; entity-map
299           (let ((table (modb-standard-entity-map msgdb))
300                 entity msg-id)
301             (dolist (number numbers)
302               (setq entity (elmo-msgdb-message-entity msgdb-append number)
303                     msg-id (modb-standard-entity-id entity))
304               (if (elmo-get-hash-val msg-id table)
305                   (setq duplicates (cons number duplicates))
306                 (elmo-set-hash-val msg-id entity table))
307               (elmo-set-hash-val (modb-standard-key number)
308                                  entity
309                                  table)))
310           ;; flag-map
311           (let ((table (modb-standard-flag-map msgdb)))
312             (mapatoms
313              (lambda (atom)
314                (elmo-set-hash-val (symbol-name atom)
315                                   (symbol-value atom)
316                                   table))
317              (modb-standard-flag-map msgdb-append)))
318           ;; flag-count
319           (dolist (pair (modb-standard-flag-count-internal msgdb-append))
320             (modb-standard-countup-flags msgdb (list (car pair)) (cdr pair)))
321           ;; modification flags
322           (dolist (number (modb-standard-number-list-internal msgdb-append))
323             (modb-standard-set-message-modified msgdb number)
324             (modb-standard-set-flag-modified msgdb number))
325           duplicates)
326       (luna-call-next-method))))
327
328 (luna-define-method elmo-msgdb-clear :after ((msgdb modb-standard))
329   (modb-standard-set-number-list-internal msgdb nil)
330   (modb-standard-set-entity-map-internal msgdb nil)
331   (modb-standard-set-flag-map-internal msgdb nil)
332   (modb-standard-set-flag-count-internal msgdb nil))
333
334 (luna-define-method elmo-msgdb-length ((msgdb modb-standard))
335   (length (modb-standard-number-list-internal msgdb)))
336
337 (luna-define-method elmo-msgdb-flag-available-p ((msgdb modb-standard) flag)
338   t)
339
340 (luna-define-method elmo-msgdb-flags ((msgdb modb-standard) number)
341   (modb-standard-message-flags msgdb number))
342
343 (luna-define-method elmo-msgdb-set-flag ((msgdb modb-standard)
344                                          number flag)
345   (case flag
346     (read
347      (elmo-msgdb-unset-flag msgdb number 'unread))
348     (uncached
349      (elmo-msgdb-unset-flag msgdb number 'cached))
350     (t
351      (let ((cur-flags (modb-standard-message-flags msgdb number))
352            new-flags diff)
353        (unless (memq flag cur-flags)
354          (setq new-flags (cons flag cur-flags))
355          (setq diff (elmo-list-diff-nonsortable new-flags cur-flags))
356          (modb-standard-countup-flags msgdb (car diff))
357          (modb-standard-countup-flags msgdb (cadr diff) -1)
358          (elmo-set-hash-val (modb-standard-key number)
359                             (cons number new-flags)
360                             (modb-standard-flag-map msgdb))
361          (modb-standard-set-flag-modified msgdb number))))))
362
363 (luna-define-method elmo-msgdb-unset-flag ((msgdb modb-standard)
364                                            number flag)
365   (case flag
366     (read
367      (elmo-msgdb-set-flag msgdb number 'unread))
368     (uncached
369      (elmo-msgdb-set-flag msgdb number 'cached))
370     (all
371      (modb-standard-countup-flags msgdb
372                                   (modb-standard-message-flags msgdb number)
373                                   -1)
374      (elmo-clear-hash-val (modb-standard-key number)
375                           (modb-standard-flag-map msgdb)))
376     (t
377      (let ((cur-flags (modb-standard-message-flags msgdb number))
378            (inhibit-quit t)
379            new-flags diff)
380        (when (memq flag cur-flags)
381          (setq new-flags (delq flag (copy-sequence cur-flags)))
382          (setq diff (elmo-list-diff-nonsortable new-flags cur-flags))
383          (modb-standard-countup-flags msgdb (car diff))
384          (modb-standard-countup-flags msgdb (cadr diff) -1)
385          (elmo-set-hash-val (modb-standard-key number)
386                             (cons number new-flags)
387                             (modb-standard-flag-map msgdb))
388          (modb-standard-set-flag-modified msgdb number))
389        (when (eq flag 'unread)
390          (elmo-msgdb-unset-flag msgdb number 'new))))))
391
392 (luna-define-method elmo-msgdb-flag-count ((msgdb modb-standard))
393   (modb-standard-flag-count-internal msgdb))
394
395 (luna-define-method elmo-msgdb-list-messages ((msgdb modb-standard))
396   (copy-sequence
397    (modb-standard-number-list-internal msgdb)))
398
399 (luna-define-method elmo-msgdb-list-flagged ((msgdb modb-standard) flag)
400   (let (entry matched)
401     (case flag
402       (read
403        (dolist (number (modb-standard-number-list-internal msgdb))
404          (unless (memq 'unread (modb-standard-message-flags msgdb number))
405            (setq matched (cons number matched)))))
406       (uncached
407        (dolist (number (modb-standard-number-list-internal msgdb))
408          (unless (memq 'cached (modb-standard-message-flags msgdb number))
409            (setq matched (cons number matched)))))
410       (any
411        (mapatoms
412         (lambda (atom)
413           (setq entry (symbol-value atom))
414           (unless (and (eq (length (cdr entry)) 1)
415                        (eq (car (cdr entry)) 'cached))
416             ;; If there is a flag other than cached, then the message
417             ;; matches to `any'.
418             (setq matched (cons (car entry) matched))))
419         (modb-standard-flag-map msgdb)))
420       (digest
421        (let ((flags (append elmo-digest-flags
422                             (elmo-get-global-flags t t))))
423          (mapatoms
424           (lambda (atom)
425             (setq entry (symbol-value atom))
426             (when (modb-standard-match-flags flags (cdr entry))
427               (setq matched (cons (car entry) matched))))
428           (modb-standard-flag-map msgdb))))
429       (t
430        (mapatoms
431         (lambda (atom)
432           (setq entry (symbol-value atom))
433           (when (memq flag (cdr entry))
434             (setq matched (cons (car entry) matched))))
435         (modb-standard-flag-map msgdb))))
436     matched))
437
438 (luna-define-method elmo-msgdb-search ((msgdb modb-standard)
439                                        condition &optional numbers)
440   (if (vectorp condition)
441       (let ((key (elmo-filter-key condition))
442             results)
443         (cond
444          ((and (string= key "flag")
445                (eq (elmo-filter-type condition) 'match))
446           (setq results (elmo-msgdb-list-flagged
447                          msgdb
448                          (intern (elmo-filter-value condition))))
449           (if numbers
450               (elmo-list-filter numbers results)
451             results))
452          ((member key '("first" "last"))
453           (let* ((numbers (or numbers
454                               (modb-standard-number-list-internal msgdb)))
455                  (len (length numbers))
456                  (lastp (string= key "last"))
457                  (value (string-to-number (elmo-filter-value condition))))
458             (when (eq (elmo-filter-type condition) 'unmatch)
459               (setq lastp (not lastp)
460                     value (- len value)))
461             (if lastp
462                 (nthcdr (max (- len value) 0) numbers)
463               (when (> value 0)
464                 (let* ((numbers (copy-sequence numbers))
465                        (last (nthcdr (1- value) numbers)))
466                   (when last
467                     (setcdr last nil))
468                   numbers)))))
469          (t
470           t)))
471     t))
472
473 (luna-define-method elmo-msgdb-append-entity ((msgdb modb-standard)
474                                               entity &optional flags)
475   (when entity
476     (let ((number (elmo-msgdb-message-entity-number
477                    (elmo-message-entity-handler entity) entity))
478           (msg-id (elmo-msgdb-message-entity-field
479                    (elmo-message-entity-handler entity) entity 'message-id))
480           duplicate)
481       (when (and number msg-id)
482         ;; number-list
483         (modb-standard-set-number-list-internal
484          msgdb
485          (nconc (modb-standard-number-list-internal msgdb)
486                 (list number)))
487         ;; entity-map
488         (let ((table (modb-standard-entity-map msgdb)))
489           (setq duplicate (elmo-get-hash-val msg-id table))
490           (elmo-set-hash-val (modb-standard-key number) entity table)
491           (elmo-set-hash-val msg-id entity table))
492         ;; modification flags
493         (modb-standard-set-message-modified msgdb number)
494         ;; flag-map
495         (when flags
496           (elmo-set-hash-val
497            (modb-standard-key number)
498            (cons number flags)
499            (modb-standard-flag-map msgdb))
500           (modb-standard-countup-flags msgdb flags)
501           (modb-standard-set-flag-modified msgdb number))
502         duplicate))))
503
504 (luna-define-method elmo-msgdb-update-entity ((msgdb modb-standard)
505                                               entity values)
506   (let ((handler (elmo-message-entity-handler entity)))
507     (when (elmo-msgdb-message-entity-update-fields handler entity values)
508       (modb-standard-set-message-modified
509        msgdb
510        (elmo-msgdb-message-entity-number handler entity))
511       t)))
512
513 (luna-define-method elmo-msgdb-delete-messages ((msgdb modb-standard)
514                                                 numbers)
515   (let ((number-list (modb-standard-number-list-internal msgdb))
516         (entity-map (modb-standard-entity-map-internal msgdb))
517         (flag-map (modb-standard-flag-map-internal msgdb))
518         key entity)
519     (dolist (number numbers)
520       (setq key (modb-standard-key number)
521             entity (elmo-get-hash-val key entity-map))
522       (when entity
523         ;; number-list
524         (setq number-list (delq number number-list))
525         ;; entity-map
526         (elmo-clear-hash-val key entity-map)
527         (elmo-clear-hash-val (modb-standard-entity-id entity) entity-map)
528         ;; flag-count (must be BEFORE flag-map)
529         (modb-standard-countup-flags
530          msgdb
531          (modb-standard-message-flags msgdb number)
532          -1)
533         ;; flag-map
534         (elmo-clear-hash-val key flag-map)
535         (modb-standard-set-message-modified msgdb number)
536         (modb-standard-set-flag-modified msgdb number)))
537     (modb-standard-set-number-list-internal msgdb number-list)
538     (modb-standard-set-entity-map-internal msgdb entity-map)
539     (modb-standard-set-flag-map-internal msgdb flag-map)
540     t))
541
542 (luna-define-method elmo-msgdb-sort-entities ((msgdb modb-standard)
543                                               predicate &optional app-data)
544   (message "Sorting...")
545   (let ((numbers (modb-standard-number-list-internal msgdb)))
546     (modb-standard-set-number-list-internal
547      msgdb
548      (sort numbers (lambda (a b)
549                      (funcall predicate
550                               (elmo-msgdb-message-entity msgdb a)
551                               (elmo-msgdb-message-entity msgdb b)
552                               app-data))))
553     (message "Sorting...done")
554     msgdb))
555
556 (defun modb-standard-message-entity (msgdb key load)
557   (let ((ret (elmo-get-hash-val
558               key
559               (modb-standard-entity-map-internal msgdb)))
560         (inhibit-quit t))
561     (if (eq 'autoload (car-safe ret))
562         (when (and load modb-standard-divide-number)
563           (modb-standard-load-entity
564            msgdb
565            (elmo-msgdb-location msgdb)
566            (/ (nth 1 ret) modb-standard-divide-number))
567           (modb-standard-message-entity msgdb key nil))
568       ret)))
569
570 (luna-define-method elmo-msgdb-message-number ((msgdb modb-standard)
571                                                message-id)
572   (let ((ret (elmo-get-hash-val
573               message-id
574               (modb-standard-entity-map-internal msgdb))))
575     (if (eq 'autoload (car-safe ret))
576         ;; Not loaded yet but can return number.
577         (nth 1 ret)
578       (elmo-message-entity-number ret))))
579
580 (luna-define-method elmo-msgdb-message-field ((msgdb modb-standard)
581                                               number field &optional type)
582   (let ((ret (elmo-get-hash-val
583               (modb-standard-key number)
584               (modb-standard-entity-map-internal msgdb))))
585     (if (and (eq 'autoload (car-safe ret)) (eq field 'message-id))
586         ;; Not loaded yet but can return message-id
587         (cdr (cdr ret))
588       (elmo-message-entity-field (elmo-msgdb-message-entity
589                                   msgdb (modb-standard-key number))
590                                  field type))))
591
592 (luna-define-method elmo-msgdb-message-entity ((msgdb modb-standard) key)
593   (when key
594     (modb-standard-message-entity
595      msgdb
596      (cond ((stringp key) key)
597            ((numberp key) (modb-standard-key key)))
598      'autoload)))
599
600 (luna-define-method elmo-msgdb-message-entity-handler ((msgdb modb-standard))
601   (or (modb-standard-overview-handler-internal msgdb)
602       (modb-standard-set-overview-handler-internal
603        msgdb
604        (luna-make-entity 'modb-standard-entity-handler
605                          :mime-charset
606                          (modb-generic-mime-charset-internal msgdb)))))
607
608 (require 'product)
609 (product-provide (provide 'modb-standard) (require 'elmo-version))
610
611 ;;; modb-standard.el ends here