浏览代码

Show clock overruns in mode line

Patch by Richard Riley.
Carsten Dominik 15 年之前
父节点
当前提交
7f0995dcab
共有 3 个文件被更改,包括 76 次插入21 次删除
  1. 10 0
      lisp/ChangeLog
  2. 55 13
      lisp/org-clock.el
  3. 11 8
      lisp/org-faces.el

+ 10 - 0
lisp/ChangeLog

@@ -1,3 +1,13 @@
+2010-01-23  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-clock.el (org-task-overrun-text): New option.
+	(org-task-overrun, org-clock-update-period): New variables.
+	(org-clock-get-clock-string, org-clock-update-mode-line): Mark
+	overrun clock.
+	(org-clock-notify-once-if-expired): Check if clock is overrun.
+
+	* org-faces.el: New face `org-mode-line-clock-overrun'.
+
 2010-01-18  Jan Böcker  <jan.boecker@jboecker.de>
 2010-01-18  Jan Böcker  <jan.boecker@jboecker.de>
 
 
 	* org.el (org-narrow-to-subtree): Position the end of the narrowed
 	* org.el (org-narrow-to-subtree): Position the end of the narrowed

+ 55 - 13
lisp/org-clock.el

@@ -200,6 +200,17 @@ auto     Automatically, either `all', or `repeat' for repeating tasks"
 	  (const :tag "All task time" all)
 	  (const :tag "All task time" all)
 	  (const :tag "Automatically, `all' or since `repeat'" auto)))
 	  (const :tag "Automatically, `all' or since `repeat'" auto)))
 
 
+(defcustom org-task-overrun-text nil
+  "The extra modeline text that should indicate that the clock is overrun.
+The can be nil to indicate that instead of adding text, the clock time
+should get a different face (`org-mode-ling-clock-overrun').
+When this is a string, it is prepended to the clock string as an indication,
+also using the face `org-mode-ling-clock-overrun'."
+  :group 'org-clock
+  :type '(choice
+	  (const :tag "Just mark the time string" nil)
+	  (string :tag "Text to prepend")))
+
 (defcustom org-show-notification-handler nil
 (defcustom org-show-notification-handler nil
   "Function or program to send notification with.
   "Function or program to send notification with.
 The function or program will be called with the notification
 The function or program will be called with the notification
@@ -388,6 +399,11 @@ pointing to it."
 	(insert (format "[%c] %-15s %s\n" i cat task))
 	(insert (format "[%c] %-15s %s\n" i cat task))
 	(cons i marker)))))
 	(cons i marker)))))
 
 
+(defvar org-task-overrun nil
+  "Internal flag indicating if the clock has overrun the planned time.")
+(defvar org-clock-update-period 60
+  "Number of seconds between mode line clock string updates.")
+
 (defun org-clock-get-clock-string ()
 (defun org-clock-get-clock-string ()
   "Form a clock-string, that will be show in the mode line.
   "Form a clock-string, that will be show in the mode line.
 If an effort estimate was defined for current item, use
 If an effort estimate was defined for current item, use
@@ -396,29 +412,50 @@ If not, show simply the clocked time like 01:50."
   (let* ((clocked-time (org-clock-get-clocked-time))
   (let* ((clocked-time (org-clock-get-clocked-time))
 	 (h (floor clocked-time 60))
 	 (h (floor clocked-time 60))
 	 (m (- clocked-time (* 60 h))))
 	 (m (- clocked-time (* 60 h))))
-    (if (and org-clock-effort)
-	(let* ((effort-in-minutes (org-hh:mm-string-to-minutes org-clock-effort))
+    (if org-clock-effort
+	(let* ((effort-in-minutes
+		(org-hh:mm-string-to-minutes org-clock-effort))
 	       (effort-h (floor effort-in-minutes 60))
 	       (effort-h (floor effort-in-minutes 60))
-	       (effort-m (- effort-in-minutes (* effort-h 60))))
-	  (format (concat "-[" org-time-clocksum-format "/" org-time-clocksum-format " (%s)]")
-		  h m effort-h effort-m  org-clock-heading))
-      (format (concat "-[" org-time-clocksum-format " (%s)]")
-	      h m org-clock-heading))))
+	       (effort-m (- effort-in-minutes (* effort-h 60)))
+	       (work-done-str
+		(org-propertize
+		 (format org-time-clocksum-format h m)
+		 'face (if (and org-task-overrun (not org-task-overrun-text))
+			   'org-mode-line-clock-overrun 'org-mode-line-clock)))
+	       (effort-str (format org-time-clocksum-format effort-h effort-m))
+	       (clockstr (org-propertize
+			  (concat  "[%s/" effort-str
+				   "] (" org-clock-heading ")")
+			  'face 'org-mode-line-clock)))
+	  (format clockstr work-done-str))
+      (org-propertize (format
+		       (concat "[" org-time-clocksum-format " (%s)]")
+		       h m org-clock-heading)
+		      'face 'org-mode-line-clock))))
 
 
 (defun org-clock-update-mode-line ()
 (defun org-clock-update-mode-line ()
+  (if org-clock-effort
+      (org-clock-notify-once-if-expired)
+    (setq org-task-overrun nil))
   (setq org-mode-line-string
   (setq org-mode-line-string
 	(org-propertize
 	(org-propertize
 	 (let ((clock-string (org-clock-get-clock-string))
 	 (let ((clock-string (org-clock-get-clock-string))
 	       (help-text "Org-mode clock is running.\nmouse-1 shows a menu\nmouse-2 will jump to task"))
 	       (help-text "Org-mode clock is running.\nmouse-1 shows a menu\nmouse-2 will jump to task"))
 	   (if (and (> org-clock-string-limit 0)
 	   (if (and (> org-clock-string-limit 0)
 		    (> (length clock-string) org-clock-string-limit))
 		    (> (length clock-string) org-clock-string-limit))
-	       (org-propertize (substring clock-string 0 org-clock-string-limit)
-			       'help-echo (concat help-text ": " org-clock-heading))
+	       (org-propertize
+		(substring clock-string 0 org-clock-string-limit)
+		'help-echo (concat help-text ": " org-clock-heading))
 	     (org-propertize clock-string 'help-echo help-text)))
 	     (org-propertize clock-string 'help-echo help-text)))
 	 'local-map org-clock-mode-line-map
 	 'local-map org-clock-mode-line-map
 	 'mouse-face (if (featurep 'xemacs) 'highlight 'mode-line-highlight)
 	 'mouse-face (if (featurep 'xemacs) 'highlight 'mode-line-highlight)
-	 'face 'org-mode-line-clock))
-  (if org-clock-effort (org-clock-notify-once-if-expired))
+	 ))
+  (if (and org-task-overrun org-task-overrun-text)
+      (setq org-mode-line-string
+	    (concat (org-propertize
+		     org-task-overrun-text
+		     'face 'org-mode-line-clock-overrun) org-mode-line-string)))
+ 
   (force-mode-line-update))
   (force-mode-line-update))
 
 
 (defun org-clock-get-clocked-time ()
 (defun org-clock-get-clocked-time ()
@@ -473,7 +510,10 @@ Notification is shown only once."
   (when (marker-buffer org-clock-marker)
   (when (marker-buffer org-clock-marker)
     (let ((effort-in-minutes (org-hh:mm-string-to-minutes org-clock-effort))
     (let ((effort-in-minutes (org-hh:mm-string-to-minutes org-clock-effort))
 	  (clocked-time (org-clock-get-clocked-time)))
 	  (clocked-time (org-clock-get-clocked-time)))
-      (if (>= clocked-time effort-in-minutes)
+      (if (setq org-task-overrun 
+		(if (or (null effort-in-minutes) (zerop effort-in-minutes))
+		    nil
+		  (>= clocked-time effort-in-minutes)))
 	  (unless org-clock-notification-was-shown
 	  (unless org-clock-notification-was-shown
 	    (setq org-clock-notification-was-shown t)
 	    (setq org-clock-notification-was-shown t)
 	    (org-notify
 	    (org-notify
@@ -989,7 +1029,9 @@ the clocking selection, associated with the letter `d'."
 	      (cancel-timer org-clock-mode-line-timer)
 	      (cancel-timer org-clock-mode-line-timer)
 	      (setq org-clock-mode-line-timer nil))
 	      (setq org-clock-mode-line-timer nil))
 	    (setq org-clock-mode-line-timer
 	    (setq org-clock-mode-line-timer
-		  (run-with-timer 60 60 'org-clock-update-mode-line))
+		  (run-with-timer org-clock-update-period
+				  org-clock-update-period
+				  'org-clock-update-mode-line))
 	    (when org-clock-idle-timer
 	    (when org-clock-idle-timer
 	      (cancel-timer org-clock-idle-timer)
 	      (cancel-timer org-clock-idle-timer)
 	      (setq org-clock-idle-timer nil))
 	      (setq org-clock-idle-timer nil))

+ 11 - 8
lisp/org-faces.el

@@ -378,10 +378,10 @@ list of attributes, like (:foreground \"blue\" :weight bold :underline t)."
 
 
 
 
 (org-copy-face 'org-todo 'org-checkbox-statistics-todo
 (org-copy-face 'org-todo 'org-checkbox-statistics-todo
-	       "Face used for unfinished checkbox statistics.")
+  "Face used for unfinished checkbox statistics.")
 
 
 (org-copy-face 'org-done 'org-checkbox-statistics-done
 (org-copy-face 'org-done 'org-checkbox-statistics-done
-	       "Face used for finished checkbox statistics.")
+  "Face used for finished checkbox statistics.")
 
 
 (defcustom org-tag-faces nil
 (defcustom org-tag-faces nil
   "Faces for specific tags.
   "Faces for specific tags.
@@ -502,17 +502,17 @@ changes."
   :group 'org-faces)
   :group 'org-faces)
 
 
 (org-copy-face 'org-agenda-structure 'org-agenda-date
 (org-copy-face 'org-agenda-structure 'org-agenda-date
-	       "Face used in agenda for normal days.")
+  "Face used in agenda for normal days.")
 
 
 (org-copy-face 'org-agenda-date 'org-agenda-date-today
 (org-copy-face 'org-agenda-date 'org-agenda-date-today
-	       "Face used in agenda for today."
-	       :weight 'bold :italic 't)
+  "Face used in agenda for today."
+  :weight 'bold :italic 't)
 
 
 (org-copy-face 'secondary-selection 'org-agenda-clocking
 (org-copy-face 'secondary-selection 'org-agenda-clocking
-	       "Face marking the current clock item in the agenda.")
+  "Face marking the current clock item in the agenda.")
 
 
 (org-copy-face 'org-agenda-date 'org-agenda-date-weekend
 (org-copy-face 'org-agenda-date 'org-agenda-date-weekend
-	       "Face used in agenda for weekend days.
+  "Face used in agenda for weekend days.
 See the variable `org-agenda-weekend-days' for a definition of which days
 See the variable `org-agenda-weekend-days' for a definition of which days
 belong to the weekend."
 belong to the weekend."
 	       :weight 'bold)
 	       :weight 'bold)
@@ -640,7 +640,10 @@ If it is less than 8, the level-1 face gets re-used for level N+1 etc."
   :group 'org-faces)
   :group 'org-faces)
 
 
 (org-copy-face 'modeline 'org-mode-line-clock
 (org-copy-face 'modeline 'org-mode-line-clock
-	       "Face used for clock display in mode line.")
+  "Face used for clock display in mode line.")
+(org-copy-face 'modeline 'org-mode-line-clock-overrun 
+  "Face used for clock display for overrun tasks in mode line."
+  :background "red")
 
 
 (provide 'org-faces)
 (provide 'org-faces)