mhc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/COPYRIGHT +28 -0
  6. data/Gemfile +8 -0
  7. data/README.org +209 -0
  8. data/Rakefile +13 -0
  9. data/bin/mhc +312 -0
  10. data/emacs/Cask +25 -0
  11. data/emacs/Makefile +58 -0
  12. data/emacs/mhc-calendar.el +1723 -0
  13. data/emacs/mhc-calfw.el +135 -0
  14. data/emacs/mhc-compat.el +90 -0
  15. data/emacs/mhc-date.el +642 -0
  16. data/emacs/mhc-day.el +149 -0
  17. data/emacs/mhc-db.el +158 -0
  18. data/emacs/mhc-draft.el +211 -0
  19. data/emacs/mhc-e21.el +167 -0
  20. data/emacs/mhc-face.el +236 -0
  21. data/emacs/mhc-file.el +224 -0
  22. data/emacs/mhc-guess.el +648 -0
  23. data/emacs/mhc-header.el +176 -0
  24. data/emacs/mhc-logic.el +563 -0
  25. data/emacs/mhc-message.el +130 -0
  26. data/emacs/mhc-minibuf.el +466 -0
  27. data/emacs/mhc-misc.el +248 -0
  28. data/emacs/mhc-mua.el +260 -0
  29. data/emacs/mhc-parse.el +286 -0
  30. data/emacs/mhc-process.el +35 -0
  31. data/emacs/mhc-ps.el +1174 -0
  32. data/emacs/mhc-record.el +201 -0
  33. data/emacs/mhc-schedule.el +202 -0
  34. data/emacs/mhc-summary.el +763 -0
  35. data/emacs/mhc-sync.el +158 -0
  36. data/emacs/mhc-vars.el +149 -0
  37. data/emacs/mhc.el +1114 -0
  38. data/icons/Anniversary.xbm +6 -0
  39. data/icons/Anniversary.xpm +27 -0
  40. data/icons/Birthday.xbm +6 -0
  41. data/icons/Birthday.xpm +25 -0
  42. data/icons/Business.xbm +6 -0
  43. data/icons/Business.xpm +24 -0
  44. data/icons/CheckBox.xbm +6 -0
  45. data/icons/CheckBox.xpm +24 -0
  46. data/icons/CheckedBox.xbm +6 -0
  47. data/icons/CheckedBox.xpm +25 -0
  48. data/icons/Conflict.xbm +6 -0
  49. data/icons/Conflict.xpm +22 -0
  50. data/icons/Date.xbm +6 -0
  51. data/icons/Date.xpm +29 -0
  52. data/icons/Holiday.xbm +6 -0
  53. data/icons/Holiday.xpm +25 -0
  54. data/icons/Link.xbm +6 -0
  55. data/icons/Link.xpm +25 -0
  56. data/icons/Other.xbm +6 -0
  57. data/icons/Other.xpm +28 -0
  58. data/icons/Party.xbm +6 -0
  59. data/icons/Party.xpm +23 -0
  60. data/icons/Private.xbm +6 -0
  61. data/icons/Private.xpm +26 -0
  62. data/icons/Recurrence.xbm +6 -0
  63. data/icons/Recurrence.xpm +98 -0
  64. data/icons/Vacation.xbm +6 -0
  65. data/icons/Vacation.xpm +26 -0
  66. data/lib/mhc.rb +45 -0
  67. data/lib/mhc/builder.rb +64 -0
  68. data/lib/mhc/caldav.rb +304 -0
  69. data/lib/mhc/calendar.rb +106 -0
  70. data/lib/mhc/command.rb +13 -0
  71. data/lib/mhc/command/cache.rb +14 -0
  72. data/lib/mhc/command/completions.rb +108 -0
  73. data/lib/mhc/command/init.rb +133 -0
  74. data/lib/mhc/command/scan.rb +33 -0
  75. data/lib/mhc/command/sync.rb +22 -0
  76. data/lib/mhc/config.rb +229 -0
  77. data/lib/mhc/converter.rb +330 -0
  78. data/lib/mhc/datastore.rb +164 -0
  79. data/lib/mhc/date_enumerator.rb +274 -0
  80. data/lib/mhc/date_frame.rb +124 -0
  81. data/lib/mhc/date_helper.rb +49 -0
  82. data/lib/mhc/etag.rb +68 -0
  83. data/lib/mhc/event.rb +396 -0
  84. data/lib/mhc/formatter.rb +312 -0
  85. data/lib/mhc/logger.rb +94 -0
  86. data/lib/mhc/modifier.rb +149 -0
  87. data/lib/mhc/occurrence.rb +94 -0
  88. data/lib/mhc/occurrence_enumerator.rb +113 -0
  89. data/lib/mhc/property_value.rb +33 -0
  90. data/lib/mhc/property_value/date.rb +190 -0
  91. data/lib/mhc/property_value/integer.rb +15 -0
  92. data/lib/mhc/property_value/list.rb +41 -0
  93. data/lib/mhc/property_value/period.rb +49 -0
  94. data/lib/mhc/property_value/range.rb +100 -0
  95. data/lib/mhc/property_value/recurrence_condition.rb +272 -0
  96. data/lib/mhc/property_value/text.rb +11 -0
  97. data/lib/mhc/property_value/time.rb +45 -0
  98. data/lib/mhc/query.rb +210 -0
  99. data/lib/mhc/sync.rb +46 -0
  100. data/lib/mhc/sync/driver.rb +108 -0
  101. data/lib/mhc/sync/status.rb +70 -0
  102. data/lib/mhc/sync/status_manager.rb +142 -0
  103. data/lib/mhc/sync/strategy.rb +233 -0
  104. data/lib/mhc/sync/syncinfo.rb +98 -0
  105. data/lib/mhc/templates/config.yml.erb +142 -0
  106. data/lib/mhc/version.rb +4 -0
  107. data/lib/mhc/webdav.rb +319 -0
  108. data/mhc.gemspec +24 -0
  109. data/samples/DOT.mhc-config.yml +116 -0
  110. data/samples/japanese-holidays.mhcc +153 -0
  111. data/samples/mhc-completions.zsh +11 -0
  112. data/spec/mhc_spec.rb +682 -0
  113. data/spec/spec_helper.rb +9 -0
  114. data/xpm/close.xpm +18 -0
  115. data/xpm/delete.xpm +19 -0
  116. data/xpm/exit.xpm +18 -0
  117. data/xpm/month.xpm +18 -0
  118. data/xpm/next.xpm +18 -0
  119. data/xpm/next2.xpm +18 -0
  120. data/xpm/next_year.xpm +18 -0
  121. data/xpm/open.xpm +19 -0
  122. data/xpm/prev.xpm +18 -0
  123. data/xpm/prev2.xpm +18 -0
  124. data/xpm/prev_year.xpm +18 -0
  125. data/xpm/save.xpm +19 -0
  126. data/xpm/today.xpm +18 -0
  127. metadata +214 -0
@@ -0,0 +1,201 @@
1
+ ;;; -*- mode: Emacs-Lisp; coding: utf-8 -*-
2
+
3
+ ;; Author: Yoshinari Nomura <nom@quickhack.net>,
4
+ ;; TSUCHIYA Masatoshi <tsuchiya@namazu.org>
5
+ ;; Created: 2000/05/15
6
+ ;; Revised: $Date$
7
+
8
+
9
+ ;;; Commentary:
10
+
11
+ ;; This file is a part of MHC, and includes functions manipulate
12
+ ;; MHC-RECORD structure.
13
+
14
+
15
+ ;;; About MHC-RECORD structure:
16
+
17
+ ;; Each MHC-RECORD structure is a cons cell has a construction as
18
+ ;; follows:
19
+ ;;
20
+ ;; MHC-RECORD ::= ( KEY . VALUE )
21
+ ;; KEY ::= string ( represents file name of record )
22
+ ;; VALUE ::= [ ID SCHEDULES SEXP ]
23
+ ;; ID ::= string ( represents unique id of recort )
24
+ ;; SCHEDULES ::= MHC-SCHEDULE*
25
+ ;; SEXP ::= S expression to get schedule.
26
+
27
+
28
+ ;;; Code:
29
+
30
+ (require 'mhc-summary)
31
+ (require 'mhc-file)
32
+ (require 'mhc-draft)
33
+ (require 'mhc-logic)
34
+
35
+ (eval-when-compile
36
+ (mhc-file-setup))
37
+
38
+ ;; Global Variable:
39
+
40
+ (defcustom mhc-record-log-file
41
+ "mhc-db.log"
42
+ "*Log file of DB transaction."
43
+ :group 'mhc
44
+ :type 'file)
45
+
46
+ ;; Internal Variable:
47
+
48
+ (defvar mhc-record/id-counter 0)
49
+
50
+
51
+ ;; Functions:
52
+
53
+ (require 'org-id)
54
+
55
+ (defun mhc-record-create-id ()
56
+ "Return unique ID string."
57
+ (org-id-new))
58
+
59
+ (defun mhc-record-new (name &optional id schedules sexp)
60
+ "Constructer of MHC-RECORD structure."
61
+ (cons name
62
+ (vector id
63
+ schedules
64
+ sexp)))
65
+
66
+ (defmacro mhc-record/key (record)
67
+ `(car ,record))
68
+ (defmacro mhc-record/value (record)
69
+ `(cdr ,record))
70
+
71
+ (defmacro mhc-record-name (record)
72
+ `(mhc-record/key ,record))
73
+ (defmacro mhc-record-id (record)
74
+ `(aref (mhc-record/value ,record) 0))
75
+ (defmacro mhc-record-schedules (record)
76
+ `(aref (mhc-record/value ,record) 1))
77
+ (defmacro mhc-record-sexp (record)
78
+ `(aref (mhc-record/value ,record) 2))
79
+
80
+ (defmacro mhc-record-set-name (record name)
81
+ `(setcar ,record ,name))
82
+ (defmacro mhc-record-set-id (record id)
83
+ `(aset (mhc-record/value ,record) 0 ,id))
84
+ (defmacro mhc-record-set-schedules (record schedules)
85
+ `(aset (mhc-record/value ,record) 1 ,schedules))
86
+ (defmacro mhc-record-set-sexp (record sexp)
87
+ `(aset (mhc-record/value ,record) 2 ,sexp))
88
+
89
+ (defun mhc-record-copy (record)
90
+ (cons (copy-sequence (mhc-record/key record))
91
+ (copy-sequence (mhc-record/value record))))
92
+
93
+ (defun mhc-record-subject (record)
94
+ (catch 'found
95
+ (let ((schedules (mhc-record-schedules record)))
96
+ (while schedules
97
+ (if (mhc-schedule-subject (car schedules))
98
+ (throw 'found (mhc-schedule-subject (car schedules))))
99
+ (setq schedules (cdr schedules))))))
100
+
101
+ (defun mhc-record-subject-as-string (record)
102
+ (or (mhc-record-subject record)
103
+ "(none)"))
104
+
105
+ (defun mhc-record-occur-multiple-p (record)
106
+ "Return t if RECORD occurs multiple times."
107
+ (let ((schedules (mhc-record-schedules record)))
108
+ (or (> (length schedules) 1)
109
+ (mhc-logic-occur-multiple-p (mhc-schedule-condition (car schedules))))))
110
+
111
+ (defun mhc-record-write-buffer (record buffer &optional old-record)
112
+ "Write BUFFER to RECORD."
113
+ (let ((modify (file-exists-p (mhc-record-name record))))
114
+ (with-current-buffer buffer
115
+ (mhc-draft-increment-sequence)
116
+ (mhc-draft-translate)
117
+ (mhc-file-make-directory
118
+ (file-name-directory (mhc-record-name record)))
119
+ (mhc-write-region-as-coding-system mhc-default-coding-system
120
+ (point-min)
121
+ (point-max)
122
+ (mhc-record-name record)
123
+ nil 'nomsg)
124
+ (set-buffer-modified-p nil)
125
+ (if modify
126
+ (prog1
127
+ (mhc-file-modify (mhc-record-name record))
128
+ (mhc-record/append-log record 'modify))
129
+ (if old-record
130
+ (prog2
131
+ (mhc-file-remove (mhc-record-name old-record))
132
+ (mhc-file-add (mhc-record-name record))
133
+ (mhc-record/append-log record 'modify))
134
+ (prog1
135
+ (mhc-file-add (mhc-record-name record))
136
+ (mhc-record/append-log record 'add)))))))
137
+
138
+ (defun mhc-record-delete (record)
139
+ (prog1 (mhc-file-remove (mhc-record-name record))
140
+ (mhc-record/append-log record 'delete)))
141
+
142
+ (defun mhc-record/append-log (record status)
143
+ (if mhc-record-log-file
144
+ (let ((tmp-buffer (mhc-get-buffer-create " *mhc-record-append-log*")))
145
+ (with-current-buffer tmp-buffer
146
+ (delete-region (point-min) (point-max))
147
+ (insert (format "%c %s %s %s %s\n"
148
+ (cond
149
+ ((eq status 'add) ?A)
150
+ ((eq status 'delete) ?D)
151
+ ((eq status 'modify) ?M)
152
+ (t ??))
153
+ (format-time-string "%Y-%m-%d %T")
154
+ (mhc-record-id record)
155
+ (mhc-record-name record)
156
+ (mhc-record-subject-as-string record)))
157
+ (mhc-write-region-as-coding-system mhc-default-coding-system
158
+ (point-min)
159
+ (point-max)
160
+ (expand-file-name
161
+ mhc-record-log-file
162
+ (expand-file-name "status/log" (mhc-config-base-directory)))
163
+ 'append
164
+ 'nomsg)))))
165
+
166
+
167
+
168
+ (provide 'mhc-record)
169
+
170
+ ;;; Copyright Notice:
171
+
172
+ ;; Copyright (C) 1999, 2000 Yoshinari Nomura. All rights reserved.
173
+ ;; Copyright (C) 2000 MHC developing team. All rights reserved.
174
+
175
+ ;; Redistribution and use in source and binary forms, with or without
176
+ ;; modification, are permitted provided that the following conditions
177
+ ;; are met:
178
+ ;;
179
+ ;; 1. Redistributions of source code must retain the above copyright
180
+ ;; notice, this list of conditions and the following disclaimer.
181
+ ;; 2. Redistributions in binary form must reproduce the above copyright
182
+ ;; notice, this list of conditions and the following disclaimer in the
183
+ ;; documentation and/or other materials provided with the distribution.
184
+ ;; 3. Neither the name of the team nor the names of its contributors
185
+ ;; may be used to endorse or promote products derived from this software
186
+ ;; without specific prior written permission.
187
+ ;;
188
+ ;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS''
189
+ ;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
190
+ ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
191
+ ;; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
192
+ ;; THE TEAM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
193
+ ;; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
194
+ ;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
195
+ ;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
196
+ ;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
197
+ ;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
198
+ ;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
199
+ ;; OF THE POSSIBILITY OF SUCH DAMAGE.
200
+
201
+ ;;; mhc-record.el ends here
@@ -0,0 +1,202 @@
1
+ ;;; -*- mode: Emacs-Lisp; coding: utf-8 -*-
2
+
3
+ ;; Author: Yoshinari Nomura <nom@quickhack.net>,
4
+ ;; TSUCHIYA Masatoshi <tsuchiya@namazu.org>
5
+ ;; Created: 1997/10/12
6
+ ;; Revised: $Date: 2004/05/06 16:35:12 $
7
+
8
+
9
+ ;;; Commentary:
10
+
11
+ ;; This file is a part of MHC, and includes functions to manipulate
12
+ ;; MHC-SCHEDULE structure.
13
+
14
+
15
+ ;; About MHC-SCHEDULE structure:
16
+
17
+ ;; Each MHC-SCHEDULE structure is a vector has a construction as
18
+ ;; follows:
19
+ ;;
20
+ ;; MHC-SCHEDULE ::= [ RECORD CONDITION SUBJECT LOCATION TIME ALARM CATEGORIES PRIORITY REGION RECURRENCE-TAG SEQUENCE]
21
+ ;; RECORD ::= MHC-RECORD
22
+ ;; CONDITION ::= MHC-LOGIC
23
+ ;; SUBJECT ::= string ( represents subject of schedule )
24
+ ;; LOCATION ::= string ( represents location of schedule )
25
+ ;; TIME ::= integer ( represents minutes of day from midnight )
26
+ ;; ALARM ::= string
27
+ ;; CATEGORIES ::= CATEGORY*
28
+ ;; CATEGORY ::= string ( represents category of schedule )
29
+ ;; PRIORITY ::= integer
30
+ ;; REGION ::= ( START . END )
31
+ ;; START ::= integer ( represents start point of headers of schedule )
32
+ ;; END ::= integer ( represents end point of headers of schedule )
33
+ ;; RECURRENCE-TAG ::= string
34
+ ;; SEQUENCE ::= integer
35
+
36
+
37
+ ;;; Codes:
38
+ (defun mhc-schedule-new
39
+ (record &optional condition subject location time alarm categories priority region recurrence-tag sequence)
40
+ "Constructor of MHC-SCHEDULE structure."
41
+ (let ((new (vector record
42
+ (or condition (mhc-logic-new))
43
+ subject
44
+ location
45
+ time
46
+ alarm
47
+ categories
48
+ priority
49
+ (or region (cons nil nil))
50
+ recurrence-tag
51
+ sequence)))
52
+ (mhc-record-set-schedules record (cons new (mhc-record-schedules record)))
53
+ new))
54
+
55
+ (defsubst mhc-schedule-record (schedule)
56
+ (if schedule (aref schedule 0)))
57
+ (defsubst mhc-schedule-condition (schedule)
58
+ (if schedule (aref schedule 1)))
59
+ (defsubst mhc-schedule-subject (schedule)
60
+ (if schedule (aref schedule 2)))
61
+ (defsubst mhc-schedule-location (schedule)
62
+ (if schedule (aref schedule 3)))
63
+ (defsubst mhc-schedule-time (schedule)
64
+ (if schedule (aref schedule 4)))
65
+ (defsubst mhc-schedule-alarm (schedule)
66
+ (if schedule (aref schedule 5)))
67
+ (defsubst mhc-schedule-categories (schedule)
68
+ (if schedule (aref schedule 6)))
69
+ (defsubst mhc-schedule-priority (schedule)
70
+ (if schedule (aref schedule 7)))
71
+ (defsubst mhc-schedule-region (schedule)
72
+ (if schedule (aref schedule 8)))
73
+ (defsubst mhc-schedule-recurrence-tag (schedule)
74
+ (if schedule (aref schedule 9)))
75
+ (defsubst mhc-schedule-sequence (schedule)
76
+ (if schedule (aref schedule 10)))
77
+
78
+ (defmacro mhc-schedule-time-begin (schedule)
79
+ `(car (mhc-schedule-time ,schedule)))
80
+ (defmacro mhc-schedule-time-end (schedule)
81
+ `(cdr (mhc-schedule-time ,schedule)))
82
+ (defmacro mhc-schedule-region-start (schedule)
83
+ `(car (mhc-schedule-region ,schedule)))
84
+ (defmacro mhc-schedule-region-end (schedule)
85
+ `(cdr (mhc-schedule-region ,schedule)))
86
+
87
+ (defmacro mhc-schedule/set-subject (schedule subject)
88
+ `(aset ,schedule 2 ,subject))
89
+ (defmacro mhc-schedule/set-location (schedule location)
90
+ `(aset ,schedule 3 ,location))
91
+ (defmacro mhc-schedule/set-time (schedule begin end)
92
+ `(aset ,schedule 4 (cons ,begin ,end)))
93
+ (defmacro mhc-schedule/set-alarm (schedule alarm)
94
+ `(aset ,schedule 5 ,alarm))
95
+ (defmacro mhc-schedule/set-categories (schedule categories)
96
+ `(aset ,schedule 6 ,categories))
97
+ (defmacro mhc-schedule/set-priority (schedule priority)
98
+ `(aset ,schedule 7 ,priority))
99
+ (defmacro mhc-schedule/set-region-start (schedule start)
100
+ `(setcar (aref ,schedule 8) ,start))
101
+ (defmacro mhc-schedule/set-region-end (schedule end)
102
+ `(setcdr (aref ,schedule 8) ,end))
103
+ (defmacro mhc-schedule/set-recurrence-tag (schedule tag)
104
+ `(aset ,schedule 9 ,tag))
105
+ (defmacro mhc-schedule/set-sequence (schedule sequence)
106
+ `(aset ,schedule 10 ,sequence))
107
+
108
+ (defun mhc-schedule-append-default (schedule default)
109
+ (or (mhc-schedule-subject schedule)
110
+ (mhc-schedule/set-subject schedule (mhc-schedule-subject default)))
111
+ (or (mhc-schedule-location schedule)
112
+ (mhc-schedule/set-location schedule (mhc-schedule-location default)))
113
+ (or (mhc-schedule-time schedule)
114
+ (not (mhc-schedule-time default))
115
+ (mhc-schedule/set-time schedule
116
+ (mhc-schedule-time-begin default)
117
+ (mhc-schedule-time-end default)))
118
+ (or (mhc-schedule-alarm schedule)
119
+ (mhc-schedule/set-alarm schedule (mhc-schedule-alarm default)))
120
+ (or (mhc-schedule-categories schedule)
121
+ (mhc-schedule/set-categories schedule (mhc-schedule-categories default)))
122
+ (or (mhc-schedule-recurrence-tag schedule)
123
+ (mhc-schedule/set-recurrence-tag schedule (mhc-schedule-recurrence-tag default))))
124
+
125
+
126
+ (defsubst mhc-schedule/time-to-string (minutes)
127
+ (format "%02d:%02d" (/ minutes 60) (% minutes 60)))
128
+
129
+
130
+ (defun mhc-schedule-time-as-string (schedule)
131
+ (let ((time (mhc-schedule-time schedule)))
132
+ (cond
133
+ ((and (car time) (cdr time))
134
+ (concat (mhc-schedule/time-to-string (car time))
135
+ "-"
136
+ (mhc-schedule/time-to-string (cdr time))))
137
+ ((car time)
138
+ (mhc-schedule/time-to-string (car time)))
139
+ ((cdr time)
140
+ (concat "-" (mhc-schedule/time-to-string (cdr time))))
141
+ (t ""))))
142
+
143
+
144
+ (defun mhc-schedule-subject-as-string (schedule)
145
+ (or (mhc-schedule-subject schedule) "(none)"))
146
+
147
+
148
+ (defun mhc-schedule-categories-as-string (schedule)
149
+ (let ((categories (mhc-schedule-categories schedule)))
150
+ (if categories
151
+ (mapconcat (function identity) categories " ")
152
+ "")))
153
+
154
+
155
+ (defun mhc-schedule-in-category-p (schedule category)
156
+ (and schedule
157
+ (if (listp category)
158
+ (catch 'found
159
+ (while category
160
+ (if (member (downcase (car category)) (mhc-schedule-categories schedule))
161
+ (throw 'found t))
162
+ (setq category (cdr category))))
163
+ (member (downcase category) (mhc-schedule-categories schedule)))))
164
+
165
+
166
+ (defun mhc-schedule-recurrence-tag-as-string (schedule)
167
+ (or (mhc-schedule-recurrence-tag schedule) ""))
168
+
169
+ (provide 'mhc-schedule)
170
+
171
+ ;;; Copyright Notice:
172
+
173
+ ;; Copyright (C) 1999, 2000 Yoshinari Nomura. All rights reserved.
174
+ ;; Copyright (C) 2000 MHC developing team. All rights reserved.
175
+
176
+ ;; Redistribution and use in source and binary forms, with or without
177
+ ;; modification, are permitted provided that the following conditions
178
+ ;; are met:
179
+ ;;
180
+ ;; 1. Redistributions of source code must retain the above copyright
181
+ ;; notice, this list of conditions and the following disclaimer.
182
+ ;; 2. Redistributions in binary form must reproduce the above copyright
183
+ ;; notice, this list of conditions and the following disclaimer in the
184
+ ;; documentation and/or other materials provided with the distribution.
185
+ ;; 3. Neither the name of the team nor the names of its contributors
186
+ ;; may be used to endorse or promote products derived from this software
187
+ ;; without specific prior written permission.
188
+ ;;
189
+ ;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS''
190
+ ;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191
+ ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
192
+ ;; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
193
+ ;; THE TEAM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
194
+ ;; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
195
+ ;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
196
+ ;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
197
+ ;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
198
+ ;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
199
+ ;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
200
+ ;; OF THE POSSIBILITY OF SUCH DAMAGE.
201
+
202
+ ;;; mhc-schedule.el ends here.
@@ -0,0 +1,763 @@
1
+ ;;; mhc-summary.el --- Summary major mode in MHC.
2
+
3
+ ;; Author: Yoshinari Nomura <nom@quickhack.net>,
4
+ ;; TSUCHIYA Masatoshi <tsuchiya@namazu.org>
5
+ ;; Created: 2000/05/01
6
+ ;; Revised: $Date$
7
+
8
+
9
+ ;;; Commentary:
10
+
11
+ ;; This file is a part of MHC.
12
+
13
+ ;; This file consists of two parts: the first part contains MUA
14
+ ;; backend functions, and the second part contains functions to make
15
+ ;; summary contents.
16
+
17
+
18
+ ;;; About MUA Backend:
19
+
20
+ ;; In order to define new MUA backend, it is required to define these
21
+ ;; methods.
22
+ ;;
23
+ ;; (mhc-foo-summary-filename)
24
+ ;; Return the file name of the article on the current line in
25
+ ;; this summary buffer.
26
+ ;;
27
+ ;; (mhc-foo-summary-display-article)
28
+ ;; Display the article on the current line in this buffer.
29
+ ;;
30
+ ;; (mhc-foo-get-import-buffer GET-ORIGINAL)
31
+ ;; Return buffer visiting import article. If GET-ORIGINAL,
32
+ ;; return it without MIME decode.
33
+ ;;
34
+ ;; (mhc-foo-generate-summary-buffer DATE)
35
+ ;; Generate summary buffer of mailer, and change current
36
+ ;; buffer to it. This function will be called at the top of
37
+ ;; mhc-scan-month.
38
+ ;;
39
+ ;; (mhc-foo-insert-summary-contents INSERTER)
40
+ ;; Insert schedule with INSERTER.
41
+ ;;
42
+ ;; (mhc-foo-summary-mode-setup DATE)
43
+ ;; Setup buffer as summary of mailer. This function will be
44
+ ;; called at the end of mhc-scan-month.
45
+ ;;
46
+ ;; (mhc-foo-highlight-message FOR-DRAFT)
47
+ ;; Hilight message in the current buffer.
48
+ ;; If FOR-DRAFT is non-nil, Hilight message as draft message."
49
+ ;;
50
+ ;; (mhc-foo-eword-decode-string STRING)
51
+ ;; Decode encoded STRING.
52
+ ;;
53
+ ;; (mhc-foo-decode-header)
54
+ ;; Decode encoded header.
55
+ ;;
56
+ ;; Define these methods appropriately, and put definitions as follows:
57
+ ;;
58
+ ;; (provide 'mhc-foo)
59
+ ;; (put 'mhc-foo 'summary-filename 'mhc-foo-summary-filename)
60
+ ;; (put 'mhc-foo 'summary-display-article 'mhc-foo-summary-display-article)
61
+ ;; (put 'mhc-foo 'get-import-buffer 'mhc-foo-get-import-buffer)
62
+ ;; (put 'mhc-foo 'generate-summary-buffer 'mhc-foo-generate-summary-buffer)
63
+ ;; (put 'mhc-foo 'insert-summary-contents 'mhc-foo-insert-summary-contents)
64
+ ;; (put 'mhc-foo 'summary-mode-setup 'mhc-foo-summary-mode-setup)
65
+ ;; (put 'mhc-foo 'highlight-message 'mhc-foo-highlight-message)
66
+ ;; (put 'mhc-foo 'eword-decode-string 'mhc-foo-eword-decode-string)
67
+ ;; (put 'mhc-foo 'decode-header 'mhc-foo-decode-header)
68
+
69
+ ;;; Code:
70
+
71
+ (require 'mhc-vars)
72
+ (require 'mhc-day)
73
+ (require 'mhc-compat)
74
+ (require 'mhc-schedule)
75
+ (require 'bytecomp)
76
+
77
+ ;;; Global Variables:
78
+
79
+ (defcustom mhc-summary-language 'english
80
+ "*Language of the summary."
81
+ :group 'mhc
82
+ :type '(choice (const :tag "English" english)
83
+ (const :tag "Japanese" japanese)))
84
+
85
+ (defcustom mhc-summary-use-cw nil
86
+ "*If non-nil, insert `Calendar week number' instead of `Monday'."
87
+ :group 'mhc
88
+ :type '(choice (const :tag "Use" t)
89
+ (const :tag "No" nil)))
90
+
91
+ (defcustom mhc-use-week-separator t
92
+ "*If non-nil insert separator in summary buffer."
93
+ :group 'mhc
94
+ :type 'boolean)
95
+
96
+ (defcustom mhc-summary-separator ?-
97
+ "*Character of the separator as 'mhc-use-week-separator'."
98
+ :group 'mhc
99
+ :type 'character)
100
+
101
+ (defcustom mhc-use-month-separator t
102
+ "*Insert separator in summary buffer for wide scope."
103
+ :group 'mhc
104
+ :type '(choice (const :tag "Insert (full width)" t)
105
+ (integer :tag "Insert (number of width)")
106
+ (const :tag "Not use" nil)))
107
+
108
+ (defcustom mhc-summary-month-separator ?=
109
+ "*Character of the separator as 'mhc-use-month-separator'."
110
+ :group 'mhc
111
+ :type 'character)
112
+
113
+ (defcustom mhc-summary-string-conflict "[C]"
114
+ "*String which indicates conflicts in summary buffer."
115
+ :group 'mhc
116
+ :type 'string)
117
+
118
+ (defcustom mhc-summary-string-recurrence "[R]"
119
+ "*String which indicates recurrences in summary buffer."
120
+ :group 'mhc
121
+ :type 'string)
122
+
123
+ (defcustom mhc-summary-string-secret "[SECRET]"
124
+ "*String which hides private subjects in summary buffer."
125
+ :group 'mhc
126
+ :type 'string)
127
+
128
+ (defcustom mhc-use-icon t
129
+ "*If non-nil, schedule icon is used."
130
+ :group 'mhc
131
+ :type 'boolean)
132
+
133
+ (defcustom mhc-icon-path (if (fboundp 'locate-data-directory)
134
+ (locate-data-directory "mhc"))
135
+ "*Icon path for MHC."
136
+ :group 'mhc
137
+ :type 'directory)
138
+
139
+ (defcustom mhc-icon-setup-hook nil
140
+ "*A hook called after icon setup."
141
+ :group 'mhc
142
+ :type 'hook)
143
+
144
+ (defcustom mhc-summary-line-format
145
+ (if (eq mhc-summary-language 'japanese)
146
+ "%Y%年%M%月%D%日%(%曜%) %b%e %c%i%s %p%l"
147
+ "%Y%/%M%/%D%S%W %b%e %c%r%i%s %p%l")
148
+ "*A format string for summary line of MHC.
149
+ It may include any of the following format specifications
150
+ which are replaced by the given information:
151
+
152
+ %Y The year of the line if first line of the day.
153
+ %M The month of the line if first line of the day.
154
+ %D The day of the line if first line of the day.
155
+ %W The weekday name of the line if first line of the day.
156
+ %b Begin time.
157
+ %e End time (includes '-').
158
+ %c Warning string for conflict (See also `mhc-summary-string-conflict').
159
+ %i The icon for the schedule.
160
+ %s The subject of the schedule.
161
+ %p The priority of the schedule.
162
+ %l The location of the schedule.
163
+ %r Indicator for recurrence-tag (See also `mhc-summary-string-recurrence').
164
+
165
+ %/ A slash character if first line of the day.
166
+ %( A left parenthesis character if first line of the day.
167
+ %) A right parenthesis character if first line of the day.
168
+ %S A space with face.
169
+
170
+ %年 The '年' of the line if first line of the day.
171
+ %月 The '月' of the line if first line of the day.
172
+ %日 The '日' of the line if first line of the day.
173
+ %曜 The japaneses weekday name of the line if first line of the day.
174
+ "
175
+ :group 'mhc
176
+ :type 'string)
177
+
178
+ ;;; Internal Variable:
179
+
180
+ (defconst mhc-summary-major-mode-alist
181
+ '((mew-summary-mode . mhc-mew)
182
+ (mew-virtual-mode . mhc-mew)
183
+ (wl-folder-mode . mhc-wl)
184
+ (wl-summary-mode . mhc-wl)
185
+ (gnus-group-mode . mhc-gnus)
186
+ (gnus-summary-mode . mhc-gnus)))
187
+
188
+ ;; Internal Variables which are bound while inserting line:
189
+ (defvar mhc-tmp-day-face nil "a face for the day.")
190
+ (defvar mhc-tmp-dayinfo nil "a dayinfo for the day.")
191
+ (defvar mhc-tmp-schedule nil "a schedule structure.")
192
+ (defvar mhc-tmp-begin nil "begin time.")
193
+ (defvar mhc-tmp-end nil "end time.")
194
+ (defvar mhc-tmp-conflict nil "non-nil if conflicted schedule.")
195
+ (defvar mhc-tmp-recurrence nil "non-nil if recurrence schedule.")
196
+ (defvar mhc-tmp-first nil "non-nil if first schedule.")
197
+ (defvar mhc-tmp-private nil "non-nil if private display mode.")
198
+ (defvar mhc-tmp-priority nil "a priority of the schedule.")
199
+ ;; For TODO.
200
+ (defvar mhc-tmp-day nil "the day.")
201
+ (defvar mhc-tmp-deadline nil "a schedule structure.")
202
+
203
+ ;; Inserter (internal variable)
204
+ (defvar mhc-summary/line-inserter nil)
205
+
206
+ (defvar mhc-summary-line-format-alist
207
+ '((?Y (mhc-summary/line-year-string)
208
+ 'face mhc-tmp-day-face)
209
+ (?/ (if mhc-tmp-first "/" " ")
210
+ 'face mhc-tmp-day-face)
211
+ (?S " " 'face mhc-tmp-day-face)
212
+ (?M (mhc-summary/line-month-string)
213
+ 'face mhc-tmp-day-face)
214
+ (?D (mhc-summary/line-day-string)
215
+ 'face mhc-tmp-day-face)
216
+ (?W (mhc-summary/line-day-of-week-string)
217
+ 'face mhc-tmp-day-face)
218
+ (?b (if (null mhc-tmp-begin)
219
+ (make-string 5 ? )
220
+ (format "%02d:%02d" (/ mhc-tmp-begin 60) (% mhc-tmp-begin 60)))
221
+ 'face 'mhc-summary-face-time)
222
+ (?e (if (null mhc-tmp-end)
223
+ (make-string 6 ? )
224
+ (format "-%02d:%02d" (/ mhc-tmp-end 60) (% mhc-tmp-end 60)))
225
+ 'face 'mhc-summary-face-time)
226
+ (?c (if mhc-tmp-conflict
227
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "conflict"))
228
+ t
229
+ mhc-summary-string-conflict))
230
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "conflict"))
231
+ 'icon 'face)
232
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "conflict"))
233
+ (list "conflict") 'mhc-summary-face-conflict))
234
+ (?r (if (and mhc-tmp-recurrence (not (string= "" mhc-tmp-recurrence)))
235
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "recurrence"))
236
+ t
237
+ mhc-summary-string-recurrence))
238
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "recurrence"))
239
+ 'icon 'face)
240
+ (if (and (mhc-use-icon-p) (mhc-icon-exists-p "recurrence"))
241
+ (list "recurrence") 'mhc-summary-face-recurrence))
242
+ (?p (if mhc-tmp-priority
243
+ (format "[%d]" mhc-tmp-priority))
244
+ 'face (cond
245
+ ((null mhc-tmp-priority) nil)
246
+ ((>= mhc-tmp-priority 80) 'mhc-summary-face-sunday)
247
+ ((>= mhc-tmp-priority 50) 'mhc-summary-face-saturday)))
248
+ (?i (not mhc-tmp-private) 'icon
249
+ (if (mhc-schedule-in-category-p mhc-tmp-schedule "done")
250
+ (delete "todo"
251
+ (copy-sequence (mhc-schedule-categories mhc-tmp-schedule)))
252
+ (mhc-schedule-categories mhc-tmp-schedule)))
253
+ (?s (mhc-summary/line-subject-string)
254
+ 'face
255
+ (if mhc-tmp-private (mhc-face-category-to-face "Private")
256
+ (mhc-face-category-to-face
257
+ (car (mhc-schedule-categories mhc-tmp-schedule)))))
258
+ (?l (mhc-summary/line-location-string)
259
+ 'face 'mhc-summary-face-location)
260
+ (?\( (if mhc-tmp-first "(" " ")
261
+ 'face mhc-tmp-day-face)
262
+ (?\) (if mhc-tmp-first ")" " ")
263
+ 'face mhc-tmp-day-face)
264
+ (?年 (if mhc-tmp-first "年" (make-string 2 ? ))
265
+ 'face mhc-tmp-day-face)
266
+ (?月 (if mhc-tmp-first "月" (make-string 2 ? ))
267
+ 'face mhc-tmp-day-face)
268
+ (?日 (if mhc-tmp-first "日" (make-string 2 ? ))
269
+ 'face mhc-tmp-day-face)
270
+ (?曜 (mhc-summary/line-day-of-week-ja-string)
271
+ 'face mhc-tmp-day-face))
272
+ "An alist of format specifications that can appear in summary lines.
273
+ Each element is a list of following:
274
+ \(SPEC STRING-EXP PROP-TYPE PROP-VALUE\)
275
+ SPEC is a character for format specification.
276
+ STRING is an expression to get string to insert.
277
+ PROP-TYPE is an expression to get one of the two symbols `face' or `icon'.
278
+ It indicates a type of the property to put on the inserted string.
279
+ PROP-VALUE is the property value correspond to PROP-TYPE.
280
+ ")
281
+
282
+
283
+ (defvar mhc-summary/cw-separator nil)
284
+ (defvar mhc-summary/cw-week nil)
285
+
286
+ ;;; MUA Backend Functions:
287
+
288
+ ;; (defun mhc-summary-mailer-type ()
289
+ ;; "Return mailer backend symbol using currently."
290
+ ;; (or (cdr (assq major-mode mhc-summary-major-mode-alist))
291
+ ;; (intern (concat "mhc-" (symbol-name mhc-mailer-package)))))
292
+
293
+ (defun mhc-summary-mailer-type () 'mhc-mua)
294
+
295
+ (defun mhc-summary/true (&rest args)
296
+ "This is the dummy backend function, which always returns t."
297
+ t)
298
+
299
+ (defsubst mhc-summary-get-function (operation &optional mailer)
300
+ "Return appropriate function to do OPERATION for MAILER."
301
+ (or (get (require (or mailer (mhc-summary-mailer-type))) operation)
302
+ 'mhc-summary/true))
303
+
304
+ (defsubst mhc-get-function (operation)
305
+ "Return appropriate function to do OPERATION."
306
+ (or (get (require (intern (concat "mhc-" (symbol-name mhc-mailer-package))))
307
+ operation)
308
+ 'mhc-summary/true))
309
+
310
+ (defsubst mhc-highlight-message (&optional for-draft)
311
+ "Hilight message in the current buffer.
312
+ If optional argument FOR-DRAFT is non-nil, Hilight message as draft message."
313
+ (funcall (mhc-get-function 'highlight-message) for-draft))
314
+
315
+ (defsubst mhc-eword-decode-string (string)
316
+ "Decode encoded STRING."
317
+ (funcall (mhc-get-function 'eword-decode-string) string))
318
+
319
+ (defsubst mhc-decode-header ()
320
+ "Decode encoded header."
321
+ (funcall (mhc-get-function 'decode-header)))
322
+
323
+ (defsubst mhc-summary-filename (&optional mailer)
324
+ "Return file name of article on current line."
325
+ (funcall (mhc-summary-get-function 'summary-filename mailer)))
326
+
327
+ (defsubst mhc-summary-display-article (&optional mailer)
328
+ "Display article on current line."
329
+ (funcall (mhc-summary-get-function 'summary-display-article mailer)))
330
+
331
+ (defsubst mhc-summary-get-import-buffer (&optional get-original mailer)
332
+ "Return buffer to import article."
333
+ (funcall (mhc-summary-get-function 'get-import-buffer mailer) get-original))
334
+
335
+ (defsubst mhc-summary-generate-buffer (date &optional mailer)
336
+ "Generate buffer with summary mode of MAILER."
337
+ (funcall (mhc-summary-get-function 'generate-summary-buffer mailer) date))
338
+
339
+ (defsubst mhc-summary-insert-contents (mhc-tmp-schedule
340
+ mhc-tmp-private
341
+ inserter
342
+ &optional mailer)
343
+ (if (eq 'direct mailer)
344
+ (let ((mhc-use-icon nil))
345
+ (mhc-summary-line-insert)
346
+ (insert "\n"))
347
+ (funcall (mhc-summary-get-function 'insert-summary-contents mailer)
348
+ inserter)))
349
+
350
+ (defsubst mhc-summary-search-date (date)
351
+ "Search day in the current buffer."
352
+ (let (dayinfo)
353
+ (goto-char (point-min))
354
+ (while (and (not (eobp))
355
+ (or (null (setq dayinfo
356
+ (get-text-property (point) 'mhc-dayinfo)))
357
+ (not (eq (mhc-day-date dayinfo) date))))
358
+ (goto-char (next-single-property-change (point) 'mhc-dayinfo)))))
359
+
360
+ (defsubst mhc-summary-mode-setup (date &optional mailer)
361
+ "Setup buffer as summary mode of MAILER."
362
+ (funcall (mhc-summary-get-function 'summary-mode-setup mailer) date))
363
+
364
+ (defun mhc-summary-record (&optional mailer)
365
+ "Return record on current line."
366
+ (let ((filename (mhc-summary-filename mailer)))
367
+ (if filename
368
+ (mhc-parse-file filename))))
369
+
370
+ ;;; Codes:
371
+ (defsubst mhc-summary/make-string (count character)
372
+ (make-string (max 4 count) character)) ;; xxxx 4 ?
373
+
374
+
375
+ (defun mhc-summary/insert-separator (&optional char banner width)
376
+ "Insert horizontal using CHAR in WIDTH.
377
+ CHAR is '-' if not specified. default WIDTH is calculated from window size.
378
+ If BANNER is set, it is printed on the horizontal line."
379
+ (let ((hr (make-string (or width (- (mhc-misc-get-width) 2)) (or char ?-)))
380
+ (bn (or banner ""))
381
+ (bn-offset 4))
382
+ (mhc-face-put hr 'mhc-summary-face-separator)
383
+ (mhc-face-put bn 'mhc-summary-face-cw)
384
+ (insert
385
+ (concat
386
+ (substring hr 0 bn-offset)
387
+ bn
388
+ (substring hr (+ bn-offset (length bn)) -1)
389
+ "\n"))))
390
+
391
+ (defvar mhc-summary/today nil)
392
+
393
+ (defun mhc-summary/insert-dayinfo (mhc-tmp-dayinfo mailer category-predicate secret)
394
+ (let ((time-max -1)
395
+ (schedules (mhc-day-schedules mhc-tmp-dayinfo))
396
+ (mhc-tmp-first t)
397
+ mhc-tmp-begin mhc-tmp-end
398
+ mhc-tmp-location mhc-tmp-schedule
399
+ mhc-tmp-conflict mhc-tmp-recurrence mhc-tmp-priority
400
+ next-begin displayed)
401
+ (if schedules
402
+ (progn
403
+ (while schedules
404
+ (if (funcall category-predicate (car schedules))
405
+ (progn
406
+ (setq mhc-tmp-begin (mhc-schedule-time-begin (car schedules))
407
+ mhc-tmp-end (mhc-schedule-time-end (car schedules))
408
+ mhc-tmp-priority (mhc-schedule-priority
409
+ (car schedules))
410
+ next-begin (if (car (cdr schedules))
411
+ (mhc-schedule-time-begin
412
+ (car (cdr schedules))))
413
+ mhc-tmp-conflict (or (and mhc-tmp-end next-begin
414
+ (< next-begin mhc-tmp-end))
415
+ (and mhc-tmp-begin time-max
416
+ (< mhc-tmp-begin time-max)))
417
+ mhc-tmp-recurrence (mhc-schedule-recurrence-tag (car schedules)))
418
+ (if mhc-tmp-end (setq time-max (max mhc-tmp-end time-max)))
419
+ (setq displayed t)
420
+ (mhc-summary-insert-contents
421
+ (car schedules)
422
+ (and secret
423
+ (mhc-schedule-in-category-p
424
+ (car schedules) mhc-category-as-private))
425
+ 'mhc-summary-line-insert
426
+ mailer)
427
+ (setq mhc-tmp-first nil)))
428
+ (setq schedules (cdr schedules)))
429
+ (if (not displayed)
430
+ (mhc-summary-insert-contents nil secret
431
+ 'mhc-summary-line-insert
432
+ mailer)))
433
+ (mhc-summary-insert-contents nil secret
434
+ 'mhc-summary-line-insert
435
+ mailer))))
436
+
437
+
438
+ (defun mhc-summary-make-contents
439
+ (dayinfo-list &optional from to mailer category-predicate secret)
440
+ (let* ((sparse (or from to))
441
+ (from (or from (mhc-day-date (car dayinfo-list))))
442
+ (to (or to (mhc-day-date (car (last dayinfo-list)))))
443
+ (date from) dayinfo
444
+ (separator-format (and mhc-summary-use-cw
445
+ mhc-use-week-separator
446
+ (eq mhc-start-day-of-week 1)
447
+ " CW %d ")))
448
+ (while (mhc-date<= date to)
449
+ (setq dayinfo (or (assoc date dayinfo-list)
450
+ (and sparse (mhc-day-new date))))
451
+ (when dayinfo
452
+ (mhc-summary/insert-dayinfo
453
+ dayinfo
454
+ (or mailer 'mhc-mua)
455
+ (or category-predicate mhc-default-category-predicate-sexp)
456
+ secret))
457
+ (setq date (mhc-date++ date))
458
+ ;; insert week separator
459
+ (and sparse mhc-use-week-separator
460
+ (eq (mhc-date-ww date) mhc-start-day-of-week)
461
+ (mhc-summary/insert-separator
462
+ mhc-summary-separator
463
+ (and separator-format (format separator-format (mhc-date-cw date)))))
464
+ ;; insert month separator
465
+ (and sparse mhc-use-month-separator
466
+ (eq (mhc-date-dd date) 1)
467
+ (mhc-summary/insert-separator
468
+ mhc-summary-month-separator)))))
469
+
470
+ (defun mhc-summary/line-year-string ()
471
+ (if mhc-tmp-first
472
+ (format "%4d" (mhc-day-year mhc-tmp-dayinfo))
473
+ (make-string 4 ? )))
474
+
475
+
476
+ (defun mhc-summary/line-month-string ()
477
+ (if mhc-tmp-first
478
+ (format "%02d" (mhc-day-month mhc-tmp-dayinfo))
479
+ (make-string 2 ? )))
480
+
481
+
482
+ (defun mhc-summary/line-day-string ()
483
+ (if mhc-tmp-first
484
+ (format "%02d" (mhc-day-day-of-month mhc-tmp-dayinfo))
485
+ (make-string 2 ? )))
486
+
487
+
488
+ (defun mhc-summary/line-day-of-week-string ()
489
+ (if mhc-tmp-first
490
+ (let ((week (mhc-day-day-of-week mhc-tmp-dayinfo)))
491
+ (if (and mhc-summary/cw-week (= week 1) )
492
+ (format "%3s"
493
+ (format "w%d" (mhc-date-cw (mhc-day-date mhc-tmp-dayinfo))))
494
+ (aref ["Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"] week)))
495
+ (make-string 3 ? )))
496
+
497
+ (defun mhc-summary/line-day-of-week-ja-string ()
498
+ (if mhc-tmp-first
499
+ (let ((week (mhc-day-day-of-week mhc-tmp-dayinfo)))
500
+ (if (and mhc-summary/cw-week(= week 1) )
501
+ (format "%2d" (mhc-date-cw (mhc-day-date mhc-tmp-dayinfo)))
502
+ (aref ["日" "月" "火" "水" "木" "金" "土"] week)))
503
+ (make-string 2 ? )))
504
+
505
+
506
+ (defun mhc-summary/line-subject-string ()
507
+ (if mhc-tmp-private
508
+ (and mhc-tmp-schedule mhc-summary-string-secret)
509
+ (or (mhc-schedule-subject mhc-tmp-schedule) "")))
510
+
511
+
512
+ (defun mhc-summary/line-location-string ()
513
+ (let ((location (mhc-schedule-location mhc-tmp-schedule)))
514
+ (and (not mhc-tmp-private)
515
+ location
516
+ (> (length location) 0)
517
+ (concat "[" location "]"))))
518
+
519
+
520
+ ;;; Line format parsing
521
+
522
+ (defmacro mhc-line-insert (string)
523
+ `(and (stringp ,string) (insert ,string)))
524
+
525
+ (defun mhc-line-parse-format (format spec-alist)
526
+ (let ((f (mhc-string-to-char-list format))
527
+ inserter entry)
528
+ (setq inserter (list 'let (list 'pos)))
529
+ (while f
530
+ (if (eq (car f) ?%)
531
+ (progn
532
+ (setq f (cdr f))
533
+ (if (eq (car f) ?%)
534
+ (setq inserter (append inserter (list (list 'insert ?%))))
535
+ (setq entry (assq (car f) spec-alist))
536
+ (unless entry
537
+ (error "Unknown format spec %%%c" (car f)))
538
+ (setq inserter
539
+ (append inserter
540
+ (list (list 'setq 'pos (list 'point)))
541
+ (list (list 'mhc-line-insert
542
+ (nth 1 entry)))
543
+ (and
544
+ (nth 2 entry)
545
+ (list
546
+ (append (cond
547
+ ((eq (eval (nth 2 entry)) 'face)
548
+ (list 'put-text-property
549
+ 'pos (list 'point)
550
+ (list 'quote 'face)
551
+ (nth 3 entry)))
552
+ ((eq (eval (nth 2 entry)) 'icon)
553
+ (list 'if
554
+ (nth 1 entry)
555
+ (list
556
+ 'and
557
+ (list 'mhc-use-icon-p)
558
+ (list 'mhc-put-icon
559
+ (nth 3 entry)))))))))))))
560
+ (setq inserter (append inserter (list (list 'insert (car f))))))
561
+ (setq f (cdr f)))
562
+ inserter))
563
+
564
+
565
+ (defmacro mhc-line-inserter-setup (inserter format alist)
566
+ `(let (byte-compile-warnings)
567
+ (setq ,inserter
568
+ (byte-compile
569
+ (list 'lambda ()
570
+ (mhc-line-parse-format ,format ,alist))))
571
+ (when (get-buffer "*Compile-Log*")
572
+ (bury-buffer "*Compile-Log*"))
573
+ (when (get-buffer "*Compile-Log-Show*")
574
+ (bury-buffer "*Compile-Log-Show*"))))
575
+
576
+
577
+ (defun mhc-summary-line-inserter-setup ()
578
+ "Setup MHC summary and line inserter."
579
+ (interactive)
580
+ (if (and (called-interactively-p 'interactive)
581
+ (mhc-use-icon-p))
582
+ (call-interactively 'mhc-icon-setup))
583
+ (setq mhc-summary/cw-separator (and mhc-summary-use-cw
584
+ mhc-use-week-separator
585
+ (eq mhc-start-day-of-week 1)))
586
+ (setq mhc-summary/cw-week (and mhc-summary-use-cw
587
+ (not mhc-summary/cw-separator)))
588
+ (mhc-line-inserter-setup
589
+ mhc-summary/line-inserter
590
+ mhc-summary-line-format
591
+ mhc-summary-line-format-alist))
592
+
593
+
594
+ (defun mhc-summary-line-insert ()
595
+ "Insert summary line."
596
+ (let ((mhc-tmp-day-face (cond
597
+ ((mhc-schedule-in-category-p
598
+ mhc-tmp-schedule "holiday")
599
+ 'mhc-category-face-holiday)
600
+ ((eq (mhc-day-day-of-week
601
+ mhc-tmp-dayinfo) 0)
602
+ 'mhc-summary-face-sunday)
603
+ ((eq (mhc-day-day-of-week mhc-tmp-dayinfo) 6)
604
+ 'mhc-summary-face-saturday)
605
+ (t 'mhc-summary-face-default)))
606
+ (pos (point)))
607
+ (if (mhc-date= (mhc-day-date mhc-tmp-dayinfo) (mhc-date-now))
608
+ (setq mhc-tmp-day-face (mhc-face-get-today-face mhc-tmp-day-face)))
609
+ (funcall mhc-summary/line-inserter)
610
+ (put-text-property pos (point) 'mhc-dayinfo mhc-tmp-dayinfo)))
611
+
612
+
613
+ (defvar mhc-summary-mode-map nil)
614
+
615
+ ;; (unless mhc-summary-mode-map
616
+ (setq mhc-summary-mode-map (make-sparse-keymap))
617
+ (define-key mhc-summary-mode-map " " 'mhc-summary-scroll-message-forward)
618
+ (define-key mhc-summary-mode-map (kbd "DEL") 'mhc-summary-scroll-message-backward)
619
+ (define-key mhc-summary-mode-map "." 'mhc-summary-display)
620
+ (define-key mhc-summary-mode-map "\C-m" 'mhc-summary-scroll-message-line-forward)
621
+ (define-key mhc-summary-mode-map "v" 'mhc-summary-toggle-display-message)
622
+
623
+ (define-key mhc-summary-mode-map "g" 'mhc-goto-month)
624
+ (define-key mhc-summary-mode-map "/" 'mhc-search)
625
+ (define-key mhc-summary-mode-map ">" 'mhc-goto-next-month)
626
+ (define-key mhc-summary-mode-map "N" 'mhc-goto-next-year)
627
+ (define-key mhc-summary-mode-map "<" 'mhc-goto-prev-month)
628
+ (define-key mhc-summary-mode-map "P" 'mhc-goto-prev-year)
629
+
630
+ (define-key mhc-summary-mode-map "s" 'mhc-rescan-month)
631
+ (define-key mhc-summary-mode-map "d" 'mhc-delete)
632
+ (define-key mhc-summary-mode-map "c" 'mhc-set-default-category)
633
+ (define-key mhc-summary-mode-map "?" 'mhc-calendar)
634
+ (define-key mhc-summary-mode-map "t" 'mhc-calendar-toggle-insert-rectangle)
635
+ (define-key mhc-summary-mode-map "E" 'mhc-edit)
636
+ (define-key mhc-summary-mode-map "M" 'mhc-modify)
637
+
638
+ (define-key mhc-summary-mode-map "n" 'mhc-summary-display-next)
639
+ (define-key mhc-summary-mode-map "p" 'mhc-summary-display-previous)
640
+ (define-key mhc-summary-mode-map "f" 'forward-char)
641
+ (define-key mhc-summary-mode-map "b" 'backward-char)
642
+
643
+ (define-key mhc-summary-mode-map "j" 'mhc-summary-display-next)
644
+ (define-key mhc-summary-mode-map "k" 'mhc-summary-display-previous)
645
+ (define-key mhc-summary-mode-map "l" 'forward-char)
646
+ (define-key mhc-summary-mode-map "h" 'backward-char)
647
+ ;; )
648
+
649
+ (defun mhc-summary-mode ()
650
+ "Major mode for MHC summary.
651
+
652
+ \\{mhc-summary-mode-map}"
653
+ (interactive)
654
+ (setq major-mode 'mhc-summary-mode
655
+ mode-name "MHC")
656
+ (setq mode-line-buffer-identification (propertized-buffer-identification
657
+ "MHC: %12b"))
658
+ (set-buffer-modified-p nil)
659
+ (setq buffer-read-only t)
660
+ (setq inhibit-read-only nil)
661
+ (setq truncate-lines t)
662
+ (use-local-map mhc-summary-mode-map)
663
+ (run-hooks 'mhc-summary-mode-hook))
664
+
665
+ (defun mhc-summary-display-message ()
666
+ (interactive)
667
+ (save-selected-window
668
+ (mhc-summary-display-article)))
669
+
670
+ (defun mhc-summary-toggle-display-message ()
671
+ (interactive)
672
+ (if (mhc-message-visible-p)
673
+ (mhc-message-delete-windows)
674
+ (mhc-summary-display-message)))
675
+
676
+ (defvar mhc-message-file-name nil)
677
+ (make-variable-buffer-local 'mhc-message-file-name)
678
+
679
+ (defun mhc-message-set-file-name (file-name)
680
+ (setq mhc-message-file-name file-name))
681
+
682
+ (defun mhc-message-visible-p (&optional file-name)
683
+ "Return non-nil if MHC message is currently displaying, or nil if none."
684
+ (and (get-buffer-window "*MHC message*")
685
+ (or (null file-name)
686
+ (save-selected-window
687
+ (pop-to-buffer "*MHC message*")
688
+ (and (stringp mhc-message-file-name)
689
+ (string= mhc-message-file-name file-name))))))
690
+
691
+ (defun mhc-message-delete-windows ()
692
+ (delete-windows-on "*MHC message*"))
693
+
694
+ (defalias 'mhc-summary-display 'mhc-summary-display-message)
695
+
696
+ (defun mhc-summary-display-next ()
697
+ (interactive)
698
+ (forward-line)
699
+ (if (mhc-message-visible-p)
700
+ (mhc-summary-display)))
701
+
702
+ (defun mhc-summary-display-previous ()
703
+ (interactive)
704
+ (forward-line -1)
705
+ (if (mhc-message-visible-p)
706
+ (mhc-summary-display)))
707
+
708
+ (defun mhc-summary-scroll-message-line-forward ()
709
+ (interactive)
710
+ (mhc-summary-scroll-message-forward 1))
711
+
712
+ (defun mhc-summary-scroll-message-forward (&optional lines)
713
+ (interactive)
714
+ (mhc-summary-scroll-message 'forward lines))
715
+
716
+ (defun mhc-summary-scroll-message-backward (&optional lines)
717
+ (interactive)
718
+ (mhc-summary-scroll-message 'backward lines))
719
+
720
+ (defun mhc-summary-scroll-message (direction &optional lines)
721
+ (interactive)
722
+ (if (mhc-message-visible-p (mhc-summary-filename))
723
+ (save-selected-window
724
+ (pop-to-buffer "*MHC message*")
725
+ (if (eq direction 'forward)
726
+ (mhc-message-scroll-page-forward lines)
727
+ (mhc-message-scroll-page-backward lines)))
728
+ (mhc-summary-display-message)))
729
+
730
+ (provide 'mhc-summary)
731
+
732
+ ;;; Copyright Notice:
733
+
734
+ ;; Copyright (C) 1999, 2000 Yoshinari Nomura. All rights reserved.
735
+ ;; Copyright (C) 2000 MHC developing team. All rights reserved.
736
+
737
+ ;; Redistribution and use in source and binary forms, with or without
738
+ ;; modification, are permitted provided that the following conditions
739
+ ;; are met:
740
+ ;;
741
+ ;; 1. Redistributions of source code must retain the above copyright
742
+ ;; notice, this list of conditions and the following disclaimer.
743
+ ;; 2. Redistributions in binary form must reproduce the above copyright
744
+ ;; notice, this list of conditions and the following disclaimer in the
745
+ ;; documentation and/or other materials provided with the distribution.
746
+ ;; 3. Neither the name of the team nor the names of its contributors
747
+ ;; may be used to endorse or promote products derived from this software
748
+ ;; without specific prior written permission.
749
+ ;;
750
+ ;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS''
751
+ ;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
752
+ ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
753
+ ;; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
754
+ ;; THE TEAM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
755
+ ;; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
756
+ ;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
757
+ ;; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
758
+ ;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
759
+ ;; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
760
+ ;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
761
+ ;; OF THE POSSIBILITY OF SUCH DAMAGE.
762
+
763
+ ;;; mhc-summary.el ends here.