ソースを参照

Add min/max/mean age operators to column view.

This lets you see how long has passed since the specified timestamp property
each entry. The three operators (@min, @max, @mean) show either the age of the
youngest or oldest entry or the average age of the children.
James TD Smith 16 年 前
コミット
2c983f0929
3 ファイル変更157 行追加85 行削除
  1. 28 10
      lisp/ChangeLog
  2. 127 73
      lisp/org-colview.el
  3. 2 2
      lisp/org.el

+ 28 - 10
lisp/ChangeLog

@@ -173,6 +173,30 @@
 	(org-clock-in): Use `org-clock-auto-clock-resolution' to determine
 	(org-clock-in): Use `org-clock-auto-clock-resolution' to determine
 	whether or not to resolve Org buffers on clock in.
 	whether or not to resolve Org buffers on clock in.
 
 
+2009-10-25  James TD Smith  <ahktenzero@mohorovi.cc>
+
+	* org-colview.el (org-format-time-period): Function to format
+	times in fractional days for display.
+	(org-columns-display-here): Add support for showing a calculated
+	value in place of the property.
+	(org-columns): Set `org-columns-time' to the current time so time
+	difference calculations will work.
+	(org-columns-time): Use to store the current time when column view
+	is displayed, so all time differences will use the same reference
+	point.
+	(org-columns-compile-map): There is now an extra position in each
+	entry specifying the function to use to calculate the displayed
+	value for the non-calculated properties in the column,
+	(org-columns-compute-all): Set `org-columns-time' to the current
+	time so time difference calculations will work.
+	(org-columns-compute): Handle column operators where the values
+	used are calculated from the underlying property.
+	(org-columns-number-to-string): Handle the 'age' column format
+	(org-columns-string-to-number): Correct the function name (was
+	org-column...). Add support for the 'age' column format.
+	(org-columns-compile-format): Support the additional parameter in
+	org-columns-compile-map.
+
 2009-10-26  Bastien Guerry  <bzg@altern.org>
 2009-10-26  Bastien Guerry  <bzg@altern.org>
 
 
 	* org.el (org-mode-hook): Turn `org-mode-hook' into a customizable
 	* org.el (org-mode-hook): Turn `org-mode-hook' into a customizable
@@ -1723,20 +1747,14 @@
 	* org-exp.el (org-export-format-source-code-or-example): Fix
 	* org-exp.el (org-export-format-source-code-or-example): Fix
 	bad line numbering when exporting examples in HTML.
 	bad line numbering when exporting examples in HTML.
 
 
-2009-07-12  James TD Smith  <ahktenzero@mohorovi.cc>
-
 	* org-colview.el (org-format-time-period): Formats a time in
 	* org-colview.el (org-format-time-period): Formats a time in
 	fractional days as days, hours, mins, seconds.
 	fractional days as days, hours, mins, seconds.
 	(org-columns-display-here): Add special handling for SINCE and
 	(org-columns-display-here): Add special handling for SINCE and
 	SINCE_IA to format for display.
 	SINCE_IA to format for display.
 
 
-	* org.el (org-time-since): Add a function to get the time since an
-	org timestamp.
-	(org-entry-properties): Add two new special properties: SINCE and
-	SINCE_IA. These give the time since any active or inactive
-	timestamp in an entry.
-	(org-special-properties): Add SINCE, SINCE_IA.
-	(org-tags-sort-function): Add custom declaration for tags
+2009-07-12  James TD Smith  <ahktenzero@mohorovi.cc>
+
+	* org.el (org-tags-sort-function): Add custom declaration for tags
 	sorting function.
 	sorting function.
 	(org-set-tags): Sort tags if org-tags-sort-function is set
 	(org-set-tags): Sort tags if org-tags-sort-function is set
 
 
@@ -4603,7 +4621,7 @@
 	(org-agenda-change-all-lines, org-tags-sparse-tree)
 	(org-agenda-change-all-lines, org-tags-sparse-tree)
 	(org-time-string-to-absolute, org-small-year-to-year)
 	(org-time-string-to-absolute, org-small-year-to-year)
 	(org-link-escape): Re-apply changes accidentially overwritten
 	(org-link-escape): Re-apply changes accidentially overwritten
-	by last commit to Emacs.
+	by last commit to Emacs
 
 
 2008-11-23  Carsten Dominik  <carsten.dominik@gmail.com>
 2008-11-23  Carsten Dominik  <carsten.dominik@gmail.com>
 
 

+ 127 - 73
lisp/org-colview.el

@@ -111,8 +111,8 @@ This is the compiled version of the format.")
 (org-defkey org-columns-map [(shift meta left)] 'org-columns-delete)
 (org-defkey org-columns-map [(shift meta left)] 'org-columns-delete)
 (dotimes (i 10)
 (dotimes (i 10)
   (org-defkey org-columns-map (number-to-string i)
   (org-defkey org-columns-map (number-to-string i)
-              `(lambda () (interactive)
-                 (org-columns-next-allowed-value nil ,i))))
+	      `(lambda () (interactive)
+		 (org-columns-next-allowed-value nil ,i))))
 
 
 (easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
 (easy-menu-define org-columns-menu org-columns-map "Org Column Menu"
   '("Column"
   '("Column"
@@ -165,7 +165,7 @@ This is the compiled version of the format.")
 	 (face1 (list color 'org-agenda-column-dateline ref-face))
 	 (face1 (list color 'org-agenda-column-dateline ref-face))
 	 (pl (or (get-text-property (point-at-bol) 'prefix-length) 0))
 	 (pl (or (get-text-property (point-at-bol) 'prefix-length) 0))
 	 (cphr (get-text-property (point-at-bol) 'org-complex-heading-regexp))
 	 (cphr (get-text-property (point-at-bol) 'org-complex-heading-regexp))
-	 pom property ass width f string ov column val modval s2 title)
+	 pom property ass width f string ov column val modval s2 title calc)
     ;; Check if the entry is in another buffer.
     ;; Check if the entry is in another buffer.
     (unless props
     (unless props
       (if (eq major-mode 'org-agenda-mode)
       (if (eq major-mode 'org-agenda-mode)
@@ -189,19 +189,25 @@ This is the compiled version of the format.")
 		      (nth 2 column)
 		      (nth 2 column)
 		      (length property))
 		      (length property))
 	    f (format "%%-%d.%ds | " width width)
 	    f (format "%%-%d.%ds | " width width)
+	    calc (nth 7 column)
 	    val (or (cdr ass) "")
 	    val (or (cdr ass) "")
-	    modval (or (and org-columns-modify-value-for-display-function
-			    (functionp
-			     org-columns-modify-value-for-display-function)
-			    (funcall
-			     org-columns-modify-value-for-display-function
-			     title val))
-		       (if (equal property "ITEM")
-			   (if (org-mode-p)
-			       (org-columns-cleanup-item
-				val org-columns-current-fmt-compiled)
-			     (org-agenda-columns-cleanup-item
-			      val pl cphr org-columns-current-fmt-compiled)))))
+	    modval (cond ((and org-columns-modify-value-for-display-function
+			       (functionp
+				org-columns-modify-value-for-display-function))
+			  (funcall org-columns-modify-value-for-display-function
+				   title val))
+			 ((equal property "ITEM")
+			  (if (org-mode-p)
+			      (org-columns-cleanup-item
+			       val org-columns-current-fmt-compiled)
+			    (org-agenda-columns-cleanup-item
+			     val pl cphr org-columns-current-fmt-compiled)))
+			 ((and calc (functionp calc)
+			       (not (get-text-property 0 'org-computed val)))
+			  (org-columns-number-to-string
+			   (funcall calc (org-columns-string-to-number
+					  val (nth 4 column)))
+			   (nth 4 column)))))
       (setq s2 (org-columns-add-ellipses (or modval val) width))
       (setq s2 (org-columns-add-ellipses (or modval val) width))
       (setq string (format f s2))
       (setq string (format f s2))
       ;; Create the overlay
       ;; Create the overlay
@@ -220,18 +226,18 @@ This is the compiled version of the format.")
 	    (save-excursion
 	    (save-excursion
 	      (goto-char beg)
 	      (goto-char beg)
 	      (org-unmodified (insert " ")))))) ;; FIXME: add props and remove later?
 	      (org-unmodified (insert " ")))))) ;; FIXME: add props and remove later?
-    ;; Make the rest of the line disappear.
-    (org-unmodified
-     (setq ov (org-columns-new-overlay beg (point-at-eol)))
-     (org-overlay-put ov 'invisible t)
-     (org-overlay-put ov 'keymap org-columns-map)
-     (org-overlay-put ov 'intangible t)
-     (push ov org-columns-overlays)
-     (setq ov (org-make-overlay (1- (point-at-eol)) (1+ (point-at-eol))))
-     (org-overlay-put ov 'keymap org-columns-map)
-     (push ov org-columns-overlays)
-     (let ((inhibit-read-only t))
-       (put-text-property (max (point-min) (1- (point-at-bol)))
+      ;; Make the rest of the line disappear.
+      (org-unmodified
+       (setq ov (org-columns-new-overlay beg (point-at-eol)))
+       (org-overlay-put ov 'invisible t)
+       (org-overlay-put ov 'keymap org-columns-map)
+       (org-overlay-put ov 'intangible t)
+       (push ov org-columns-overlays)
+       (setq ov (org-make-overlay (1- (point-at-eol)) (1+ (point-at-eol))))
+       (org-overlay-put ov 'keymap org-columns-map)
+       (push ov org-columns-overlays)
+       (let ((inhibit-read-only t))
+	 (put-text-property (max (point-min) (1- (point-at-bol)))
 			  (min (point-max) (1+ (point-at-eol)))
 			  (min (point-max) (1+ (point-at-eol)))
 			  'read-only "Type `e' to edit property")))))
 			  'read-only "Type `e' to edit property")))))
 
 
@@ -257,6 +263,7 @@ for the duration of the command.")
 
 
 (defvar header-line-format)
 (defvar header-line-format)
 (defvar org-columns-previous-hscroll 0)
 (defvar org-columns-previous-hscroll 0)
+
 (defun org-columns-display-here-title ()
 (defun org-columns-display-here-title ()
   "Overlay the newline before the current line with the table title."
   "Overlay the newline before the current line with the table title."
   (interactive)
   (interactive)
@@ -347,6 +354,7 @@ for the duration of the command.")
   s)
   s)
 
 
 (defvar org-agenda-columns-remove-prefix-from-item)
 (defvar org-agenda-columns-remove-prefix-from-item)
+
 (defun org-agenda-columns-cleanup-item (item pl cphr fmt)
 (defun org-agenda-columns-cleanup-item (item pl cphr fmt)
   "Cleanup the time property for agenda column view.
   "Cleanup the time property for agenda column view.
 See also the variable `org-agenda-columns-remove-prefix-from-item'."
 See also the variable `org-agenda-columns-remove-prefix-from-item'."
@@ -366,6 +374,7 @@ See also the variable `org-agenda-columns-remove-prefix-from-item'."
     (message "Value is: %s" (or value ""))))
     (message "Value is: %s" (or value ""))))
 
 
 (defvar org-agenda-columns-active) ;; defined in org-agenda.el
 (defvar org-agenda-columns-active) ;; defined in org-agenda.el
+
 (defun org-columns-quit ()
 (defun org-columns-quit ()
   "Remove the column overlays and in this way exit column editing."
   "Remove the column overlays and in this way exit column editing."
   (interactive)
   (interactive)
@@ -417,6 +426,7 @@ Where possible, use the standard interface for changing this line."
 				   (<= (overlay-start x) eol)
 				   (<= (overlay-start x) eol)
 				   x))
 				   x))
 			    org-columns-overlays)))
 			    org-columns-overlays)))
+	 (org-columns-time (time-to-number-of-days (current-time)))
 	 nval eval allowed)
 	 nval eval allowed)
     (cond
     (cond
      ((equal key "CLOCKSUM")
      ((equal key "CLOCKSUM")
@@ -661,7 +671,8 @@ around it."
   (org-verify-version 'columns)
   (org-verify-version 'columns)
   (org-columns-remove-overlays)
   (org-columns-remove-overlays)
   (move-marker org-columns-begin-marker (point))
   (move-marker org-columns-begin-marker (point))
-  (let (beg end fmt cache maxwidths)
+  (let ((org-columns-time (time-to-number-of-days (current-time)))
+	beg end fmt cache maxwidths)
     (setq fmt (org-columns-get-format-and-top-level))
     (setq fmt (org-columns-get-format-and-top-level))
     (save-excursion
     (save-excursion
       (goto-char org-columns-top-level-marker)
       (goto-char org-columns-top-level-marker)
@@ -678,7 +689,7 @@ around it."
 	    (narrow-to-region beg end)
 	    (narrow-to-region beg end)
 	    (org-clock-sum))))
 	    (org-clock-sum))))
       (while (re-search-forward (concat "^" outline-regexp) end t)
       (while (re-search-forward (concat "^" outline-regexp) end t)
-	(if (and org-columns-skip-arrchived-trees
+	(if (and org-columns-skip-archived-trees
 		 (looking-at (concat ".*:" org-archive-tag ":")))
 		 (looking-at (concat ".*:" org-archive-tag ":")))
 	    (org-end-of-subtree t)
 	    (org-end-of-subtree t)
 	  (push (cons (org-current-line) (org-entry-properties)) cache)))
 	  (push (cons (org-current-line) (org-entry-properties)) cache)))
@@ -698,20 +709,34 @@ around it."
 		(org-columns-display-here (cdr x)))
 		(org-columns-display-here (cdr x)))
 	      cache)))))
 	      cache)))))
 
 
+(eval-when-compile (defvar org-columns-time))
+
 (defvar org-columns-compile-map
 (defvar org-columns-compile-map
-  '(("none"  none              +)
-    (":"     add_times         +)
-    ("+"     add_numbers       +)
-    ("$"     currency          +)
-    ("X"     checkbox          +)
-    ("X/"    checkbox-n-of-m   +)
-    ("X%"    checkbox-percent  +)
-    ("max"   max_numbers       max)
-    ("min"   min_numbers       min)
-    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
-    (":max"  max_times         max)
-    (":min"  min_times         min)
-    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  '(("none" none + identity)
+    (":" add_times + identity)
+    ("+" add_numbers + identity)
+    ("$" currency + identity)
+    ("X" checkbox + identity)
+    ("X/" checkbox-n-of-m + identity)
+    ("X%" checkbox-percent + identity)
+    ("max" max_numbers max identity)
+    ("min" min_numbers min identity)
+    ("mean" mean_numbers
+     (lambda (&rest x) (/ (apply '+ x) (float (length x))))
+     identity)
+    (":max" max_times max identity)
+    (":min" min_times min identity)
+    (":mean" mean_times
+     (lambda (&rest x) (/ (apply '+ x) (float (length x))))
+     identity)
+    ("@min" age min
+     (lambda (x) (- org-columns-time x)))
+    ("@max" age max
+     (lambda (x) (- org-columns-time x)))
+    ("@mean" age
+     (lambda (&rest x)
+       (/ (apply '+ x) (float (length x))))
+     (lambda (x) (- org-columns-time x))))
   "Operator <-> format,function map.
   "Operator <-> format,function map.
 Used to compile/uncompile columns format and completing read in
 Used to compile/uncompile columns format and completing read in
 interactive function org-columns-new.")
 interactive function org-columns-new.")
@@ -860,7 +885,9 @@ Don't set this, this is meant for dynamic scoping.")
   "Compute all columns that have operators defined."
   "Compute all columns that have operators defined."
   (org-unmodified
   (org-unmodified
    (remove-text-properties (point-min) (point-max) '(org-summaries t)))
    (remove-text-properties (point-min) (point-max) '(org-summaries t)))
-  (let ((columns org-columns-current-fmt-compiled) col)
+  (let ((columns org-columns-current-fmt-compiled)
+	(org-columns-time (time-to-number-of-days (current-time)))
+	col)
     (while (setq col (pop columns))
     (while (setq col (pop columns))
       (when (nth 3 col)
       (when (nth 3 col)
 	(save-excursion
 	(save-excursion
@@ -895,6 +922,7 @@ Don't set this, this is meant for dynamic scoping.")
 	 (format (nth 4 ass))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
 	 (printf (nth 5 ass))
 	 (fun (nth 6 ass))
 	 (fun (nth 6 ass))
+	 (calc (or (nth 7 ass) 'identity))
 	 (beg org-columns-top-level-marker)
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
     (save-excursion
@@ -927,10 +955,12 @@ Don't set this, this is meant for dynamic scoping.")
 				  (list 'org-summaries sum-alist))))
 				  (list 'org-summaries sum-alist))))
 	  (when (and val (not (equal val (if flag str val))))
 	  (when (and val (not (equal val (if flag str val))))
 	    (org-entry-put nil property (if flag str val)))
 	    (org-entry-put nil property (if flag str val)))
-	  ;; add current to current  level accumulator
+	  ;; add current to current level accumulator
 	  (when (or flag valflag)
 	  (when (or flag valflag)
-	    (push (if flag sum
-		    (org-column-string-to-number (if flag str val) format))
+	    (push (if flag
+		      sum
+		    (funcall calc (org-columns-string-to-number
+				   (if flag str val) format)))
 		  (aref lvals level))
 		  (aref lvals level))
 	    (aset lflag level t))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  ;; clear accumulators for deeper levels
@@ -940,8 +970,8 @@ Don't set this, this is meant for dynamic scoping.")
 	 ((>= level last-level)
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
 	  ;; add what we have here to the accumulator for this level
 	  (when valflag
 	  (when valflag
-	    (push (org-column-string-to-number val format)
-		(aref lvals level))
+	    (push (funcall calc (org-columns-string-to-number val format))
+		  (aref lvals level))
 	    (aset lflag level t)))
 	    (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 	 (t (error "This should not happen")))))))
 
 
@@ -967,7 +997,6 @@ Don't set this, this is meant for dynamic scoping.")
   (if (eq major-mode 'org-agenda-mode)
   (if (eq major-mode 'org-agenda-mode)
       (error "This command is only allowed in Org-mode buffers")))
       (error "This command is only allowed in Org-mode buffers")))
 
 
-
 (defun org-string-to-number (s)
 (defun org-string-to-number (s)
   "Convert string to number, and interpret hh:mm:ss."
   "Convert string to number, and interpret hh:mm:ss."
   (if (not (string-match ":" s))
   (if (not (string-match ":" s))
@@ -994,6 +1023,8 @@ Don't set this, this is meant for dynamic scoping.")
    (printf (format printf n))
    (printf (format printf n))
    ((eq fmt 'currency)
    ((eq fmt 'currency)
     (format "%.2f" n))
     (format "%.2f" n))
+   ((eq fmt 'age)
+    (org-format-time-period n))
    (t (number-to-string n))))
    (t (number-to-string n))))
 
 
 (defun org-nofm-to-completion (n m &optional percent)
 (defun org-nofm-to-completion (n m &optional percent)
@@ -1001,17 +1032,23 @@ Don't set this, this is meant for dynamic scoping.")
       (format "[%d/%d]" n m)
       (format "[%d/%d]" n m)
     (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m)))))))
     (format "[%d%%]"(floor (+ 0.5 (* 100. (/ (* 1.0 n) m)))))))
 
 
-(defun org-column-string-to-number (s fmt)
+(defun org-columns-string-to-number (s fmt)
   "Convert a column value to a number that can be used for column computing."
   "Convert a column value to a number that can be used for column computing."
-  (cond
-   ((string-match ":" s)
-    (let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
-      (while l
-	(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
-      sum))
-   ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
-    (if (equal s "[X]") 1. 0.000001))
-   (t (string-to-number s))))
+  (if s
+      (cond
+       ((eq fmt 'age)
+	(if (string= s "")
+	    org-columns-time
+	  (time-to-number-of-days (apply 'encode-time (org-parse-time-string s t)))))
+       ((string-match ":" s)
+	(let ((l (nreverse (org-split-string s ":"))) (sum 0.0))
+	  (while l
+	    (setq sum (+ (string-to-number (pop l)) (/ sum 60))))
+	  sum))
+       ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent))
+	(if (equal s "[X]") 1. 0.000001))
+       (t (string-to-number s)))
+    0))
 
 
 (defun org-columns-uncompile-format (cfmt)
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
   "Turn the compiled columns format back into a string representation."
@@ -1045,8 +1082,10 @@ width        the column width in characters, can be nil for automatic
 operator     the operator if any
 operator     the operator if any
 format       the output format for computed results, derived from operator
 format       the output format for computed results, derived from operator
 printf       a printf format for computed values
 printf       a printf format for computed values
-fun          the lisp function to compute values, derived from operator"
-  (let ((start 0) width prop title op op-match f printf fun)
+fun          the lisp function to compute summary values, derived from operator
+calc         function to get values from base elements
+"
+  (let ((start 0) width prop title op op-match f printf fun calc)
     (setq org-columns-current-fmt-compiled nil)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1058,15 +1097,18 @@ fun          the lisp function to compute values, derived from operator"
 	    op (match-string 4 fmt)
 	    op (match-string 4 fmt)
 	    f nil
 	    f nil
 	    printf nil
 	    printf nil
-	    fun '+)
+	    fun '+
+	    calc nil)
       (if width (setq width (string-to-number width)))
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
 	      op (substring op 0 (match-beginning 0))))
       (when (setq op-match (assoc op org-columns-compile-map))
       (when (setq op-match (assoc op org-columns-compile-map))
 	(setq f (cadr op-match)
 	(setq f (cadr op-match)
-	      fun (caddr op-match)))
-      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
+	      fun (caddr op-match)
+	      calc (cadddr op-match)))
+      (push (list prop title width op f printf fun calc)
+	    org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 	  (nreverse org-columns-current-fmt-compiled))))
 
 
@@ -1121,18 +1163,18 @@ PARAMS is a property list of parameters:
 
 
 :width    enforce same column widths with <N> specifiers.
 :width    enforce same column widths with <N> specifiers.
 :id       the :ID: property of the entry where the columns view
 :id       the :ID: property of the entry where the columns view
-          should be built.  When the symbol `local', call locally.
-          When `global' call column view with the cursor at the beginning
-          of the buffer (usually this means that the whole buffer switches
-          to column view).  When \"file:path/to/file.org\", invoke column
-          view at the start of that file.  Otherwise, the ID is located
-          using `org-id-find'.
+	  should be built.  When the symbol `local', call locally.
+	  When `global' call column view with the cursor at the beginning
+	  of the buffer (usually this means that the whole buffer switches
+	  to column view).  When \"file:path/to/file.org\", invoke column
+	  view at the start of that file.  Otherwise, the ID is located
+	  using `org-id-find'.
 :hlines   When t, insert a hline before each item.  When a number, insert
 :hlines   When t, insert a hline before each item.  When a number, insert
-          a hline before each level <= that number.
+	  a hline before each level <= that number.
 :vlines   When t, make each column a colgroup to enforce vertical lines.
 :vlines   When t, make each column a colgroup to enforce vertical lines.
 :maxlevel When set to a number, don't capture headlines below this level.
 :maxlevel When set to a number, don't capture headlines below this level.
 :skip-empty-rows
 :skip-empty-rows
-          When t, skip rows where all specifiers other than ITEM are empty."
+	  When t, skip rows where all specifiers other than ITEM are empty."
   (let ((pos (move-marker (make-marker) (point)))
   (let ((pos (move-marker (make-marker) (point)))
 	(hlines (plist-get params :hlines))
 	(hlines (plist-get params :hlines))
 	(vlines (plist-get params :vlines))
 	(vlines (plist-get params :vlines))
@@ -1351,7 +1393,7 @@ This will add overlays to the date lines, to show the summary for each day."
 			 (mapc (lambda (x)
 			 (mapc (lambda (x)
 				 (setq v (cdr (assoc prop x)))
 				 (setq v (cdr (assoc prop x)))
 				 (if v (setq lsum (+ lsum
 				 (if v (setq lsum (+ lsum
-						     (org-column-string-to-number
+						     (org-columns-string-to-number
 						      v stype)))))
 						      v stype)))))
 			       entries)
 			       entries)
 			 (setq lsum (org-columns-number-to-string lsum stype))
 			 (setq lsum (org-columns-number-to-string lsum stype))
@@ -1390,6 +1432,18 @@ This will add overlays to the date lines, to show the summary for each day."
 			   (equal (nth 4 a) (nth 4 fm)))
 			   (equal (nth 4 a) (nth 4 fm)))
 		  (org-columns-compute (car fm)))))))))))
 		  (org-columns-compute (car fm)))))))))))
 
 
+(defun org-format-time-period (interval)
+  "Convert time in fractional days to days/hours/minutes/seconds"
+  (if (numberp interval)
+    (let* ((days (floor interval))
+	   (frac-hours (* 24 (- interval days)))
+	   (hours (floor frac-hours))
+	   (minutes (floor (* 60 (- frac-hours hours))))
+	   (seconds (floor (* 60 (- (* 60 (- frac-hours hours)) minutes)))))
+      (format "%dd %02dh %02dm %02ds" days hours minutes seconds))
+    ""))
+
+
 (provide 'org-colview)
 (provide 'org-colview)
 
 
 ;; arch-tag: 61f5128d-747c-4983-9479-e3871fa3d73c
 ;; arch-tag: 61f5128d-747c-4983-9479-e3871fa3d73c

+ 2 - 2
lisp/org.el

@@ -3394,8 +3394,8 @@ Instead, use the key `v' to cycle the archives-mode in the agenda."
   :group 'org-agenda-skip
   :group 'org-agenda-skip
   :type 'boolean)
   :type 'boolean)
 
 
-(defcustom org-columns-skip-arrchived-trees t
-  "Non-nil means, irgnore archived trees when creating column view."
+(defcustom org-columns-skip-archived-trees t
+  "Non-nil means, ignore archived trees when creating column view."
   :group 'org-archive
   :group 'org-archive
   :group 'org-properties
   :group 'org-properties
   :type 'boolean)
   :type 'boolean)