Mercurial > emacs
comparison lisp/calendar/timeclock.el @ 51861:91e4e5fd11de
(timeclock-use-display-time, timeclock-day-over-hook)
(timeclock-workday-remaining, timeclock-status-string)
(timeclock-when-to-leave, timeclock-when-to-leave-string)
(timeclock-log-data, timeclock-find-discrep, timeclock-day-base)
(timeclock-generate-report, timeclock-visit-timelog): Doc fix.
(timeclock-modeline-display): Set the variable `timeclock-modeline-display'.
(timeclock-update-modeline): Doc fix. Respect value of `timeclock-relative'.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Thu, 10 Jul 2003 01:02:11 +0000 |
parents | 48facdb1558e |
children | 0c6d39d0f49d |
comparison
equal
deleted
inserted
replaced
51860:f9ae39b1c1e6 | 51861:91e4e5fd11de |
---|---|
153 The advantage to this is that it means one less timer has to be set | 153 The advantage to this is that it means one less timer has to be set |
154 running amok in Emacs' process space. The disadvantage is that it | 154 running amok in Emacs' process space. The disadvantage is that it |
155 requires you to have `display-time' running. If you don't want to use | 155 requires you to have `display-time' running. If you don't want to use |
156 `display-time', but still want the modeline to show how much time is | 156 `display-time', but still want the modeline to show how much time is |
157 left, set this variable to nil. You will need to restart Emacs (or | 157 left, set this variable to nil. You will need to restart Emacs (or |
158 toggle the value of `timeclock-modeline-display') for the change to | 158 toggle the function `timeclock-modeline-display') for the change to |
159 take effect." | 159 take effect." |
160 :set (lambda (symbol value) | 160 :set (lambda (symbol value) |
161 (let ((currently-displaying | 161 (let ((currently-displaying |
162 (and (boundp 'timeclock-modeline-display) | 162 (and (boundp 'timeclock-modeline-display) |
163 timeclock-modeline-display))) | 163 timeclock-modeline-display))) |
202 :type 'hook | 202 :type 'hook |
203 :group 'timeclock) | 203 :group 'timeclock) |
204 | 204 |
205 (defcustom timeclock-day-over-hook nil | 205 (defcustom timeclock-day-over-hook nil |
206 "*A hook that is run when the workday has been completed. | 206 "*A hook that is run when the workday has been completed. |
207 This hook is only run if the current time remaining is being display | 207 This hook is only run if the current time remaining is being displayed |
208 in the modeline. See the variable `timeclock-modeline-display'." | 208 in the modeline. See the variable `timeclock-modeline-display'." |
209 :type 'hook | 209 :type 'hook |
210 :group 'timeclock) | 210 :group 'timeclock) |
211 | 211 |
212 (defcustom timeclock-out-hook nil | 212 (defcustom timeclock-out-hook nil |
299 ;; on calling this function. | 299 ;; on calling this function. |
300 (if display-time-mode (timeclock-update-modeline)) | 300 (if display-time-mode (timeclock-update-modeline)) |
301 (add-hook 'display-time-hook 'timeclock-update-modeline)) | 301 (add-hook 'display-time-hook 'timeclock-update-modeline)) |
302 (setq timeclock-update-timer | 302 (setq timeclock-update-timer |
303 (run-at-time nil 60 'timeclock-update-modeline)))) | 303 (run-at-time nil 60 'timeclock-update-modeline)))) |
304 (setq global-mode-string | 304 (setq global-mode-string |
305 (delq 'timeclock-mode-string global-mode-string)) | 305 (delq 'timeclock-mode-string global-mode-string)) |
306 (remove-hook 'timeclock-event-hook 'timeclock-update-modeline) | 306 (remove-hook 'timeclock-event-hook 'timeclock-update-modeline) |
307 (if (boundp 'display-time-hook) | 307 (if (boundp 'display-time-hook) |
308 (remove-hook 'display-time-hook | 308 (remove-hook 'display-time-hook |
309 'timeclock-update-modeline)) | 309 'timeclock-update-modeline)) |
310 (when timeclock-update-timer | 310 (when timeclock-update-timer |
311 (cancel-timer timeclock-update-timer) | 311 (cancel-timer timeclock-update-timer) |
312 (setq timeclock-update-timer nil))) | 312 (setq timeclock-update-timer nil))) |
313 (force-mode-line-update) | 313 (force-mode-line-update) |
314 on-p)) | 314 (setq timeclock-modeline-display on-p))) |
315 | 315 |
316 ;; This has to be here so that the function definition of | 316 ;; This has to be here so that the function definition of |
317 ;; `timeclock-modeline-display' is known to the "set" function. | 317 ;; `timeclock-modeline-display' is known to the "set" function. |
318 (defcustom timeclock-modeline-display nil | 318 (defcustom timeclock-modeline-display nil |
319 "Toggle modeline display of time remaining. | 319 "Toggle modeline display of time remaining. |
398 (funcall timeclock-get-reason-function)))) | 398 (funcall timeclock-get-reason-function)))) |
399 (run-hooks 'timeclock-out-hook) | 399 (run-hooks 'timeclock-out-hook) |
400 (if arg | 400 (if arg |
401 (run-hooks 'timeclock-done-hook)))) | 401 (run-hooks 'timeclock-done-hook)))) |
402 | 402 |
403 ;; Should today-only be removed in favour of timeclock-relative? - gm | |
403 (defsubst timeclock-workday-remaining (&optional today-only) | 404 (defsubst timeclock-workday-remaining (&optional today-only) |
404 "Return the number of seconds until the workday is complete. | 405 "Return the number of seconds until the workday is complete. |
405 The amount returned is relative to the value of `timeclock-workday'. | 406 The amount returned is relative to the value of `timeclock-workday'. |
406 If TODAY-ONLY is non-nil, the value returned will be relative only to | 407 If TODAY-ONLY is non-nil, the value returned will be relative only to |
407 the time worked today, and not to past time. This argument only makes | 408 the time worked today, and not to past time." |
408 a difference if `timeclock-relative' is non-nil." | |
409 (let ((discrep (timeclock-find-discrep))) | 409 (let ((discrep (timeclock-find-discrep))) |
410 (if discrep | 410 (if discrep |
411 (if today-only | 411 (- (if today-only (cadr discrep) |
412 (- (cadr discrep)) | 412 (car discrep))) |
413 (- (car discrep))) | |
414 0.0))) | 413 0.0))) |
415 | 414 |
416 ;;;###autoload | 415 ;;;###autoload |
417 (defun timeclock-status-string (&optional show-seconds today-only) | 416 (defun timeclock-status-string (&optional show-seconds today-only) |
418 "Report the overall timeclock status at the present moment." | 417 "Report the overall timeclock status at the present moment. |
418 If SHOW-SECONDS is non-nil, display second resolution. | |
419 If TODAY-ONLY is non-nil, the display will be relative only to time | |
420 worked today, ignoring the time worked on previous days." | |
419 (interactive "P") | 421 (interactive "P") |
420 (let ((remainder (timeclock-workday-remaining)) | 422 (let ((remainder (timeclock-workday-remaining)) ; today-only? |
421 (last-in (equal (car timeclock-last-event) "i")) | 423 (last-in (equal (car timeclock-last-event) "i")) |
422 status) | 424 status) |
423 (setq status | 425 (setq status |
424 (format "Currently %s since %s (%s), %s %s, leave at %s" | 426 (format "Currently %s since %s (%s), %s %s, leave at %s" |
425 (if last-in "IN" "OUT") | 427 (if last-in "IN" "OUT") |
540 "Convert SECONDS (a floating point number) to an Emacs time structure." | 542 "Convert SECONDS (a floating point number) to an Emacs time structure." |
541 (list (floor seconds 65536) | 543 (list (floor seconds 65536) |
542 (floor (mod seconds 65536)) | 544 (floor (mod seconds 65536)) |
543 (floor (* (- seconds (ffloor seconds)) 1000000)))) | 545 (floor (* (- seconds (ffloor seconds)) 1000000)))) |
544 | 546 |
547 ;; Should today-only be removed in favour of timeclock-relative? - gm | |
545 (defsubst timeclock-when-to-leave (&optional today-only) | 548 (defsubst timeclock-when-to-leave (&optional today-only) |
546 "Return a time value representing at when the workday ends today. | 549 "Return a time value representing at when the workday ends today. |
547 If TODAY-ONLY is non-nil, the value returned will be relative only to | 550 If TODAY-ONLY is non-nil, the value returned will be relative only to |
548 the time worked today, and not to past time. This argument only makes | 551 the time worked today, and not to past time." |
549 a difference if `timeclock-relative' is non-nil." | |
550 (timeclock-seconds-to-time | 552 (timeclock-seconds-to-time |
551 (- (timeclock-time-to-seconds (current-time)) | 553 (- (timeclock-time-to-seconds (current-time)) |
552 (let ((discrep (timeclock-find-discrep))) | 554 (let ((discrep (timeclock-find-discrep))) |
553 (if discrep | 555 (if discrep |
554 (if today-only | 556 (if today-only |
559 ;;;###autoload | 561 ;;;###autoload |
560 (defun timeclock-when-to-leave-string (&optional show-seconds | 562 (defun timeclock-when-to-leave-string (&optional show-seconds |
561 today-only) | 563 today-only) |
562 "Return a string representing at what time the workday ends today. | 564 "Return a string representing at what time the workday ends today. |
563 This string is relative to the value of `timeclock-workday'. If | 565 This string is relative to the value of `timeclock-workday'. If |
564 NO-MESSAGE is non-nil, no messages will be displayed in the | 566 SHOW-SECONDS is non-nil, the value printed/returned will include |
565 minibuffer. If SHOW-SECONDS is non-nil, the value printed/returned | 567 seconds. If TODAY-ONLY is non-nil, the value returned will be |
566 will include seconds. If TODAY-ONLY is non-nil, the value returned | 568 relative only to the time worked today, and not to past time." |
567 will be relative only to the time worked today, and not to past time. | 569 ;; Should today-only be removed in favour of timeclock-relative? - gm |
568 This argument only makes a difference if `timeclock-relative' is | |
569 non-nil." | |
570 (interactive) | 570 (interactive) |
571 (let* ((then (timeclock-when-to-leave today-only)) | 571 (let* ((then (timeclock-when-to-leave today-only)) |
572 (string | 572 (string |
573 (if show-seconds | 573 (if show-seconds |
574 (format-time-string "%-I:%M:%S %p" then) | 574 (format-time-string "%-I:%M:%S %p" then) |
607 "Ask the user for the reason they are clocking out." | 607 "Ask the user for the reason they are clocking out." |
608 (timeclock-completing-read "Reason for clocking out: " | 608 (timeclock-completing-read "Reason for clocking out: " |
609 (mapcar 'list timeclock-reason-list))) | 609 (mapcar 'list timeclock-reason-list))) |
610 | 610 |
611 (defun timeclock-update-modeline () | 611 (defun timeclock-update-modeline () |
612 "Update the `timeclock-mode-string' displayed in the modeline." | 612 "Update the `timeclock-mode-string' displayed in the modeline. |
613 The value of `timeclock-relative' affects the display as described in | |
614 that variable's documentation." | |
613 (interactive) | 615 (interactive) |
614 (let ((remainder (timeclock-workday-remaining)) | 616 (let ((remainder (timeclock-workday-remaining (not timeclock-relative))) |
615 (last-in (equal (car timeclock-last-event) "i"))) | 617 (last-in (equal (car timeclock-last-event) "i"))) |
616 (when (and (< remainder 0) | 618 (when (and (< remainder 0) |
617 (not (and timeclock-day-over | 619 (not (and timeclock-day-over |
618 (equal timeclock-day-over | 620 (equal timeclock-day-over |
619 (timeclock-time-to-date | 621 (timeclock-time-to-date |
825 (nth 2 (or log-data (timeclock-log-data)))) | 827 (nth 2 (or log-data (timeclock-log-data)))) |
826 | 828 |
827 | 829 |
828 (defun timeclock-log-data (&optional recent-only filename) | 830 (defun timeclock-log-data (&optional recent-only filename) |
829 "Return the contents of the timelog file, in a useful format. | 831 "Return the contents of the timelog file, in a useful format. |
832 If the optional argument RECENT-ONLY is non-nil, only show the contents | |
833 from the last point where the time debt (see below) was set. | |
834 If the optional argument FILENAME is non-nil, it is used instead of | |
835 the file specified by `timeclock-file.' | |
836 | |
830 A timelog contains data in the form of a single entry per line. | 837 A timelog contains data in the form of a single entry per line. |
831 Each entry has the form: | 838 Each entry has the form: |
832 | 839 |
833 CODE YYYY/MM/DD HH:MM:SS [COMMENT] | 840 CODE YYYY/MM/DD HH:MM:SS [COMMENT] |
834 | 841 |
1019 (cons (cons last-date day) | 1026 (cons (cons last-date day) |
1020 (cadr log-data)))) | 1027 (cadr log-data)))) |
1021 log-data))) | 1028 log-data))) |
1022 | 1029 |
1023 (defun timeclock-find-discrep () | 1030 (defun timeclock-find-discrep () |
1024 "Find overall discrepancy from `timeclock-workday' (in seconds)." | 1031 "Calculate time discrepancies, in seconds. |
1032 The result is a three element list, containing the total time | |
1033 discrepancy, today's discrepancy, and the time worked today." | |
1025 ;; This is not implemented in terms of the functions above, because | 1034 ;; This is not implemented in terms of the functions above, because |
1026 ;; it's a bit wasteful to read all of that data in, just to throw | 1035 ;; it's a bit wasteful to read all of that data in, just to throw |
1027 ;; away more than 90% of the information afterwards. | 1036 ;; away more than 90% of the information afterwards. |
1028 ;; | 1037 ;; |
1029 ;; If it were implemented using those functions, it would look | 1038 ;; If it were implemented using those functions, it would look |
1120 (or (< (car t1) (car t2)) | 1129 (or (< (car t1) (car t2)) |
1121 (and (= (car t1) (car t2)) | 1130 (and (= (car t1) (car t2)) |
1122 (< (nth 1 t1) (nth 1 t2))))) | 1131 (< (nth 1 t1) (nth 1 t2))))) |
1123 | 1132 |
1124 (defun timeclock-day-base (&optional time) | 1133 (defun timeclock-day-base (&optional time) |
1125 "Given a time within a day, return 0:0:0 within that day." | 1134 "Given a time within a day, return 0:0:0 within that day. |
1135 If optional argument TIME is non-nil, use that instead of the current time." | |
1126 (let ((decoded (decode-time (or time (current-time))))) | 1136 (let ((decoded (decode-time (or time (current-time))))) |
1127 (setcar (nthcdr 0 decoded) 0) | 1137 (setcar (nthcdr 0 decoded) 0) |
1128 (setcar (nthcdr 1 decoded) 0) | 1138 (setcar (nthcdr 1 decoded) 0) |
1129 (setcar (nthcdr 2 decoded) 0) | 1139 (setcar (nthcdr 2 decoded) 0) |
1130 (apply 'encode-time decoded))) | 1140 (apply 'encode-time decoded))) |
1140 (if (> count 0) | 1150 (if (> count 0) |
1141 (/ total count) | 1151 (/ total count) |
1142 0))) | 1152 0))) |
1143 | 1153 |
1144 (defun timeclock-generate-report (&optional html-p) | 1154 (defun timeclock-generate-report (&optional html-p) |
1145 "Generate a summary report based on the current timelog file." | 1155 "Generate a summary report based on the current timelog file. |
1156 By default, the report is in plain text, but if the optional argument | |
1157 HTML-P is non-nil html markup is added." | |
1146 (interactive) | 1158 (interactive) |
1147 (let ((log (timeclock-log-data)) | 1159 (let ((log (timeclock-log-data)) |
1148 (today (timeclock-day-base))) | 1160 (today (timeclock-day-base))) |
1149 (if html-p (insert "<p>")) | 1161 (if html-p (insert "<p>")) |
1150 (insert "Currently ") | 1162 (insert "Currently ") |
1332 </td></table>"))))) | 1344 </td></table>"))))) |
1333 | 1345 |
1334 ;;; A helpful little function | 1346 ;;; A helpful little function |
1335 | 1347 |
1336 (defun timeclock-visit-timelog () | 1348 (defun timeclock-visit-timelog () |
1337 "Open up the .timelog file in another window." | 1349 "Open the file named by `timeclock-file' in another window." |
1338 (interactive) | 1350 (interactive) |
1339 (find-file-other-window timeclock-file)) | 1351 (find-file-other-window timeclock-file)) |
1340 | 1352 |
1341 (provide 'timeclock) | 1353 (provide 'timeclock) |
1342 | 1354 |