diff options
| author | Glenn Morris | 2011-06-11 10:54:53 -0700 |
|---|---|---|
| committer | Glenn Morris | 2011-06-11 10:54:53 -0700 |
| commit | 0a2bb1a9cfcd6948d2912882b6be53574b575327 (patch) | |
| tree | 12690a3338d0715d3327174753ffa5fa397e394b | |
| parent | 6198ccd0b2e8cebc14415e13765de6bb758ec786 (diff) | |
| download | emacs-0a2bb1a9cfcd6948d2912882b6be53574b575327.tar.gz emacs-0a2bb1a9cfcd6948d2912882b6be53574b575327.zip | |
Handle overlapping appointments in appt.el (bug#8377)
* lisp/calendar/appt.el (appt-disp-window-function): Doc fix.
(appt-check): Handle overlapping appointments.
* etc/NEWS: Mention appt-disp-window-function should handle lists now.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/calendar/appt.el | 121 |
3 files changed, 76 insertions, 55 deletions
| @@ -511,6 +511,11 @@ See the variable `diary-comment-start'. | |||
| 511 | *** Appointments can specify their individual warning times. | 511 | *** Appointments can specify their individual warning times. |
| 512 | See the variable `appt-warning-time-regexp'. | 512 | See the variable `appt-warning-time-regexp'. |
| 513 | 513 | ||
| 514 | --- | ||
| 515 | *** The function specified by `appt-disp-window-function' may be passed | ||
| 516 | lists of arguments if multiple appointments are due at similar times. | ||
| 517 | If you are using a custom function for this, you should update it. | ||
| 518 | |||
| 514 | +++ | 519 | +++ |
| 515 | *** New function `diary-hebrew-birthday'. | 520 | *** New function `diary-hebrew-birthday'. |
| 516 | 521 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7c258be6d9b..31264f720bf 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2011-06-11 Glenn Morris <rgm@gnu.org> | ||
| 2 | |||
| 3 | * calendar/appt.el (appt-disp-window-function): Doc fix. | ||
| 4 | (appt-check): Handle overlapping appointments. (Bug#8337) | ||
| 5 | |||
| 1 | 2011-06-11 Martin Rudalics <rudalics@gmx.at> | 6 | 2011-06-11 Martin Rudalics <rudalics@gmx.at> |
| 2 | 7 | ||
| 3 | * window.el (window-tree-1, window-tree): New functions, moving | 8 | * window.el (window-tree-1, window-tree): New functions, moving |
diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el index 6148babfd11..c44eb6e1b5d 100644 --- a/lisp/calendar/appt.el +++ b/lisp/calendar/appt.el | |||
| @@ -154,7 +154,9 @@ always updates every minute." | |||
| 154 | "Function called to display appointment window. | 154 | "Function called to display appointment window. |
| 155 | Only relevant if reminders are being displayed in a window. | 155 | Only relevant if reminders are being displayed in a window. |
| 156 | It should take three string arguments: the number of minutes till | 156 | It should take three string arguments: the number of minutes till |
| 157 | the appointment, the current time, and the text of the appointment." | 157 | the appointment, the current time, and the text of the appointment. |
| 158 | Each argument may also be a list, if multiple appointments are | ||
| 159 | relevant at any one time." | ||
| 158 | :type 'function | 160 | :type 'function |
| 159 | :group 'appt) | 161 | :group 'appt) |
| 160 | 162 | ||
| @@ -321,13 +323,12 @@ displayed in a window: | |||
| 321 | `appt-delete-window-function' | 323 | `appt-delete-window-function' |
| 322 | Function called to remove appointment window and buffer." | 324 | Function called to remove appointment window and buffer." |
| 323 | (interactive "P") ; so people can force updates | 325 | (interactive "P") ; so people can force updates |
| 324 | (let* ((min-to-app -1) | 326 | (let* ((prev-appt-mode-string appt-mode-string) |
| 325 | (prev-appt-mode-string appt-mode-string) | ||
| 326 | (prev-appt-display-count appt-display-count) | 327 | (prev-appt-display-count appt-display-count) |
| 327 | ;; Convert current time to minutes after midnight (12.01am = 1). | 328 | ;; Convert current time to minutes after midnight (12.01am = 1). |
| 328 | (now (decode-time)) | 329 | (now (decode-time)) |
| 329 | (now-mins (+ (* 60 (nth 2 now)) (nth 1 now))) | 330 | (now-mins (+ (* 60 (nth 2 now)) (nth 1 now))) |
| 330 | appt-mins appt-warn-time) | 331 | appt-mins appt-warn-time min-to-app min-list string-list) |
| 331 | (save-excursion ; FIXME ? | 332 | (save-excursion ; FIXME ? |
| 332 | ;; At first check in any day, update appointments to today's list. | 333 | ;; At first check in any day, update appointments to today's list. |
| 333 | (if (or force ; eg initialize, diary save | 334 | (if (or force ; eg initialize, diary save |
| @@ -349,57 +350,67 @@ displayed in a window: | |||
| 349 | (setq appt-prev-comp-time now-mins | 350 | (setq appt-prev-comp-time now-mins |
| 350 | appt-mode-string nil | 351 | appt-mode-string nil |
| 351 | appt-display-count 0) | 352 | appt-display-count 0) |
| 352 | ;; Remove any entries that are in the past. | 353 | ;; If there are entries in the list get each time off of the |
| 353 | ;; FIXME how can there be any such entries, given that this | 354 | ;; list and calculate the number of minutes until the appointment. |
| 354 | ;; function removes entries when they hit zero minutes, | 355 | ;; TODO we are looping over all the appointments each time. |
| 355 | ;; and appt-make-list doesn't add any in the past in the first place? | 356 | ;; We could instead sort them by the time at which we need to |
| 356 | (while (and appt-time-msg-list | 357 | ;; start warning. But then removing entries in the past becomes |
| 357 | (< (setq appt-mins (caar (car appt-time-msg-list))) | 358 | ;; less straightforward. |
| 358 | now-mins)) | 359 | (dolist (appt appt-time-msg-list) |
| 359 | (setq appt-time-msg-list (cdr appt-time-msg-list))) | 360 | ;; Remove any entries that are in the past. |
| 360 | ;; If there are entries in the list, and the user wants a | 361 | ;; FIXME how can there be any such entries, given that this |
| 361 | ;; message issued, get the first time off of the list and | 362 | ;; function removes entries when they hit zero minutes, |
| 362 | ;; calculate the number of minutes until the appointment. | 363 | ;; and appt-make-list doesn't add any in the past in the first place? |
| 363 | (when appt-time-msg-list | 364 | (if (< (setq appt-mins (caar appt)) now-mins) |
| 364 | (setq appt-warn-time (or (nth 3 (car appt-time-msg-list)) | 365 | (setq appt-time-msg-list (cdr appt-time-msg-list)) |
| 365 | appt-message-warning-time) | 366 | (setq appt-warn-time (or (nth 3 appt) appt-message-warning-time) |
| 366 | min-to-app (- appt-mins now-mins)) | 367 | min-to-app (- appt-mins now-mins)) |
| 367 | ;; If we have an appointment between midnight and | 368 | ;; If we have an appointment between midnight and |
| 368 | ;; `appt-warn-time' minutes after midnight, we | 369 | ;; `appt-warn-time' minutes after midnight, we |
| 369 | ;; must begin to issue a message before midnight. Midnight | 370 | ;; must begin to issue a message before midnight. Midnight |
| 370 | ;; is considered 0 minutes and 11:59pm is 1439 | 371 | ;; is considered 0 minutes and 11:59pm is 1439 |
| 371 | ;; minutes. Therefore we must recalculate the minutes to | 372 | ;; minutes. Therefore we must recalculate the minutes to |
| 372 | ;; appointment variable. It is equal to the number of | 373 | ;; appointment variable. It is equal to the number of |
| 373 | ;; minutes before midnight plus the number of minutes after | 374 | ;; minutes before midnight plus the number of minutes after |
| 374 | ;; midnight our appointment is. | 375 | ;; midnight our appointment is. |
| 375 | ;; FIXME but appt-make-list constructs appt-time-msg-list to only | 376 | ;; FIXME but appt-make-list constructs appt-time-msg-list to only |
| 376 | ;; contain entries with today's date, so this cannot work? | 377 | ;; contain entries with today's date, so this cannot work? |
| 377 | ;; Also above we just removed anything with appt-mins < now-mins. | 378 | ;; Also above we just removed anything with appt-mins < now-mins. |
| 378 | (if (and (< appt-mins appt-warn-time) | 379 | (if (and (< appt-mins appt-warn-time) |
| 379 | (> (+ now-mins appt-warn-time) appt-max-time)) | 380 | (> (+ now-mins appt-warn-time) appt-max-time)) |
| 380 | (setq min-to-app (+ (- (1+ appt-max-time) now-mins) | 381 | (setq min-to-app (+ (- (1+ appt-max-time) now-mins) |
| 381 | appt-mins))) | 382 | appt-mins))) |
| 382 | ;; Issue warning if the appointment time is within | 383 | ;; Issue warning if the appointment time is within the warning time. |
| 383 | ;; appt-message-warning time. | 384 | (when (and (<= min-to-app appt-warn-time) |
| 384 | (when (and (<= min-to-app appt-warn-time) | 385 | (>= min-to-app 0)) |
| 385 | (>= min-to-app 0)) | 386 | (push min-to-app min-list) |
| 386 | ;; This is true every appt-display-interval minutes. | 387 | (push (cadr appt) string-list) |
| 387 | (and (zerop (mod prev-appt-display-count appt-display-interval)) | 388 | ;; When an appointment is reached, delete it from the list. |
| 388 | (appt-display-message (cadr (car appt-time-msg-list)) | 389 | (if (zerop min-to-app) |
| 389 | min-to-app)) | 390 | (setq appt-time-msg-list (delete appt appt-time-msg-list)))))) |
| 390 | (when appt-display-mode-line | 391 | (when min-list |
| 391 | (setq appt-mode-string | 392 | (setq min-list (nreverse min-list) |
| 392 | (concat " " (propertize | 393 | string-list (nreverse string-list)) |
| 393 | (appt-mode-line (mapcar 'number-to-string | 394 | ;; This is true every appt-display-interval minutes from the |
| 394 | (list min-to-app)) t) | 395 | ;; time at which we first started reminding. |
| 395 | 'face 'mode-line-emphasis)))) | 396 | ;; TODO in the case of multiple appointments, whose interval |
| 396 | ;; When an appointment is reached, delete it from the | 397 | ;; should we respect? The first one that we started warning about? |
| 397 | ;; list. Reset the count to 0 in case we display another | 398 | ;; That's what we do now, and this makes sense if you interpret |
| 398 | ;; appointment on the next cycle. | 399 | ;; a-d-i as "don't remind me any more frequently than this". |
| 399 | (if (zerop min-to-app) | 400 | ;; But should we always show a message when a new appt becomes due? |
| 400 | (setq appt-time-msg-list (cdr appt-time-msg-list) | 401 | ;; When one appt gets removed, should we switch to the interval |
| 401 | appt-display-count 0) | 402 | ;; of the next? |
| 402 | (setq appt-display-count (1+ prev-appt-display-count))))) | 403 | (and (zerop (mod prev-appt-display-count appt-display-interval)) |
| 404 | (appt-display-message string-list min-list)) | ||
| 405 | (when appt-display-mode-line | ||
| 406 | (setq appt-mode-string | ||
| 407 | (concat " " (propertize | ||
| 408 | (appt-mode-line (mapcar 'number-to-string | ||
| 409 | min-list) t) | ||
| 410 | 'face 'mode-line-emphasis)))) | ||
| 411 | ;; Reset count to 0 in case we display another appt on the next cycle. | ||
| 412 | (setq appt-display-count (if (eq '(0) min-list) 0 | ||
| 413 | (1+ prev-appt-display-count)))) | ||
| 403 | ;; If we have changed the mode line string, redisplay all mode lines. | 414 | ;; If we have changed the mode line string, redisplay all mode lines. |
| 404 | (and appt-display-mode-line | 415 | (and appt-display-mode-line |
| 405 | (not (string-equal appt-mode-string prev-appt-mode-string)) | 416 | (not (string-equal appt-mode-string prev-appt-mode-string)) |