Merge Org 7.9.3 (commit 31c1aea)
[bpt/emacs.git] / lisp / org / org-clock.el
index 4e30dd9..32cfa9a 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.4
 ;;
 ;; This file is part of GNU Emacs.
 ;;
@@ -27,7 +26,7 @@
 
 ;; This file contains the time clocking code for Org-mode
 
-(require 'org)
+(require 'org-exp)
 ;;; Code:
 
 (eval-when-compile
 
 (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."
@@ -62,6 +65,22 @@ which see."
          (const :tag "Into LOGBOOK drawer" "LOGBOOK")
          (string :tag "Into Drawer named...")))
 
+(defun org-clock-into-drawer ()
+  "Return the value of `org-clock-into-drawer', but let properties overrule.
+If the current entry has or inherits a CLOCK_INTO_DRAWER
+property, it will be used instead of the default value; otherwise
+if the current entry has or inherits a LOG_INTO_DRAWER property,
+it will be used instead of the default value.
+The default is the value of the customizable variable `org-clock-into-drawer',
+which see."
+  (let ((p (org-entry-get nil "CLOCK_INTO_DRAWER" 'inherit))
+       (q (org-entry-get nil "LOG_INTO_DRAWER" 'inherit)))
+    (cond
+     ((or (not (or p q)) (equal p "nil") (equal q "nil")) org-clock-into-drawer)
+     ((or (equal p "t") (equal q "t")) "LOGBOOK")
+     ((not p) q)
+     (t p))))
+
 (defcustom org-clock-out-when-done t
   "When non-nil, clock will be stopped when the clocked entry is marked DONE.
 DONE here means any DONE-like state.
@@ -125,7 +144,7 @@ The function is called with point at the beginning of the headline."
   :type '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)
 
@@ -141,12 +160,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.
 
-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"
+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)
@@ -183,8 +205,11 @@ file name  play this sound file.  If not possible, fall back to beep"
          (const :tag "Standard beep" t)
          (file :tag "Play sound file")))
 
-(defcustom org-clock-modeline-total 'auto
-  "Default setting for the time included for the modeline clock.
+(org-define-obsolete-variable-alias 'org-clock-modeline-total
+  'org-clock-mode-line-total "24.3")
+
+(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:
 
@@ -201,13 +226,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.
+(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")))
@@ -229,6 +256,7 @@ string as argument."
 (defcustom org-clocktable-defaults
   (list
    :maxlevel 2
+   :lang org-export-default-language
    :scope 'file
    :block nil
    :tstart nil
@@ -248,14 +276,27 @@ string as argument."
    :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"
+(defcustom org-clock-clocktable-language-setup
+  '(("en" "File"     "L"  "Timestamp"  "Headline" "Time"  "ALL"   "Total time"   "File time" "Clock summary at")
+    ("es" "Archivo"  "N"  "Fecha y hora" "Tarea" "Tiempo" "TODO" "Tiempo total" "Tiempo archivo" "Clock summary at")
+    ("fr" "Fichier"  "N"  "Horodatage" "En-tête"  "Durée" "TOUT"  "Durée totale" "Durée fichier" "Horodatage sommaire à")
+    ("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)
   "Default properties for new clocktables.
 These will be inserted into the BEGIN line, to make it easy for users to
@@ -281,13 +322,62 @@ 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 'boolean)
 
+(defcustom org-clock-file-time-cell-format "*%s*"
+  "Format string for the file time cells."
+  :group 'org-clock
+  :version "24.1"
+  :type 'boolean)
+
+(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)
+
 (defvar org-clock-in-prepare-hook nil
   "Hook run when preparing the clock.
 This hook is run before anything happens to the task that
@@ -387,6 +477,9 @@ of a different task.")
   "Return t when clocking a task."
   (not (equal (org-clocking-buffer) nil)))
 
+(defvar org-clock-before-select-task-hook nil
+  "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."
   (interactive)
@@ -419,6 +512,7 @@ of a different task.")
           (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))
@@ -441,13 +535,11 @@ pointing to it."
            (ignore-errors
              (goto-char marker)
              (setq file (buffer-file-name (marker-buffer marker))
-                   cat (or (org-get-category)
-                           (progn (org-refresh-category-properties)
-                                  (org-get-category)))
+                   cat (org-get-category)
                    heading (org-get-heading 'notags)
                    prefix (save-excursion
                             (org-back-to-heading t)
-                            (looking-at "\\*+ ")
+                            (looking-at org-outline-regexp)
                             (match-string 0))
                    task (substring
                          (org-fontify-like-in-org-mode
@@ -458,7 +550,7 @@ pointing to it."
        (insert (format "[%c] %-15s %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.")
@@ -473,17 +565,17 @@ If not, show simply the clocked time like 01:50."
         (m (- clocked-time (* 60 h))))
     (if org-clock-effort
        (let* ((effort-in-minutes
-               (org-hh:mm-string-to-minutes org-clock-effort))
+               (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))
+                '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))
               (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))
@@ -495,7 +587,7 @@ If not, show simply the clocked time like 01:50."
 (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))
@@ -507,12 +599,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))
 
@@ -526,39 +617,40 @@ 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-hh:mm-string-to-minutes current)
-                value (substring value 1))
-        (setq current 0))
-       (setq value (org-hh:mm-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))))
+  (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-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))
+    (message "Clock is not currently active")))
 
 (defvar org-clock-notification-was-shown nil
   "Shows if we have shown notification already.")
@@ -567,9 +659,9 @@ the mode line."
   "Show notification if we spent more time than we estimated before.
 Notification is shown only once."
   (when (org-clocking-p)
-    (let ((effort-in-minutes (org-hh:mm-string-to-minutes org-clock-effort))
+    (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)))
@@ -594,15 +686,14 @@ 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
@@ -618,20 +709,15 @@ Use alsa's aplay tool if available."
    ((stringp org-clock-sound)
     (let ((file (expand-file-name org-clock-sound)))
       (if (file-exists-p file)
-         (if (org-program-exists "aplay")
+         (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)))))))))
 
-(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))))
-
 (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."
@@ -660,7 +746,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)
@@ -676,7 +762,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)
@@ -691,9 +777,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)
@@ -746,7 +832,8 @@ If necessary, clock-out of the currently active clock."
 
 (defun org-clock-jump-to-current-clock (&optional effective-clock)
   (interactive)
-  (let ((clock (or effective-clock (cons org-clock-marker
+  (let ((org-clock-into-drawer (org-clock-into-drawer))
+       (clock (or effective-clock (cons org-clock-marker
                                         org-clock-start-time))))
     (unless (marker-buffer (car clock))
       (error "No clock is currently running"))
@@ -882,6 +969,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
@@ -895,18 +983,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."
@@ -919,6 +1007,13 @@ 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" "x11idle") 0)
+       ;; Check that x11idle can retrieve the idle time
+       (eq (call-process-shell-command "x11idle" 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))
@@ -929,7 +1024,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))))
@@ -961,23 +1056,40 @@ 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-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)
                     (eq t org-clock-auto-clock-resolution))
@@ -986,11 +1098,22 @@ the clocking selection, associated with the letter `d'."
        (setq org-clock-leftover-time nil)
        (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
            (setq selected-task (copy-marker selected-task))
          (error "Abort")))
+
+      (when (equal select '(16))
+       ;; Mark as default clocking task
+       (org-clock-mark-default-task))
+
       (when interrupting
        ;; We are interrupting the clocking of a different task.
        ;; Save a marker to this task, so that we can go back.
@@ -1005,25 +1128,21 @@ the clocking selection, associated with the letter `d'."
                     (= (marker-position org-clock-hd-marker)
                        (if selected-task
                            (marker-position selected-task)
-                         (point)))))
+                         (point)))
+                    (equal org-clock-current-task (nth 4 (org-heading-components)))))
          (message "Clock continues in \"%s\"" org-clock-heading)
          (throw 'abort nil))
        (move-marker org-clock-interrupted-task
                     (marker-position org-clock-marker)
                     (marker-buffer org-clock-marker))
        (let ((org-clock-clocking-in t))
-         (org-clock-out t)))
-
-      (when (equal select '(16))
-       ;; Mark as default clocking task
-       (org-clock-mark-default-task))
+         (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
@@ -1037,7 +1156,13 @@ 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))
-           (org-clock-history-push)
+           (save-excursion
+             (forward-char) ;; make sure the marker is not at the
+             ;; beginning of the heading, since the
+             ;; user is liking to insert stuff here
+             ;; manually
+             (run-hooks 'org-clock-in-prepare-hook)
+             (org-clock-history-push))
            (org-clock-set-current)
            (cond ((functionp org-clock-in-switch-to-state)
                   (looking-at org-complex-heading-regexp)
@@ -1045,7 +1170,7 @@ the clocking selection, associated with the letter `d'."
                                            (match-string 2))))
                     (if newstate (org-todo newstate))))
                  ((and org-clock-in-switch-to-state
-                       (not (looking-at (concat outline-regexp "[ \t]*"
+                       (not (looking-at (concat org-outline-regexp "[ \t]*"
                                                 org-clock-in-switch-to-state
                                                 "\\>"))))
                   (org-todo org-clock-in-switch-to-state)))
@@ -1058,7 +1183,8 @@ the clocking selection, associated with the letter `d'."
                  (cond ((and org-clock-heading-function
                              (functionp org-clock-heading-function))
                         (funcall org-clock-heading-function))
-                       ((looking-at org-complex-heading-regexp)
+                       ((and (looking-at org-complex-heading-regexp)
+                             (match-string 4))
                         (replace-regexp-in-string
                          "\\[\\[.*?\\]\\[\\(.*?\\)\\]\\]" "\\1"
                          (match-string 4)))
@@ -1069,16 +1195,16 @@ the clocking selection, associated with the letter `d'."
            (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 (get-text-property (point) 'org-effort))
              (setq org-clock-total-time (org-clock-sum-current-item
                                          (org-clock-get-sum-start))))
             ((eq org-clock-in-resume 'auto-restart)
@@ -1091,18 +1217,19 @@ 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 (get-text-property (point) 'org-effort))
              (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? "
@@ -1118,18 +1245,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))
@@ -1138,15 +1273,40 @@ the clocking selection, associated with the letter `d'."
            (message "Clock starts at %s - %s" ts msg-extra)
            (run-hooks 'org-clock-in-hook)))))))
 
-(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))
+;;;###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 (current-time))
+                       (current-time))))
+      (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."
@@ -1161,10 +1321,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")
@@ -1197,22 +1357,23 @@ When FIND-UNCLOSED is non-nil, first check if there is an unclosed clock
 line and position cursor in that line."
   (org-back-to-heading t)
   (catch 'exit
-    (let ((beg (save-excursion
-                (beginning-of-line 2)
-                (or (bolp) (newline))
-                (point)))
-         (end (progn (outline-next-heading) (point)))
-         (re (concat "^[ \t]*" org-clock-string))
-         (cnt 0)
-         (drawer (if (stringp org-clock-into-drawer)
-                     org-clock-into-drawer "LOGBOOK"))
-         first last ind-last)
+    (let* ((org-clock-into-drawer (org-clock-into-drawer))
+          (beg (save-excursion
+                 (beginning-of-line 2)
+                 (or (bolp) (newline))
+                 (point)))
+          (end (progn (outline-next-heading) (point)))
+          (re (concat "^[ \t]*" org-clock-string))
+          (cnt 0)
+          (drawer (if (stringp org-clock-into-drawer)
+                      org-clock-into-drawer "LOGBOOK"))
+          first last ind-last)
       (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))
@@ -1239,14 +1400,17 @@ line and position cursor in that line."
        (beginning-of-line 2)
        (if (and (>= (org-get-indentation) ind-last)
                 (org-at-item-p))
-           (org-end-of-item))
+           (when (and (>= (org-get-indentation) ind-last)
+                      (org-at-item-p))
+             (let ((struct (org-list-struct)))
+               (goto-char (org-list-get-bottom-point struct)))))
        (insert ":END:\n")
        (beginning-of-line 0)
        (org-indent-line-to ind-last)
        (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
@@ -1266,28 +1430,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 (current-time))
+         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)
@@ -1299,8 +1477,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))
@@ -1327,6 +1504,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)
@@ -1339,7 +1517,7 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
                                           (match-string 2))))
                    (if newstate (org-todo newstate))))
                 ((and org-clock-out-switch-to-state
-                      (not (looking-at (concat outline-regexp "[ \t]*"
+                      (not (looking-at (concat org-outline-regexp "[ \t]*"
                                                org-clock-out-switch-to-state
                                                "\\>"))))
                  (org-todo org-clock-out-switch-to-state))))))
@@ -1347,30 +1525,108 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
          (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))))))
+         (unless (org-clocking-p)
+           (org-clock-delete-current)))))))
+
+(add-hook 'org-clock-out-hook 'org-clock-remove-empty-clock-drawer)
+
+(defun org-clock-remove-empty-clock-drawer nil
+  "Remove empty clock drawer in the current subtree."
+  (let* ((olid (or (org-entry-get (point) "LOG_INTO_DRAWER")
+                  org-log-into-drawer))
+        (clock-drawer (if (eq t olid) "LOGBOOK" olid))
+        (end (save-excursion (org-end-of-subtree t t))))
+    (when clock-drawer
+      (save-excursion
+       (org-back-to-heading 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-down nil
+  "Increase CLOCK timestamps at cursor."
+  (interactive)
+  (org-clock-timestamps-change 'down))
+
+(defun org-clock-timestamps-change (updown)
+  "Change CLOCK timestamps synchronously at cursor.
+UPDOWN tells whether to change 'up or 'down."
+  (setq org-ts-what nil)
+  (when (org-at-timestamp-p t)
+    (let ((tschange (if (eq updown 'up) 'org-timestamp-up
+                     'org-timestamp-down))
+         ts1 begts1 ts2 begts2 updatets1 tdiff)
+      (save-excursion
+       (move-beginning-of-line 1)
+       (re-search-forward org-ts-regexp3 nil t)
+       (setq ts1 (match-string 0) begts1 (match-beginning 0))
+       (when (re-search-forward org-ts-regexp3 nil t)
+         (setq ts2 (match-string 0) begts2 (match-beginning 0))))
+      ;; Are we on the second timestamp?
+      (if (<= begts2 (point)) (setq updatets1 t))
+      (if (not ts2)
+         ;; fall back on org-timestamp-up if there is only one
+         (funcall tschange)
+       ;; setq this so that (boundp 'org-ts-what is non-nil)
+       (funcall tschange)
+       (let ((ts (if updatets1 ts2 ts1))
+             (begts (if updatets1 begts1 begts2)))
+         (setq tdiff
+               (subtract-time
+                (org-time-string-to-time org-last-changed-timestamp)
+                (org-time-string-to-time ts)))
+         (save-excursion
+           (goto-char begts)
+           (org-timestamp-change
+            (round (/ (org-float-time tdiff)
+                      (cond ((eq org-ts-what 'minute) 60)
+                            ((eq org-ts-what 'hour) 3600)
+                            ((eq org-ts-what 'day) (* 24 3600))
+                            ((eq org-ts-what 'month) (* 24 3600 31))
+                            ((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))
 
+;;;###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."
@@ -1387,7 +1643,7 @@ 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)
@@ -1403,13 +1659,21 @@ 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]*"
@@ -1426,7 +1690,7 @@ nil are excluded from the clock summation."
     (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
+                            `(,(or propname :org-clock-minutes) t
                               :org-clock-force-headline-inclusion t))
     (save-excursion
       (goto-char (point-max))
@@ -1475,7 +1739,8 @@ nil are excluded from the clock summation."
                           (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)
+               (put-text-property (point) (point-at-eol)
+                                  (or propname :org-clock-minutes) time)
                 (if headline-filter
                     (save-excursion
                       (save-match-data
@@ -1499,10 +1764,13 @@ 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
-in the echo area."
+in the echo area.
+
+Use \\[org-clock-remove-overlays] to remove the subtree times."
   (interactive)
   (org-clock-remove-overlays)
   (let (time h m p)
@@ -1548,8 +1816,8 @@ will be easy to remove."
     (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
@@ -1579,16 +1847,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))
@@ -1605,7 +1875,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."
@@ -1625,10 +1895,14 @@ 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
-will be updated.  If not, a new clocktable will be inserted.
+will be updated.  If not, a new clocktable will be inserted.  The scope
+of the new clock will be subtree when called from within a subtree, and
+file elsewhere.
+
 When called with a prefix argument, move to the first clock table in the
 buffer and update it."
   (interactive "P")
@@ -1638,21 +1912,14 @@ buffer and update it."
     (org-show-entry))
   (if (org-in-clocktable-p)
       (goto-char (org-in-clocktable-p))
-    (org-create-dblock (append (list :name "clocktable")
-                              org-clock-clocktable-default-properties)))
+    (let ((props (if (ignore-errors
+                      (save-excursion (org-back-to-heading)))
+                    (list :name "clocktable" :scope 'subtree)
+                  (list :name "clocktable"))))
+      (org-create-dblock
+       (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
@@ -1747,13 +2014,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)
@@ -1764,12 +2031,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))
@@ -1783,27 +2049,27 @@ the returned times will be formatted strings."
      ((memq key '(month thismonth))
       (setq d 1 h 0 m 0 d1 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)))
@@ -1821,7 +2087,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)
@@ -1859,61 +2125,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))
@@ -1931,7 +2200,6 @@ 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
@@ -1964,7 +2232,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
@@ -1973,7 +2241,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))
@@ -1986,7 +2254,7 @@ the currently selected interval size."
            (setq level (string-to-number (match-string 1 (symbol-name scope))))
            (catch 'exit
              (while (org-up-heading-safe)
-               (looking-at outline-regexp)
+               (looking-at org-outline-regexp)
                (if (<= (org-reduced-level (funcall outline-level)) level)
                    (throw 'exit nil))))
            (org-narrow-to-subtree)))
@@ -2006,13 +2274,17 @@ 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."
-  ;; This function looks quite complicated, mainly because there are a lot
-  ;; of options which can add or remove columns.  I have massively commented
-  ;; function, to I hope it is understandable.  If someone want to write
-  ;; there own special formatter, this maybe much easier because there can
-  ;; be a fixed format with a well-defined number of columns...
+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
+  ;; someone wants to write their own special formatter, this maybe
+  ;; much easier because there can be a fixed format with a
+  ;; well-defined number of columns...
   (let* ((hlchars '((1 . "*") (2 . "/")))
+        (lwords (assoc (or (plist-get params :lang)
+                           org-export-default-language)
+                       org-clock-clocktable-language-setup))
         (multifile (plist-get params :multifile))
         (block (plist-get params :block))
         (ts (plist-get params :tstart))
@@ -2024,9 +2296,11 @@ from the dynamic block defintion."
         (emph (plist-get params :emphasize))
         (level-p (plist-get params :level))
         (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)
@@ -2036,181 +2310,196 @@ 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))))
-
-      (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))))
+    (unless (integerp ntcol)
+      (setq params (plist-put params :tcolumns (setq ntcol 100))))
 
-      ;; Compute the total time
-      (setq total-time (apply '+ (mapcar 'cadr tables)))
+    (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))))
 
-      ;; 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
-           "Clock summary at ["
-           (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
-        (format "<%d>| |\n" narrow)))  ; headline and time columns
-
-      ;; Insert the table header line
-      (insert-before-markers
-       "|"                              ; table line starter
-       (if multifile "File|"      "")   ; file column, maybe
-       (if level-p   "L|"         "")   ; level column, maybe
-       (if timestamp "Timestamp|" "")   ; timestamp column, maybe
-       "Headline|Time|\n")              ; headline and time columns
+    (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 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))))
+
+    ;; 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
+         (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
-       "|-\n"                           ; a hline
-       "|"                              ; table line starter
-       (if multifile "| ALL " "")       ; file column, maybe
-       (if level-p   "|"      "")       ; level column, maybe
-       (if timestamp "|"      "")       ; timestamp column, maybe
-       "*Total time*| "                 ; 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 colleted from this file
-             (insert-before-markers
-              (format "| %s %s | %s*File time* | *%s*|\n"
-                      (file-name-nondirectory (car tbl))
-                      (if level-p   "| " "") ; level column, maybe
-                      (if timestamp "| " "") ; timestamp column, 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 indent (org-clocktable-indent-string level) "") ; indentation
-              hlc headline hlc "|"                                ; headline
-              (make-string (min (1- ntcol) (or (- level 1))) ?|)
+       "|"                            ; 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
+    (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-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"
+                            (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-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))) ?|)
                                        ; 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-hh:mm-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)
@@ -2305,6 +2594,9 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
         (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)
 
@@ -2327,7 +2619,9 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
       (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)
@@ -2358,8 +2652,15 @@ TIME:      The sum of all time spend in this tree, in minutes.  This time
                          (or (cdr (assoc "SCHEDULED" props))
                              (cdr (assoc "DEADLINE" props))
                              (cdr (assoc "TIMESTAMP" props))
-                             (cdr (assoc "TIMESTAMP_IA" props)))))
-             (when (> time 0) (push (list level hdl tsp time) tbl))))))
+                             (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))))
+             (when (> time 0) (push (list level hdl tsp time props) tbl))))))
       (setq tbl (nreverse tbl))
       (list file org-clock-file-total-minutes tbl))))
 
@@ -2387,9 +2688,53 @@ This function is made for clock tables."
                        tot))))
        0))))
 
+;; Saving and loading the clock
+
 (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
@@ -2420,7 +2765,7 @@ The details of what will be saved are regulated by the variable
                      (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)
@@ -2478,20 +2823,16 @@ The details of what will be saved are regulated by the variable
              (goto-char (cdr resume-clock))
              (let ((org-clock-auto-clock-resolution nil))
                (org-clock-in)
-               (if (org-invisible-p)
+               (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
-