Browse Source

Merge branch 'MobileOrg'

Carsten Dominik 16 years ago
parent
commit
8c2a918fd9
8 changed files with 880 additions and 139 deletions
  1. 2 0
      Makefile
  2. 6 0
      doc/ChangeLog
  3. 146 30
      doc/org.texi
  4. 24 0
      lisp/ChangeLog
  5. 254 82
      lisp/org-agenda.el
  6. 11 10
      lisp/org-id.el
  7. 406 0
      lisp/org-mobile.el
  8. 31 17
      lisp/org.el

+ 2 - 0
Makefile

@@ -91,6 +91,7 @@ LISPF      = 	org.el			\
 	     	org-macs.el		\
 	     	org-macs.el		\
 		org-mew.el              \
 		org-mew.el              \
 		org-mhe.el		\
 		org-mhe.el		\
+		org-mobile.el		\
 		org-mouse.el		\
 		org-mouse.el		\
 		org-publish.el		\
 		org-publish.el		\
 		org-plot.el		\
 		org-plot.el		\
@@ -362,6 +363,7 @@ lisp/org-mac-message.elc:	lisp/org.el
 lisp/org-macs.elc:
 lisp/org-macs.elc:
 lisp/org-mew.elc:	lisp/org.el
 lisp/org-mew.elc:	lisp/org.el
 lisp/org-mhe.elc:	lisp/org.el
 lisp/org-mhe.elc:	lisp/org.el
+lisp/org-mobile.elc:	lisp/org.el
 lisp/org-mouse.elc:	lisp/org.el
 lisp/org-mouse.elc:	lisp/org.el
 lisp/org-plot.elc:	lisp/org.el lisp/org-exp.el lisp/org-table.el
 lisp/org-plot.elc:	lisp/org.el lisp/org-exp.el lisp/org-table.el
 lisp/org-publish.elc:
 lisp/org-publish.elc:

+ 6 - 0
doc/ChangeLog

@@ -1,3 +1,9 @@
+2009-09-15  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.texi (MobileOrg): New section.
+	(Agenda commands, Exporting Agenda Views): Document exporting the
+	agenda view to Org files.
+
 2009-08-29  Carsten Dominik  <carsten.dominik@gmail.com>
 2009-08-29  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
 	* orgcard.tex: Document new effort setting commands.
 	* orgcard.tex: Document new effort setting commands.

+ 146 - 30
doc/org.texi

@@ -109,6 +109,7 @@ license to the document, as described in section 6 of the license.
 * Publishing::                  Create a web site of linked Org files
 * Publishing::                  Create a web site of linked Org files
 * Miscellaneous::               All the rest which did not fit elsewhere
 * Miscellaneous::               All the rest which did not fit elsewhere
 * Hacking::                     How to hack your way around
 * Hacking::                     How to hack your way around
+* MobileOrg::                   Viewing and capture on a mobile device
 * History and Acknowledgments::  How Org came into being
 * History and Acknowledgments::  How Org came into being
 * Main Index::                  An index of Org's concepts and features
 * Main Index::                  An index of Org's concepts and features
 * Key Index::                   Key bindings and where they are described
 * Key Index::                   Key bindings and where they are described
@@ -258,7 +259,7 @@ Capture
 
 
 Remember
 Remember
 
 
-* Setting up Remember for Org:: Some code for .emacs to get things going
+* Setting up Remember for Org::  Some code for .emacs to get things going
 * Remember templates::          Define the outline of different note types
 * Remember templates::          Define the outline of different note types
 * Storing notes::               Directly get the note to where it belongs
 * Storing notes::               Directly get the note to where it belongs
 * Refiling notes::              Moving a note or task to a project
 * Refiling notes::              Moving a note or task to a project
@@ -271,7 +272,7 @@ Agenda Views
 * Presentation and sorting::    How agenda items are prepared for display
 * Presentation and sorting::    How agenda items are prepared for display
 * Agenda commands::             Remote editing of Org trees
 * Agenda commands::             Remote editing of Org trees
 * Custom agenda views::         Defining special searches and views
 * Custom agenda views::         Defining special searches and views
-* Exporting Agenda Views::
+* Exporting Agenda Views::      Writing a view to a file
 * Agenda column view::          Using column view for collected entries
 * Agenda column view::          Using column view for collected entries
 
 
 The built-in agenda views
 The built-in agenda views
@@ -420,6 +421,12 @@ Tables and lists in arbitrary syntax
 * Translator functions::        Copy and modify
 * Translator functions::        Copy and modify
 * Radio lists::                 Doing the same for lists
 * Radio lists::                 Doing the same for lists
 
 
+MobileOrg
+
+* Setting up the staging area::  Where to interact with the mobile device
+* Pushing to MobileOrg::        Uploading Org files and agendas
+* Pulling from MobileOrg::      Integrating captured and flagged items
+
 @end detailmenu
 @end detailmenu
 @end menu
 @end menu
 
 
@@ -5669,7 +5676,7 @@ with specific templates.  It also allows you to select the location where a
 note should be stored interactively, on the fly.
 note should be stored interactively, on the fly.
 
 
 @menu
 @menu
-* Setting up Remember for Org:: Some code for .emacs to get things going
+* Setting up Remember for Org::  Some code for .emacs to get things going
 * Remember templates::          Define the outline of different note types
 * Remember templates::          Define the outline of different note types
 * Storing notes::               Directly get the note to where it belongs
 * Storing notes::               Directly get the note to where it belongs
 * Refiling notes::              Moving a note or task to a project
 * Refiling notes::              Moving a note or task to a project
@@ -6160,7 +6167,7 @@ window configuration is restored when the agenda exits:
 * Presentation and sorting::    How agenda items are prepared for display
 * Presentation and sorting::    How agenda items are prepared for display
 * Agenda commands::             Remote editing of Org trees
 * Agenda commands::             Remote editing of Org trees
 * Custom agenda views::         Defining special searches and views
 * Custom agenda views::         Defining special searches and views
-* Exporting Agenda Views::
+* Exporting Agenda Views::      Writing a view to a file
 * Agenda column view::          Using column view for collected entries
 * Agenda column view::          Using column view for collected entries
 @end menu
 @end menu
 
 
@@ -7407,10 +7414,10 @@ This is a globally available command, and also available in the agenda menu.
 Write the agenda view to a file.  Depending on the extension of the selected
 Write the agenda view to a file.  Depending on the extension of the selected
 file name, the view will be exported as HTML (extension @file{.html} or
 file name, the view will be exported as HTML (extension @file{.html} or
 @file{.htm}), Postscript (extension @file{.ps}), PDF (extension @file{.pdf}),
 @file{.htm}), Postscript (extension @file{.ps}), PDF (extension @file{.pdf}),
-or plain text (any other extension).  When called with a @kbd{C-u} prefix
-argument, immediately open the newly created file.  Use the variable
-@code{org-agenda-exporter-settings} to set options for @file{ps-print} and
-for @file{htmlize} to be used during export.
+Org-mode (extension @file{.org}), and plain text (any other extension).  When
+called with a @kbd{C-u} prefix argument, immediately open the newly created
+file.  Use the variable @code{org-agenda-exporter-settings} to set options
+for @file{ps-print} and for @file{htmlize} to be used during export.
 
 
 @tsubheading{Quit and Exit}
 @tsubheading{Quit and Exit}
 @kindex q
 @kindex q
@@ -7634,13 +7641,13 @@ you want to do this only occasionally, use the command
 @cindex exporting agenda views
 @cindex exporting agenda views
 @cindex agenda views, exporting
 @cindex agenda views, exporting
 @vindex org-agenda-exporter-settings
 @vindex org-agenda-exporter-settings
-Write the agenda view to a file.  Depending on the extension of the
-selected file name, the view will be exported as HTML (extension
-@file{.html} or @file{.htm}), Postscript (extension @file{.ps}),
-iCalendar (extension @file{.ics}), or plain text (any other extension).
-Use the variable @code{org-agenda-exporter-settings} to
-set options for @file{ps-print} and for @file{htmlize} to be used during
-export, for example
+Write the agenda view to a file.  Depending on the extension of the selected
+file name, the view will be exported as HTML (extension @file{.html} or
+@file{.htm}), Postscript (extension @file{.ps}), iCalendar (extension
+@file{.ics}), Org-mode (extension @file{.org}), or plain text (any other
+extension).  Use the variable @code{org-agenda-exporter-settings} to set
+options for @file{ps-print} and for @file{htmlize} to be used during export,
+for example
 
 
 @vindex org-agenda-add-entry-text-maxlines
 @vindex org-agenda-add-entry-text-maxlines
 @vindex htmlize-output-type
 @vindex htmlize-output-type
@@ -10690,7 +10697,8 @@ in the paragraph above about CUA mode also applies here.
 
 
 @end table
 @end table
 
 
-@node Hacking, History and Acknowledgments, Miscellaneous, Top
+
+@node Hacking, MobileOrg, Miscellaneous, Top
 @appendix Hacking
 @appendix Hacking
 @cindex hacking
 @cindex hacking
 
 
@@ -11456,19 +11464,6 @@ foreach $line (split(/\n/,$agenda)) @{
 @}
 @}
 @end example
 @end example
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
 @node Using the property API, Using the mapping API, Extracting agenda information, Hacking
 @node Using the property API, Using the mapping API, Extracting agenda information, Hacking
 @section Using the property API
 @section Using the property API
 @cindex API, for properties
 @cindex API, for properties
@@ -11648,7 +11643,124 @@ The following example counts the number of entries with TODO keyword
 (length (org-map-entries t "/+WAITING" 'agenda))
 (length (org-map-entries t "/+WAITING" 'agenda))
 @end lisp
 @end lisp
 
 
-@node History and Acknowledgments, Main Index, Hacking, Top
+@node MobileOrg, History and Acknowledgments, Hacking, Top
+@appendix MobileOrg
+@cindex iPhone
+@cindex MobileOrg
+
+@i{MobileOrg} is an application for the @i{iPhone/iPod Touch} series of
+devices, developed by Richard Moreland.  Instead of trying to implement the
+full feature set of Org and fighting with synchronization issues, this
+application chooses a different path.  @i{MobileOrg} provides offline viewing
+and capture support for an Org-mode system rooted on a ``real'' computer.
+Synchronization issues are avoided by making @i{MobileOrg} only @i{write} to
+a special capture file, that is only @i{read} by the computer-based system.
+
+This appendix describes the support Org has for creating agenda views in a
+format that can be displayed by @i{MobileOrg}, and for integrating notes
+captured by @i{MobileOrg} into the main system.  It does not cover the
+operation of @i{MobileOrg} itself (see @uref{http://ncogni.to/mobileorg/}).
+
+@menu
+* Setting up the staging area::  Where to interact with the mobile device
+* Pushing to MobileOrg::        Uploading Org files and agendas
+* Pulling from MobileOrg::      Integrating captured and flagged items
+@end menu
+
+@node Setting up the staging area, Pushing to MobileOrg, MobileOrg, MobileOrg
+@section Setting up the staging area
+
+Org-mode has commands to prepare a directory with files for @i{MobileOrg}, and to
+read captured notes from there.  If Emacs can directly write to the WebDAV
+directory accessed by @i{MobileOrg}, all you need to do is to point to this
+directory using the variable @code{org-mobile-directory}.
+
+If Emacs cannot access the WebDAV directory directly, you can use a local
+directory for staging.  Other means must then be used to keep this directory
+in sync with the WebDAV directory.  In the following example, files are
+staged in @file{~/stage}, and Org-mode hooks take care of moving files to and
+from the WebDAV directory using @file{scp}.
+
+@example
+(setq org-mobile-directory "~/MobileOrg/stage/")
+(add-hook 'org-mobile-post-push-hook
+  (lambda ()
+   (shell-command "scp ~/stage/* user@@webdavhost:mobile/")))
+(add-hook 'org-mobile-pre-pull-hook
+  (lambda ()
+   (shell-command "scp user@@webdavhost:mobile/mobile-capture.org ~/stage/ ")))
+(add-hook 'org-mobile-post-pull-hook
+  (lambda ()
+   (shell-command "scp ~/stage/mobile-capture.org user@@webdavhost:mobile/")))
+@end example
+
+@node Pushing to MobileOrg, Pulling from MobileOrg, Setting up the staging area, MobileOrg
+@section Pushing to MobileOrg
+
+
+This operation copies all files currently listed in @code{org-agenda-files}
+to the directory @code{org-mobile-directory}.  It also creates (in the same
+directory) a special Org file @file{agendas.org}.  This file is an Org-mode
+style outline, containing every custom agenda view defined by the user.
+While creating the agendas, Org-mode will force@footnote{See the variable
+@code{org-mobile-force-id-on-agenda-items}.} an ID property on all entries
+referenced by the agendas, so that these entries can be uniquely identified
+if @i{MobileOrg} flags them for further action.  Finally, Org writes the file
+@file{index.org}, containing links to all other files.  If @i{MobileOrg} is
+configured to request this file from the WebDAV server, all agendas and Org
+files will be downloaded to the iPhone.
+
+@node Pulling from MobileOrg,  , Pushing to MobileOrg, MobileOrg
+@section Pulling from MobileOrg
+
+When @i{MobileOrg} synchronizes with the WebDAV server, it not only pulls the
+Org files for viewing.  It also appends captured entries and pointers to
+flagged entries to the file @file{mobile-capture.org} on the server.  Org has
+a @emph{pull} operation that integrates this information into an inbox file
+and operates on the pointers to flagged entries.  Here is how it works:
+
+@enumerate
+@item
+Org moves all entries found in @file{mobile-capture.org} and appends them to
+the file pointed to by the variable @code{org-mobile-inbox-for-pull}.  Each
+captured entry will be a top-level entry in the inbox file.
+@item
+After moving the entries, Org will attempt to act on the flags.  Some flags
+specify simple operations that will be executed directly and without user
+interaction.  Examples are marking an entry as DONE and/or archiving
+it@footnote{as specified by the variable @code{org-archive-default-action}}.
+All other flagged entries will receive a tag @code{:FLAGGED:}, so that they
+can be easily found again.  When there is a problem finding the entry that
+should be flagged, the pointer entry will remain in the inbox and will be
+marked with an error message.
+@item
+Org will then generate an agenda view with all flagged entries.  The user
+should then go through these entries and do whatever actions are necessary.
+If a note has been stored while flagging an entry in @i{MobileOrg}, that note
+will be displayed in the echo area when the cursor is on the corresponding
+agenda line.
+@table @kbd
+@kindex ?
+@item ?
+Pressing @kbd{?} in that special agenda will display the full flagging note in
+another window and also push it onto the kill ring.  So you could use @kbd{?
+z C-y C-c C-c} to store that flagging note as a normal note in the entry.
+Pressing @kbd{?} twice in succession will offer to remove the
+@code{:FLAGGED:} tag along with the recorded flagging note (which is stored
+in a property).
+@end table
+@end enumerate
+
+@kindex C-c a ?
+If you are not able to process all flagged entries directly, you can always
+return to this agenda view using @kbd{C-c a ?}.  Note, however, that there is
+a subtle difference.  The view created automatically by @kbd{M-x
+org-mobile-pull RET} is guaranteed to search all files that have been
+addressed by the last pull.  This might include a file that is not currently
+in your list of agenda files.  If you later use @kbd{C-c a ?} to regenerate
+the view, only the current agenda files will be searched.
+
+@node History and Acknowledgments, Main Index, MobileOrg, Top
 @appendix History and Acknowledgments
 @appendix History and Acknowledgments
 @cindex acknowledgments
 @cindex acknowledgments
 @cindex history
 @cindex history
@@ -11775,6 +11887,8 @@ basis.
 @i{Stefan Monnier} provided a patch to keep the Emacs-Lisp compiler
 @i{Stefan Monnier} provided a patch to keep the Emacs-Lisp compiler
 happy.
 happy.
 @item
 @item
+@i{Richard Moreland} wrote @i{MobileOrg} for the iPhone.
+@item
 @i{Rick Moynihan} proposed allowing multiple TODO sequences in a file
 @i{Rick Moynihan} proposed allowing multiple TODO sequences in a file
 and being able to quickly restrict the agenda to a subtree.
 and being able to quickly restrict the agenda to a subtree.
 @item
 @item
@@ -11913,3 +12027,5 @@ org-customize @key{RET}} and then klick yourself through the tree.
 @c fill-column: 77
 @c fill-column: 77
 @c End:
 @c End:
 
 
+
+@c  LocalWords:  webdavhost pre

+ 24 - 0
lisp/ChangeLog

@@ -13,6 +13,30 @@
 
 
 	* org.el: Add an entry for org-crypt.
 	* org.el: Add an entry for org-crypt.
 
 
+2009-09-15  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-agenda.el (org-agenda-menu): Reorganize the menu for more
+	consistency.
+	(org-batch-store-agenda-views): New function.
+	(org-mobile-force-id-on-agenda-items): Mention variable.
+	(org-agenda-title-append): Define variable.
+	(org-write-agenda): New export to Org files.
+	(org-agenda-get-some-entry-text): New arguments INDENT and KEEP.
+	(org-agenda): Allow to keep the restricted file list if a special
+	variable is bound to t.
+	(org-agenda): Define a special agenda view for working on flagged
+	entries.
+	(org-agenda-get-restriction-and-command): List the new agenda
+	view.
+	(org-agenda-show-the-flagging-note): New command.
+	(org-agenda-mode-map): New key `?' for looking at the flagging
+	note.
+
+	* org.el (org-autoload): Autoload org-mobile.el.
+	(org-org-menu): Add menu commands for MobileOrg in the Org menu.
+
+	* org-id.el (org-id-get): Fix bug with forcing ID on an item.
+
 2009-09-15  Carsten Dominik  <carsten.dominik@gmail.com>
 2009-09-15  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
 	* org-table.el (orgtbl-line-start-regexp): Match also TBLNAME
 	* org-table.el (orgtbl-line-start-regexp): Match also TBLNAME

+ 254 - 82
lisp/org-agenda.el

@@ -55,10 +55,12 @@
 (declare-function calendar-persian-date-string  "cal-persia" (&optional date))
 (declare-function calendar-persian-date-string  "cal-persia" (&optional date))
 (declare-function org-columns-quit              "org-colview" ())
 (declare-function org-columns-quit              "org-colview" ())
 (defvar calendar-mode-map)
 (defvar calendar-mode-map)
+(defvar org-mobile-force-id-on-agenda-items) ; defined in org-mobile.el
 
 
 ;; Defined somewhere in this file, but used before definition.
 ;; Defined somewhere in this file, but used before definition.
 (defvar org-agenda-buffer-name)
 (defvar org-agenda-buffer-name)
 (defvar org-agenda-overriding-header)
 (defvar org-agenda-overriding-header)
+(defvar org-agenda-title-append nil)
 (defvar entry)
 (defvar entry)
 (defvar date)
 (defvar date)
 (defvar org-agenda-undo-list)
 (defvar org-agenda-undo-list)
@@ -1449,6 +1451,7 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "/" 'org-agenda-filter-by-tag)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
 (org-defkey org-agenda-mode-map "\\" 'org-agenda-filter-by-tag-refine)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
 (org-defkey org-agenda-mode-map ";" 'org-timer-set-timer)
+(define-key org-agenda-mode-map "?" 'org-agenda-show-the-flagging-note)
 
 
 (defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
 (defvar org-agenda-keymap (copy-keymap org-agenda-mode-map)
   "Local keymap for agenda entries from Org-mode.")
   "Local keymap for agenda entries from Org-mode.")
@@ -1463,40 +1466,93 @@ The following commands are available:
   '("Agenda"
   '("Agenda"
     ("Agenda Files")
     ("Agenda Files")
     "--"
     "--"
-    ["Show" org-agenda-show t]
+    ("Agenda Dates"
+     ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
+     ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
+     ["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)]
+     ["Jump to date" org-agenda-goto-date (org-agenda-check-type nil 'agenda)])
+    "--"
+    ("View"
+     ["Day View" org-agenda-day-view
+      :active (org-agenda-check-type nil 'agenda)
+      :style radio :selected (equal org-agenda-ndays 1)
+      :keys "v d  (or just d)"]
+     ["Week View" org-agenda-week-view
+      :active (org-agenda-check-type nil 'agenda)
+      :style radio :selected (equal org-agenda-ndays 7)
+      :keys "v w  (or just w)"]
+     ["Month View" org-agenda-month-view
+      :active (org-agenda-check-type nil 'agenda)
+      :style radio :selected (member org-agenda-ndays '(28 29 30 31))
+      :keys "v m"]
+     ["Year View" org-agenda-year-view
+      :active (org-agenda-check-type nil 'agenda)
+      :style radio :selected (member org-agenda-ndays '(365 366))
+      :keys "v y"]
+     "--"
+     ["Include Diary" org-agenda-toggle-diary
+      :style toggle :selected org-agenda-include-diary
+      :active (org-agenda-check-type nil 'agenda)]
+     ["Use Time Grid" org-agenda-toggle-time-grid
+      :style toggle :selected org-agenda-use-time-grid
+      :active (org-agenda-check-type nil 'agenda)]
+     "--"
+     ["Show clock report" org-agenda-clockreport-mode
+      :style toggle :selected org-agenda-clockreport-mode
+      :active (org-agenda-check-type nil 'agenda)]
+     ["Show some entry text" org-agenda-entry-text-mode
+      :style toggle :selected org-agenda-entry-text-mode
+      :active t]
+    "--"
+     ["Show Logbook entries" org-agenda-log-mode
+      :style toggle :selected org-agenda-show-log
+      :active (org-agenda-check-type nil 'agenda 'timeline)
+      :keys "v l (or just l)"]
+     ["Include archived trees" org-agenda-archives-mode
+      :style toggle :selected org-agenda-archives-mode :active t
+      :keys "v a"]
+     ["Include archive files" (org-agenda-archives-mode t)
+      :style toggle :selected (eq org-agenda-archives-mode t) :active t
+      :keys "v A"]
+     "--"
+     ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
+    ["Write view to file" org-write-agenda t]
+    ["Rebuild buffer" org-agenda-redo t]
+    ["Save all Org-mode Buffers" org-save-all-org-buffers t]
+    "--"
+    ["Show original entry" org-agenda-show t]
     ["Go To (other window)" org-agenda-goto t]
     ["Go To (other window)" org-agenda-goto t]
     ["Go To (this window)" org-agenda-switch-to t]
     ["Go To (this window)" org-agenda-switch-to t]
     ["Follow Mode" org-agenda-follow-mode
     ["Follow Mode" org-agenda-follow-mode
      :style toggle :selected org-agenda-follow-mode :active t]
      :style toggle :selected org-agenda-follow-mode :active t]
-    ["Tree to indirect frame" org-agenda-tree-to-indirect-buffer t]
+;    ["Tree to indirect frame" org-agenda-tree-to-indirect-buffer t]
     "--"
     "--"
-    ["Cycle TODO" org-agenda-todo t]
-    ("Archive and Refile"
+    ("TODO"
+     ["Cycle TODO" org-agenda-todo t]
+     ["Next TODO set" org-agenda-todo-nextset t]
+     ["Previous TODO set" org-agenda-todo-previousset t]
+     ["Add note" org-agenda-add-note t])
+    ("Archive/Refile/Delete"
      ["Toggle ARCHIVE tag" org-agenda-toggle-archive-tag t]
      ["Toggle ARCHIVE tag" org-agenda-toggle-archive-tag t]
      ["Move to archive sibling" org-agenda-archive-to-archive-sibling t]
      ["Move to archive sibling" org-agenda-archive-to-archive-sibling t]
      ["Archive subtree" org-agenda-archive t]
      ["Archive subtree" org-agenda-archive t]
-     ["Refile" org-agenda-refile t])
-    ["Delete subtree" org-agenda-kill t]
+     "--"
+     ["Refile" org-agenda-refile t]
+     "--"
+     ["Delete subtree" org-agenda-kill t])
     ("Bulk action"
     ("Bulk action"
      ["Mark entry" org-agenda-bulk-mark t]
      ["Mark entry" org-agenda-bulk-mark t]
      ["Unmark entry" org-agenda-bulk-unmark t]
      ["Unmark entry" org-agenda-bulk-unmark t]
      ["Act on all marked" org-agenda-bulk-action t]
      ["Act on all marked" org-agenda-bulk-action t]
      ["Unmark all entries" org-agenda-bulk-remove-all-marks :active t :keys "C-u s"])
      ["Unmark all entries" org-agenda-bulk-remove-all-marks :active t :keys "C-u s"])
     "--"
     "--"
-    ["Add note" org-agenda-add-note t]
-    "--"
-    ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
-    ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
-    ["Previous Dates" org-agenda-earlier (org-agenda-check-type nil 'agenda)]
-    ["Jump to date" org-agenda-goto-date (org-agenda-check-type nil 'agenda)]
-    "--"
     ("Tags and Properties"
     ("Tags and Properties"
      ["Show all Tags" org-agenda-show-tags t]
      ["Show all Tags" org-agenda-show-tags t]
      ["Set Tags current line" org-agenda-set-tags (not (org-region-active-p))]
      ["Set Tags current line" org-agenda-set-tags (not (org-region-active-p))]
      ["Change tag in region" org-agenda-set-tags (org-region-active-p)]
      ["Change tag in region" org-agenda-set-tags (org-region-active-p)]
      "--"
      "--"
      ["Column View" org-columns t])
      ["Column View" org-columns t])
-    ("Date/Schedule"
+    ("Deadline/Schedule"
      ["Schedule" org-agenda-schedule t]
      ["Schedule" org-agenda-schedule t]
      ["Set Deadline" org-agenda-deadline t]
      ["Set Deadline" org-agenda-deadline t]
      "--"
      "--"
@@ -1534,57 +1590,17 @@ The following commands are available:
      ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda 'timeline)]
      ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda 'timeline)]
      ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda 'timeline)]
      ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda 'timeline)]
      "--"
      "--"
-     ["Create iCalendar file" org-export-icalendar-combine-agenda-files t])
+     ["Create iCalendar File" org-export-icalendar-combine-agenda-files t])
     "--"
     "--"
-    ("View"
-     ["Day View" org-agenda-day-view
-      :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (equal org-agenda-ndays 1)
-      :keys "v d  (or just d)"]
-     ["Week View" org-agenda-week-view
-      :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (equal org-agenda-ndays 7)
-      :keys "v w  (or just w)"]
-     ["Month View" org-agenda-month-view
-      :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (member org-agenda-ndays '(28 29 30 31))
-      :keys "v m"]
-     ["Year View" org-agenda-year-view
-      :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (member org-agenda-ndays '(365 366))
-      :keys "v y"]
-     "--"
-     ["Include Diary" org-agenda-toggle-diary
-      :style toggle :selected org-agenda-include-diary
-      :active (org-agenda-check-type nil 'agenda)]
-     ["Use Time Grid" org-agenda-toggle-time-grid
-      :style toggle :selected org-agenda-use-time-grid
-      :active (org-agenda-check-type nil 'agenda)]
-     "--"
-     ["Show clock report" org-agenda-clockreport-mode
-      :style toggle :selected org-agenda-clockreport-mode
-      :active (org-agenda-check-type nil 'agenda)]
-     ["Show some entry text" org-agenda-entry-text-mode
-      :style toggle :selected org-agenda-entry-text-mode
-      :active t]
+    ["Undo Remote Editing" org-agenda-undo org-agenda-undo-list]
     "--"
     "--"
-     ["Show Logbook entries" org-agenda-log-mode
-      :style toggle :selected org-agenda-show-log
-      :active (org-agenda-check-type nil 'agenda 'timeline)
-      :keys "v l (or just l)"]
-     ["Include archived trees" org-agenda-archives-mode
-      :style toggle :selected org-agenda-archives-mode :active t
-      :keys "v a"]
-     ["Include archive files" (org-agenda-archives-mode t)
-      :style toggle :selected (eq org-agenda-archives-mode t) :active t
-      :keys "v A"]
+    ("MobileOrg"
+     ["Push Files and Views" org-mobile-push t]
+     ["Pull Captured and Flagged" org-mobile-pull t]
+     ["Find FLAGGED Tasks" (org-agenda nil "?") t]
+     ["Show note / unflag" org-agenda-show-the-flagging-note t]
      "--"
      "--"
-     ["Remove Restriction" org-agenda-remove-restriction-lock org-agenda-restrict])
-    ["Write view to file" org-write-agenda t]
-    ["Rebuild buffer" org-agenda-redo t]
-    ["Save all Org-mode Buffers" org-save-all-org-buffers t]
-    "--"
-    ["Undo Remote Editing" org-agenda-undo org-agenda-undo-list]
+     ["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t])
     "--"
     "--"
     ["Quit" org-agenda-quit t]
     ["Quit" org-agenda-quit t]
     ["Exit and Release Buffers" org-agenda-exit t]
     ["Exit and Release Buffers" org-agenda-exit t]
@@ -1707,9 +1723,11 @@ Pressing `<' twice means to restrict to the current subtree or region
 	   (buf (current-buffer))
 	   (buf (current-buffer))
 	   (bfn (buffer-file-name (buffer-base-buffer)))
 	   (bfn (buffer-file-name (buffer-base-buffer)))
 	   entry key type match lprops ans)
 	   entry key type match lprops ans)
-      ;; Turn off restriction unless there is an overriding one
+      ;; Turn off restriction unless there is an overriding one,
       (unless org-agenda-overriding-restriction
       (unless org-agenda-overriding-restriction
-	(put 'org-agenda-files 'org-restrict nil)
+	(unless (org-bound-and-true-p org-agenda-keep-restriced-file-list)
+	  ;; There is a request to keep the file list in place
+	  (put 'org-agenda-files 'org-restrict nil))
 	(setq org-agenda-restrict nil)
 	(setq org-agenda-restrict nil)
 	(move-marker org-agenda-restrict-begin nil)
 	(move-marker org-agenda-restrict-begin nil)
 	(move-marker org-agenda-restrict-end nil))
 	(move-marker org-agenda-restrict-end nil))
@@ -1788,6 +1806,22 @@ Pressing `<' twice means to restrict to the current subtree or region
        ((equal keys "m") (call-interactively 'org-tags-view))
        ((equal keys "m") (call-interactively 'org-tags-view))
        ((equal keys "M") (org-call-with-arg 'org-tags-view (or arg '(4))))
        ((equal keys "M") (org-call-with-arg 'org-tags-view (or arg '(4))))
        ((equal keys "e") (call-interactively 'org-store-agenda-views))
        ((equal keys "e") (call-interactively 'org-store-agenda-views))
+       ((equal keys "?") (org-tags-view nil "+FLAGGED")
+	(org-add-hook
+	 'post-command-hook
+	 (lambda ()
+	   (unless (current-message)
+	     (let* ((m (org-agenda-get-any-marker))
+		    (note (and m (org-entry-get m "THEFLAGGINGNOTE"))))
+	       (when note
+		 (message (concat
+			   "FLAGGING-NOTE ([?] for more info): "
+			   (org-add-props
+			       (replace-regexp-in-string
+				"\\\\n" "//"
+				(copy-sequence note))
+			       nil 'face 'org-warning)))))))
+	 t t))
        ((equal keys "L")
        ((equal keys "L")
 	(unless (org-mode-p)
 	(unless (org-mode-p)
 	  (error "This is not an Org-mode file"))
 	  (error "This is not an Org-mode file"))
@@ -1833,7 +1867,7 @@ t   List of all TODO entries            T   Entries with special TODO kwd
 m   Match a TAGS/PROP/TODO query        M   Like m, but only TODO entries
 m   Match a TAGS/PROP/TODO query        M   Like m, but only TODO entries
 L   Timeline for current buffer         #   List stuck projects (!=configure)
 L   Timeline for current buffer         #   List stuck projects (!=configure)
 s   Search for keywords                 C   Configure custom agenda commands
 s   Search for keywords                 C   Configure custom agenda commands
-/   Multi-occur
+/   Multi-occur                         ?   Find :FLAGGED: entries
 ")
 ")
 			(start 0))
 			(start 0))
 		    (while (string-match
 		    (while (string-match
@@ -1952,7 +1986,7 @@ s   Search for keywords                 C   Configure custom agenda commands
 	   ((eq c ?>)
 	   ((eq c ?>)
 	    (org-agenda-remove-restriction-lock 'noupdate)
 	    (org-agenda-remove-restriction-lock 'noupdate)
 	    (setq restriction nil))
 	    (setq restriction nil))
-	   ((and (equal selstring "") (memq c '(?s ?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/)))
+	   ((and (equal selstring "") (memq c '(?s ?a ?t ?m ?L ?C ?e ?T ?M ?# ?! ?/ ??)))
 	    (throw 'exit (cons (setq selstring (char-to-string c)) restriction)))
 	    (throw 'exit (cons (setq selstring (char-to-string c)) restriction)))
            ((and (> (length selstring) 0) (eq c ?\d))
            ((and (> (length selstring) 0) (eq c ?\d))
             (delete-window)
             (delete-window)
@@ -2166,6 +2200,17 @@ so the export commands can easily use it."
 	  (and (get-buffer org-agenda-buffer-name)
 	  (and (get-buffer org-agenda-buffer-name)
 	       (kill-buffer org-agenda-buffer-name)))))))
 	       (kill-buffer org-agenda-buffer-name)))))))
 
 
+(defun org-agenda-mark-header-line (pos)
+  "Mark the line at POS as an agenda structure header."
+  (save-excursion
+    (goto-char pos)
+    (put-text-property (point-at-bol) (point-at-eol)
+		       'org-agenda-structural-header t)
+    (when org-agenda-title-append
+      (put-text-property (point-at-bol) (point-at-eol)
+			 'org-agenda-title-append org-agenda-title-append))))
+
+
 (defun org-write-agenda (file &optional open nosettings)
 (defun org-write-agenda (file &optional open nosettings)
   "Write the current buffer (an agenda view) as a file.
   "Write the current buffer (an agenda view) as a file.
 Depending on the extension of the file name, plain text (.txt),
 Depending on the extension of the file name, plain text (.txt),
@@ -2188,7 +2233,7 @@ higher priority settings."
     '(save-excursion
     '(save-excursion
        (save-window-excursion
        (save-window-excursion
 	 (org-agenda-mark-filtered-text)
 	 (org-agenda-mark-filtered-text)
-	 (let ((bs (copy-sequence (buffer-string))) beg)
+	 (let ((bs (copy-sequence (buffer-string))) beg app)
 	   (org-agenda-unmark-filtered-text)
 	   (org-agenda-unmark-filtered-text)
 	   (with-temp-buffer
 	   (with-temp-buffer
 	     (insert bs)
 	     (insert bs)
@@ -2228,6 +2273,63 @@ higher priority settings."
 			      (concat (file-name-sans-extension file) ".ps"))
 			      (concat (file-name-sans-extension file) ".ps"))
 			     (expand-file-name file))
 			     (expand-file-name file))
 	       (message "PDF written to %s" file))
 	       (message "PDF written to %s" file))
+	      ((string-match "\\.org\\'" file)
+	       (let ((all (buffer-string)) in-date id pl prefix line)
+		 (with-temp-file file
+		   (org-mode)
+		   (insert all)
+		   (goto-char (point-min))
+		   (while (not (eobp))
+		     (cond
+		      ((looking-at "[ \t]*$")) ; keep empty lines
+		      ((looking-at "=+$")
+		       ;; remove underlining
+		       (delete-region (point) (point-at-eol)))
+		      ((get-text-property (point) 'org-agenda-structural-header)
+		       (setq in-date nil)
+		       (setq app (get-text-property (point)
+						     'org-agenda-title-append))
+		       (setq short (get-text-property (point)
+						      'short-heading))
+		       (when (and short (looking-at ".+"))
+			 (replace-match short)
+			 (beginning-of-line 1))
+		       (when app
+			 (end-of-line 1)
+			 (insert app)
+			 (beginning-of-line 1))
+		       (insert "* "))
+		      ((get-text-property (point) 'org-agenda-date-header)
+		       (setq in-date t)
+		       (insert "** "))
+		      ((setq m (or (get-text-property (point) 'org-hd-marker)
+				   (get-text-property (point) 'org-marker)))
+		       (if (setq pl (get-text-property (point) 'prefix-length))
+			   (progn
+			     (setq prefix (org-trim (buffer-substring
+						     (point) (+ (point) pl)))
+				   line (org-trim (buffer-substring
+						   (+ (point) pl)
+						   (point-at-eol))))
+			     (delete-region (point-at-bol) (point-at-eol))
+			     (insert line "<break>" prefix)
+			     (beginning-of-line 1))
+			 (and (looking-at "[ \t]+") (replace-match "")))
+		       (insert (if in-date "***  " "**  "))
+		       (end-of-line 1)
+		       (insert "\n")
+		       (insert (org-agenda-get-some-entry-text
+				m 10 "   " 'planning)
+			       "\n")
+		       (when (setq id
+				   (if (org-bound-and-true-p
+					org-mobile-force-id-on-agenda-items)
+				       (org-id-get m 'create)
+				     (org-entry-get m "ID")))
+			 (insert "   :PROPERTIES:\n   :ORIGINAL_ID: " id
+				 "\n   :END:\n"))))
+		     (beginning-of-line 2)))
+		 (message "Agenda written to Org file %s" file)))
 	      ((string-match "\\.ics\\'" file)
 	      ((string-match "\\.ics\\'" file)
 	       (require 'org-icalendar)
 	       (require 'org-icalendar)
 	       (let ((org-agenda-marker-table
 	       (let ((org-agenda-marker-table
@@ -2289,13 +2391,17 @@ Drawers will be excluded, also the line with scheduling/deadline info."
 	(if (not (setq m (get-text-property (point) 'org-hd-marker)))
 	(if (not (setq m (get-text-property (point) 'org-hd-marker)))
 	    (beginning-of-line 2)
 	    (beginning-of-line 2)
 	  (setq txt (org-agenda-get-some-entry-text
 	  (setq txt (org-agenda-get-some-entry-text
-		     m org-agenda-add-entry-text-maxlines))
+		     m org-agenda-add-entry-text-maxlines "    > "))
 	  (end-of-line 1)
 	  (end-of-line 1)
 	  (if (string-match "\\S-" txt) (insert "\n" txt)))))))
 	  (if (string-match "\\S-" txt) (insert "\n" txt)))))))
 
 
-(defun org-agenda-get-some-entry-text (marker n-lines)
+(defun org-agenda-get-some-entry-text (marker n-lines &optional indent
+					      &rest keep)
   "Extract entry text from MARKER, at most N-LINES lines.
   "Extract entry text from MARKER, at most N-LINES lines.
-This will ignore drawers etc, just get the text."
+This will ignore drawers etc, just get the text.
+If INDENT is given, prefix every line with this string.  If KEEP is
+given, it is a list of symbols, defining stuff that hould not be
+removed from the entry content.  Currently only `planning' is allowed here."
   (let (txt drawer-re kwd-time-re ind)
   (let (txt drawer-re kwd-time-re ind)
     (save-excursion
     (save-excursion
       (with-current-buffer (marker-buffer marker)
       (with-current-buffer (marker-buffer marker)
@@ -2330,9 +2436,10 @@ This will ignore drawers etc, just get the text."
 		   (progn (re-search-forward
 		   (progn (re-search-forward
 			   "^[ \t]*:END:.*\n?" nil 'move)
 			   "^[ \t]*:END:.*\n?" nil 'move)
 			  (point))))
 			  (point))))
-		(goto-char (point-min))
-		(while (re-search-forward kwd-time-re nil t)
-		  (replace-match ""))
+		(unless (member 'planning keep)
+		  (goto-char (point-min))
+		  (while (re-search-forward kwd-time-re nil t)
+		    (replace-match "")))
 		(goto-char (point-min))
 		(goto-char (point-min))
 		(when org-agenda-entry-text-exclude-regexps
 		(when org-agenda-entry-text-exclude-regexps
 		  (let ((re-list org-agenda-entry-text-exclude-regexps)	re)
 		  (let ((re-list org-agenda-entry-text-exclude-regexps)	re)
@@ -2362,8 +2469,9 @@ This will ignore drawers etc, just get the text."
 		(run-hooks 'org-agenda-entry-text-cleanup-hook)
 		(run-hooks 'org-agenda-entry-text-cleanup-hook)
 
 
 		(goto-char (point-min))
 		(goto-char (point-min))
-		(while (and (not (eobp)) (re-search-forward "^" nil t))
-		  (replace-match "    > "))
+		(when indent
+		  (while (and (not (eobp)) (re-search-forward "^" nil t))
+		    (replace-match indent t t)))
 		(goto-char (point-min))
 		(goto-char (point-min))
 		(while (looking-at "[ \t]*\n") (replace-match ""))
 		(while (looking-at "[ \t]*\n") (replace-match ""))
 		(goto-char (point-max))
 		(goto-char (point-max))
@@ -2514,7 +2622,7 @@ bind it in the options section.")
       (org-agenda-mark-clocking-task)
       (org-agenda-mark-clocking-task)
       (when org-agenda-entry-text-mode
       (when org-agenda-entry-text-mode
 	(org-agenda-entry-text-hide)
 	(org-agenda-entry-text-hide)
-	(org-agenda-entry-text-show))	
+	(org-agenda-entry-text-show))
       (run-hooks 'org-finalize-agenda-hook)
       (run-hooks 'org-finalize-agenda-hook)
       (setq org-agenda-type (get-text-property (point) 'org-agenda-type))
       (setq org-agenda-type (get-text-property (point) 'org-agenda-type))
       (when (get 'org-agenda-filter :preset-filter)
       (when (get 'org-agenda-filter :preset-filter)
@@ -2679,7 +2787,7 @@ no longer in use."
       (error "No marker points to an entry here"))
       (error "No marker points to an entry here"))
     (setq txt (concat "\n" (org-no-properties
     (setq txt (concat "\n" (org-no-properties
 			    (org-agenda-get-some-entry-text
 			    (org-agenda-get-some-entry-text
-			     m org-agenda-entry-text-maxlines))))
+			     m org-agenda-entry-text-maxlines "    > "))))
     (when (string-match "\\S-" txt)
     (when (string-match "\\S-" txt)
       (setq o (org-make-overlay (point-at-bol) (point-at-eol)))
       (setq o (org-make-overlay (point-at-bol) (point-at-eol)))
       (org-overlay-put o 'evaporate t)
       (org-overlay-put o 'evaporate t)
@@ -2754,6 +2862,10 @@ dates."
     (push :scheduled args)
     (push :scheduled args)
     (push :sexp args)
     (push :sexp args)
     (if dotodo (push :todo args))
     (if dotodo (push :todo args))
+    (insert "Timeline of file " entry "\n")
+    (add-text-properties (point-min) (point)
+			 (list 'face 'org-agenda-structure))
+    (org-agenda-mark-header-line (point-min))
     (while (setq d (pop day-numbers))
     (while (setq d (pop day-numbers))
       (if (and (listp d) (eq (car d) :omitted))
       (if (and (listp d) (eq (car d) :omitted))
 	  (progn
 	  (progn
@@ -2786,6 +2898,7 @@ dates."
 				     'org-agenda-date-weekend
 				     'org-agenda-date-weekend
 				   'org-agenda-date))
 				   'org-agenda-date))
 	      (put-text-property s (1- (point)) 'org-date-line t)
 	      (put-text-property s (1- (point)) 'org-date-line t)
+	      (put-text-property s (1- (point)) 'org-agenda-date-header t)
 	      (if (equal d today)
 	      (if (equal d today)
 		  (put-text-property s (1- (point)) 'org-today t))
 		  (put-text-property s (1- (point)) 'org-today t))
 	      (and rtn (insert (org-finalize-agenda-entries rtn) "\n"))
 	      (and rtn (insert (org-finalize-agenda-entries rtn) "\n"))
@@ -2934,9 +3047,10 @@ given in `org-agenda-start-on-weekday'."
 		     file date :todo))
 		     file date :todo))
 	  (setq rtnall (append rtnall rtn))))
 	  (setq rtnall (append rtnall rtn))))
       (when rtnall
       (when rtnall
-	(insert "ALL CURRENTLY OPEN TODO ITEMS:\n")
+	(insert "All currently open TODO items:\n")
 	(add-text-properties (point-min) (1- (point))
 	(add-text-properties (point-min) (1- (point))
-			     (list 'face 'org-agenda-structure))
+			     (list 'face 'org-agenda-structure
+				   'short-heading "All TODO items"))
 	(insert (org-finalize-agenda-entries rtnall) "\n")))
 	(insert (org-finalize-agenda-entries rtnall) "\n")))
     (unless org-agenda-compact-blocks
     (unless org-agenda-compact-blocks
       (let* ((d1 (car day-numbers))
       (let* ((d1 (car day-numbers))
@@ -2956,7 +3070,8 @@ given in `org-agenda-start-on-weekday'."
 		    "")
 		    "")
 		  ":\n")))
 		  ":\n")))
       (add-text-properties s (1- (point)) (list 'face 'org-agenda-structure
       (add-text-properties s (1- (point)) (list 'face 'org-agenda-structure
-						'org-date-line t)))
+						'org-date-line t))
+      (org-agenda-mark-header-line s))
     (while (setq d (pop day-numbers))
     (while (setq d (pop day-numbers))
       (setq date (calendar-gregorian-from-absolute d)
       (setq date (calendar-gregorian-from-absolute d)
 	    wd (calendar-day-of-week date)
 	    wd (calendar-day-of-week date)
@@ -3003,6 +3118,7 @@ given in `org-agenda-start-on-weekday'."
 				   'org-agenda-date-weekend
 				   'org-agenda-date-weekend
 				 'org-agenda-date))
 				 'org-agenda-date))
 	    (put-text-property s (1- (point)) 'org-date-line t)
 	    (put-text-property s (1- (point)) 'org-date-line t)
+	    (put-text-property s (1- (point)) 'org-agenda-date-header t)
 	    (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
 	    (put-text-property s (1- (point)) 'org-day-cnt day-cnt)
 	    (when todayp
 	    (when todayp
 	      (put-text-property s (1- (point)) 'org-today t)
 	      (put-text-property s (1- (point)) 'org-today t)
@@ -3233,6 +3349,7 @@ in `org-agenda-text-search-extra-files'."
 	(insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n")
 	(insert "Press `[', `]' to add/sub word, `{', `}' to add/sub regexp, `C-u r' to edit\n")
 	(add-text-properties pos (1- (point))
 	(add-text-properties pos (1- (point))
 			     (list 'face 'org-agenda-structure))))
 			     (list 'face 'org-agenda-structure))))
+    (org-agenda-mark-header-line (point-min))
     (when rtnall
     (when rtnall
       (insert (org-finalize-agenda-entries rtnall) "\n"))
       (insert (org-finalize-agenda-entries rtnall) "\n"))
     (goto-char (point-min))
     (goto-char (point-min))
@@ -3287,7 +3404,11 @@ for a keyword.  A numeric prefix directly selects the Nth keyword in
 		    nil 'face 'org-agenda-structure) "\n")
 		    nil 'face 'org-agenda-structure) "\n")
       (insert "Global list of TODO items of type: ")
       (insert "Global list of TODO items of type: ")
       (add-text-properties (point-min) (1- (point))
       (add-text-properties (point-min) (1- (point))
-			   (list 'face 'org-agenda-structure))
+			   (list 'face 'org-agenda-structure
+				 'short-heading
+				 (concat "ToDo: "
+					 (or org-select-this-todo-keyword "ALL"))))
+      (org-agenda-mark-header-line (point-min))
       (setq pos (point))
       (setq pos (point))
       (insert (or org-select-this-todo-keyword "ALL") "\n")
       (insert (or org-select-this-todo-keyword "ALL") "\n")
       (add-text-properties pos (1- (point)) (list 'face 'org-warning))
       (add-text-properties pos (1- (point)) (list 'face 'org-warning))
@@ -3303,6 +3424,7 @@ for a keyword.  A numeric prefix directly selects the Nth keyword in
 		kwds))
 		kwds))
 	(insert "\n"))
 	(insert "\n"))
       (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
       (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
+    (org-agenda-mark-header-line (point-min))
     (when rtnall
     (when rtnall
       (insert (org-finalize-agenda-entries rtnall) "\n"))
       (insert (org-finalize-agenda-entries rtnall) "\n"))
     (goto-char (point-min))
     (goto-char (point-min))
@@ -3362,7 +3484,9 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
 		    nil 'face 'org-agenda-structure) "\n")
 		    nil 'face 'org-agenda-structure) "\n")
       (insert "Headlines with TAGS match: ")
       (insert "Headlines with TAGS match: ")
       (add-text-properties (point-min) (1- (point))
       (add-text-properties (point-min) (1- (point))
-			   (list 'face 'org-agenda-structure))
+			   (list 'face 'org-agenda-structure
+				 'short-heading
+				 (concat "Match: " match)))
       (setq pos (point))
       (setq pos (point))
       (insert match "\n")
       (insert match "\n")
       (add-text-properties pos (1- (point)) (list 'face 'org-warning))
       (add-text-properties pos (1- (point)) (list 'face 'org-warning))
@@ -3370,6 +3494,7 @@ The prefix arg TODO-ONLY limits the search to TODO entries."
       (unless org-agenda-multi
       (unless org-agenda-multi
 	(insert "Press `C-u r' to search again with new search string\n"))
 	(insert "Press `C-u r' to search again with new search string\n"))
       (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
       (add-text-properties pos (1- (point)) (list 'face 'org-agenda-structure)))
+    (org-agenda-mark-header-line (point-min))
     (when rtnall
     (when rtnall
       (insert (org-finalize-agenda-entries rtnall) "\n"))
       (insert (org-finalize-agenda-entries rtnall) "\n"))
     (goto-char (point-min))
     (goto-char (point-min))
@@ -6701,6 +6826,53 @@ This will remove the markers, and the overlays."
 	       (format ", skipped %d (disappeared before their turn)"
 	       (format ", skipped %d (disappeared before their turn)"
 		       cntskip)))))
 		       cntskip)))))
 
 
+;;; Flagging notes
+
+(defun org-agenda-show-the-flagging-note ()
+  "Display the flagging note in the other window.
+When called a second time in direct sequence, offer to remove the FLAGGING
+tag and (if present) the flagging note."
+  (interactive)
+  (let ((hdmarker (get-text-property (point) 'org-hd-marker))
+	(win (selected-window))
+	note heading newhead)
+    (unless hdmarker
+      (error "No linked entry at point"))
+    (if (and (eq this-command last-command)
+	     (y-or-n-p "Unflag and remove any flagging note? "))
+	(progn
+	  (org-agenda-remove-flag hdmarker)
+	  (let ((win (get-buffer-window "*Flagging Note*")))
+	    (and win (delete-window win)))
+	  (message "Entry unflaged"))
+      (setq note (org-entry-get hdmarker "THEFLAGGINGNOTE"))
+      (unless note
+	(error "No flagging note"))
+      (org-kill-new note)
+      (org-switch-to-buffer-other-window "*Flagging Note*")
+      (erase-buffer)
+      (insert note)
+      (goto-char (point-min))
+      (while (re-search-forward "\\\\n" nil t)
+	(replace-match "\n" t t))
+      (goto-char (point-min))
+      (select-window win)
+      (message "Flagging note pushed to kill ring.  Press [?] again to remove tag and note"))))
+
+(defun org-agenda-remove-flag (marker)
+  "Remove the FLAGGED tag and any flaging note in the entry."
+  (let (newhead)
+    (org-with-point-at marker
+      (org-toggle-tag "FLAGGED" 'off)
+      (org-entry-delete nil "THEFLAGGINGNOTE")
+      (setq newhead (org-get-heading)))
+    (org-agenda-change-all-lines newhead marker)
+    (message "Entry unflaged")))
+
+(defun org-agenda-get-any-marker (&optional pos)
+  (or (get-text-property (or pos (point)) 'org-hd-marker)
+      (get-text-property (or pos (point)) 'org-marker)))
+
 ;;; Appointment reminders
 ;;; Appointment reminders
 
 
 (defvar appt-time-msg-list)
 (defvar appt-time-msg-list)

+ 11 - 10
lisp/org-id.el

@@ -212,16 +212,17 @@ If the entry does not have an ID, the function returns nil.
 However, when CREATE is non nil, create an ID if none is present already.
 However, when CREATE is non nil, create an ID if none is present already.
 PREFIX will be passed through to `org-id-new'.
 PREFIX will be passed through to `org-id-new'.
 In any case, the ID of the entry is returned."
 In any case, the ID of the entry is returned."
-  (let ((id (org-entry-get pom "ID")))
-    (cond
-     ((and id (stringp id) (string-match "\\S-" id))
-      id)
-     (create
-      (setq id (org-id-new prefix))
-      (org-entry-put pom "ID" id)
-      (org-id-add-location id (buffer-file-name (buffer-base-buffer)))
-      id)
-     (t nil))))
+  (org-with-point-at pom
+    (let ((id (org-entry-get nil "ID")))
+      (cond
+       ((and id (stringp id) (string-match "\\S-" id))
+	id)
+       (create
+	(setq id (org-id-new prefix))
+	(org-entry-put pom "ID" id)
+	(org-id-add-location id (buffer-file-name (buffer-base-buffer)))
+	id)
+       (t nil)))))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-id-get-with-outline-path-completion (&optional targets)
 (defun org-id-get-with-outline-path-completion (&optional targets)

+ 406 - 0
lisp/org-mobile.el

@@ -0,0 +1,406 @@
+;;; org-mobile.el --- Code for asymmetric sync with a mobile device
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+;;
+;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: http://orgmode.org
+;; Version: 6.30trans
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; This file contains the code to interact with Richard Moreland's iPhone
+;; application MobileOrg.  This code is documented in Appendix B of the
+;; Org-mode manual.
+
+(require 'org)
+(require 'org-agenda)
+
+(defgroup org-mobile nil
+  "Options concerning support for a viewer on a mobile device."
+  :tag "Org Mobile"
+  :group 'org)
+
+(defcustom org-mobile-directory ""
+  "The WebDAV directory where the interaction with the mobile takes place."
+  :group 'org-mobile
+  :type 'directory)
+
+(defcustom org-mobile-inbox-for-pull "~/org/from-mobile.org"
+  "The file where captured notes and flags will be appended to.
+During the execution of `org-mobile-pull', the file
+`org-mobile-capture-file' will be emptied it's contents have
+been appended to the file given here."
+  :group 'org-mobile
+  :type 'file)
+
+(defcustom org-mobile-capture-file "mobile-capture.org"
+  "The capture file where the mobile stores captured notes and flags.
+Relative to `org-mobile-directory'."
+  :group 'org-mobile
+  :type 'file)
+
+(defcustom org-mobile-index-file "index.org"
+  "The index file with inks to all Org files that should be loaded by MobileOrg.
+Relative to `org-mobile-directory'."
+  :group 'org-mobile
+  :type 'file)
+
+(defcustom org-mobile-force-id-on-agenda-items t
+  "Non-nil means make all agenda items carry and ID."
+  :group 'org-mobile
+  :type 'boolean)
+
+(defcustom org-mobile-action-alist
+  '(("d" . (org-todo 'done))
+    ("a" . (org-archive-subtree-default))
+    ("d-a" . (progn (org-todo 'done) (org-archive-subtree-default))))
+  "Alist with flags and actions for mobile sync.
+When flagging an entry, MobileOrg will create entries that look like
+
+  * F(action)  [[id:entry-id][entry title]]
+
+This alist defines that the action in the parentheses of F() should mean,
+i.e. what action should be taken.  The car of each elements of the alist
+is an actions string.  The cdr is an Emacs Lisp form that will be evaluated
+with the cursor on the headline of that entry."
+  :group 'org-mobile
+  :type '(repeat
+	  (cons (string :tag "Action flag")
+		(sexp   :tag "Action form"))))
+
+(defvar org-mobile-pre-push-hook nil
+  "Hook run before running `org-mobile-push'.
+This could be used to clean up `org-mobile-directory', for example to
+remove files that used to be included in the agenda but no longer are.
+The presence of such files would not really be a problem, but after time
+they may accumulate.")
+
+(defvar org-mobile-post-push-hook nil
+  "Hook run after running `org-mobile-push'.
+If Emacs does not have direct write access to the WebDAV directory used
+by the mobile device, this hook could be used to copy all files from the
+local `org-mobile-directory' to the WebDAV directory, for example using
+`rsync' or `scp'.")
+
+(defvar org-mobile-pre-pull-hook nil
+  "Hook run before executing `org-mobile-pull'.
+If Emacs does not have direct write access to the WebDAV directory used
+by the mobile device, this hook could be used to copy all files from the
+WebDAV location to the local staging directory `org-mobile-directory'.")
+
+(defvar org-mobile-post-pull-hook nil
+  "Hook run after running `org-mobile-pull'.
+If Emacs does not have direct write access to the WebDAV directory used
+by the mobile device, this hook could be used to copy all files from the
+local `org-mobile-directory' to the WebDAV directory, for example using
+`rsync' or `scp'.  The only file that will be changed after a pull is
+`org-mobile-capture-file'.")
+
+(defvar org-mobile-last-flagged-files nil
+  "List of files containing entreis flagged in the latest pull.")
+
+;;;###autoload
+(defun org-mobile-push ()
+  "Push the current state of Org affairs to the WebDAV directory.
+This will create the index file, copy all agenda files there, and also
+create all custom agenda views, for upload to the mobile phone."
+  (interactive)
+  (org-mobile-check-setup)
+  (run-hooks 'org-mobile-pre-push-hook)
+  (org-mobile-create-sumo-agenda)
+  (org-save-all-org-buffers) ; to save any IDs created by this process
+  (org-mobile-copy-agenda-files)
+  (org-mobile-create-index-file)
+  (org-mobile-write-checksums)
+  (run-hooks 'org-mobile-post-push-hook)
+  (message "Files for mobile viewer staged"))
+
+;;;###autoload
+(defun org-mobile-pull ()
+  "Pull the contents of `org-mobile-capture-file' and integrate them.
+Apply all flagged actions, flag entries to be flagged and then call an
+agenda view showing the flagged items."
+  (interactive)
+  (org-mobile-check-setup)
+  (run-hooks 'org-mobile-pre-pull-hook)
+  (let ((insertion-marker (org-mobile-move-capture)))
+    (if (not (markerp insertion-marker))
+	(message "No new items")
+      (org-with-point-at insertion-marker
+	(org-mobile-apply-flags (point) (point-max)))
+      (move-marker insertion-marker nil)
+      (run-hooks 'org-mobile-post-pull-hook)
+      (when org-mobile-last-flagged-files
+	;; Make an agenda view of flagged entries, but only in the files
+	;; where stuff has been added.
+	(put 'org-agenda-files 'org-restrict org-mobile-last-flagged-files)
+	(let ((org-agenda-keep-restriced-file-list t))
+	  (org-agenda nil "?"))))))
+
+(defun org-mobile-check-setup ()
+  "Check if org-mobile-directory has been set up."
+  (when (or (not org-mobile-directory)
+	    (not (stringp org-mobile-directory))
+	    (not (string-match "\\S-" org-mobile-directory))
+	    (not (file-exists-p org-mobile-directory))
+	    (not (file-directory-p org-mobile-directory)))
+    (error
+     "Variable `org-mobile-directory' must point to an existing directory"))
+  (when (or (not org-mobile-inbox-for-pull)
+	    (not (stringp org-mobile-inbox-for-pull))
+	    (not (string-match "\\S-" org-mobile-inbox-for-pull))
+	    (not (file-exists-p
+		  (file-name-directory org-mobile-inbox-for-pull))))
+    (error
+     "Variable `org-mobile-inbox-for-pull' must point to a file in an existing directory")))
+
+(defun org-mobile-create-index-file ()
+  "Write the index file in the WebDAV directory."
+  (interactive)
+  (with-temp-file (expand-file-name org-mobile-index-file org-mobile-directory)
+    (insert "* [[file:agendas.org][Agenda Views]]\n")
+    (let ((files (org-agenda-files t)) file)
+      (while (setq file (pop files))
+	(insert (format "* [[file:%s][%s]]\n"
+			(file-name-nondirectory file)
+			(capitalize
+			 (file-name-sans-extension
+			  (file-name-nondirectory file))))))
+      (insert (format "* [[file:%s][Captured before last sync]]\n"
+		      (file-name-sans-extension org-mobile-capture-file))))))
+
+(defun org-mobile-copy-agenda-files ()
+  "Copy all agenda files to the stage or WebDAV directory."
+  (let ((files (org-agenda-files t)) file)
+    (while (setq file (pop files))
+      (if (file-exists-p file)
+	  (copy-file file (expand-file-name (file-name-nondirectory file)
+					    org-mobile-directory)
+		     'ok-if-exists)))))
+
+(defun org-mobile-write-checksums ()
+  "Create checksums for all files in `org-mobile-directory'.
+The table of checksums is written to the file mobile-checksums."
+  (let ((cmd (cond ((executable-find "shasum"))
+		   ((executable-find "sha1sum"))
+		   ((executable-find "md5sum"))
+		   ((executable-find "md5")))))
+    (if (not cmd)
+	(message "Checksums could not be generated: no executable")
+      (with-temp-buffer
+	(cd org-mobile-directory)
+	(if (equal 0 (shell-command (concat cmd " *.org > checksums.dat")))
+	    (message "Checksums written")
+	  (message "Checksums could not be generated"))))))
+
+(defun org-mobile-sumo-agenda-command ()
+  "Return an agenda custom command that comprises all custom commands."
+  (let ((custom-list
+	 ;; normalize different versions
+	 (delq nil
+	       (mapcar
+		(lambda (x)
+		  (cond ((stringp (cdr x)) nil)
+			((stringp (nth 1 x)) x)
+			((not (nth 1 x)) (cons (car x) (cons "" (cddr x))))
+			(t (cons (car x) (cons "" (cdr x))))))
+		org-agenda-custom-commands)))
+	new e key desc type match settings cmds gkey gdesc gsettings cnt)
+    (while (setq e (pop custom-list))
+      (cond
+       ((stringp (cdr e))
+	;; this is a description entry - skip it
+	)
+       ((eq (nth 2 e) 'search)
+	;; Search view is interactive, skip
+	)
+       ((memq (nth 2 e) '(todo-tree tags-tree occur-tree))
+	;; These are trees, not really agenda commands
+	)
+       ((memq (nth 2 e) '(agenda todo tags))
+	;; a normal command
+	(setq key (car e) desc (nth 1 e) type (nth 2 e) match (nth 3 e)
+	      settings (nth 4 e))
+	(setq settings
+	      (cons (list 'org-agenda-title-append
+			  (concat "<break>KEYS=" key " TITLE: "
+				  (if (and (stringp desc) (> (length desc) 0))
+				      desc (symbol-name type))
+				  " " match))
+		    settings))
+	(push (list type match settings) new))
+       ((symbolp (nth 2 e))
+	;; A user-defined function, not sure how to handle that yet
+	)
+       (t
+	;; a block agenda
+	(setq gkey (car e) gdesc (nth 1 e) gsettings (nth 3 e) cmds (nth 2 e))
+	(setq cnt 0)
+	(while (setq e (pop cmds))
+	  (setq type (car e) match (nth 1 e) settings (nth 2 e))
+	  (setq settings (append gsettings settings))
+	  (setq settings
+		(cons (list 'org-agenda-title-append
+			    (concat "<break>KEYS=" gkey "#" (number-to-string
+						      (setq cnt (1+ cnt)))
+				    " TITLE: " gdesc " " match))
+		      settings))
+	  (push (list type match settings) new)))))
+    (list "X" "SUMO" (reverse new) nil)))
+
+;;;###autoload
+(defun org-mobile-create-sumo-agenda ()
+  "Create a file that contains all custom agenda views."
+  (interactive)
+  (let* ((file (expand-file-name "agendas.org"
+				 org-mobile-directory))
+	 (org-agenda-custom-commands
+	  (list (append (org-mobile-sumo-agenda-command)
+			(list (list file))))))
+    (unless (file-writable-p file)
+      (error "Cannot write to file %s" file))
+    (org-batch-store-agenda-views)))
+
+(defun org-mobile-move-capture ()
+  "Move the contents of the capture file to the inbox file.
+Return a marker to the location where the new content has been added.
+If nothing new has beed added, return nil."
+  (interactive)
+  (let ((inbox-buffer (find-file-noselect org-mobile-inbox-for-pull))
+	(capture-buffer (find-file-noselect
+			 (expand-file-name org-mobile-capture-file
+					   org-mobile-directory)))
+	(insertion-point (make-marker))
+	not-empty content)
+    (save-excursion
+      (set-buffer capture-buffer)
+      (setq content (buffer-string))
+      (setq not-empty (string-match "\\S-" content))
+      (when not-empty
+	(set-buffer inbox-buffer)
+	(widen)
+	(goto-char (point-max))
+	(or (bolp) (newline))
+	(move-marker insertion-point
+		     (prog1 (point) (insert content)))
+	(save-buffer)
+	(set-buffer capture-buffer)
+	(erase-buffer)
+	(save-buffer)))
+    (kill-buffer capture-buffer)
+    (if not-empty insertion-point)))
+
+(defun org-mobile-apply-flags (&optional beg end)
+  "Apply all flags in the current buffer.
+If BEG and END are given, only do this in that region."
+  (interactive)
+  (setq org-mobile-last-flagged-files nil)
+  (setq beg (or beg (point-min)) end (or end (point-max)))
+  (goto-char beg)
+  (let ((marker (make-marker))
+	(end (move-marker (make-marker) end))
+	action id id-pos cmd text)
+    (while (re-search-forward
+	    "^\\*+[ \t]+F(\\([^()\n]*\\))[ \t]+\\[\\[id:\\([^]\n ]+\\)" end t)
+      (goto-char (- (match-beginning 1) 2))
+      (catch 'next
+	(setq action (match-string 1)
+	      id (match-string 2)
+	      cmd (if (equal action "")
+		      '(progn
+			 (org-toggle-tag "FLAGGED" 'on)
+			 (and text (org-entry-put nil "THEFLAGGINGNOTE" text)))
+		    (cdr (assoc action org-mobile-action-alist)))
+	      text (org-trim (buffer-substring (1+ (point-at-eol))
+					       (save-excursion
+						 (org-end-of-subtree t))))
+	      id-pos (org-id-find id 'marker))
+	(if (> (length text) 0)
+	    ;; Make TEXT into a single line, to fit into a property
+	    (setq text (mapconcat 'identity
+				  (org-split-string text "\n")
+				  "\\n"))
+	  (setq text nil))
+	(unless id-pos
+	  (insert "BAD ID REFERENCE ")
+	  (throw 'next t))
+	(unless cmd
+	  (insert "BAD FLAG ")
+	  (throw 'next t))
+	(move-marker marker (point))
+	(save-excursion
+	  (condition-case nil
+	      (org-with-point-at id-pos
+		(progn
+		  (eval cmd)
+		  (if (member "FLAGGED" (org-get-tags))
+		      (add-to-list 'org-mobile-last-flagged-files
+				   (buffer-file-name (current-buffer))))))
+	    (error
+	     (progn
+	       (switch-to-buffer (marker-buffer marker))
+	       (goto-char marker)
+	       (insert "EXECUTION FAILED ")
+	       (throw 'next t)))))
+	;; If we get here, the action has been applied successfully
+	;; So remove the entry
+	(org-back-to-heading t)
+	(delete-region (point) (org-end-of-subtree t t))))
+    (move-marker marker nil)
+    (move-marker end nil)))
+
+(defun org-mobile-smart-read ()
+  "Parse the entry at point for shortcuts and expand them.
+These shortcuts are meant for fast and easy typing on the limited
+keyboards of a mobile device.  Below we show a list of the shortcuts
+currently implemented.
+
+The entry is expected to contain an inactive time stamp indicating when
+the entry was created.  When setting dates and
+times (for example for deadlines), the time strings are interpreted
+relative to that creation date.
+Abbreviations are expected to take up entire lines, jst because it is so
+easy to type RET on a mobile device.  Abbreviations start with one or two
+letters, followed immediately by a dot and then additional information.
+Generally the entire shortcut line is removed after action have been taken.
+Time stamps will be constructed using `org-read-date'.  So for example a
+line \"dd. 2tue\" will set a deadline on the second Tuesday after the
+creation date.
+
+Here are the shortcuts currently implemented:
+
+dd. string             set deadline
+ss. string             set scheduling
+tt. string             set time tamp, here.
+ti. string             set inactive time
+
+tg. tag1 tag2 tag3     set all these tags, change case where necessary
+td. kwd                set this todo keyword, change case where necessary
+
+FIXME: Hmmm, not sure if we can make his work against the
+auto-correction feature.  Needs a bit more thinking.  So this function
+is currently a noop.")
+
+(provide 'org-mobile)
+
+;; arch-tag: ace0e26c-58f2-4309-8a61-05ec1535f658
+
+;;; org-mobile.el ends here
+

+ 31 - 17
lisp/org.el

@@ -3223,6 +3223,13 @@ If yes, offer to stop it and to save the buffer with the changes."
    "org-indent"
    "org-indent"
    '(org-indent-mode)))
    '(org-indent-mode)))
 
 
+;; Autoload org-mobile.el
+
+(eval-and-compile
+  (org-autoload
+   "org-mobile"
+   '(org-mobile-push org-mobile-pull org-mobile-create-sumo-agenda)))
+
 ;; Autoload archiving code
 ;; Autoload archiving code
 ;; The stuff that is needed for cycling and tags has to be defined here.
 ;; The stuff that is needed for cycling and tags has to be defined here.
 
 
@@ -7914,7 +7921,7 @@ application the system uses for this file type."
   (cond
   (cond
    ((and (org-on-heading-p)
    ((and (org-on-heading-p)
 	 (not (org-in-regexp
 	 (not (org-in-regexp
-	       (concat org-plain-link-re "\\|" 
+	       (concat org-plain-link-re "\\|"
 		       org-bracket-link-regexp "\\|"
 		       org-bracket-link-regexp "\\|"
 		       org-angle-link-re "\\|"
 		       org-angle-link-re "\\|"
 		       "[ \t]:[^ \t\n]+:[ \t]*$"))))
 		       "[ \t]:[^ \t\n]+:[ \t]*$"))))
@@ -7983,12 +7990,12 @@ application the system uses for this file type."
 	    ;; Check if we need to translate the link
 	    ;; Check if we need to translate the link
 	    (let ((tmp (funcall org-link-translation-function type path)))
 	    (let ((tmp (funcall org-link-translation-function type path)))
 	      (setq type (car tmp) path (cdr tmp))))
 	      (setq type (car tmp) path (cdr tmp))))
-	
+
 	(cond
 	(cond
-	 
+
 	 ((assoc type org-link-protocols)
 	 ((assoc type org-link-protocols)
 	  (funcall (nth 1 (assoc type org-link-protocols)) path))
 	  (funcall (nth 1 (assoc type org-link-protocols)) path))
-	 
+
 	 ((equal type "mailto")
 	 ((equal type "mailto")
 	  (let ((cmd (car org-link-mailto-program))
 	  (let ((cmd (car org-link-mailto-program))
 		(args (cdr org-link-mailto-program)) args1
 		(args (cdr org-link-mailto-program)) args1
@@ -8006,14 +8013,14 @@ application the system uses for this file type."
 		      (setq a (replace-match subject t t a)))
 		      (setq a (replace-match subject t t a)))
 		  (push a args1))))
 		  (push a args1))))
 	    (apply cmd (nreverse args1))))
 	    (apply cmd (nreverse args1))))
-	 
+
 	 ((member type '("http" "https" "ftp" "news"))
 	 ((member type '("http" "https" "ftp" "news"))
 	  (browse-url (concat type ":" (org-link-escape
 	  (browse-url (concat type ":" (org-link-escape
 					path org-link-escape-chars-browser))))
 					path org-link-escape-chars-browser))))
-	 
+
 	 ((member type '("message"))
 	 ((member type '("message"))
 	  (browse-url (concat type ":" path)))
 	  (browse-url (concat type ":" path)))
-	 
+
 	 ((string= type "tags")
 	 ((string= type "tags")
 	  (org-tags-view in-emacs path))
 	  (org-tags-view in-emacs path))
 	 ((string= type "thisfile")
 	 ((string= type "thisfile")
@@ -8029,10 +8036,10 @@ application the system uses for this file type."
 		       ,pos)))
 		       ,pos)))
 	    (condition-case nil (eval cmd)
 	    (condition-case nil (eval cmd)
 	      (error (progn (widen) (eval cmd))))))
 	      (error (progn (widen) (eval cmd))))))
-	 
+
 	 ((string= type "tree-match")
 	 ((string= type "tree-match")
 	  (org-occur (concat "\\[" (regexp-quote path) "\\]")))
 	  (org-occur (concat "\\[" (regexp-quote path) "\\]")))
-	 
+
 	 ((string= type "file")
 	 ((string= type "file")
 	  (if (string-match "::\\([0-9]+\\)\\'" path)
 	  (if (string-match "::\\([0-9]+\\)\\'" path)
 	      (setq line (string-to-number (match-string 1 path))
 	      (setq line (string-to-number (match-string 1 path))
@@ -8043,11 +8050,11 @@ application the system uses for this file type."
 	  (if (string-match "[*?{]" (file-name-nondirectory path))
 	  (if (string-match "[*?{]" (file-name-nondirectory path))
 	      (dired path)
 	      (dired path)
 	    (org-open-file path in-emacs line search)))
 	    (org-open-file path in-emacs line search)))
-	 
+
 	 ((string= type "news")
 	 ((string= type "news")
 	  (require 'org-gnus)
 	  (require 'org-gnus)
 	  (org-gnus-follow-link path))
 	  (org-gnus-follow-link path))
-	 
+
 	 ((string= type "shell")
 	 ((string= type "shell")
 	  (let ((cmd path))
 	  (let ((cmd path))
 	    (if (or (not org-confirm-shell-link-function)
 	    (if (or (not org-confirm-shell-link-function)
@@ -8059,7 +8066,7 @@ application the system uses for this file type."
 		  (message "Executing %s" cmd)
 		  (message "Executing %s" cmd)
 		  (shell-command cmd))
 		  (shell-command cmd))
 	      (error "Abort"))))
 	      (error "Abort"))))
-	 
+
 	 ((string= type "elisp")
 	 ((string= type "elisp")
 	  (let ((cmd path))
 	  (let ((cmd path))
 	    (if (or (not org-confirm-elisp-link-function)
 	    (if (or (not org-confirm-elisp-link-function)
@@ -8072,7 +8079,7 @@ application the system uses for this file type."
 			     (eval (read cmd))
 			     (eval (read cmd))
 			   (call-interactively (read cmd))))
 			   (call-interactively (read cmd))))
 	      (error "Abort"))))
 	      (error "Abort"))))
-	 
+
 	 (t
 	 (t
 	  (browse-url-at-point))))))
 	  (browse-url-at-point))))))
    (move-marker org-open-link-marker nil)
    (move-marker org-open-link-marker nil)
@@ -8099,7 +8106,7 @@ there is one, offer it as link number zero."
       (while (re-search-forward re end t)
       (while (re-search-forward re end t)
 	(push (match-string 0) links))
 	(push (match-string 0) links))
       (setq links (org-uniquify (reverse links))))
       (setq links (org-uniquify (reverse links))))
-    
+
     (cond
     (cond
      ((null links) (error "No links"))
      ((null links) (error "No links"))
      ((equal (length links) 1)
      ((equal (length links) 1)
@@ -8866,7 +8873,7 @@ See also `org-refile-use-outline-path' and `org-completion-use-ido'"
     (setq answ (funcall cfunc prompt tbl nil (not new-nodes)
     (setq answ (funcall cfunc prompt tbl nil (not new-nodes)
 			nil 'org-refile-history))
 			nil 'org-refile-history))
     (setq pa (or (assoc answ tbl) (assoc (concat answ "/") tbl)))
     (setq pa (or (assoc answ tbl) (assoc (concat answ "/") tbl)))
-    (if pa 
+    (if pa
 	(progn
 	(progn
 	  (when (or (not org-refile-history)
 	  (when (or (not org-refile-history)
 		    (not (eq old-hist org-refile-history))
 		    (not (eq old-hist org-refile-history))
@@ -8918,7 +8925,7 @@ See also `org-refile-use-outline-path' and `org-completion-use-ido'"
   "Read an outline path like a file name."
   "Read an outline path like a file name."
   (let ((thetable collection)
   (let ((thetable collection)
 	(org-completion-use-ido nil)	   ; does not work with ido.
 	(org-completion-use-ido nil)	   ; does not work with ido.
-	(org-completion-use-iswitchb nil)) ; or iswitchb 
+	(org-completion-use-iswitchb nil)) ; or iswitchb
     (apply
     (apply
      'org-icompleting-read prompt
      'org-icompleting-read prompt
      (lambda (string predicate &optional flag)
      (lambda (string predicate &optional flag)
@@ -9716,7 +9723,7 @@ This should be called with the cursor in a line with a statistics cookie."
 	      (error "No data for statistics cookie"))))
 	      (error "No data for statistics cookie"))))
 	(goto-char pos)
 	(goto-char pos)
 	(move-marker pos nil)))))
 	(move-marker pos nil)))))
-  
+
 (defvar org-entry-property-inherited-from) ;; defined below
 (defvar org-entry-property-inherited-from) ;; defined below
 (defun org-update-parent-todo-statistics ()
 (defun org-update-parent-todo-statistics ()
   "Update any statistics cookie in the parent of the current headline.
   "Update any statistics cookie in the parent of the current headline.
@@ -15492,6 +15499,13 @@ See the individual commands for more information."
       :style toggle :selected (and (boundp 'org-export-with-LaTeX-fragments)
       :style toggle :selected (and (boundp 'org-export-with-LaTeX-fragments)
 				   org-export-with-LaTeX-fragments)])
 				   org-export-with-LaTeX-fragments)])
     "--"
     "--"
+    ("MobileOrg"
+     ["Push Files and Views" org-mobile-push t]
+     ["Pull Captured and Flagged" org-mobile-pull t]
+     ["Find FLAGGED Tasks" (org-agenda nil "?") t]
+     "--"
+     ["Setup" (progn (require 'org-mobile) (customize-group 'org-mobile)) t])
+    "--"
     ("Documentation"
     ("Documentation"
      ["Show Version" org-version t]
      ["Show Version" org-version t]
      ["Info Documentation" org-info t])
      ["Info Documentation" org-info t])