Browse Source

Timer: Pause and continue, and mode-line display.

The relative timer is now shown in the mode-line while running.
There is a new command to pause and continue it.

Thanks to Alan Davis for driving this change.
Carsten Dominik 16 years ago
parent
commit
b0f848e873
6 changed files with 127 additions and 14 deletions
  1. 16 3
      ORGWEBPAGE/Changes.org
  2. 4 0
      doc/ChangeLog
  3. 9 1
      doc/org.texi
  4. 9 0
      lisp/ChangeLog
  5. 83 7
      lisp/org-timer.el
  6. 6 3
      lisp/org.el

+ 16 - 3
ORGWEBPAGE/Changes.org

@@ -10,6 +10,22 @@
 #+LINK_UP: index.html
 #+LINK_HOME: http://orgmode.org
 
+* Version 6.18 (in preparation)
+  :PROPERTIES:
+  :VISIBILITY: content
+  :END:
+
+** Details
+
+*** The relative timer can be paused
+
+    The new command `C-c C-x ,' will pause the relative timer.
+    When the relative timer is running, its value will be shown
+    in the mode line.  To get rid of this display, you need to
+    really stop the timer with `C-u C-c C-x ,'.
+
+    Thanks to Alan Davis for driving this change.
+
 * Version 6.17
 
 ** Overview
@@ -209,9 +225,6 @@ remote highlighting possible.
     the current file would not work.
 
 * Version 6.16
-  :PROPERTIES:
-  :VISIBILITY: content
-  :END:
   Cleanup of many small bugs, and one new feature.
 
 ** Details

+ 4 - 0
doc/ChangeLog

@@ -1,3 +1,7 @@
+2009-01-08  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.texi (Relative timer): Document `org-timer-stop'.
+
 2008-12-31  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org.texi (Footnotes): New section.

+ 9 - 1
doc/org.texi

@@ -5078,8 +5078,16 @@ Insert a description list item with the current relative time.  With a prefix
 argument, first reset the timer to 0.
 @kindex M-@key{RET}
 @item M-@key{RET}
-One the timer list is started, you can also use @kbd{M-@key{RET}} to insert
+Once the timer list is started, you can also use @kbd{M-@key{RET}} to insert
 new timer items.
+@kindex C-c C-x ,
+@item C-c C-x ,
+Pause the timer, or continue it if it is already paused.  With prefix
+argument, stop it entirely.
+@kindex C-u C-c C-x ,
+@item C-u C-c C-x ,
+Stop the timer.  After this, you can only start a new timer, not continue the
+old one.  This command also removes the timer from the mode line.
 @kindex C-c C-x 0
 @item C-c C-x 0
 Reset the timer without inserting anything into the buffer.  By default, the

+ 9 - 0
lisp/ChangeLog

@@ -1,7 +1,16 @@
 2009-01-08  Carsten Dominik  <carsten.dominik@gmail.com>
 
+	* org-timer.el (org-timer-pause-or-continue): Implement stopping
+	and mode line display.
+	(org-timer-stop): New command.
+	(org-timer-seconds): Return correct time when timer is paused.
+	(org-timer-mode-line-timer): New variable.
+	(org-timer-set-mode-line, org-timer-update-mode-line): New
+	functions.
+
 	* org.el (org-insert-heading):  Handle new value `auto' for
 	`org-blank-before-new-entry'.
+	(org-org-menu): Add new items for timer functions.
 
 	* org-list.el (org-insert-item): Handle new value `auto' for
 	`org-blank-before-new-entry'.

+ 83 - 7
lisp/org-timer.el

@@ -1,4 +1,4 @@
-;;; org-clock.el --- The time clocking code for Org-mode
+;;; org-timer.el --- The relative timer code for Org-mode
 
 ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
@@ -32,6 +32,9 @@
 (defvar org-timer-start-time nil
   "t=0 for the running timer.")
 
+(defvar org-timer-pause-time nil
+  "Time when the timer was paused.")
+
 (defconst org-timer-re "\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)"
   "Regular expression used to match timer stamps.")
 
@@ -75,10 +78,41 @@ the region 0:00:00."
 	       (-
 		(time-to-seconds (current-time))
 		(org-timer-hms-to-secs s)))))
+      (org-timer-set-mode-line 'on)
       (message "Timer start time set to %s, current value is %s"
 	       (format-time-string "%T" org-timer-start-time)
 	       (org-timer-secs-to-hms (or delta 0))))))
 
+(defun org-timer-pause-or-continue (&optional stop)
+  "Pause or continue the relative timer.  With prefix arg, stop it entirely."
+  (interactive "P")
+  (cond
+   (stop (org-timer-stop))
+   ((not org-timer-start-time) (error "No timer is running"))
+   (org-timer-pause-time
+    ;; timer is paused, continue
+    (setq org-timer-start-time
+	  (seconds-to-time
+	   (-
+	    (time-to-seconds (current-time))
+	    (- (time-to-seconds org-timer-pause-time)
+	       (time-to-seconds org-timer-start-time))))
+	  org-timer-pause-time nil)
+    (org-timer-set-mode-line 'on)
+    (message "Timer continues at %s" (org-timer-value-string)))
+   (t
+    ;; pause timer
+    (setq org-timer-pause-time (current-time))
+    (org-timer-set-mode-line 'pause)
+    (message "Timer paused at %s" (org-timer-value-string)))))
+
+(defun org-timer-stop ()
+  "Stop the relative timer."
+  (interactive)
+  (setq org-timer-start-time nil
+	org-timer-pause-time nil)
+  (org-timer-set-mode-line 'off))
+
 ;;;###autoload
 (defun org-timer (&optional restart)
   "Insert a H:MM:SS string from the timer into the buffer.
@@ -90,12 +124,14 @@ that was not started at the correct moment."
   (interactive "P")
   (if (equal restart '(4)) (org-timer-start))
   (or org-timer-start-time (org-timer-start))
-  (insert (format
-	   org-timer-format
-	   (org-timer-secs-to-hms
-	    (floor
-	     (- (time-to-seconds (current-time))
-		(time-to-seconds org-timer-start-time)))))))
+  (insert (org-timer-value-string)))
+
+(defun org-timer-value-string ()
+  (format org-timer-format (org-timer-secs-to-hms (floor (org-timer-seconds)))))
+
+(defun org-timer-seconds ()
+  (- (time-to-seconds (or org-timer-pause-time (current-time)))
+     (time-to-seconds org-timer-start-time)))
 
 ;;;###autoload
 (defun org-timer-change-times-in-region (beg end delta)
@@ -176,6 +212,46 @@ If the integer is negative, the string will start with \"-\"."
 	  h (/ m 60) m (- m (* 60 h)))
     (format "%s%d:%02d:%02d" sign h m s)))
 
+(defvar org-timer-mode-line-timer nil)
+
+(defun org-timer-set-mode-line (value)
+  "Set the mode-line dispay of the relative timer.
+VALUE can be `on', `off', or `pause'."
+  (or global-mode-string (setq global-mode-string '("")))
+  (or (memq 'org-timer-mode-line-string global-mode-string)
+      (setq global-mode-string
+	    (append global-mode-string '(org-timer-mode-line-string))))
+  (cond
+   ((equal value 'off)
+    (when org-timer-mode-line-timer
+      (cancel-timer org-timer-mode-line-timer)
+      (setq org-timer-mode-line-timer nil))
+    (setq global-mode-string
+	  (delq 'org-timer-mode-line-string global-mode-string))
+    (force-mode-line-update))
+   ((equal value 'pause)
+    (when org-timer-mode-line-timer
+      (cancel-timer org-timer-mode-line-timer)
+      (setq org-timer-mode-line-timer nil)))
+   ((equal value 'on)
+    (or global-mode-string (setq global-mode-string '("")))
+    (or (memq 'org-timer-mode-line-string global-mode-string)
+	(setq global-mode-string
+	      (append global-mode-string '(org-timer-mode-line-string))))
+    (org-timer-update-mode-line)
+    (when org-timer-mode-line-timer
+      (cancel-timer org-timer-mode-line-timer))
+    (setq org-timer-mode-line-timer
+	  (run-with-timer 1 1 'org-timer-update-mode-line)))))
+
+(defun org-timer-update-mode-line ()
+  "Update the timer time in the mode line."
+  (if org-timer-pause-time
+      nil
+    (setq org-timer-mode-line-string
+	  (concat " <" (substring (org-timer-value-string) 0 -1) ">"))
+    (force-mode-line-update)))
+
 ;; arch-tag: 97538f8c-3871-4509-8f23-1e7b3ff3d107
 
 ;;; org-timer.el ends here

+ 6 - 3
lisp/org.el

@@ -12750,6 +12750,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]."
 (org-defkey org-mode-map "\C-c\C-x."    'org-timer)
 (org-defkey org-mode-map "\C-c\C-x-"    'org-timer-item)
 (org-defkey org-mode-map "\C-c\C-x0"    'org-timer-start)
+(org-defkey org-mode-map "\C-c\C-x,"    'org-timer-pause-or-continue)
 
 (define-key org-mode-map "\C-c\C-x\C-c" 'org-columns)
 
@@ -13538,9 +13539,11 @@ See the individual commands for more information."
      ["Goto Calendar" org-goto-calendar t]
      ["Date from Calendar" org-date-from-calendar t]
      "--"
-     ["Start/restart timer" org-timer-start t]
-     ["Insert timer string" org-timer t]
-     ["Insert timer item" org-timer-item t])
+     ["Start/Restart Timer" org-timer-start t]
+     ["Pause/Continue Timer" org-timer-pause-or-continue t]
+     ["Stop Timer" org-timer-pause-or-continue :active t :keys "C-u C-c C-x ,"]
+     ["Insert Timer String" org-timer t]
+     ["Insert Timer Item" org-timer-item t])
     ("Logging work"
      ["Clock in" org-clock-in t]
      ["Clock out" org-clock-out t]