]> code.delx.au - gnu-emacs/blobdiff - lisp/org/org-clock.el
Merge Org version 8.2.3a.
[gnu-emacs] / lisp / org / org-clock.el
index de5087e163cbc8da228877bb7714212309cb4948..9f2256286b19012bcde28605efa52556d96bcdff 100644 (file)
@@ -1,11 +1,10 @@
 ;;; org-clock.el --- The time clocking code for Org-mode
 
-;; Copyright (C) 2004-201 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2013 Free Software Foundation, Inc.
 
 ;; Author: Carsten Dominik <carsten at orgmode dot org>
 ;; Keywords: outlines, hypermedia, calendar, wp
 ;; Homepage: http://orgmode.org
-;; Version: 7.7
 ;;
 ;; This file is part of GNU Emacs.
 ;;
 
 ;; This file contains the time clocking code for Org-mode
 
-(require 'org)
-(require 'org-exp)
 ;;; Code:
 
 (eval-when-compile
   (require 'cl))
+(require 'org)
 
 (declare-function calendar-absolute-from-iso "cal-iso" (&optional date))
 (declare-function notifications-notify "notifications" (&rest params))
+(declare-function org-pop-to-buffer-same-window "org-compat" (&optional buffer-or-name norecord label))
+(declare-function org-refresh-properties "org" (dprop tprop))
 (defvar org-time-stamp-formats)
 (defvar org-ts-what)
+(defvar org-frame-title-format-backup frame-title-format)
 
 (defgroup org-clock nil
   "Options concerning clocking working time in Org-mode."
@@ -94,6 +95,24 @@ clocking out."
          (repeat :tag "State list"
                  (string :tag "TODO keyword"))))
 
+(defcustom org-clock-rounding-minutes 0
+  "Rounding minutes when clocking in or out.
+The default value is 0 so that no rounding is done.
+When set to a non-integer value, use the car of
+`org-time-stamp-rounding-minutes', like for setting a time-stamp.
+
+E.g. if `org-clock-rounding-minutes' is set to 5, time is 14:47
+and you clock in: then the clock starts at 14:45.  If you clock
+out within the next 5 minutes, the clock line will be removed;
+if you clock out 8 minutes after your clocked in, the clock
+out time will be 14:50."
+  :group 'org-clock
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type '(choice
+         (integer :tag "Minutes (0 for no rounding)")
+         (symbol  :tag "Use `org-time-stamp-rounding-minutes'" 'same-as-time-stamp)))
+
 (defcustom org-clock-out-remove-zero-time-clocks nil
   "Non-nil means remove the clock line when the resulting time is zero."
   :group 'org-clock
@@ -140,10 +159,10 @@ state to switch it to."
 This is the string shown in the mode line when a clock is running.
 The function is called with point at the beginning of the headline."
   :group 'org-clock
-  :type 'function)
+  :type '(choice (const nil) (function)))
 
 (defcustom org-clock-string-limit 0
-  "Maximum length of clock strings in the modeline.  0 means no limit."
+  "Maximum length of clock strings in the mode line.  0 means no limit."
   :group 'org-clock
   :type 'integer)
 
@@ -159,12 +178,15 @@ the clock can be resumed from that point."
 The clock is resumed when Emacs restarts.
 When this is t, both the running clock, and the entire clock
 history are saved.  When this is the symbol `clock', only the
-running clock is saved.
+running clock is saved.  When this is the symbol `history', only
+the clock history is saved.
 
-When Emacs restarts with saved clock information, the file containing the
-running clock as well as all files mentioned in the clock history will
-be visited.
-All this depends on running `org-clock-persistence-insinuate' in .emacs"
+When Emacs restarts with saved clock information, the file containing
+the running clock as well as all files mentioned in the clock history
+will be visited.
+
+All this depends on running `org-clock-persistence-insinuate' in your
+Emacs initialization file."
   :group 'org-clock
   :type '(choice
          (const :tag "Just the running clock" clock)
@@ -173,7 +195,7 @@ All this depends on running `org-clock-persistence-insinuate' in .emacs"
          (const :tag "No persistence" nil)))
 
 (defcustom org-clock-persist-file (convert-standard-filename
-                                  "~/.emacs.d/org-clock-save.el")
+                                  (concat user-emacs-directory "org-clock-save.el"))
   "File to save clock data to."
   :group 'org-clock
   :type 'string)
@@ -189,20 +211,23 @@ All this depends on running `org-clock-persistence-insinuate' in .emacs"
   :type 'boolean)
 
 (defcustom org-clock-sound nil
-  "Sound that will used for notifications.
-Possible values:
+  "Sound to use for notifications.
+Possible values are:
 
-nil        no sound played.
-t          standard Emacs beep
-file name  play this sound file.  If not possible, fall back to beep"
+nil        No sound played
+t          Standard Emacs beep
+file name  Play this sound file, fall back to beep"
   :group 'org-clock
   :type '(choice
          (const :tag "No sound" nil)
          (const :tag "Standard beep" t)
-         (file :tag "Play sound file")))
+         (file  :tag "Play sound file")))
+
+(define-obsolete-variable-alias 'org-clock-modeline-total
+  'org-clock-mode-line-total "24.3")
 
-(defcustom org-clock-modeline-total 'auto
-  "Default setting for the time included for the modeline clock.
+(defcustom org-clock-mode-line-total 'auto
+  "Default setting for the time included for the mode line clock.
 This can be overruled locally using the CLOCK_MODELINE_TOTAL property.
 Allowed values are:
 
@@ -219,13 +244,15 @@ auto     Automatically, either `all', or `repeat' for repeating tasks"
          (const :tag "All task time" all)
          (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.
+(org-defvaralias 'org-task-overrun-text 'org-clock-task-overrun-text)
+(defcustom org-clock-task-overrun-text nil
+  "Extra mode line text to 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-line-clock-overrun').
 When this is a string, it is prepended to the clock string as an indication,
 also using the face `org-mode-line-clock-overrun'."
   :group 'org-clock
+  :version "24.1"
   :type '(choice
          (const :tag "Just mark the time string" nil)
          (string :tag "Text to prepend")))
@@ -236,6 +263,7 @@ The function or program will be called with the notification
 string as argument."
   :group 'org-clock
   :type '(choice
+         (const nil)
          (string :tag "Program")
          (function :tag "Function")))
 
@@ -245,34 +273,38 @@ string as argument."
   :group 'org-clock)
 
 (defcustom org-clocktable-defaults
-  `(list
-    :maxlevel 2
-    :lang ,org-export-default-language
-    :scope 'file
-    :block nil
-    :tstart nil
-    :tend nil
-    :step nil
-    :stepskip0 nil
-    :fileskip0 nil
-    :tags nil
-    :emphasize nil
-    :link nil
-    :narrow '40!
-    :indent t
-    :formula nil
-    :timestamp nil
-    :level nil
-    :tcolumns nil
-    :formatter nil)
+  (list
+   :maxlevel 2
+   :lang (or (org-bound-and-true-p org-export-default-language) "en")
+   :scope 'file
+   :block nil
+   :wstart 1
+   :mstart 1
+   :tstart nil
+   :tend nil
+   :step nil
+   :stepskip0 nil
+   :fileskip0 nil
+   :tags nil
+   :emphasize nil
+   :link nil
+   :narrow '40!
+   :indent t
+   :formula nil
+   :timestamp nil
+   :level nil
+   :tcolumns nil
+   :formatter nil)
   "Default properties for clock tables."
   :group 'org-clock
+  :version "24.1"
   :type 'plist)
 
 (defcustom org-clock-clocktable-formatter 'org-clocktable-write-default
   "Function to turn clocking data into a table.
 For more information, see `org-clocktable-write-default'."
   :group 'org-clocktable
+  :version "24.1"
   :type 'function)
 
 ;; FIXME: translate es and nl last string "Clock summary at"
@@ -283,6 +315,7 @@ For more information, see `org-clocktable-write-default'."
     ("nl" "Bestand"  "N"  "Tijdstip"   "Hoofding" "Duur"  "ALLES" "Totale duur"  "Bestandstijd" "Clock summary at"))
   "Terms used in clocktable, translated to different languages."
   :group 'org-clocktable
+  :version "24.1"
   :type 'alist)
 
 (defcustom org-clock-clocktable-default-properties '(:maxlevel 2 :scope file)
@@ -310,13 +343,76 @@ play with them."
 (defcustom org-clock-report-include-clocking-task nil
   "When non-nil, include the current clocking task time in clock reports."
   :group 'org-clock
+  :version "24.1"
   :type 'boolean)
 
 (defcustom org-clock-resolve-expert nil
   "Non-nil means do not show the splash buffer with the clock resolver."
   :group 'org-clock
+  :version "24.1"
   :type 'boolean)
 
+(defcustom org-clock-continuously nil
+  "Non-nil means to start clocking from the last clock-out time, if any."
+  :type 'boolean
+  :version "24.1"
+  :group 'org-clock)
+
+(defcustom org-clock-total-time-cell-format "*%s*"
+  "Format string for the total time cells."
+  :group 'org-clock
+  :version "24.1"
+  :type 'string)
+
+(defcustom org-clock-file-time-cell-format "*%s*"
+  "Format string for the file time cells."
+  :group 'org-clock
+  :version "24.1"
+  :type 'string)
+
+(defcustom org-clock-clocked-in-display 'mode-line
+  "When clocked in for a task, org-mode can display the current
+task and accumulated time in the mode line and/or frame title.
+Allowed values are:
+
+both         displays in both mode line and frame title
+mode-line    displays only in mode line (default)
+frame-title  displays only in frame title
+nil          current clock is not displayed"
+  :group 'org-clock
+  :type '(choice
+         (const :tag "Mode line" mode-line)
+         (const :tag "Frame title" frame-title)
+         (const :tag "Both" both)
+         (const :tag "None" nil)))
+
+(defcustom org-clock-frame-title-format '(t org-mode-line-string)
+  "The value for `frame-title-format' when clocking in.
+
+When `org-clock-clocked-in-display' is set to 'frame-title
+or 'both, clocking in will replace `frame-title-format' with
+this value.  Clocking out will restore `frame-title-format'.
+
+`org-frame-title-string' is a format string using the same
+specifications than `frame-title-format', which see."
+  :version "24.1"
+  :group 'org-clock
+  :type 'sexp)
+
+(defcustom org-clock-x11idle-program-name "x11idle"
+  "Name of the program which prints X11 idle time in milliseconds.
+
+You can find x11idle.c in the contrib/scripts directory of the
+Org git distribution. Or, you can do:
+
+    sudo apt-get install xprintidle
+
+if you are using Debian."
+  :group 'org-clock
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type 'string)
+
 (defvar org-clock-in-prepare-hook nil
   "Hook run when preparing the clock.
 This hook is run before anything happens to the task that
@@ -342,7 +438,6 @@ to add an effort property.")
 (defvar org-clock-mode-line-timer nil)
 (defvar org-clock-idle-timer nil)
 (defvar org-clock-heading) ; defined in org.el
-(defvar org-clock-heading-for-remember "")
 (defvar org-clock-start-time "")
 
 (defvar org-clock-leftover-time nil
@@ -420,46 +515,55 @@ of a different task.")
   "Hook called in task selection just before prompting the user.")
 
 (defun org-clock-select-task (&optional prompt)
-  "Select a task that recently was associated with clocking."
+  "Select a task that was recently associated with clocking."
   (interactive)
-  (let (sel-list rpl (i 0) s)
-    (save-window-excursion
-      (org-switch-to-buffer-other-window
-       (get-buffer-create "*Clock Task Select*"))
-      (erase-buffer)
-      (when (marker-buffer org-clock-default-task)
-       (insert (org-add-props "Default Task\n" nil 'face 'bold))
-       (setq s (org-clock-insert-selection-line ?d org-clock-default-task))
-       (push s sel-list))
-      (when (marker-buffer org-clock-interrupted-task)
-       (insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
-       (setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
-       (push s sel-list))
-      (when (org-clocking-p)
-       (insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
-       (setq s (org-clock-insert-selection-line ?c org-clock-marker))
-       (push s sel-list))
-      (insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
-      (mapc
-       (lambda (m)
-        (when (marker-buffer m)
-          (setq i (1+ i)
-                s (org-clock-insert-selection-line
-                   (if (< i 10)
-                       (+ i ?0)
-                     (+ i (- ?A 10))) m))
-          (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
-          (push s sel-list)))
-       org-clock-history)
-      (run-hooks 'org-clock-before-select-task-hook)
-      (org-fit-window-to-buffer)
-      (message (or prompt "Select task for clocking:"))
-      (setq rpl (read-char-exclusive))
-      (cond
-       ((eq rpl ?q) nil)
-       ((eq rpl ?x) nil)
-       ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
-       (t (error "Invalid task choice %c" rpl))))))
+  (let (och chl sel-list rpl (i 0) s)
+    ;; Remove successive dups from the clock history to consider
+    (mapc (lambda (c) (if (not (equal c (car och))) (push c och)))
+         org-clock-history)
+    (setq och (reverse och) chl (length och))
+    (if (zerop chl)
+       (user-error "No recent clock")
+      (save-window-excursion
+       (org-switch-to-buffer-other-window
+        (get-buffer-create "*Clock Task Select*"))
+       (erase-buffer)
+       (when (marker-buffer org-clock-default-task)
+         (insert (org-add-props "Default Task\n" nil 'face 'bold))
+         (setq s (org-clock-insert-selection-line ?d org-clock-default-task))
+         (push s sel-list))
+       (when (marker-buffer org-clock-interrupted-task)
+         (insert (org-add-props "The task interrupted by starting the last one\n" nil 'face 'bold))
+         (setq s (org-clock-insert-selection-line ?i org-clock-interrupted-task))
+         (push s sel-list))
+       (when (org-clocking-p)
+         (insert (org-add-props "Current Clocking Task\n" nil 'face 'bold))
+         (setq s (org-clock-insert-selection-line ?c org-clock-marker))
+         (push s sel-list))
+       (insert (org-add-props "Recent Tasks\n" nil 'face 'bold))
+       (mapc
+        (lambda (m)
+          (when (marker-buffer m)
+            (setq i (1+ i)
+                  s (org-clock-insert-selection-line
+                     (if (< i 10)
+                         (+ i ?0)
+                       (+ i (- ?A 10))) m))
+            (if (fboundp 'int-to-char) (setf (car s) (int-to-char (car s))))
+            (push s sel-list)))
+        och)
+       (run-hooks 'org-clock-before-select-task-hook)
+       (goto-char (point-min))
+       ;; Set min-height relatively to circumvent a possible but in
+       ;; `fit-window-to-buffer'
+       (fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl)))
+       (message (or prompt "Select task for clocking:"))
+       (setq cursor-type nil rpl (read-char-exclusive))
+       (cond
+        ((eq rpl ?q) nil)
+        ((eq rpl ?x) nil)
+        ((assoc rpl sel-list) (cdr (assoc rpl sel-list)))
+        (t (user-error "Invalid task choice %c" rpl)))))))
 
 (defun org-clock-insert-selection-line (i marker)
   "Insert a line for the clock selection menu.
@@ -486,10 +590,10 @@ pointing to it."
                           org-odd-levels-only)
                          (length prefix)))))))
       (when (and cat task)
-       (insert (format "[%c] %-15s %s\n" i cat task))
+       (insert (format "[%c] %-12s  %s\n" i cat task))
        (cons i marker)))))
 
-(defvar org-task-overrun nil
+(defvar org-clock-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.")
@@ -499,34 +603,37 @@ pointing to it."
 If an effort estimate was defined for the current item, use
 01:30/01:50 format (clocked/estimated).
 If not, show simply the clocked time like 01:50."
-  (let* ((clocked-time (org-clock-get-clocked-time))
-        (h (floor clocked-time 60))
-        (m (- clocked-time (* 60 h))))
+  (let ((clocked-time (org-clock-get-clocked-time)))
     (if org-clock-effort
        (let* ((effort-in-minutes
                (org-duration-string-to-minutes org-clock-effort))
-              (effort-h (floor effort-in-minutes 60))
-              (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-minutes-to-clocksum-string clocked-time)
+                'face (if (and org-clock-task-overrun (not org-clock-task-overrun-text))
                           'org-mode-line-clock-overrun 'org-mode-line-clock)))
-              (effort-str (format org-time-clocksum-format effort-h effort-m))
+              (effort-str (org-minutes-to-clocksum-string effort-in-minutes))
               (clockstr (org-propertize
-                         (concat  "[%s/" effort-str
+                         (concat  " [%s/" effort-str
                                   "] (" (replace-regexp-in-string "%" "%%" 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)
+      (org-propertize (concat "[" (org-minutes-to-clocksum-string clocked-time)
+                             (format " (%s)" org-clock-heading) "]")
                      'face 'org-mode-line-clock))))
 
+(defun org-clock-get-last-clock-out-time ()
+  "Get the last clock-out time for the current subtree."
+  (save-excursion
+    (let ((end (save-excursion (org-end-of-subtree))))
+      (when (re-search-forward (concat org-clock-string
+                                      ".*\\]--\\(\\[[^]]+\\]\\)") end t)
+       (org-time-string-to-time (match-string 1))))))
+
 (defun org-clock-update-mode-line ()
   (if org-clock-effort
       (org-clock-notify-once-if-expired)
-    (setq org-task-overrun nil))
+    (setq org-clock-task-overrun nil))
   (setq org-mode-line-string
        (org-propertize
         (let ((clock-string (org-clock-get-clock-string))
@@ -538,12 +645,11 @@ If not, show simply the clocked time like 01:50."
                'help-echo (concat help-text ": " org-clock-heading))
             (org-propertize clock-string 'help-echo help-text)))
         'local-map org-clock-mode-line-map
-        'mouse-face (if (featurep 'xemacs) 'highlight 'mode-line-highlight)
-        ))
-  (if (and org-task-overrun org-task-overrun-text)
+        'mouse-face (if (featurep 'xemacs) 'highlight 'mode-line-highlight)))
+  (if (and org-clock-task-overrun org-clock-task-overrun-text)
       (setq org-mode-line-string
            (concat (org-propertize
-                    org-task-overrun-text
+                    org-clock-task-overrun-text
                     'face 'org-mode-line-clock-overrun) org-mode-line-string)))
   (force-mode-line-update))
 
@@ -557,39 +663,43 @@ previous clocking intervals."
     (+ currently-clocked-time (or org-clock-total-time 0))))
 
 (defun org-clock-modify-effort-estimate (&optional value)
- "Add to or set the effort estimate of the item currently being clocked.
 "Add to or set the effort estimate of the item currently being clocked.
 VALUE can be a number of minutes, or a string with format hh:mm or mm.
 When the string starts with a + or a - sign, the current value of the effort
-property will be changed by that amount.
-This will update the \"Effort\" property of currently clocked item, and
-the mode line."
- (interactive)
- (when (org-clock-is-active)
-   (let ((current org-clock-effort) sign)
-     (unless value
-       ;; Prompt user for a value or a change
-       (setq value
-            (read-string
-             (format "Set effort (hh:mm or mm%s): "
-                     (if current
-                         (format ", prefix + to add to %s" org-clock-effort)
-                       "")))))
-     (when (stringp value)
-       ;; A string.  See if it is a delta
-       (setq sign (string-to-char value))
-       (if (member sign '(?- ?+))
-          (setq current (org-duration-string-to-minutes current)
-                value (substring value 1))
-        (setq current 0))
-       (setq value (org-duration-string-to-minutes value))
-       (if (equal ?- sign)
-          (setq value (- current value))
-        (if (equal ?+ sign) (setq value (+ current value)))))
-     (setq value (max 0 value)
-          org-clock-effort (org-minutes-to-hh:mm-string value))
-     (org-entry-put org-clock-marker "Effort" org-clock-effort)
-     (org-clock-update-mode-line)
-     (message "Effort is now %s" org-clock-effort))))
+property will be changed by that amount.  If the effort value is expressed
+as an `org-effort-durations' (e.g. \"3h\"), the modificied value will be
+converted to a hh:mm duration.
+
+This command will update the \"Effort\" property of the currently
+clocked item, and the value displayed in the mode line."
+  (interactive)
+  (if (org-clock-is-active)
+      (let ((current org-clock-effort) sign)
+       (unless value
+         ;; Prompt user for a value or a change
+         (setq value
+               (read-string
+                (format "Set effort (hh:mm or mm%s): "
+                        (if current
+                            (format ", prefix + to add to %s" org-clock-effort)
+                          "")))))
+       (when (stringp value)
+         ;; A string.  See if it is a delta
+         (setq sign (string-to-char value))
+         (if (member sign '(?- ?+))
+             (setq current (org-duration-string-to-minutes current)
+                   value (substring value 1))
+           (setq current 0))
+         (setq value (org-duration-string-to-minutes value))
+         (if (equal ?- sign)
+             (setq value (- current value))
+           (if (equal ?+ sign) (setq value (+ current value)))))
+       (setq value (max 0 value)
+             org-clock-effort (org-minutes-to-clocksum-string value))
+       (org-entry-put org-clock-marker "Effort" org-clock-effort)
+       (org-clock-update-mode-line)
+       (message "Effort is now %s" org-clock-effort))
+    (message "Clock is not currently active")))
 
 (defvar org-clock-notification-was-shown nil
   "Shows if we have shown notification already.")
@@ -600,7 +710,7 @@ Notification is shown only once."
   (when (org-clocking-p)
     (let ((effort-in-minutes (org-duration-string-to-minutes org-clock-effort))
          (clocked-time (org-clock-get-clocked-time)))
-      (if (setq org-task-overrun
+      (if (setq org-clock-task-overrun
                (if (or (null effort-in-minutes) (zerop effort-in-minutes))
                    nil
                  (>= clocked-time effort-in-minutes)))
@@ -608,13 +718,14 @@ Notification is shown only once."
            (setq org-clock-notification-was-shown t)
            (org-notify
             (format "Task '%s' should be finished by now. (%s)"
-                    org-clock-heading org-clock-effort) t))
+                    org-clock-heading org-clock-effort) org-clock-sound))
        (setq org-clock-notification-was-shown nil)))))
 
 (defun org-notify (notification &optional play-sound)
-  "Send a NOTIFICATION and maybe PLAY-SOUND."
+  "Send a NOTIFICATION and maybe PLAY-SOUND.
+If PLAY-SOUND is non-nil, it overrides `org-clock-sound'."
   (org-show-notification notification)
-  (if play-sound (org-clock-play-sound)))
+  (if play-sound (org-clock-play-sound play-sound)))
 
 (defun org-show-notification (notification)
   "Show notification.
@@ -625,44 +736,40 @@ use libnotify if available, or fall back on a message."
        ((stringp org-show-notification-handler)
         (start-process "emacs-timer-notification" nil
                        org-show-notification-handler notification))
-       ((featurep 'notifications)
-        (require 'notifications)
+       ((fboundp 'notifications-notify)
         (notifications-notify
          :title "Org-mode message"
          :body notification
          ;; FIXME how to link to the Org icon?
          ;; :app-icon "~/.emacs.d/icons/mail.png"
          :urgency 'low))
-       ((org-program-exists "notify-send")
+       ((executable-find "notify-send")
         (start-process "emacs-timer-notification" nil
                        "notify-send" notification))
        ;; Maybe the handler will send a message, so only use message as
        ;; a fall back option
        (t (message "%s" notification))))
 
-(defun org-clock-play-sound ()
+(defun org-clock-play-sound (&optional clock-sound)
   "Play sound as configured by `org-clock-sound'.
-Use alsa's aplay tool if available."
-  (cond
-   ((not org-clock-sound))
-   ((eq org-clock-sound t) (beep t) (beep t))
-   ((stringp org-clock-sound)
-    (let ((file (expand-file-name org-clock-sound)))
-      (if (file-exists-p file)
-         (if (org-program-exists "aplay")
-             (start-process "org-clock-play-notification" nil
-                            "aplay" file)
-           (condition-case nil
-               (play-sound-file file)
-             (error (beep t) (beep t)))))))))
-
-(defun org-program-exists (program-name)
-  "Checks whenever we can locate program and launch it."
-  (if (eq system-type 'gnu/linux)
-      (= 0 (call-process "which" nil nil nil program-name))))
+Use alsa's aplay tool if available.
+If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
+  (let ((org-clock-sound (or clock-sound org-clock-sound)))
+    (cond
+     ((not org-clock-sound))
+     ((eq org-clock-sound t) (beep t) (beep t))
+     ((stringp org-clock-sound)
+      (let ((file (expand-file-name org-clock-sound)))
+       (if (file-exists-p file)
+           (if (executable-find "aplay")
+               (start-process "org-clock-play-notification" nil
+                              "aplay" file)
+             (condition-case nil
+                 (play-sound-file file)
+               (error (beep t) (beep t))))))))))
 
 (defvar org-clock-mode-line-entry nil
-  "Information for the modeline about the running clock.")
+  "Information for the mode line about the running clock.")
 
 (defun org-find-open-clocks (file)
   "Search through the given file and find all open clocks."
@@ -691,7 +798,7 @@ Use alsa's aplay tool if available."
         (goto-char (car ,clock))
         (beginning-of-line)
         ,@forms))))
-
+(def-edebug-spec org-with-clock-position (form body))
 (put 'org-with-clock-position 'lisp-indent-function 1)
 
 (defmacro org-with-clock (clock &rest forms)
@@ -707,7 +814,7 @@ This macro also protects the current active clock from being altered."
                                  (outline-back-to-heading t)
                                  (point-marker))))
        ,@forms)))
-
+(def-edebug-spec org-with-clock (form body))
 (put 'org-with-clock 'lisp-indent-function 1)
 
 (defsubst org-clock-clock-in (clock &optional resume start-time)
@@ -722,9 +829,9 @@ If necessary, clock-out of the currently active clock."
   (let ((temp (copy-marker (car clock)
                           (marker-insertion-type (car clock)))))
     (if (org-is-active-clock clock)
-       (org-clock-out fail-quietly at-time)
+       (org-clock-out nil fail-quietly at-time)
       (org-with-clock clock
-       (org-clock-out fail-quietly at-time)))
+       (org-clock-out nil fail-quietly at-time)))
     (setcar clock temp)))
 
 (defsubst org-clock-clock-cancel (clock)
@@ -832,19 +939,23 @@ was started."
                (with-output-to-temp-buffer "*Org Clock*"
                  (princ "Select a Clock Resolution Command:
 
-i/q/C-g  Ignore this question; the same as keeping all the idle time.
+i/q      Ignore this question; the same as keeping all the idle time.
 
 k/K      Keep X minutes of the idle time (default is all).  If this
          amount is less than the default, you will be clocked out
          that many minutes after the time that idling began, and then
          clocked back in at the present time.
+
 g/G      Indicate that you \"got back\" X minutes ago.  This is quite
          different from 'k': it clocks you out from the beginning of
          the idle period and clock you back in X minutes ago.
+
 s/S      Subtract the idle time from the current clock.  This is the
          same as keeping 0 minutes.
+
 C        Cancel the open timer altogether.  It will be as though you
          never clocked in.
+
 j/J      Jump to the current clock, to make manual adjustments.
 
 For all these options, using uppercase makes your final state
@@ -914,6 +1025,7 @@ to be CLOCKED OUT.")))
            (not (memq ch '(?K ?G ?S ?C))))
        fail-quietly)))))
 
+;;;###autoload
 (defun org-resolve-clocks (&optional only-dangling-p prompt-fn last-valid)
   "Resolve all currently open org-mode clocks.
 If `only-dangling-p' is non-nil, only ask to resolve dangling
@@ -927,18 +1039,18 @@ If `only-dangling-p' is non-nil, only ask to resolve dangling
            (let ((dangling (or (not (org-clock-is-active))
                                (/= (car clock) org-clock-marker))))
              (if (or (not only-dangling-p) dangling)
-               (org-clock-resolve
-                clock
-                (or prompt-fn
-                    (function
-                     (lambda (clock)
-                       (format
-                        "Dangling clock started %d mins ago"
-                        (floor
-                         (/ (- (org-float-time (current-time))
-                               (org-float-time (cdr clock))) 60))))))
-                (or last-valid
-                    (cdr clock)))))))))))
+                 (org-clock-resolve
+                  clock
+                  (or prompt-fn
+                      (function
+                       (lambda (clock)
+                         (format
+                          "Dangling clock started %d mins ago"
+                          (floor
+                           (/ (- (org-float-time (current-time))
+                                 (org-float-time (cdr clock))) 60))))))
+                  (or last-valid
+                      (cdr clock)))))))))))
 
 (defun org-emacs-idle-seconds ()
   "Return the current Emacs idle time in seconds, or nil if not idle."
@@ -951,9 +1063,16 @@ If `only-dangling-p' is non-nil, only ask to resolve dangling
   "Return the current Mac idle time in seconds."
   (string-to-number (shell-command-to-string "ioreg -c IOHIDSystem | perl -ane 'if (/Idle/) {$idle=(pop @F)/1000000000; print $idle; last}'")))
 
+(defvar org-x11idle-exists-p
+  ;; Check that x11idle exists
+  (and (eq window-system 'x)
+       (eq (call-process-shell-command "command" nil nil nil "-v" org-clock-x11idle-program-name) 0)
+       ;; Check that x11idle can retrieve the idle time
+       (eq (call-process-shell-command org-clock-x11idle-program-name nil nil nil) 0)))
+
 (defun org-x11-idle-seconds ()
   "Return the current X11 idle time in seconds."
-  (/ (string-to-number (shell-command-to-string "x11idle")) 1000))
+  (/ (string-to-number (shell-command-to-string org-clock-x11idle-program-name)) 1000))
 
 (defun org-user-idle-seconds ()
   "Return the number of seconds the user has been idle for.
@@ -961,7 +1080,7 @@ This routine returns a floating point number."
   (cond
    ((eq system-type 'darwin)
     (org-mac-idle-seconds))
-   ((eq window-system 'x)
+   ((and (eq window-system 'x) org-x11idle-exists-p)
     (org-x11-idle-seconds))
    (t
     (org-emacs-idle-seconds))))
@@ -974,7 +1093,7 @@ This is performed after `org-clock-idle-time' minutes, to check
 if the user really wants to stay clocked in after being idle for
 so long."
   (when (and org-clock-idle-time (not org-clock-resolving-clocks)
-            org-clock-marker)
+            org-clock-marker (marker-buffer org-clock-marker))
     (let* ((org-clock-user-idle-seconds (org-user-idle-seconds))
           (org-clock-user-idle-start
            (time-subtract (current-time)
@@ -993,33 +1112,30 @@ so long."
                         60.0))))
           org-clock-user-idle-start)))))
 
-(defvar org-clock-current-task nil
-  "Task currently clocked in.")
-(defun org-clock-set-current ()
-  "Set `org-clock-current-task' to the task currently clocked in."
-  (setq org-clock-current-task (nth 4 (org-heading-components))))
-
-(defun org-clock-delete-current ()
-  "Reset `org-clock-current-task' to nil."
-  (setq org-clock-current-task nil))
+(defvar org-clock-current-task nil "Task currently clocked in.")
+(defvar org-clock-out-time nil) ; store the time of the last clock-out
 
+;;;###autoload
 (defun org-clock-in (&optional select start-time)
   "Start the clock on the current item.
 If necessary, clock-out of the currently active clock.
-With a prefix argument SELECT (\\[universal-argument]), offer a list of \
-recently clocked tasks to
-clock into.  When SELECT is \\[universal-argument] \\[universal-argument], \
-clock into the current task and mark
-is as the default task, a special task that will always be offered in
-the clocking selection, associated with the letter `d'."
+With a prefix argument SELECT (\\[universal-argument]), offer a list of recently clocked
+tasks to clock into.  When SELECT is \\[universal-argument] \\[universal-argument], clock into the current task
+and mark it as the default task, a special task that will always be offered
+in the clocking selection, associated with the letter `d'.
+When SELECT is \\[universal-argument] \\[universal-argument] \\[universal-argument], \
+clock in by using the last clock-out
+time as the start time \(see `org-clock-continuously' to
+make this the default behavior.)"
   (interactive "P")
   (setq org-clock-notification-was-shown nil)
+  (org-refresh-properties org-effort-property 'org-effort)
   (catch 'abort
     (let ((interrupting (and (not org-clock-resolving-clocks-due-to-idleness)
                             (org-clocking-p)))
          ts selected-task target-pos (msg-extra "")
          (leftover (and (not org-clock-resolving-clocks)
-                         org-clock-leftover-time)))
+                        org-clock-leftover-time)))
 
       (when (and org-clock-auto-clock-resolution
                 (or (not interrupting)
@@ -1030,6 +1146,11 @@ the clocking selection, associated with the letter `d'."
        (let ((org-clock-clocking-in t))
          (org-resolve-clocks)))        ; check if any clocks are dangling
 
+      (when (equal select '(64))
+       ;; Set start-time to `org-clock-out-time'
+       (let ((org-clock-continuously t))
+         (org-clock-in nil org-clock-out-time)))
+
       (when (equal select '(4))
        (setq selected-task (org-clock-select-task "Clock-in on task: "))
        (if selected-task
@@ -1062,14 +1183,13 @@ the clocking selection, associated with the letter `d'."
                     (marker-position org-clock-marker)
                     (marker-buffer org-clock-marker))
        (let ((org-clock-clocking-in t))
-         (org-clock-out t)))
+         (org-clock-out nil t)))
 
       ;; Clock in at which position?
       (setq target-pos
-           (if (and (eobp) (not (org-on-heading-p)))
+           (if (and (eobp) (not (org-at-heading-p)))
                (point-at-bol 0)
              (point)))
-      (run-hooks 'org-clock-in-prepare-hook)
       (save-excursion
        (when (and selected-task (marker-buffer selected-task))
          ;; There is a selected task, move to the correct buffer
@@ -1083,8 +1203,9 @@ the clocking selection, associated with the letter `d'."
            (goto-char target-pos)
            (org-back-to-heading t)
            (or interrupting (move-marker org-clock-interrupted-task nil))
+           (run-hooks 'org-clock-in-prepare-hook)
            (org-clock-history-push)
-           (org-clock-set-current)
+           (setq org-clock-current-task (nth 4 (org-heading-components)))
            (cond ((functionp org-clock-in-switch-to-state)
                   (looking-at org-complex-heading-regexp)
                   (let ((newstate (funcall org-clock-in-switch-to-state
@@ -1095,36 +1216,29 @@ the clocking selection, associated with the letter `d'."
                                                 org-clock-in-switch-to-state
                                                 "\\>"))))
                   (org-todo org-clock-in-switch-to-state)))
-           (setq org-clock-heading-for-remember
-                 (and (looking-at org-complex-heading-regexp)
-                      (match-end 4)
-                      (org-trim (buffer-substring (match-end 1)
-                                                  (match-end 4)))))
            (setq org-clock-heading
                  (cond ((and org-clock-heading-function
                              (functionp org-clock-heading-function))
                         (funcall org-clock-heading-function))
-                       ((looking-at org-complex-heading-regexp)
+                       ((nth 4 (org-heading-components))
                         (replace-regexp-in-string
                          "\\[\\[.*?\\]\\[\\(.*?\\)\\]\\]" "\\1"
-                         (match-string 4)))
+                         (match-string-no-properties 4)))
                        (t "???")))
-           (setq org-clock-heading (org-propertize org-clock-heading
-                                                   'face nil))
            (org-clock-find-position org-clock-in-resume)
            (cond
             ((and org-clock-in-resume
                   (looking-at
-                   (concat "^[ \t]* " org-clock-string
+                   (concat "^[ \t]*" org-clock-string
                            " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
-                           " +\\sw+\.? +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
+                           " *\\sw+\.? +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
              (message "Matched %s" (match-string 1))
              (setq ts (concat "[" (match-string 1) "]"))
              (goto-char (match-end 1))
              (setq org-clock-start-time
                    (apply 'encode-time
                           (org-parse-time-string (match-string 1))))
-             (setq org-clock-effort (org-get-effort))
+             (setq org-clock-effort (org-entry-get (point) org-effort-property))
              (setq org-clock-total-time (org-clock-sum-current-item
                                          (org-clock-get-sum-start))))
             ((eq org-clock-in-resume 'auto-restart)
@@ -1137,26 +1251,28 @@ the clocking selection, associated with the letter `d'."
             (t
              (insert-before-markers "\n")
              (backward-char 1)
-             (org-indent-line-function)
+             (org-indent-line)
              (when (and (save-excursion
                           (end-of-line 0)
                           (org-in-item-p)))
                (beginning-of-line 1)
                (org-indent-line-to (- (org-get-indentation) 2)))
              (insert org-clock-string " ")
-             (setq org-clock-effort (org-get-effort))
+             (setq org-clock-effort (org-entry-get (point) org-effort-property))
              (setq org-clock-total-time (org-clock-sum-current-item
                                          (org-clock-get-sum-start)))
              (setq org-clock-start-time
-                   (or (and leftover
+                   (or (and org-clock-continuously org-clock-out-time)
+                       (and leftover
                             (y-or-n-p
                              (format
                               "You stopped another clock %d mins ago; start this one from then? "
-                              (/ (- (org-float-time (current-time))
+                              (/ (- (org-float-time
+                                     (org-current-time org-clock-rounding-minutes t))
                                     (org-float-time leftover)) 60)))
                             leftover)
                        start-time
-                       (current-time)))
+                       (org-current-time org-clock-rounding-minutes t)))
              (setq ts (org-insert-time-stamp org-clock-start-time
                                              'with-hm 'inactive))))
            (move-marker org-clock-marker (point) (buffer-base-buffer))
@@ -1164,18 +1280,26 @@ the clocking selection, associated with the letter `d'."
                         (save-excursion (org-back-to-heading t) (point))
                         (buffer-base-buffer))
            (setq org-clock-has-been-used t)
-           (or global-mode-string (setq global-mode-string '("")))
-           (or (memq 'org-mode-line-string global-mode-string)
-               (setq global-mode-string
-                     (append global-mode-string '(org-mode-line-string))))
+           ;; add to mode line
+           (when (or (eq org-clock-clocked-in-display 'mode-line)
+                     (eq org-clock-clocked-in-display 'both))
+             (or global-mode-string (setq global-mode-string '("")))
+             (or (memq 'org-mode-line-string global-mode-string)
+                 (setq global-mode-string
+                       (append global-mode-string '(org-mode-line-string)))))
+           ;; add to frame title
+           (when (or (eq org-clock-clocked-in-display 'frame-title)
+                     (eq org-clock-clocked-in-display 'both))
+             (setq frame-title-format org-clock-frame-title-format))
            (org-clock-update-mode-line)
            (when 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
-                 (run-with-timer org-clock-update-period
-                                 org-clock-update-period
-                                 'org-clock-update-mode-line))
+           (when org-clock-clocked-in-display
+             (setq org-clock-mode-line-timer
+                   (run-with-timer org-clock-update-period
+                                   org-clock-update-period
+                                   'org-clock-update-mode-line)))
            (when org-clock-idle-timer
              (cancel-timer org-clock-idle-timer)
              (setq org-clock-idle-timer nil))
@@ -1184,6 +1308,42 @@ the clocking selection, associated with the letter `d'."
            (message "Clock starts at %s - %s" ts msg-extra)
            (run-hooks 'org-clock-in-hook)))))))
 
+;;;###autoload
+(defun org-clock-in-last (&optional arg)
+  "Clock in the last closed clocked item.
+When already clocking in, send an warning.
+With a universal prefix argument, select the task you want to
+clock in from the last clocked in tasks.
+With two universal prefix arguments, start clocking using the
+last clock-out time, if any.
+With three universal prefix arguments, interactively prompt
+for a todo state to switch to, overriding the existing value
+`org-clock-in-switch-to-state'."
+  (interactive "P")
+  (if (equal arg '(4))
+      (org-clock-in (org-clock-select-task))
+    (let ((start-time (if (or org-clock-continuously (equal arg '(16)))
+                         (or org-clock-out-time
+                             (org-current-time org-clock-rounding-minutes t))
+                       (org-current-time org-clock-rounding-minutes t))))
+      (if (null org-clock-history)
+         (message "No last clock")
+       (let ((org-clock-in-switch-to-state
+              (if (and (not org-clock-current-task) (equal arg '(64)))
+                  (completing-read "Switch to state: "
+                                   (and org-clock-history
+                                        (with-current-buffer
+                                            (marker-buffer (car org-clock-history))
+                                          org-todo-keywords-1)))
+                org-clock-in-switch-to-state))
+             (already-clocking org-clock-current-task))
+         (org-clock-clock-in (list (car org-clock-history)) nil start-time)
+         (or already-clocking
+             ;; Don't display a message if we are already clocking in
+             (message "Clocking back: %s (in %s)"
+                      org-clock-current-task
+                      (buffer-name (marker-buffer org-clock-marker)))))))))
+
 (defun org-clock-mark-default-task ()
   "Mark current task as default task."
   (interactive)
@@ -1197,10 +1357,10 @@ the clocking selection, associated with the letter `d'."
 This is for the currently running clock as it is displayed
 in the mode line.  This function looks at the properties
 LAST_REPEAT and in particular CLOCK_MODELINE_TOTAL and the
-corresponding variable `org-clock-modeline-total' and then
+corresponding variable `org-clock-mode-line-total' and then
 decides which time to use."
   (let ((cmt (or (org-entry-get nil "CLOCK_MODELINE_TOTAL")
-                (symbol-name org-clock-modeline-total)))
+                (symbol-name org-clock-mode-line-total)))
        (lr (org-entry-get nil "LAST_REPEAT")))
     (cond
      ((equal cmt "current")
@@ -1247,9 +1407,9 @@ line and position cursor in that line."
       (goto-char beg)
       (when (and find-unclosed
                 (re-search-forward
-                 (concat "^[ \t]* " org-clock-string
+                 (concat "^[ \t]*" org-clock-string
                          " \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
-                         " +\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")
+                         " *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")
                  end t))
        (beginning-of-line 1)
        (throw 'exit t))
@@ -1277,7 +1437,7 @@ line and position cursor in that line."
        (if (and (>= (org-get-indentation) ind-last)
                 (org-at-item-p))
            (when (and (>= (org-get-indentation) ind-last)
-                  (org-at-item-p))
+                      (org-at-item-p))
              (let ((struct (org-list-struct)))
                (goto-char (org-list-get-bottom-point struct)))))
        (insert ":END:\n")
@@ -1286,7 +1446,7 @@ line and position cursor in that line."
        (goto-char first)
        (insert ":" drawer ":\n")
        (beginning-of-line 0)
-       (org-indent-line-function)
+       (org-indent-line)
        (org-flag-drawer t)
        (beginning-of-line 2)
        (or org-log-states-order-reversed
@@ -1306,28 +1466,42 @@ line and position cursor in that line."
                     (< org-clock-into-drawer 2)))
        (insert ":" drawer ":\n:END:\n")
        (beginning-of-line -1)
-       (org-indent-line-function)
+       (org-indent-line)
        (org-flag-drawer t)
        (beginning-of-line 2)
-       (org-indent-line-function)
+       (org-indent-line)
        (beginning-of-line)
        (or org-log-states-order-reversed
            (and (re-search-forward org-property-end-re nil t)
                 (goto-char (match-beginning 0))))))))
 
-(defun org-clock-out (&optional fail-quietly at-time)
+;;;###autoload
+(defun org-clock-out (&optional switch-to-state fail-quietly at-time)
   "Stop the currently running clock.
-If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
-  (interactive)
+Throw an error if there is no running clock and FAIL-QUIETLY is nil.
+With a universal prefix, prompt for a state to switch the clocked out task
+to, overriding the existing value of `org-clock-out-switch-to-state'."
+  (interactive "P")
   (catch 'exit
     (when (not (org-clocking-p))
       (setq global-mode-string
            (delq 'org-mode-line-string global-mode-string))
+      (setq frame-title-format org-frame-title-format-backup)
       (force-mode-line-update)
-      (if fail-quietly (throw 'exit t) (error "No active clock")))
-    (let (ts te s h m remove)
+      (if fail-quietly (throw 'exit t) (user-error "No active clock")))
+    (let ((org-clock-out-switch-to-state
+          (if switch-to-state
+              (completing-read "Switch to state: "
+                               (with-current-buffer
+                                   (marker-buffer org-clock-marker)
+                                 org-todo-keywords-1)
+                               nil t "DONE")
+            org-clock-out-switch-to-state))
+         (now (org-current-time org-clock-rounding-minutes))
+         ts te s h m remove)
+      (setq org-clock-out-time now)
       (save-excursion ; Do not replace this with `with-current-buffer'.
-       (with-no-warnings (set-buffer (org-clocking-buffer)))
+       (org-no-warnings (set-buffer (org-clocking-buffer)))
        (save-restriction
          (widen)
          (goto-char org-clock-marker)
@@ -1339,8 +1513,7 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
          (goto-char (match-end 0))
          (delete-region (point) (point-at-eol))
          (insert "--")
-         (setq te (org-insert-time-stamp (or at-time (current-time))
-                                         'with-hm 'inactive))
+         (setq te (org-insert-time-stamp (or at-time now) 'with-hm 'inactive))
          (setq s (- (org-float-time (apply 'encode-time (org-parse-time-string te)))
                     (org-float-time (apply 'encode-time (org-parse-time-string ts))))
                h (floor (/ s 3600))
@@ -1367,6 +1540,7 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
            (setq org-clock-idle-timer nil))
          (setq global-mode-string
                (delq 'org-mode-line-string global-mode-string))
+         (setq frame-title-format org-frame-title-format-backup)
          (when org-clock-out-switch-to-state
            (save-excursion
              (org-back-to-heading t)
@@ -1384,10 +1558,20 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
                                                "\\>"))))
                  (org-todo org-clock-out-switch-to-state))))))
          (force-mode-line-update)
-         (message (concat "Clock stopped at %s after HH:MM = " org-time-clocksum-format "%s") te h m
-                  (if remove " => LINE REMOVED" ""))
-          (run-hooks 'org-clock-out-hook)
-         (org-clock-delete-current))))))
+         (message (concat "Clock stopped at %s after "
+                          (org-minutes-to-clocksum-string (+ (* 60 h) m)) "%s")
+                  te (if remove " => LINE REMOVED" ""))
+         (let ((h org-clock-out-hook))
+           ;; If a closing note needs to be stored in the drawer
+           ;; where clocks are stored, let's temporarily disable
+           ;; `org-clock-remove-empty-clock-drawer'
+           (if (and (equal org-clock-into-drawer org-log-into-drawer)
+                    (eq org-log-done 'note)
+                    org-clock-out-when-done)
+               (setq h (delq 'org-clock-remove-empty-clock-drawer h)))
+           (mapc (lambda (f) (funcall f)) h))
+         (unless (org-clocking-p)
+           (setq org-clock-current-task nil)))))))
 
 (add-hook 'org-clock-out-hook 'org-clock-remove-empty-clock-drawer)
 
@@ -1400,30 +1584,28 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
     (when clock-drawer
       (save-excursion
        (org-back-to-heading t)
-       (while (search-forward clock-drawer end t)
+       (while (and (< (point) end)
+                   (search-forward clock-drawer end t))
          (goto-char (match-beginning 0))
          (org-remove-empty-drawer-at clock-drawer (point))
          (forward-line 1))))))
 
-(defun org-at-clock-log-p nil
-  "Is the cursor on the clock log line?"
-  (save-excursion
-    (move-beginning-of-line 1)
-    (looking-at "^[ \t]*CLOCK:")))
-
-(defun org-clock-timestamps-up nil
-  "Increase CLOCK timestamps at cursor."
-  (interactive)
-  (org-clock-timestamps-change 'up))
+(defun org-clock-timestamps-up (&optional n)
+  "Increase CLOCK timestamps at cursor.
+Optional argument N tells to change by that many units."
+  (interactive "P")
+  (org-clock-timestamps-change 'up n))
 
-(defun org-clock-timestamps-down nil
-  "Increase CLOCK timestamps at cursor."
-  (interactive)
-  (org-clock-timestamps-change 'down))
+(defun org-clock-timestamps-down (&optional n)
+  "Increase CLOCK timestamps at cursor.
+Optional argument N tells to change by that many units."
+  (interactive "P")
+  (org-clock-timestamps-change 'down n))
 
-(defun org-clock-timestamps-change (updown)
+(defun org-clock-timestamps-change (updown &optional n)
   "Change CLOCK timestamps synchronously at cursor.
-UPDOWN tells whether to change 'up or 'down."
+UPDOWN tells whether to change 'up or 'down.
+Optional argument N tells to change by that many units."
   (setq org-ts-what nil)
   (when (org-at-timestamp-p t)
     (let ((tschange (if (eq updown 'up) 'org-timestamp-up
@@ -1439,9 +1621,9 @@ UPDOWN tells whether to change 'up or 'down."
       (if (<= begts2 (point)) (setq updatets1 t))
       (if (not ts2)
          ;; fall back on org-timestamp-up if there is only one
-         (funcall tschange)
+         (funcall tschange n)
        ;; setq this so that (boundp 'org-ts-what is non-nil)
-       (funcall tschange)
+       (funcall tschange n)
        (let ((ts (if updatets1 ts2 ts1))
              (begts (if updatets1 begts1 begts2)))
          (setq tdiff
@@ -1459,28 +1641,40 @@ UPDOWN tells whether to change 'up or 'down."
                             ((eq org-ts-what 'year) (* 24 3600 365.2)))))
             org-ts-what 'updown)))))))
 
+;;;###autoload
 (defun org-clock-cancel ()
   "Cancel the running clock by removing the start timestamp."
   (interactive)
   (when (not (org-clocking-p))
     (setq global-mode-string
-         (delq 'org-mode-line-string global-mode-string))
+         (delq 'org-mode-line-string global-mode-string))
+    (setq frame-title-format org-frame-title-format-backup)
     (force-mode-line-update)
     (error "No active clock"))
   (save-excursion ; Do not replace this with `with-current-buffer'.
-    (with-no-warnings (set-buffer (org-clocking-buffer)))
+    (org-no-warnings (set-buffer (org-clocking-buffer)))
     (goto-char org-clock-marker)
-    (delete-region (1- (point-at-bol)) (point-at-eol))
-    ;; Just in case, remove any empty LOGBOOK left over
-    (org-remove-empty-drawer-at "LOGBOOK" (point)))
+    (if (org-looking-back (concat "^[ \t]*" org-clock-string ".*"))
+       (progn (delete-region (1- (point-at-bol)) (point-at-eol))
+              (org-remove-empty-drawer-at "LOGBOOK" (point)))
+      (message "Clock gone, cancel the timer anyway")
+      (sit-for 2)))
   (move-marker org-clock-marker nil)
   (move-marker org-clock-hd-marker nil)
   (setq global-mode-string
        (delq 'org-mode-line-string global-mode-string))
+  (setq frame-title-format org-frame-title-format-backup)
   (force-mode-line-update)
   (message "Clock canceled")
   (run-hooks 'org-clock-cancel-hook))
 
+(defcustom org-clock-goto-before-context 2
+  "Number of lines of context to display before currently clocked-in entry.
+This applies when using `org-clock-goto'."
+  :group 'org-clock
+  :type 'integer)
+
+;;;###autoload
 (defun org-clock-goto (&optional select)
   "Go to the currently clocked-in entry, or to the most recently clocked one.
 With prefix arg SELECT, offer recently clocked tasks for selection."
@@ -1497,13 +1691,13 @@ With prefix arg SELECT, offer recently clocked tasks for selection."
              (setq recent t)
              (car org-clock-history))
             (t (error "No active or recent clock task")))))
-    (switch-to-buffer (marker-buffer m))
+    (org-pop-to-buffer-same-window (marker-buffer m))
     (if (or (< m (point-min)) (> m (point-max))) (widen))
     (goto-char m)
     (org-show-entry)
     (org-back-to-heading t)
     (org-cycle-hide-drawers 'children)
-    (recenter)
+    (recenter org-clock-goto-before-context)
     (org-reveal)
     (if recent
        (message "No running clock, this is the most recently clocked task"))
@@ -1513,93 +1707,101 @@ With prefix arg SELECT, offer recently clocked tasks for selection."
   "Holds the file total time in minutes, after a call to `org-clock-sum'.")
 (make-variable-buffer-local 'org-clock-file-total-minutes)
 
-(defun org-clock-sum (&optional tstart tend headline-filter)
+(defun org-clock-sum-today (&optional headline-filter)
+  "Sum the times for each subtree for today."
+  (interactive)
+  (let ((range (org-clock-special-range 'today)))
+    (org-clock-sum (car range) (cadr range) nil :org-clock-minutes-today)))
+
+;;;###autoload
+(defun org-clock-sum (&optional tstart tend headline-filter propname)
   "Sum the times for each subtree.
 Puts the resulting times in minutes as a text property on each headline.
-TSTART and TEND can mark a time range to be considered.  HEADLINE-FILTER is a
-zero-arg function that, if specified, is called for each headline in the time
-range with point at the headline.  Headlines for which HEADLINE-FILTER returns
-nil are excluded from the clock summation."
+TSTART and TEND can mark a time range to be considered.
+HEADLINE-FILTER is a zero-arg function that, if specified, is called for
+each headline in the time range with point at the headline.  Headlines for
+which HEADLINE-FILTER returns nil are excluded from the clock summation.
+PROPNAME lets you set a custom text property instead of :org-clock-minutes."
   (interactive)
-  (let* ((bmp (buffer-modified-p))
-        (re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*"
-                    org-clock-string
-                    "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
-        (lmax 30)
-        (ltimes (make-vector lmax 0))
-        (t1 0)
-        (level 0)
-        ts te dt
-        time)
-    (if (stringp tstart) (setq tstart (org-time-string-to-seconds tstart)))
-    (if (stringp tend) (setq tend (org-time-string-to-seconds tend)))
-    (if (consp tstart) (setq tstart (org-float-time tstart)))
-    (if (consp tend) (setq tend (org-float-time tend)))
-    (remove-text-properties (point-min) (point-max)
-                            '(:org-clock-minutes t
-                              :org-clock-force-headline-inclusion t))
-    (save-excursion
-      (goto-char (point-max))
-      (while (re-search-backward re nil t)
-       (cond
-        ((match-end 2)
-         ;; Two time stamps
-         (setq ts (match-string 2)
-               te (match-string 3)
-               ts (org-float-time
-                   (apply 'encode-time (org-parse-time-string ts)))
-               te (org-float-time
-                   (apply 'encode-time (org-parse-time-string te)))
-               ts (if tstart (max ts tstart) ts)
-               te (if tend (min te tend) te)
-               dt (- te ts)
-               t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
-        ((match-end 4)
-         ;; A naked time
-         (setq t1 (+ t1 (string-to-number (match-string 5))
-                     (* 60 (string-to-number (match-string 4))))))
-        (t ;; A headline
-         ;; Add the currently clocking item time to the total
-         (when (and org-clock-report-include-clocking-task
-                    (equal (org-clocking-buffer) (current-buffer))
-                    (equal (marker-position org-clock-hd-marker) (point))
-                    tstart
-                    tend
-                    (>= (org-float-time org-clock-start-time) tstart)
-                    (<= (org-float-time org-clock-start-time) tend))
-           (let ((time (floor (- (org-float-time)
-                                 (org-float-time org-clock-start-time)) 60)))
-             (setq t1 (+ t1 time))))
-         (let* ((headline-forced
-                 (get-text-property (point)
-                                     :org-clock-force-headline-inclusion))
-                 (headline-included
-                  (or (null headline-filter)
-                      (save-excursion
-                        (save-match-data (funcall headline-filter))))))
-           (setq level (- (match-end 1) (match-beginning 1)))
-           (when (or (> t1 0) (> (aref ltimes level) 0))
-             (when (or headline-included headline-forced)
-                (if headline-included
-                    (loop for l from 0 to level do
-                          (aset ltimes l (+ (aref ltimes l) t1))))
-               (setq time (aref ltimes level))
-               (goto-char (match-beginning 0))
-               (put-text-property (point) (point-at-eol) :org-clock-minutes time)
-                (if headline-filter
-                    (save-excursion
-                      (save-match-data
-                        (while
-                            (> (funcall outline-level) 1)
-                          (outline-up-heading 1 t)
-                          (put-text-property
-                           (point) (point-at-eol)
-                           :org-clock-force-headline-inclusion t))))))
-             (setq t1 0)
-             (loop for l from level to (1- lmax) do
-                   (aset ltimes l 0)))))))
-      (setq org-clock-file-total-minutes (aref ltimes 0)))
-    (set-buffer-modified-p bmp)))
+  (org-with-silent-modifications
+   (let* ((re (concat "^\\(\\*+\\)[ \t]\\|^[ \t]*"
+                     org-clock-string
+                     "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
+         (lmax 30)
+         (ltimes (make-vector lmax 0))
+         (t1 0)
+         (level 0)
+         ts te dt
+         time)
+     (if (stringp tstart) (setq tstart (org-time-string-to-seconds tstart)))
+     (if (stringp tend) (setq tend (org-time-string-to-seconds tend)))
+     (if (consp tstart) (setq tstart (org-float-time tstart)))
+     (if (consp tend) (setq tend (org-float-time tend)))
+     (remove-text-properties (point-min) (point-max)
+                            `(,(or propname :org-clock-minutes) t
+                              :org-clock-force-headline-inclusion t))
+     (save-excursion
+       (goto-char (point-max))
+       (while (re-search-backward re nil t)
+        (cond
+         ((match-end 2)
+          ;; Two time stamps
+          (setq ts (match-string 2)
+                te (match-string 3)
+                ts (org-float-time
+                    (apply 'encode-time (org-parse-time-string ts)))
+                te (org-float-time
+                    (apply 'encode-time (org-parse-time-string te)))
+                ts (if tstart (max ts tstart) ts)
+                te (if tend (min te tend) te)
+                dt (- te ts)
+                t1 (if (> dt 0) (+ t1 (floor (/ dt 60))) t1)))
+         ((match-end 4)
+          ;; A naked time
+          (setq t1 (+ t1 (string-to-number (match-string 5))
+                      (* 60 (string-to-number (match-string 4))))))
+         (t ;; A headline
+          ;; Add the currently clocking item time to the total
+          (when (and org-clock-report-include-clocking-task
+                     (equal (org-clocking-buffer) (current-buffer))
+                     (equal (marker-position org-clock-hd-marker) (point))
+                     tstart
+                     tend
+                     (>= (org-float-time org-clock-start-time) tstart)
+                     (<= (org-float-time org-clock-start-time) tend))
+            (let ((time (floor (- (org-float-time)
+                                  (org-float-time org-clock-start-time)) 60)))
+              (setq t1 (+ t1 time))))
+          (let* ((headline-forced
+                  (get-text-property (point)
+                                     :org-clock-force-headline-inclusion))
+                 (headline-included
+                  (or (null headline-filter)
+                      (save-excursion
+                        (save-match-data (funcall headline-filter))))))
+            (setq level (- (match-end 1) (match-beginning 1)))
+            (when (or (> t1 0) (> (aref ltimes level) 0))
+              (when (or headline-included headline-forced)
+                (if headline-included
+                    (loop for l from 0 to level do
+                          (aset ltimes l (+ (aref ltimes l) t1))))
+                (setq time (aref ltimes level))
+                (goto-char (match-beginning 0))
+                (put-text-property (point) (point-at-eol)
+                                   (or propname :org-clock-minutes) time)
+                (if headline-filter
+                    (save-excursion
+                      (save-match-data
+                        (while
+                            (> (funcall outline-level) 1)
+                          (outline-up-heading 1 t)
+                          (put-text-property
+                           (point) (point-at-eol)
+                           :org-clock-force-headline-inclusion t))))))
+              (setq t1 0)
+              (loop for l from level to (1- lmax) do
+                    (aset ltimes l 0)))))))
+       (setq org-clock-file-total-minutes (aref ltimes 0))))))
 
 (defun org-clock-sum-current-item (&optional tstart)
   "Return time, clocked on current item in total."
@@ -1609,6 +1811,7 @@ nil are excluded from the clock summation."
       (org-clock-sum tstart)
       org-clock-file-total-minutes)))
 
+;;;###autoload
 (defun org-clock-display (&optional total-only)
   "Show subtree times in the entire buffer.
 If TOTAL-ONLY is non-nil, only show the total time for the entire file
@@ -1635,12 +1838,9 @@ Use \\[org-clock-remove-overlays] to remove the subtree times."
        (when org-remove-highlights-with-change
          (org-add-hook 'before-change-functions 'org-clock-remove-overlays
                        nil 'local))))
-    (if org-time-clocksum-use-fractional
-       (message (concat "Total file time: " org-time-clocksum-fractional-format
-                        " (%d hours and %d minutes)")
-                (/ (+ (* h 60.0) m) 60.0) h m)
-      (message (concat "Total file time: " org-time-clocksum-format
-                      " (%d hours and %d minutes)") h m h m))))
+      (message (concat "Total file time: "
+                      (org-minutes-to-clocksum-string org-clock-file-total-minutes)
+                      " (%d hours and %d minutes)") h m)))
 
 (defvar org-clock-overlays nil)
 (make-variable-buffer-local 'org-clock-overlays)
@@ -1652,25 +1852,17 @@ This creates a new overlay and stores it in `org-clock-overlays', so that it
 will be easy to remove."
   (let* ((c 60) (h (floor (/ time 60))) (m (- time (* 60 h)))
         (l (if level (org-get-valid-level level 0) 0))
-        (fmt (concat "%s " (if org-time-clocksum-use-fractional
-                               org-time-clocksum-fractional-format
-                             org-time-clocksum-format) "%s"))
         (off 0)
         ov tx)
     (org-move-to-column c)
     (unless (eolp) (skip-chars-backward "^ \t"))
     (skip-chars-backward " \t")
-    (setq ov (make-overlay (1- (point)) (point-at-eol))
-         tx (concat (buffer-substring (1- (point)) (point))
+    (setq ov (make-overlay (point-at-bol) (point-at-eol))
+         tx (concat (buffer-substring (point-at-bol) (point))
                     (make-string (+ off (max 0 (- c (current-column)))) ?.)
-                    (org-add-props (if org-time-clocksum-use-fractional
-                                       (format fmt
-                                               (make-string l ?*)
-                                               (/ (+ (* h 60.0) m) 60.0)
-                                               (make-string (- 16 l) ?\ ))
-                                     (format fmt
-                                             (make-string l ?*) h m
-                                             (make-string (- 16 l) ?\ )))
+                    (org-add-props (concat (make-string l ?*) " "
+                                           (org-minutes-to-clocksum-string time)
+                                           (make-string (- 16 l) ?\ ))
                         (list 'face 'org-clock-overlay))
                     ""))
     (if (not (featurep 'xemacs))
@@ -1691,16 +1883,18 @@ from the `before-change-functions' in the current buffer."
       (remove-hook 'before-change-functions
                   'org-clock-remove-overlays 'local))))
 
-(defvar state) ;; dynamically scoped into this function
+(defvar org-state) ;; dynamically scoped into this function
 (defun org-clock-out-if-current ()
   "Clock out if the current entry contains the running clock.
 This is used to stop the clock after a TODO entry is marked DONE,
 and is only done if the variable `org-clock-out-when-done' is not nil."
-  (when (and org-clock-out-when-done
+  (when (and (org-clocking-p)
+            org-clock-out-when-done
+            (marker-buffer org-clock-marker)
             (or (and (eq t org-clock-out-when-done)
-                     (member state org-done-keywords))
+                     (member org-state org-done-keywords))
                 (and (listp org-clock-out-when-done)
-                     (member state org-clock-out-when-done)))
+                     (member org-state org-clock-out-when-done)))
             (equal (or (buffer-base-buffer (org-clocking-buffer))
                        (org-clocking-buffer))
                    (or (buffer-base-buffer (current-buffer))
@@ -1717,7 +1911,7 @@ and is only done if the variable `org-clock-out-when-done' is not nil."
          'org-clock-out-if-current)
 
 ;;;###autoload
-(defun org-get-clocktable (&rest props)
+(defun org-clock-get-clocktable (&rest props)
   "Get a formatted clocktable with parameters according to PROPS.
 The table is created in a temporary buffer, fully formatted and
 fontified, and then returned."
@@ -1737,6 +1931,7 @@ fontified, and then returned."
                                (re-search-forward "^[ \t]*#\\+END" nil t)
                                (point-at-bol)))))
 
+;;;###autoload
 (defun org-clock-report (&optional arg)
   "Create a table containing a report about clocked time.
 If the cursor is inside an existing clocktable block, then the table
@@ -1761,17 +1956,6 @@ buffer and update it."
        (org-combine-plists org-clock-clocktable-default-properties props))))
   (org-update-dblock))
 
-(defun org-in-clocktable-p ()
-  "Check if the cursor is in a clocktable."
-  (let ((pos (point)) start)
-    (save-excursion
-      (end-of-line 1)
-      (and (re-search-backward "^[ \t]*#\\+BEGIN:[ \t]+clocktable" nil t)
-          (setq start (match-beginning 0))
-          (re-search-forward "^[ \t]*#\\+END:.*" nil t)
-          (>= (match-end 0) pos)
-          start))))
-
 (defun org-day-of-week (day month year)
   "Returns the day of the week as an integer."
   (nth 6
@@ -1828,20 +2012,27 @@ buffer and update it."
        ((> startday 4)
        (list 39 startday year)))))))
 
-(defun org-clock-special-range (key &optional time as-strings)
+(defun org-clock-special-range (key &optional time as-strings wstart mstart)
   "Return two times bordering a special time range.
 Key is a symbol specifying the range and can be one of `today', `yesterday',
 `thisweek', `lastweek', `thismonth', `lastmonth', `thisyear', `lastyear'.
-A week starts Monday 0:00 and ends Sunday 24:00.
-The range is determined relative to TIME.  TIME defaults to the current time.
+By default, a week starts Monday 0:00 and ends Sunday 24:00.
+The range is determined relative to TIME, which defaults to current time.
 The return value is a cons cell with two internal times like the ones
-returned by `current time' or `encode-time'. if AS-STRINGS is non-nil,
-the returned times will be formatted strings."
+returned by `current time' or `encode-time'.
+If AS-STRINGS is non-nil, the returned times will be formatted strings.
+If WSTART is non-nil, use this number to specify the starting day of a
+week (monday is 1).
+If MSTART is non-nil, use this number to specify the starting day of a
+month (1 is the first day of the month).
+If you can combine both, the month starting day will have priority."
   (if (integerp key) (setq key (intern (number-to-string key))))
   (let* ((tm (decode-time (or time (current-time))))
         (s 0) (m (nth 1 tm)) (h (nth 2 tm))
         (d (nth 3 tm)) (month (nth 4 tm)) (y (nth 5 tm))
         (dow (nth 6 tm))
+        (ws (or wstart 1))
+        (ms (or mstart 1))
         (skey (symbol-name key))
         (shift 0)
          (q (cond ((>= (nth 4 tm) 10) 4)
@@ -1866,13 +2057,13 @@ the returned times will be formatted strings."
       (setq d (nth 1 date) month (car date) y (nth 2 date)
            dow 1
            key 'week))
-      ((string-match "^\\([0-9]+\\)-[qQ]\\([1-4]\\)$" skey)
-       (require 'cal-iso)
-       (setq y (string-to-number (match-string 1 skey)))
-       (setq q (string-to-number (match-string 2 skey)))
-       (setq date (calendar-gregorian-from-absolute
-                   (calendar-absolute-from-iso (org-quarter-to-date q y))))
-       (setq d (nth 1 date) month (car date) y (nth 2 date)
+     ((string-match "^\\([0-9]+\\)-[qQ]\\([1-4]\\)$" skey)
+      (require 'cal-iso)
+      (setq y (string-to-number (match-string 1 skey)))
+      (setq q (string-to-number (match-string 2 skey)))
+      (setq date (calendar-gregorian-from-absolute
+                 (calendar-absolute-from-iso (org-quarter-to-date q y))))
+      (setq d (nth 1 date) month (car date) y (nth 2 date)
             dow 1
             key 'quarter))
      ((string-match "^\\([0-9]+\\)-\\([0-9]\\{1,2\\}\\)-\\([0-9]\\{1,2\\}\\)$" skey)
@@ -1883,12 +2074,11 @@ the returned times will be formatted strings."
      ((string-match "\\([-+][0-9]+\\)$" skey)
       (setq shift (string-to-number (match-string 1 skey))
             key (intern (substring skey 0 (match-beginning 1))))
-       (if(and (memq key '(quarter thisq)) (> shift 0))
-         (error "Looking forward with quarters isn't implemented.")
-        ())))
+      (if (and (memq key '(quarter thisq)) (> shift 0))
+         (error "Looking forward with quarters isn't implemented"))))
 
     (when (= shift 0)
-       (cond ((eq key 'yesterday) (setq key 'today   shift -1))
+      (cond ((eq key 'yesterday) (setq key 'today   shift -1))
             ((eq key 'lastweek)  (setq key 'week    shift -1))
             ((eq key 'lastmonth) (setq key 'month   shift -1))
             ((eq key 'lastyear)  (setq key 'year    shift -1))
@@ -1897,32 +2087,33 @@ the returned times will be formatted strings."
      ((memq key '(day today))
       (setq d (+ d shift) h 0 m 0 h1 24 m1 0))
      ((memq key '(week thisweek))
-      (setq diff (+ (* -7 shift) (if (= dow 0) 6 (1- dow)))
+      (setq diff (+ (* -7 shift) (if (= dow 0) (- 7 ws) (- dow ws)))
            m 0 h 0 d (- d diff) d1 (+ 7 d)))
      ((memq key '(month thismonth))
-      (setq d 1 h 0 m 0 d1 1 month (+ month shift) month1 (1+ month) h1 0 m1 0))
+      (setq d (or ms 1) h 0 m 0 d1 (or ms 1)
+           month (+ month shift) month1 (1+ month) h1 0 m1 0))
      ((memq key '(quarter thisq))
-      ; compute if this shift remains in this year
-      ; if not, compute how many years and quarters we have to shift (via floor*)
-      ; and compute the shifted years, months and quarters
+      ;; Compute if this shift remains in this year.  If not, compute
+      ;; how many years and quarters we have to shift (via floor*) and
+      ;; compute the shifted years, months and quarters.
       (cond
        ((< (+ (- q 1) shift) 0) ; shift not in this year
-       (setq interval (* -1 (+ (- q 1) shift)))
-       ; set tmp to ((years to shift) (quarters to shift))
-       (setq tmp (org-floor* interval 4))
-       ; due to the use of floor, 0 quarters actually means 4
-       (if (= 0 (nth 1 tmp))
-           (setq shiftedy (- y (nth 0 tmp))
-                 shiftedm 1
-                 shiftedq 1)
-         (setq shiftedy (- y (+ 1 (nth 0 tmp)))
-               shiftedm (- 13 (* 3 (nth 1 tmp)))
-               shiftedq (- 5 (nth 1 tmp))))
-       (setq d 1 h 0 m 0 d1 1 month shiftedm month1 (+ 3 shiftedm) h1 0 m1 0 y shiftedy))
-       ((> (+ q shift) 0) ; shift is whitin this year
-       (setq shiftedq (+ q shift))
-       (setq shiftedy y)
-       (setq d 1 h 0 m 0 d1 1 month (+ 1 (* 3 (- (+ q shift) 1))) month1 (+ 4 (* 3 (- (+ q shift) 1))) h1 0 m1 0))))
+       (setq interval (* -1 (+ (- q 1) shift)))
+       ;; Set tmp to ((years to shift) (quarters to shift)).
+       (setq tmp (org-floor* interval 4))
+       ;; Due to the use of floor, 0 quarters actually means 4.
+       (if (= 0 (nth 1 tmp))
+           (setq shiftedy (- y (nth 0 tmp))
+                 shiftedm 1
+                 shiftedq 1)
+         (setq shiftedy (- y (+ 1 (nth 0 tmp)))
+               shiftedm (- 13 (* 3 (nth 1 tmp)))
+               shiftedq (- 5 (nth 1 tmp))))
+       (setq d 1 h 0 m 0 d1 1 month shiftedm month1 (+ 3 shiftedm) h1 0 m1 0 y shiftedy))
+       ((> (+ q shift) 0) ; shift is within this year
+       (setq shiftedq (+ q shift))
+       (setq shiftedy y)
+       (setq d 1 h 0 m 0 d1 1 month (+ 1 (* 3 (- (+ q shift) 1))) month1 (+ 4 (* 3 (- (+ q shift) 1))) h1 0 m1 0))))
      ((memq key '(year thisyear))
       (setq m 0 h 0 d 1 month 1 y (+ y shift) y1 (1+ y)))
      (t (error "No such time block %s" key)))
@@ -1940,8 +2131,7 @@ the returned times will be formatted strings."
      ((memq key '(year thisyear))
       (setq txt (format-time-string "the year %Y" ts)))
      ((memq key '(quarter thisq))
-      (setq txt (concatenate 'string (org-count-quarter shiftedq) " quarter of " (number-to-string shiftedy))))
-     )
+      (setq txt (concat (org-count-quarter shiftedq) " quarter of " (number-to-string shiftedy)))))
     (if as-strings
        (list (format-time-string fm ts) (format-time-string fm te) txt)
       (list ts te txt))))
@@ -1978,61 +2168,64 @@ the currently selected interval size."
         ((equal s "lastyear") (setq s "thisyear-1"))
         ((equal s "lastq") (setq s "thisq-1")))
 
-       (cond
-        ((string-match "^\\(today\\|thisweek\\|thismonth\\|thisyear\\|thisq\\)\\([-+][0-9]+\\)?$" s)
-         (setq block (match-string 1 s)
-               shift (if (match-end 2)
-                         (string-to-number (match-string 2 s))
-                       0))
-         (setq shift (+ shift n))
-         (setq ins (if (= shift 0) block (format "%s%+d" block shift))))
-       ((string-match "\\([0-9]+\\)\\(-\\([wWqQ]?\\)\\([0-9]\\{1,2\\}\\)\\(-\\([0-9]\\{1,2\\}\\)\\)?\\)?" s)
-        ;;               1        1  2   3       3  4                  4  5   6                6  5   2
-         (setq y (string-to-number (match-string 1 s))
-               wp (and (match-end 3) (match-string 3 s))
-               mw (and (match-end 4) (string-to-number (match-string 4 s)))
-              d (and (match-end 6) (string-to-number (match-string 6 s))))
-        (cond
-         (d (setq ins (format-time-string
-                        "%Y-%m-%d"
-                        (encode-time 0 0 0 (+ d n) m y))))
-          ((and wp (string-match "w\\|W" wp) mw (> (length wp) 0))
-           (require 'cal-iso)
-           (setq date (calendar-gregorian-from-absolute (calendar-absolute-from-iso (list (+ mw n) 1 y))))
-           (setq ins (format-time-string
-                      "%G-W%V"
-                      (encode-time 0 0 0 (nth 1 date) (car date) (nth 2 date)))))
-         ((and wp (string-match "q\\|Q" wp) mw (> (length wp) 0))
-           (require 'cal-iso)
-          ; if the 4th + 1 quarter is requested we flip to the 1st quarter of the next year
-           (if (> (+ mw n) 4)
-               (setq mw 0
-                     y (+ 1 y))
-            ())
-          ; if the 1st - 1 quarter is requested we flip to the 4th quarter of the previous year
-           (if (= (+ mw n) 0)
-               (setq mw 5
-                     y (- y 1))
-             ())
-           (setq date (calendar-gregorian-from-absolute (calendar-absolute-from-iso (org-quarter-to-date (+ mw n) y))))
-           (setq ins (format-time-string
-                      (concatenate 'string (number-to-string y) "-Q" (number-to-string (+ mw n)))
-                      (encode-time 0 0 0 (nth 1 date) (car date) (nth 2 date)))))
-          (mw
-           (setq ins (format-time-string
-                      "%Y-%m"
-                     (encode-time 0 0 0 1 (+ mw n) y))))
-         (y
-          (setq ins (number-to-string (+ y n))))))
-       (t (error "Cannot shift clocktable block")))
-       (when ins
-        (goto-char b)
-        (insert ins)
-        (delete-region (point) (+ (point) (- e b)))
-        (beginning-of-line 1)
-        (org-update-dblock)
-        t)))))
+       (cond
+        ((string-match "^\\(today\\|thisweek\\|thismonth\\|thisyear\\|thisq\\)\\([-+][0-9]+\\)?$" s)
+         (setq block (match-string 1 s)
+               shift (if (match-end 2)
+                         (string-to-number (match-string 2 s))
+                       0))
+         (setq shift (+ shift n))
+         (setq ins (if (= shift 0) block (format "%s%+d" block shift))))
+        ((string-match "\\([0-9]+\\)\\(-\\([wWqQ]?\\)\\([0-9]\\{1,2\\}\\)\\(-\\([0-9]\\{1,2\\}\\)\\)?\\)?" s)
+         ;;               1        1  2   3       3  4                  4  5   6                6  5   2
+         (setq y (string-to-number (match-string 1 s))
+               wp (and (match-end 3) (match-string 3 s))
+               mw (and (match-end 4) (string-to-number (match-string 4 s)))
+               d (and (match-end 6) (string-to-number (match-string 6 s))))
+         (cond
+          (d (setq ins (format-time-string
+                        "%Y-%m-%d"
+                        (encode-time 0 0 0 (+ d n) m y))))
+          ((and wp (string-match "w\\|W" wp) mw (> (length wp) 0))
+           (require 'cal-iso)
+           (setq date (calendar-gregorian-from-absolute
+                       (calendar-absolute-from-iso (list (+ mw n) 1 y))))
+           (setq ins (format-time-string
+                      "%G-W%V"
+                      (encode-time 0 0 0 (nth 1 date) (car date) (nth 2 date)))))
+          ((and wp (string-match "q\\|Q" wp) mw (> (length wp) 0))
+           (require 'cal-iso)
+                                       ; if the 4th + 1 quarter is requested we flip to the 1st quarter of the next year
+           (if (> (+ mw n) 4)
+               (setq mw 0
+                     y (+ 1 y))
+             ())
+                                       ; if the 1st - 1 quarter is requested we flip to the 4th quarter of the previous year
+           (if (= (+ mw n) 0)
+               (setq mw 5
+                     y (- y 1))
+             ())
+           (setq date (calendar-gregorian-from-absolute
+                       (calendar-absolute-from-iso (org-quarter-to-date (+ mw n) y))))
+           (setq ins (format-time-string
+                      (concat (number-to-string y) "-Q" (number-to-string (+ mw n)))
+                      (encode-time 0 0 0 (nth 1 date) (car date) (nth 2 date)))))
+          (mw
+           (setq ins (format-time-string
+                      "%Y-%m"
+                      (encode-time 0 0 0 1 (+ mw n) y))))
+          (y
+           (setq ins (number-to-string (+ y n))))))
+        (t (error "Cannot shift clocktable block")))
+       (when ins
+         (goto-char b)
+         (insert ins)
+         (delete-region (point) (+ (point) (- e b)))
+         (beginning-of-line 1)
+         (org-update-dblock)
+         t)))))
 
+;;;###autoload
 (defun org-dblock-write:clocktable (params)
   "Write the standard clocktable."
   (setq params (org-combine-plists org-clocktable-defaults params))
@@ -2043,6 +2236,8 @@ the currently selected interval size."
           (te (plist-get params :tend))
           (link (plist-get params :link))
           (maxlevel (or (plist-get params :maxlevel) 3))
+          (ws (plist-get params :wstart))
+          (ms (plist-get params :mstart))
           (step (plist-get params :step))
           (timestamp (plist-get params :timestamp))
           (formatter (or (plist-get params :formatter)
@@ -2050,11 +2245,10 @@ the currently selected interval size."
                          'org-clocktable-write-default))
           cc range-text ipos pos one-file-with-archives
           scope-is-list tbls level)
-
       ;; Check if we need to do steps
       (when block
        ;; Get the range text for the header
-       (setq cc (org-clock-special-range block nil t)
+       (setq cc (org-clock-special-range block nil t ws ms)
              ts (car cc) te (nth 1 cc) range-text (nth 2 cc)))
       (when step
        ;; Write many tables, in steps
@@ -2083,7 +2277,7 @@ the currently selected interval size."
          ;; we collect from several files
          (let* ((files scope)
                 file)
-           (org-prepare-agenda-buffers files)
+           (org-agenda-prepare-buffers files)
            (while (setq file (pop files))
              (with-current-buffer (find-buffer-visiting file)
                (save-excursion
@@ -2092,7 +2286,7 @@ the currently selected interval size."
        ;; Just from the current file
        (save-restriction
          ;; get the right range into the restriction
-         (org-prepare-agenda-buffers (list (buffer-file-name)))
+         (org-agenda-prepare-buffers (list (buffer-file-name)))
          (cond
           ((not scope))  ; use the restriction as it is now
           ((eq scope 'file) (widen))
@@ -2125,7 +2319,7 @@ the currently selected interval size."
   "Write out a clock table at position IPOS in the current buffer.
 TABLES is a list of tables with clocking data as produced by
 `org-clock-get-table-data'.  PARAMS is the parameter property list obtained
-from the dynamic block defintion."
+from the dynamic block definition."
   ;; This function looks quite complicated, mainly because there are a
   ;; lot of options which can add or remove columns.  I have massively
   ;; commented this function, the I hope it is understandable.  If
@@ -2134,7 +2328,8 @@ from the dynamic block defintion."
   ;; well-defined number of columns...
   (let* ((hlchars '((1 . "*") (2 . "/")))
         (lwords (assoc (or (plist-get params :lang)
-                           org-export-default-language)
+                           (org-bound-and-true-p org-export-default-language)
+                           "en")
                        org-clock-clocktable-language-setup))
         (multifile (plist-get params :multifile))
         (block (plist-get params :block))
@@ -2142,15 +2337,20 @@ from the dynamic block defintion."
         (te (plist-get params :tend))
         (header (plist-get  params :header))
         (narrow (plist-get params :narrow))
+        (ws (or (plist-get params :wstart) 1))
+        (ms (or (plist-get params :mstart) 1))
         (link (plist-get params :link))
         (maxlevel (or (plist-get params :maxlevel) 3))
         (emph (plist-get params :emphasize))
         (level-p (plist-get params :level))
+        (org-time-clocksum-use-effort-durations
+         (plist-get params :effort-durations))
         (timestamp (plist-get params :timestamp))
         (properties (plist-get params :properties))
         (ntcol (max 1 (or (plist-get params :tcolumns) 100)))
         (rm-file-column (plist-get params :one-file-with-archives))
         (indent (plist-get params :indent))
+        (case-fold-search t)
         range-text total-time tbl level hlc formula pcol
         file-time entries entry headline
         recalc content narrow-cut-p tcol)
@@ -2160,192 +2360,197 @@ from the dynamic block defintion."
       (setq level nil indent t narrow (or narrow '40!) ntcol 1))
 
     ;; Some consistency test for parameters
-      (unless (integerp ntcol)
-       (setq params (plist-put params :tcolumns (setq ntcol 100))))
+    (unless (integerp ntcol)
+      (setq params (plist-put params :tcolumns (setq ntcol 100))))
 
-      (when (and narrow (integerp narrow) link)
-       ;; We cannot have both integer narrow and link
-       (message
-        "Using hard narrowing in clocktable to allow for links")
-       (setq narrow (intern (format "%d!" narrow))))
+    (when (and narrow (integerp narrow) link)
+      ;; We cannot have both integer narrow and link
+      (message
+       "Using hard narrowing in clocktable to allow for links")
+      (setq narrow (intern (format "%d!" narrow))))
 
-      (when narrow
-       (cond
-        ((integerp narrow))
-        ((and (symbolp narrow)
-              (string-match "\\`[0-9]+!\\'" (symbol-name narrow)))
-         (setq narrow-cut-p t
-               narrow (string-to-number (substring (symbol-name narrow)
-                                                   0 -1))))
-        (t
-         (error "Invalid value %s of :narrow property in clock table"
-                narrow))))
-
-      (when block
-       ;; Get the range text for the header
-       (setq range-text (nth 2 (org-clock-special-range block nil t))))
-
-      ;; Compute the total time
-      (setq total-time (apply '+ (mapcar 'cadr tables)))
-
-      ;; Now we need to output this tsuff
-      (goto-char ipos)
+    (when narrow
+      (cond
+       ((integerp narrow))
+       ((and (symbolp narrow)
+            (string-match "\\`[0-9]+!\\'" (symbol-name narrow)))
+       (setq narrow-cut-p t
+             narrow (string-to-number (substring (symbol-name narrow)
+                                                 0 -1))))
+       (t
+       (error "Invalid value %s of :narrow property in clock table"
+              narrow))))
 
-      ;; Insert the text *before* the actual table
-      (insert-before-markers
-       (or header
-          ;; Format the standard header
-          (concat
-           (nth 9 lwords) " ["
-           (substring
-            (format-time-string (cdr org-time-stamp-formats))
-            1 -1)
-           "]"
-           (if block (concat ", for " range-text ".") "")
-           "\n\n")))
-
-      ;; Insert the narrowing line
-      (when (and narrow (integerp narrow) (not narrow-cut-p))
-       (insert-before-markers
-        "|"                            ; table line starter
-        (if multifile "|" "")          ; file column, maybe
-        (if level-p   "|" "")          ; level column, maybe
-        (if timestamp "|" "")          ; timestamp column, maybe
-        (if properties (make-string (length properties) ?|) "")  ;properties columns, maybe
-        (format "<%d>| |\n" narrow)))  ; headline and time columns
-
-      ;; Insert the table header line
-      (insert-before-markers
-       "|"                              ; table line starter
-       (if multifile (concat (nth 1 lwords) "|") "")  ; file column, maybe
-       (if level-p   (concat (nth 2 lwords) "|") "")  ; level column, maybe
-       (if timestamp (concat (nth 3 lwords) "|") "")  ; timestamp column, maybe
-       (if properties (concat (mapconcat 'identity properties "|") "|") "") ;properties columns, maybe
-       (concat (nth 4 lwords) "|"
-              (nth 5 lwords) "|\n"))                 ; headline and time columns
-
-      ;; Insert the total time in the table
+    (when block
+      ;; Get the range text for the header
+      (setq range-text (nth 2 (org-clock-special-range block nil t ws ms))))
+
+    ;; Compute the total time
+    (setq total-time (apply '+ (mapcar 'cadr tables)))
+
+    ;; Now we need to output this tsuff
+    (goto-char ipos)
+
+    ;; Insert the text *before* the actual table
+    (insert-before-markers
+     (or header
+        ;; Format the standard header
+        (concat
+         "#+CAPTION: "
+         (nth 9 lwords) " ["
+         (substring
+          (format-time-string (cdr org-time-stamp-formats))
+          1 -1)
+         "]"
+         (if block (concat ", for " range-text ".") "")
+         "\n")))
+
+    ;; Insert the narrowing line
+    (when (and narrow (integerp narrow) (not narrow-cut-p))
       (insert-before-markers
-       "|-\n"                            ; a hline
-       "|"                               ; table line starter
-       (if multifile (concat "| " (nth 6 lwords) " ") "")
-                                        ; file column, maybe
-       (if level-p   "|"      "")        ; level column, maybe
-       (if timestamp "|"      "")        ; timestamp column, maybe
+       "|"                            ; table line starter
+       (if multifile "|" "")          ; file column, maybe
+       (if level-p   "|" "")          ; level column, maybe
+       (if timestamp "|" "")          ; timestamp column, maybe
        (if properties (make-string (length properties) ?|) "")  ;properties columns, maybe
-       (concat "*" (nth 7 lwords) "*| ") ; instead of a headline
-       "*"
-       (org-minutes-to-hh:mm-string (or total-time 0)) ; the time
-       "*|\n")                          ; close line
-
-      ;; Now iterate over the tables and insert the data
-      ;; but only if any time has been collected
-      (when (and total-time (> total-time 0))
-
-       (while (setq tbl (pop tables))
-         ;; now tbl is the table resulting from one file.
-         (setq file-time (nth 1 tbl))
-         (when (or (and file-time (> file-time 0))
-                   (not (plist-get params :fileskip0)))
-           (insert-before-markers "|-\n")  ; a hline because a new file starts
-           ;; First the file time, if we have multiple files
-           (when multifile
-             ;; Summarize the time collected from this file
-             (insert-before-markers
-              (format (concat "| %s %s | %s%s*" (nth 8 lwords) "* | *%s*|\n")
-                      (file-name-nondirectory (car tbl))
-                      (if level-p   "| " "") ; level column, maybe
-                      (if timestamp "| " "") ; timestamp column, maybe
-                      (if properties (make-string (length properties) ?|) "")  ;properties columns, maybe
-                      (org-minutes-to-hh:mm-string (nth 1 tbl))))) ; the time
-
-           ;; Get the list of node entries and iterate over it
-           (setq entries (nth 2 tbl))
-           (while (setq entry (pop entries))
-             (setq level (car entry)
-                   headline (nth 1 entry)
-                   hlc (if emph (or (cdr (assoc level hlchars)) "") ""))
-             (when narrow-cut-p
-               (if (and (string-match (concat "\\`" org-bracket-link-regexp
-                                              "\\'")
-                                      headline)
-                        (match-end 3))
-                   (setq headline
-                         (format "[[%s][%s]]"
-                                 (match-string 1 headline)
-                                 (org-shorten-string (match-string 3 headline)
-                                                     narrow)))
-                 (setq headline (org-shorten-string headline narrow))))
-             (insert-before-markers
-              "|"                      ; start the table line
-              (if multifile "|" "")    ; free space for file name column?
-              (if level-p (format "%d|" (car entry)) "")   ; level, maybe
-              (if timestamp (concat (nth 2 entry) "|") "") ; timestamp, maybe
-              (if properties
-                  (concat
-                   (mapconcat
-                    (lambda (p) (or (cdr (assoc p (nth 4 entry))) ""))
-                    properties "|") "|") "")  ;properties columns, maybe
-              (if indent (org-clocktable-indent-string level) "") ; indentation
-              hlc headline hlc "|"                                ; headline
-              (make-string (min (1- ntcol) (or (- level 1))) ?|)
+       (format "<%d>| |\n" narrow)))  ; headline and time columns
+
+    ;; Insert the table header line
+    (insert-before-markers
+     "|"                              ; table line starter
+     (if multifile (concat (nth 1 lwords) "|") "")  ; file column, maybe
+     (if level-p   (concat (nth 2 lwords) "|") "")  ; level column, maybe
+     (if timestamp (concat (nth 3 lwords) "|") "")  ; timestamp column, maybe
+     (if properties (concat (mapconcat 'identity properties "|") "|") "") ;properties columns, maybe
+     (concat (nth 4 lwords) "|"
+            (nth 5 lwords) "|\n"))                 ; headline and time columns
+
+    ;; Insert the total time in the table
+    (insert-before-markers
+     "|-\n"                            ; a hline
+     "|"                               ; table line starter
+     (if multifile (concat "| " (nth 6 lwords) " ") "")
+                                       ; file column, maybe
+     (if level-p   "|"      "")        ; level column, maybe
+     (if timestamp "|"      "")        ; timestamp column, maybe
+     (if properties (make-string (length properties) ?|) "")  ; properties columns, maybe
+     (concat (format org-clock-total-time-cell-format (nth 7 lwords))  "| ") ; instead of a headline
+     (format org-clock-total-time-cell-format
+            (org-minutes-to-clocksum-string (or total-time 0))) ; the time
+     "|\n")                          ; close line
+
+    ;; Now iterate over the tables and insert the data
+    ;; but only if any time has been collected
+    (when (and total-time (> total-time 0))
+
+      (while (setq tbl (pop tables))
+       ;; now tbl is the table resulting from one file.
+       (setq file-time (nth 1 tbl))
+       (when (or (and file-time (> file-time 0))
+                 (not (plist-get params :fileskip0)))
+         (insert-before-markers "|-\n")  ; a hline because a new file starts
+         ;; First the file time, if we have multiple files
+         (when multifile
+           ;; Summarize the time collected from this file
+           (insert-before-markers
+            (format (concat "| %s %s | %s%s"
+                            (format org-clock-file-time-cell-format (nth 8 lwords))
+                            " | *%s*|\n")
+                    (file-name-nondirectory (car tbl))
+                    (if level-p   "| " "") ; level column, maybe
+                    (if timestamp "| " "") ; timestamp column, maybe
+                    (if properties (make-string (length properties) ?|) "")  ;properties columns, maybe
+                    (org-minutes-to-clocksum-string (nth 1 tbl))))) ; the time
+
+         ;; Get the list of node entries and iterate over it
+         (setq entries (nth 2 tbl))
+         (while (setq entry (pop entries))
+           (setq level (car entry)
+                 headline (nth 1 entry)
+                 hlc (if emph (or (cdr (assoc level hlchars)) "") ""))
+           (when narrow-cut-p
+             (if (and (string-match (concat "\\`" org-bracket-link-regexp
+                                            "\\'")
+                                    headline)
+                      (match-end 3))
+                 (setq headline
+                       (format "[[%s][%s]]"
+                               (match-string 1 headline)
+                               (org-shorten-string (match-string 3 headline)
+                                                   narrow)))
+               (setq headline (org-shorten-string headline narrow))))
+           (insert-before-markers
+            "|"                      ; start the table line
+            (if multifile "|" "")    ; free space for file name column?
+            (if level-p (format "%d|" (car entry)) "")   ; level, maybe
+            (if timestamp (concat (nth 2 entry) "|") "") ; timestamp, maybe
+            (if properties
+                (concat
+                 (mapconcat
+                  (lambda (p) (or (cdr (assoc p (nth 4 entry))) ""))
+                  properties "|") "|") "")  ;properties columns, maybe
+            (if indent (org-clocktable-indent-string level) "") ; indentation
+            hlc headline hlc "|"                                ; headline
+            (make-string (min (1- ntcol) (or (- level 1))) ?|)
                                        ; empty fields for higher levels
-              hlc (org-minutes-to-hh:mm-string (nth 3 entry)) hlc ; time
-              "|\n"                                               ; close line
-              )))))
-      (backward-delete-char 1)
-      (if (setq formula (plist-get params :formula))
-         (cond
-          ((eq formula '%)
-           ;; compute the column where the % numbers need to go
-           (setq pcol (+ 2
-                         (if multifile 1 0)
-                         (if level-p 1 0)
-                         (if timestamp 1 0)
-                         (min maxlevel (or ntcol 100))))
-           ;; compute the column where the total time is
-           (setq tcol (+ 2
-                         (if multifile 1 0)
-                         (if level-p 1 0)
-                         (if timestamp 1 0)))
-           (insert
-            (format
-             "\n#+TBLFM: $%d='(org-clock-time%% @%d$%d $%d..$%d);%%.1f"
-             pcol            ; the column where the % numbers should go
-             (if (and narrow (not narrow-cut-p)) 3 2) ; row of the total time
-             tcol            ; column of the total time
-             tcol (1- pcol)  ; range of columns where times can be found
-             ))
-           (setq recalc t))
-          ((stringp formula)
-           (insert "\n#+TBLFM: " formula)
-           (setq recalc t))
-          (t (error "invalid formula in clocktable")))
-       ;; Should we rescue an old formula?
-       (when (stringp (setq content (plist-get params :content)))
-         (when (string-match "^\\([ \t]*#\\+TBLFM:.*\\)" content)
-           (setq recalc t)
-           (insert "\n" (match-string 1 (plist-get params :content)))
-           (beginning-of-line 0))))
-      ;; Back to beginning, align the table, recalculate if necessary
-      (goto-char ipos)
-      (skip-chars-forward "^|")
-      (org-table-align)
-      (when org-hide-emphasis-markers
-       ;; we need to align a second time
-       (org-table-align))
-      (when recalc
-       (if (eq formula '%)
-           (save-excursion
-             (if (and narrow (not narrow-cut-p)) (beginning-of-line 2))
-             (org-table-goto-column pcol nil 'force)
-             (insert "%")))
-       (org-table-recalculate 'all))
-      (when rm-file-column
-       ;; The file column is actually not wanted
-       (forward-char 1)
-       (org-table-delete-column))
-      total-time))
+            hlc (org-minutes-to-clocksum-string (nth 3 entry)) hlc ; time
+            "|\n"                                               ; close line
+            )))))
+    ;; When exporting subtrees or regions the region might be
+    ;; activated, so let's disable ̀€delete-active-region'
+    (let ((delete-active-region nil)) (backward-delete-char 1))
+    (if (setq formula (plist-get params :formula))
+       (cond
+        ((eq formula '%)
+         ;; compute the column where the % numbers need to go
+         (setq pcol (+ 2
+                       (if multifile 1 0)
+                       (if level-p 1 0)
+                       (if timestamp 1 0)
+                       (min maxlevel (or ntcol 100))))
+         ;; compute the column where the total time is
+         (setq tcol (+ 2
+                       (if multifile 1 0)
+                       (if level-p 1 0)
+                       (if timestamp 1 0)))
+         (insert
+          (format
+           "\n#+TBLFM: $%d='(org-clock-time%% @%d$%d $%d..$%d);%%.1f"
+           pcol            ; the column where the % numbers should go
+           (if (and narrow (not narrow-cut-p)) 3 2) ; row of the total time
+           tcol            ; column of the total time
+           tcol (1- pcol)  ; range of columns where times can be found
+           ))
+         (setq recalc t))
+        ((stringp formula)
+         (insert "\n#+TBLFM: " formula)
+         (setq recalc t))
+        (t (error "Invalid formula in clocktable")))
+      ;; Should we rescue an old formula?
+      (when (stringp (setq content (plist-get params :content)))
+       (when (string-match "^\\([ \t]*#\\+tblfm:.*\\)" content)
+         (setq recalc t)
+         (insert "\n" (match-string 1 (plist-get params :content)))
+         (beginning-of-line 0))))
+    ;; Back to beginning, align the table, recalculate if necessary
+    (goto-char ipos)
+    (skip-chars-forward "^|")
+    (org-table-align)
+    (when org-hide-emphasis-markers
+      ;; we need to align a second time
+      (org-table-align))
+    (when recalc
+      (if (eq formula '%)
+         (save-excursion
+           (if (and narrow (not narrow-cut-p)) (beginning-of-line 2))
+           (org-table-goto-column pcol nil 'force)
+           (insert "%")))
+      (org-table-recalculate 'all))
+    (when rm-file-column
+      ;; The file column is actually not wanted
+      (forward-char 1)
+      (org-table-delete-column))
+    total-time))
 
 (defun org-clocktable-indent-string (level)
   (if (= level 1)
@@ -2361,13 +2566,15 @@ from the dynamic block defintion."
   (let* ((p1 (copy-sequence params))
         (ts (plist-get p1 :tstart))
         (te (plist-get p1 :tend))
+        (ws (plist-get p1 :wstart))
+        (ms (plist-get p1 :mstart))
         (step0 (plist-get p1 :step))
         (step (cdr (assoc step0 '((day . 86400) (week . 604800)))))
         (stepskip0 (plist-get p1 :stepskip0))
         (block (plist-get p1 :block))
-        cc range-text step-time)
+        cc range-text step-time tsb)
     (when block
-      (setq cc (org-clock-special-range block nil t)
+      (setq cc (org-clock-special-range block nil t ws ms)
            ts (car cc) te (nth 1 cc) range-text (nth 2 cc)))
     (cond
      ((numberp ts)
@@ -2385,17 +2592,21 @@ from the dynamic block defintion."
      (te
       (setq te (org-float-time
                (apply 'encode-time (org-parse-time-string te))))))
+    (setq tsb
+         (if (eq step0 'week)
+             (- ts (* 86400 (- (nth 6 (decode-time (seconds-to-time ts))) ws)))
+           ts))
     (setq p1 (plist-put p1 :header ""))
     (setq p1 (plist-put p1 :step nil))
     (setq p1 (plist-put p1 :block nil))
-    (while (< ts te)
+    (while (< tsb te)
       (or (bolp) (insert "\n"))
       (setq p1 (plist-put p1 :tstart (format-time-string
                                      (org-time-stamp-format nil t)
-                                     (seconds-to-time ts))))
+                                     (seconds-to-time (max tsb ts)))))
       (setq p1 (plist-put p1 :tend (format-time-string
                                    (org-time-stamp-format nil t)
-                                   (seconds-to-time (setq ts (+ ts step))))))
+                                   (seconds-to-time (min te (setq tsb (+ tsb step)))))))
       (insert "\n" (if (eq step0 'day) "Daily report: "
                     "Weekly report starting on: ")
              (plist-get p1 :tstart) "\n")
@@ -2437,17 +2648,20 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
         (timestamp (plist-get params :timestamp))
         (ts (plist-get params :tstart))
         (te (plist-get params :tend))
+        (ws (plist-get params :wstart))
+        (ms (plist-get params :mstart))
         (block (plist-get params :block))
         (link (plist-get params :link))
         (tags (plist-get params :tags))
         (properties (plist-get params :properties))
         (inherit-property-p (plist-get params :inherit-props))
+        todo-only
         (matcher (if tags (cdr (org-make-tags-matcher tags))))
         cc range-text st p time level hdl props tsp tbl)
 
     (setq org-clock-file-total-minutes nil)
     (when block
-      (setq cc (org-clock-special-range block nil t)
+      (setq cc (org-clock-special-range block nil t ws ms)
            ts (car cc) te (nth 1 cc) range-text (nth 2 cc)))
     (when (integerp ts) (setq ts (calendar-gregorian-from-absolute ts)))
     (when (integerp te) (setq te (calendar-gregorian-from-absolute te)))
@@ -2457,14 +2671,16 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
       (setq te (format "%4d-%02d-%02d" (nth 2 te) (car te) (nth 1 te))))
     ;; Now the times are strings we can parse.
     (if ts (setq ts (org-float-time
-                    (apply 'encode-time (org-parse-time-string ts)))))
+                    (seconds-to-time (org-matcher-time ts)))))
     (if te (setq te (org-float-time
-                    (apply 'encode-time (org-parse-time-string te)))))
+                    (seconds-to-time (org-matcher-time te)))))
     (save-excursion
       (org-clock-sum ts te
                     (unless (null matcher)
                       (lambda ()
-                        (let ((tags-list (org-get-tags-at)))
+                        (let* ((tags-list (org-get-tags-at))
+                               (org-scanner-tags tags-list)
+                               (org-trust-scanner-tags t))
                           (eval matcher)))))
       (goto-char (point-min))
       (setq st t)
@@ -2496,13 +2712,13 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
                              (cdr (assoc "DEADLINE" props))
                              (cdr (assoc "TIMESTAMP" props))
                              (cdr (assoc "TIMESTAMP_IA" props))))
-           props (when properties
-                   (remove nil
-                           (mapcar
-                            (lambda (p)
-                              (when (org-entry-get (point) p inherit-property-p)
-                                (cons p (org-entry-get (point) p inherit-property-p))))
-                            properties))))
+                   props (when properties
+                           (remove nil
+                                   (mapcar
+                                    (lambda (p)
+                                      (when (org-entry-get (point) p inherit-property-p)
+                                        (cons p (org-entry-get (point) p inherit-property-p))))
+                                    properties))))
              (when (> time 0) (push (list level hdl tsp time props) tbl))))))
       (setq tbl (nreverse tbl))
       (list file org-clock-file-total-minutes tbl))))
@@ -2536,6 +2752,48 @@ This function is made for clock tables."
 (defvar org-clock-loaded nil
   "Was the clock file loaded?")
 
+(defun org-clock-update-time-maybe ()
+  "If this is a CLOCK line, update it and return t.
+Otherwise, return nil."
+  (interactive)
+  (save-excursion
+    (beginning-of-line 1)
+    (skip-chars-forward " \t")
+    (when (looking-at org-clock-string)
+      (let ((re (concat "[ \t]*" org-clock-string
+                       " *[[<]\\([^]>]+\\)[]>]\\(-+[[<]\\([^]>]+\\)[]>]"
+                       "\\([ \t]*=>.*\\)?\\)?"))
+           ts te h m s neg)
+       (cond
+        ((not (looking-at re))
+         nil)
+        ((not (match-end 2))
+         (when (and (equal (marker-buffer org-clock-marker) (current-buffer))
+                    (> org-clock-marker (point))
+                    (<= org-clock-marker (point-at-eol)))
+           ;; The clock is running here
+           (setq org-clock-start-time
+                 (apply 'encode-time
+                        (org-parse-time-string (match-string 1))))
+           (org-clock-update-mode-line)))
+        (t
+         (and (match-end 4) (delete-region (match-beginning 4) (match-end 4)))
+         (end-of-line 1)
+         (setq ts (match-string 1)
+               te (match-string 3))
+         (setq s (- (org-float-time
+                     (apply 'encode-time (org-parse-time-string te)))
+                    (org-float-time
+                     (apply 'encode-time (org-parse-time-string ts))))
+               neg (< s 0)
+               s (abs s)
+               h (floor (/ s 3600))
+               s (- s (* 3600 h))
+               m (floor (/ s 60))
+               s (- s (* 60 s)))
+         (insert " => " (format (if neg "-%d:%02d" "%2d:%02d") h m))
+         t))))))
+
 (defun org-clock-save ()
   "Persist various clock-related data to disk.
 The details of what will be saved are regulated by the variable
@@ -2559,14 +2817,12 @@ The details of what will be saved are regulated by the variable
                   (buffer-file-name b)
                   (or (not org-clock-persist-query-save)
                       (y-or-n-p (concat "Save current clock ("
-                                        (substring-no-properties
-                                         org-clock-heading)
-                                        ") "))))
+                                        org-clock-heading ") "))))
              (insert "(setq resume-clock '(\""
                      (buffer-file-name (org-clocking-buffer))
                      "\" . " (int-to-string (marker-position org-clock-marker))
                      "))\n"))
-         ;; Store clocked task history. Tasks are stored reversed to make
+         ;; Store clocked task history.  Tasks are stored reversed to make
          ;; reading simpler
          (when (and (memq org-clock-persist '(t history))
                     org-clock-history)
@@ -2627,18 +2883,13 @@ The details of what will be saved are regulated by the variable
                (if (outline-invisible-p)
                    (org-show-context))))))))))
 
-;;;###autoload
-(defun org-clock-persistence-insinuate ()
-  "Set up hooks for clock persistence."
-  (add-hook 'org-mode-hook 'org-clock-load)
-  (add-hook 'kill-emacs-hook 'org-clock-save))
-
 ;; Suggested bindings
 (org-defkey org-mode-map "\C-c\C-x\C-e" 'org-clock-modify-effort-estimate)
 
 (provide 'org-clock)
 
-
+;; Local variables:
+;; generated-autoload-file: "org-loaddefs.el"
+;; End:
 
 ;;; org-clock.el ends here
-