mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Merge branch 'master' into 1.5.0
Conflicts: ChangeLog NEWS configure.ac html/task.html src/task.cpp src/task.h
This commit is contained in:
commit
ee961daef6
29 changed files with 813 additions and 447 deletions
14
ChangeLog
14
ChangeLog
|
@ -11,14 +11,18 @@
|
||||||
|
|
||||||
------ old releases ------------------------------
|
------ old releases ------------------------------
|
||||||
|
|
||||||
1.4.3 (10/9/2008)
|
1.4.3 (11/1/2008)
|
||||||
+ Fixed misleading task count at bottom on "info" report.
|
+ Fixed misleading task count at bottom on "info" report.
|
||||||
+ Added support for a shadow file that contains a plain text task report,
|
+ Added support for a shadow file that contains a plain text task report,
|
||||||
with the "shadow.file" and "shadow.command" configuration variables.
|
with the "shadow.file" and "shadow.command" configuration variables
|
||||||
The shadow file is automatically updated whenever the task database
|
The shadow file is automatically updated whenever the task database
|
||||||
changes. Useful for integrating with "Samurize".
|
changes. Useful for integrating with "Samurize"
|
||||||
|
+ Task now displays a message whenever a shadow file is updated, if the
|
||||||
------ old releases ------------------------------
|
"shadow.notify" configuration variable is set "on"
|
||||||
|
+ Bug: adding a task with a \n, \r or \f in it now fails properly
|
||||||
|
+ Removed "task usage" command.
|
||||||
|
+ Added documentation for Shadow files.
|
||||||
|
+ Added documentation for task filters.
|
||||||
|
|
||||||
1.4.2 (9/18/2008)
|
1.4.2 (9/18/2008)
|
||||||
+ "task undo" can now retract a "task done" command, provided no reports
|
+ "task undo" can now retract a "task done" command, provided no reports
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
Some considerable time ago - longer than I had hoped - I demonstrated an
|
|
||||||
alternate implementation of the todo script, called task, in the form of a
|
|
||||||
YouTube movie:
|
|
||||||
|
|
||||||
http://www.youtube.com/watch?v=l68LCl6BYvs
|
|
||||||
|
|
||||||
A lot has happened since then, and the task program has been slowly improving
|
|
||||||
thanks to feedback from some early testers, and continuous use by me. Today,
|
|
||||||
I have uploaded a new movie:
|
|
||||||
|
|
||||||
http://www.youtube.com/watch?v=D2Kn4DMOVSw
|
|
||||||
|
|
||||||
This movie includes most of the changes and improvements to task, but behind
|
|
||||||
the scenes are the biggest changes. There was a rewrite of the underlying
|
|
||||||
storage mechanism yielding a clean API for the front end, and the code was
|
|
||||||
reviewed for portability and converted to use GNU autoconf/automake.
|
|
||||||
|
|
||||||
Task has been released under GPL, and so far has been tested on:
|
|
||||||
|
|
||||||
Max OS X 10.4 (Tiger)
|
|
||||||
Max OS X 10.5 (Leopard)
|
|
||||||
Fedora 8
|
|
||||||
Fedora 9
|
|
||||||
Ubuntu 8 (Hardy Heron)
|
|
||||||
Solaris 10
|
|
||||||
|
|
||||||
Task has been making me more organized and productive for some time now.
|
|
||||||
Perhaps some of you might find it useful, and I welcome feedback of all kinds.
|
|
||||||
|
|
||||||
You can find the task source code at:
|
|
||||||
|
|
||||||
http://www.beckingham.net/task-1.0.0.tar.gz
|
|
||||||
|
|
||||||
Thank you.
|
|
||||||
Paul Beckingham
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ AC_CHECK_LIB(ncurses,endwin)
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([stdlib.h sys/file.h sys/stat.h sys/time.h unistd.h])
|
AC_CHECK_HEADERS([stdlib.h sys/file.h sys/stat.h sys/time.h unistd.h])
|
||||||
AC_CHECK_HEADERS([string vector map])
|
AC_CHECK_HEADERS([sstream string vector map])
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_HEADER_STDBOOL
|
AC_HEADER_STDBOOL
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
@ -315,6 +316,12 @@ ID Project Pri Description
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt>shadow.notify</dt>
|
||||||
|
<dd>
|
||||||
|
When this value is set to "on", task will display a message
|
||||||
|
whenever the shadow file is updated by some task command.
|
||||||
|
</dd>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
@ -34,10 +35,49 @@
|
||||||
<h2 class="title">Task Filters</h2>
|
<h2 class="title">Task Filters</h2>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
<p>
|
||||||
|
A task filter is a means of reducing a task report to a
|
||||||
|
subset that may consist of all tasks that have a specific
|
||||||
|
project, priority, tag, or part of the description.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A task filter consists of additional command line options,
|
||||||
|
that are specified in the same way as when a task is added.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
All task reports can make use of filters.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For example, the report:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<code><pre>% task list</pre></code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Lists all tasks.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<code><pre>% task list the</pre></code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Lists only tasks with "the" in the task description.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<code><pre>% task list project:Home priority:H</pre></code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Lists only tasks with both the "Home" project and "H" priority.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<code><pre>% task list +shopping</pre></code>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Lists only tasks with the "shopping" tag.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
188
html/links.html
Normal file
188
html/links.html
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Task on the Web</title>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<link rel="stylesheet" href="task.css" type="text/css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div id="toolbar">
|
||||||
|
<a href="task.html">Home</a>
|
||||||
|
<a href="setup.html">Setup</a>
|
||||||
|
<a href="30second.html">30-second Tutorial</a>
|
||||||
|
<a href="simple.html">Simple</a>
|
||||||
|
<a href="advanced.html">Advanced</a>
|
||||||
|
<a href="shell.html">Shell</a>
|
||||||
|
<a href="config.html">Configuration</a>
|
||||||
|
<a href="color.html">Colors</a>
|
||||||
|
<a href="usage.html">Usage</a>
|
||||||
|
<a href="recur.html">Recurrence</a>
|
||||||
|
<a href="date.html">Date Handling</a>
|
||||||
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<h1 class="title">Task on the Web</h1>
|
||||||
|
<p>
|
||||||
|
Task links from around the web...
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
November 2008, <a href="http://github.com/pbeckingham/task/tree/master/">Task repository on GitHub</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
For developers: the task git repository on github.com is now public.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
October 2008, <a href="http://blog.rfquerin.org/2008/10/07/using-task-and-dropbox-to-manage-your-to-do-list/">Using Task and Dropbox to manage your To-Do list</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Richard Querin. Richard discusses the ease of setting up task to
|
||||||
|
use DropBox to share todo lists between work and home.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
September 2008, <a href="http://stasantons.blogspot.com/2008/09/task-program-visually-simple.html">Task visualization</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Stas Antons. Stas - a colleague of mine - presents a visualization
|
||||||
|
of the simplicity of task.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
June 2008, <a href="http://blog.rfquerin.org/2008/06/17/building-debian-packages-for-task/">Building Debian Packages For Task</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Richard Querin. Richard has been providing Debian packages for the
|
||||||
|
various task releases, and discusses how he got up to speed.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
June 2008, <a href="http://blog.rfquerin.org/2008/06/06/task-101-an-attempt-at-a-cygwin-build-how-to/">Task 1.0.1 - an attempt at a Cygwin Build How-To</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Richard Querin. Richard shows us how to build task using Cygwin, after
|
||||||
|
a cry for help on the todo.txt mailing list.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
June 2008, <a href="http://www.youtube.com/watch?v=D2Kn4DMOVSw">The second task movie</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
This YouTube movie was made to illustrate some of the features of the task
|
||||||
|
program, back when task 1.0.0 was released. While task has grown
|
||||||
|
significantly since then, the commands shown are still valid. It will
|
||||||
|
soon be time for a new movie!
|
||||||
|
<p>
|
||||||
|
|
||||||
|
This movie has a voice-over that explains what is going on.
|
||||||
|
<p>
|
||||||
|
|
||||||
|
For a higher-quality version, download the whole
|
||||||
|
<a href="http://www.beckingham.net/todo2.mov">movie file (10MB)</a>.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
December 2006, <a href="http://www.youtube.com/watch?v=l68LCl6BYvs">The first task movie</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
This original YouTube task movie was made to illustrate the features of the
|
||||||
|
then-unreleased task program. The idea was to get some feedback and see
|
||||||
|
whether anyone was interested in a new implementation of todo.sh, that added
|
||||||
|
features that are not easily possible with a shell implementation.
|
||||||
|
<p>
|
||||||
|
|
||||||
|
This movie has no voice-over, and you may notice that it exactly duplicates
|
||||||
|
the commands used in the original todo.sh movie (below). That is, until it
|
||||||
|
deviates because of new task commands.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
June 2006, <a href="http://www.youtube.com/watch?v=daJ1Hs_y738">The original todo.sh movie</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Gina Trapani. This is the original YouTube todo.sh movie, made to
|
||||||
|
illustrate the power and simplicity of the original todo.sh program.
|
||||||
|
</dd>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<dt>
|
||||||
|
June 2006, <a href="http://todotxt.com/">Todo.sh, the inspiration for task</a>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
by Gina Trapani. The website that introduced me to the power and
|
||||||
|
simplicity of the original todo.sh program. Contains useful links
|
||||||
|
and resources - take a look!
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
Copyright 2006-2008, P. Beckingham. All rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td align="right" valign="top" width="200px">
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<script type="text/javascript"><!--
|
||||||
|
google_ad_client = "pub-9709799404235424";
|
||||||
|
/* Task Main */
|
||||||
|
google_ad_slot = "8660617875";
|
||||||
|
google_ad_width = 120;
|
||||||
|
google_ad_height = 600;
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||||
|
</script>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||||
|
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var pageTracker = _gat._getTracker("UA-4737637-1");
|
||||||
|
pageTracker._initData();
|
||||||
|
pageTracker._trackPageview();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
@ -34,10 +35,42 @@
|
||||||
<h2 class="title">Task Shadow Files</h2>
|
<h2 class="title">Task Shadow Files</h2>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
<p>
|
||||||
|
A shadow file is a text file containing a copy of a task
|
||||||
|
report. It is automatically maintained by task whenever
|
||||||
|
something changes in the task database.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This means there is always a current version of the task
|
||||||
|
report kept in a text file. Products such as
|
||||||
|
<a href="www.samurize.com">Samurize</a>,
|
||||||
|
<a href="http://www.mulle-kybernetik.com/software/MkConsole/">MkConsole</a>,
|
||||||
|
or
|
||||||
|
<a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a>
|
||||||
|
can display this file on the computer desktop, so that it
|
||||||
|
is readily visible.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To use a shadow file, edit your .taskrc configuration file,
|
||||||
|
and add two entries as shown:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><code>shadow.file=/path/to/file
|
||||||
|
shadow.command=list pri:H</code></pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In this example the shadow file contains a report equivalent
|
||||||
|
to running "task list pri:H".
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You can use any task command that generates a report, and of
|
||||||
|
course, you can specify any file name, provided the directory
|
||||||
|
it resides in already exists.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
@ -54,8 +55,8 @@
|
||||||
<li><a href="date.html">Date Handling</a>
|
<li><a href="date.html">Date Handling</a>
|
||||||
<li><a href="troubleshooting.html">Troubleshooting</a>
|
<li><a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<li><a href="versions.html">Old Versions</a>
|
<li><a href="versions.html">Old Versions</a>
|
||||||
<li><a href="filter.html">Filters (coming soon)</a>
|
<li><a href="filter.html">Filters</a>
|
||||||
<li><a href="shadow.html">Shadow Files (coming soon)</a>
|
<li><a href="shadow.html">Shadow Files</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -77,6 +78,7 @@
|
||||||
<td>Source:</td>
|
<td>Source:</td>
|
||||||
<td><a href="http://www.beckingham.net/task-1.5.0.tar.gz">task-1.5.0.tar.gz</a></td>
|
<td><a href="http://www.beckingham.net/task-1.5.0.tar.gz">task-1.5.0.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!--
|
||||||
<tr>
|
<tr>
|
||||||
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
<td>Mac OS X 10.5 (Leopard) Intel-only:</td>
|
||||||
<td><a href="http://www.beckingham.net/task-1.5.0.pkg">task-1.5.0.pkg</a></td>
|
<td><a href="http://www.beckingham.net/task-1.5.0.pkg">task-1.5.0.pkg</a></td>
|
||||||
|
@ -88,13 +90,12 @@
|
||||||
</td>
|
</td>
|
||||||
<td><a href="http://www.beckingham.net/task_1.5.0-1_i386.deb">task_1.5.0-1_i386.deb</a></td>
|
<td><a href="http://www.beckingham.net/task_1.5.0-1_i386.deb">task_1.5.0-1_i386.deb</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
-->
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h4>New in version 1.5.0 (?)</h4>
|
<h4>New in version 1.5.0 (?)</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Removed deprecated TUTORIAL file.
|
<li>Removed deprecated TUTORIAL file.
|
||||||
<li>Removed "usage" command, and support for "command.logging" configuration
|
|
||||||
variable.
|
|
||||||
<li>"task stop" can remove the start time from a started task.
|
<li>"task stop" can remove the start time from a started task.
|
||||||
<li>"task ghistory" now displays a differently aligned graph, allowing
|
<li>"task ghistory" now displays a differently aligned graph, allowing
|
||||||
easier comparison by month of tasks added versus completed and deleted.
|
easier comparison by month of tasks added versus completed and deleted.
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
<a href="date.html">Date Handling</a>
|
<a href="date.html">Date Handling</a>
|
||||||
<a href="troubleshooting.html">Troubleshooting</a>
|
<a href="troubleshooting.html">Troubleshooting</a>
|
||||||
<a href="versions.html">Old Versions</a>
|
<a href="versions.html">Old Versions</a>
|
||||||
|
<a href="links.html">Task on the Web</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
@ -35,6 +36,32 @@
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
<h4>New in version 1.4.3 (11/1/2008)</h4>
|
||||||
|
<a href="http://www.beckingham.net/task-1.4.3.tar.gz">task-1.4.3.tar.gz</a>
|
||||||
|
<br />
|
||||||
|
Mac OS X 10.5 (Leopard) Intel-only:
|
||||||
|
<a href="http://www.beckingham.net/task-1.4.3.pkg">task-1.4.3.pkg</a>
|
||||||
|
<br />
|
||||||
|
Debian package: <a href="http://www.beckingham.net/task_1.4.3-1_i386.deb">task_1.4.3-1_i386.deb</a>
|
||||||
|
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Fixed misleading task count at bottom of "info" report.
|
||||||
|
<li>Added support for a shadow file that contains a plain text task report,
|
||||||
|
with the "shadow.file" and "shadow.command" configuration variables.
|
||||||
|
The shadow file is automatically updated whenever the task database
|
||||||
|
changes. Useful for integrating with "Samurize".
|
||||||
|
<li>Task now displays a message whenever a shadow file is updated, if the
|
||||||
|
"shadow.notify" configuration variable is set "on".
|
||||||
|
<li>Fixed bug whereby adding a task with a \n, \r or \f dit not fail properly.
|
||||||
|
<li>Removed "task usage" command.
|
||||||
|
<li>Added documentation for Shadow files.
|
||||||
|
<li>Added documentation for task filters.
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<h4>New in version 1.4.2 (9/18/2008)</h4>
|
<h4>New in version 1.4.2 (9/18/2008)</h4>
|
||||||
<a href="http://www.beckingham.net/task-1.4.2.tar.gz">task-1.4.2.tar.gz</a>
|
<a href="http://www.beckingham.net/task-1.4.2.tar.gz">task-1.4.2.tar.gz</a>
|
||||||
|
|
1
src/.gitignore
vendored
1
src/.gitignore
vendored
|
@ -1,2 +1 @@
|
||||||
./Makefile
|
|
||||||
*.o
|
*.o
|
||||||
|
|
|
@ -130,6 +130,10 @@ void Config::createDefault (const std::string& home)
|
||||||
fprintf (out, "#color.tag.bug=yellow\n");
|
fprintf (out, "#color.tag.bug=yellow\n");
|
||||||
fprintf (out, "#color.project.home=on_green\n");
|
fprintf (out, "#color.project.home=on_green\n");
|
||||||
fprintf (out, "#color.keyword.car=on_blue\n");
|
fprintf (out, "#color.keyword.car=on_blue\n");
|
||||||
|
fprintf (out, "#shadow.file=%s/shadow.txt\n", dataDir.c_str ());
|
||||||
|
fprintf (out, "#shadow.command=list\n");
|
||||||
|
fprintf (out, "#shadow.notify=on\n");
|
||||||
|
fprintf (out, "#default.command=list\n");
|
||||||
|
|
||||||
fclose (out);
|
fclose (out);
|
||||||
|
|
||||||
|
|
33
src/TDB.cpp
33
src/TDB.cpp
|
@ -204,9 +204,7 @@ bool TDB::deleteT (const T& t)
|
||||||
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
||||||
it->setAttribute ("end", endTime);
|
it->setAttribute ("end", endTime);
|
||||||
|
|
||||||
bool status = overwritePending (all);
|
return overwritePending (all);
|
||||||
dbChanged ();
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -230,9 +228,7 @@ bool TDB::completeT (const T& t)
|
||||||
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
sprintf (endTime, "%u", (unsigned int) time (NULL));
|
||||||
it->setAttribute ("end", endTime);
|
it->setAttribute ("end", endTime);
|
||||||
|
|
||||||
bool status = overwritePending (all);
|
return overwritePending (all);
|
||||||
dbChanged ();
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -259,14 +255,10 @@ bool TDB::addT (const T& t)
|
||||||
if (task.getStatus () == T::pending ||
|
if (task.getStatus () == T::pending ||
|
||||||
task.getStatus () == T::recurring)
|
task.getStatus () == T::recurring)
|
||||||
{
|
{
|
||||||
bool status = writePending (task);
|
return writePending (task);
|
||||||
dbChanged ();
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool status = writeCompleted (task);
|
return writeCompleted (task);
|
||||||
dbChanged ();
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -291,9 +283,7 @@ bool TDB::modifyT (const T& t)
|
||||||
pending.push_back (*it);
|
pending.push_back (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool status = overwritePending (pending);
|
return overwritePending (pending);
|
||||||
dbChanged ();
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -324,6 +314,7 @@ bool TDB::overwritePending (std::vector <T>& all)
|
||||||
fputs (it->compose ().c_str (), out);
|
fputs (it->compose ().c_str (), out);
|
||||||
|
|
||||||
fclose (out);
|
fclose (out);
|
||||||
|
dbChanged ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +322,7 @@ bool TDB::overwritePending (std::vector <T>& all)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool TDB::writePending (const T& t) const
|
bool TDB::writePending (const T& t)
|
||||||
{
|
{
|
||||||
// Write a single task to the pending file
|
// Write a single task to the pending file
|
||||||
FILE* out;
|
FILE* out;
|
||||||
|
@ -346,6 +337,7 @@ bool TDB::writePending (const T& t) const
|
||||||
fputs (t.compose ().c_str (), out);
|
fputs (t.compose ().c_str (), out);
|
||||||
|
|
||||||
fclose (out);
|
fclose (out);
|
||||||
|
dbChanged ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +345,7 @@ bool TDB::writePending (const T& t) const
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool TDB::writeCompleted (const T& t) const
|
bool TDB::writeCompleted (const T& t)
|
||||||
{
|
{
|
||||||
// Write a single task to the pending file
|
// Write a single task to the pending file
|
||||||
FILE* out;
|
FILE* out;
|
||||||
|
@ -368,6 +360,8 @@ bool TDB::writeCompleted (const T& t) const
|
||||||
fputs (t.compose ().c_str (), out);
|
fputs (t.compose ().c_str (), out);
|
||||||
|
|
||||||
fclose (out);
|
fclose (out);
|
||||||
|
// Note: No call to dbChanged here because this call never occurs by itself.
|
||||||
|
// It is always accompanied by an overwritePending call.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,8 +433,11 @@ int TDB::gc ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all clean tasks into pending.
|
// Dump all clean tasks into pending. But don't bother unless at least one
|
||||||
|
// task was transferred.
|
||||||
|
if (count)
|
||||||
overwritePending (pending);
|
overwritePending (pending);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ public:
|
||||||
private:
|
private:
|
||||||
bool lock (FILE*) const;
|
bool lock (FILE*) const;
|
||||||
bool overwritePending (std::vector <T>&);
|
bool overwritePending (std::vector <T>&);
|
||||||
bool writePending (const T&) const;
|
bool writePending (const T&);
|
||||||
bool writeCompleted (const T&) const;
|
bool writeCompleted (const T&);
|
||||||
bool readLockedFile (const std::string&, std::vector <std::string>&) const;
|
bool readLockedFile (const std::string&, std::vector <std::string>&) const;
|
||||||
void dbChanged ();
|
void dbChanged ();
|
||||||
|
|
||||||
|
|
122
src/command.cpp
122
src/command.cpp
|
@ -26,6 +26,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -67,7 +68,6 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
|
||||||
task.setAttribute ("mask", "");
|
task.setAttribute ("mask", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**/
|
|
||||||
// Override with default.project, if not specified.
|
// Override with default.project, if not specified.
|
||||||
if (task.getAttribute ("project") == "")
|
if (task.getAttribute ("project") == "")
|
||||||
task.setAttribute ("project", conf.get ("default.project", ""));
|
task.setAttribute ("project", conf.get ("default.project", ""));
|
||||||
|
@ -79,18 +79,20 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
|
||||||
if (validPriority (defaultPriority))
|
if (validPriority (defaultPriority))
|
||||||
task.setAttribute ("priority", defaultPriority);
|
task.setAttribute ("priority", defaultPriority);
|
||||||
}
|
}
|
||||||
/**/
|
|
||||||
|
|
||||||
|
// Disallow blank descriptions.
|
||||||
if (task.getDescription () == "")
|
if (task.getDescription () == "")
|
||||||
throw std::string ("Cannot add a blank task.");
|
throw std::string ("Cannot add a task that is blank, or contains <CR> or <LF> characters.");
|
||||||
|
|
||||||
if (!tdb.addT (task))
|
if (!tdb.addT (task))
|
||||||
throw std::string ("Could not create new task.");
|
throw std::string ("Could not create new task.");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleProjects (TDB& tdb, T& task, Config& conf)
|
std::string handleProjects (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Get all the tasks, including deleted ones.
|
// Get all the tasks, including deleted ones.
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
|
@ -127,7 +129,7 @@ void handleProjects (TDB& tdb, T& task, Config& conf)
|
||||||
table.addCell (row, 1, i->second);
|
table.addCell (row, 1, i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< unique.size ()
|
<< unique.size ()
|
||||||
|
@ -135,13 +137,17 @@ void handleProjects (TDB& tdb, T& task, Config& conf)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << "No projects."
|
out << "No projects."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleTags (TDB& tdb, T& task, Config& conf)
|
std::string handleTags (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
|
@ -166,20 +172,23 @@ void handleTags (TDB& tdb, T& task, Config& conf)
|
||||||
std::cout << i->first << std::endl;
|
std::cout << i->first << std::endl;
|
||||||
|
|
||||||
if (unique.size ())
|
if (unique.size ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< unique.size ()
|
<< unique.size ()
|
||||||
<< (unique.size () == 1 ? " tag" : " tags")
|
<< (unique.size () == 1 ? " tag" : " tags")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No tags."
|
out << "No tags."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// If a task is deleted, but is still in the pending file, then it may be
|
// If a task is deleted, but is still in the pending file, then it may be
|
||||||
// undeleted simply by changing it's status.
|
// undeleted simply by changing it's status.
|
||||||
void handleUndelete (TDB& tdb, T& task, Config& conf)
|
std::string handleUndelete (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
tdb.allPendingT (all);
|
tdb.allPendingT (all);
|
||||||
|
|
||||||
|
@ -193,8 +202,8 @@ void handleUndelete (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
if (it->getAttribute ("recur") != "")
|
if (it->getAttribute ("recur") != "")
|
||||||
{
|
{
|
||||||
std::cout << "Task does not support 'undelete' for recurring tasks." << std::endl;
|
out << "Task does not support 'undelete' for recurring tasks." << std::endl;
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
T restored (*it);
|
T restored (*it);
|
||||||
|
@ -202,27 +211,31 @@ void handleUndelete (TDB& tdb, T& task, Config& conf)
|
||||||
restored.removeAttribute ("end");
|
restored.removeAttribute ("end");
|
||||||
tdb.modifyT (restored);
|
tdb.modifyT (restored);
|
||||||
|
|
||||||
std::cout << "Task " << id << " successfully undeleted." << std::endl;
|
out << "Task " << id << " successfully undeleted." << std::endl;
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Task " << id << " is not deleted - therefore cannot undelete." << std::endl;
|
out << "Task " << id << " is not deleted - therefore cannot undelete." << std::endl;
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Task " << id
|
out << "Task " << id
|
||||||
<< " not found - tasks can only be reliably undeleted if the undelete" << std::endl
|
<< " not found - tasks can only be reliably undeleted if the undelete" << std::endl
|
||||||
<< "command is run immediately after the errant delete command." << std::endl;
|
<< "command is run immediately after the errant delete command." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// If a task is done, but is still in the pending file, then it may be undone
|
// If a task is done, but is still in the pending file, then it may be undone
|
||||||
// simply by changing it's status.
|
// simply by changing it's status.
|
||||||
void handleUndo (TDB& tdb, T& task, Config& conf)
|
std::string handleUndo (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
tdb.allPendingT (all);
|
tdb.allPendingT (all);
|
||||||
|
|
||||||
|
@ -235,35 +248,36 @@ void handleUndo (TDB& tdb, T& task, Config& conf)
|
||||||
if (it->getStatus () == T::completed)
|
if (it->getStatus () == T::completed)
|
||||||
{
|
{
|
||||||
if (it->getAttribute ("recur") != "")
|
if (it->getAttribute ("recur") != "")
|
||||||
{
|
return std::string ("Task does not support 'undo' for recurring tasks.\n");
|
||||||
std::cout << "Task does not support 'undo' for recurring tasks." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
T restored (*it);
|
T restored (*it);
|
||||||
restored.setStatus (T::pending);
|
restored.setStatus (T::pending);
|
||||||
restored.removeAttribute ("end");
|
restored.removeAttribute ("end");
|
||||||
tdb.modifyT (restored);
|
tdb.modifyT (restored);
|
||||||
|
|
||||||
std::cout << "Task " << id << " successfully undone." << std::endl;
|
out << "Task " << id << " successfully undone." << std::endl;
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Task " << id << " is not done - therefore cannot be undone." << std::endl;
|
out << "Task " << id << " is not done - therefore cannot be undone." << std::endl;
|
||||||
return;
|
return out.str ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Task " << id
|
out << "Task " << id
|
||||||
<< " not found - tasks can only be reliably undone if the undo" << std::endl
|
<< " not found - tasks can only be reliably undone if the undo" << std::endl
|
||||||
<< "command is run immediately after the errant done command." << std::endl;
|
<< "command is run immediately after the errant done command." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleVersion (Config& conf)
|
std::string handleVersion (Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -329,7 +343,7 @@ void handleVersion (Config& conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Copyright (C) 2006 - 2008, P. Beckingham."
|
out << "Copyright (C) 2006 - 2008, P. Beckingham."
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, PACKAGE) : PACKAGE)
|
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, PACKAGE) : PACKAGE)
|
||||||
<< " "
|
<< " "
|
||||||
|
@ -345,24 +359,26 @@ void handleVersion (Config& conf)
|
||||||
// ensure everything is properly installed.
|
// ensure everything is properly installed.
|
||||||
|
|
||||||
if (all.size () == 0)
|
if (all.size () == 0)
|
||||||
std::cout << "Configuration error: .taskrc contains no entries"
|
out << "Configuration error: .taskrc contains no entries"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (conf.get ("data.location") == "")
|
if (conf.get ("data.location") == "")
|
||||||
std::cout << "Configuration error: data.location not specified in .taskrc "
|
out << "Configuration error: data.location not specified in .taskrc "
|
||||||
"file."
|
"file."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (access (expandPath (conf.get ("data.location")).c_str (), X_OK))
|
if (access (expandPath (conf.get ("data.location")).c_str (), X_OK))
|
||||||
std::cout << "Configuration error: data.location contains a directory name"
|
out << "Configuration error: data.location contains a directory name"
|
||||||
" that doesn't exist, or is unreadable."
|
" that doesn't exist, or is unreadable."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleDelete (TDB& tdb, T& task, Config& conf)
|
std::string handleDelete (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
if (conf.get ("confirmation") != "yes" || confirm ("Permanently delete task?"))
|
if (conf.get ("confirmation") != "yes" || confirm ("Permanently delete task?"))
|
||||||
{
|
{
|
||||||
|
@ -386,7 +402,7 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
|
||||||
sibling->getUUID () == parent)
|
sibling->getUUID () == parent)
|
||||||
tdb.deleteT (*sibling);
|
tdb.deleteT (*sibling);
|
||||||
|
|
||||||
return;
|
return std::string ("");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -394,7 +410,7 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
|
||||||
t->setStatus (T::deleted);
|
t->setStatus (T::deleted);
|
||||||
updateRecurrenceMask (tdb, all, *t);
|
updateRecurrenceMask (tdb, all, *t);
|
||||||
tdb.deleteT (*t);
|
tdb.deleteT (*t);
|
||||||
return;
|
return std::string ("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -405,11 +421,13 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << "Task not deleted." << std::endl;
|
return std::string ("Task not deleted.\n");
|
||||||
|
|
||||||
|
return std::string ("");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleStart (TDB& tdb, T& task, Config& conf)
|
std::string handleStart (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
tdb.pendingT (all);
|
tdb.pendingT (all);
|
||||||
|
@ -431,18 +449,23 @@ void handleStart (TDB& tdb, T& task, Config& conf)
|
||||||
tdb.modifyT (original);
|
tdb.modifyT (original);
|
||||||
|
|
||||||
nag (tdb, task, conf);
|
nag (tdb, task, conf);
|
||||||
return;
|
return std::string ("");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << "Task " << task.getId () << " already started." << std::endl;
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
out << "Task " << task.getId () << " already started." << std::endl;
|
||||||
|
return out.str ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::string ("Task not found.");
|
throw std::string ("Task not found.");
|
||||||
|
return std::string (""); // To satisfy gcc.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleStop (TDB& tdb, T& task, Config& conf)
|
std::string handleStop (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
std::vector <T> all;
|
std::vector <T> all;
|
||||||
tdb.pendingT (all);
|
tdb.pendingT (all);
|
||||||
|
@ -461,14 +484,19 @@ void handleStop (TDB& tdb, T& task, Config& conf)
|
||||||
tdb.modifyT (original);
|
tdb.modifyT (original);
|
||||||
|
|
||||||
nag (tdb, task, conf);
|
nag (tdb, task, conf);
|
||||||
return;
|
return std::string ("");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << "Task " << task.getId () << " not started." << std::endl;
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
out << "Task " << task.getId () << " not started." << std::endl;
|
||||||
|
return out.str ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::string ("Task not found.");
|
throw std::string ("Task not found.");
|
||||||
|
return std::string (""); // To satisfy gcc.
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -627,11 +655,13 @@ void handleModify (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleColor (Config& conf)
|
std::string handleColor (Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
if (conf.get ("color", true))
|
if (conf.get ("color", true))
|
||||||
{
|
{
|
||||||
std::cout << optionalBlankLine (conf) << "Foreground" << std::endl
|
out << optionalBlankLine (conf) << "Foreground" << std::endl
|
||||||
<< " "
|
<< " "
|
||||||
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
||||||
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
||||||
|
@ -706,8 +736,10 @@ void handleColor (Config& conf)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Color is currently turned off in your .taskrc file." << std::endl;
|
out << "Color is currently turned off in your .taskrc file." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -284,10 +284,21 @@ static bool validTag (const std::string& input)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
static bool validDescription (const std::string& input)
|
static bool validDescription (const std::string& input)
|
||||||
{
|
{
|
||||||
if (input.length () > 0)
|
/*
|
||||||
|
if (input.length () > 0 &&
|
||||||
|
input.find ("\r") == std::string::npos &&
|
||||||
|
input.find ("\f") == std::string::npos &&
|
||||||
|
input.find ("\n") == std::string::npos)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
*/
|
||||||
|
if (input.length () == 0) return false;
|
||||||
|
if (input.find ("\r") != std::string::npos) return false;
|
||||||
|
if (input.find ("\f") != std::string::npos) return false;
|
||||||
|
if (input.find ("\n") != std::string::npos) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
189
src/report.cpp
189
src/report.cpp
|
@ -26,6 +26,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -110,8 +111,10 @@ void filter (std::vector<T>& all, T& task)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
// line. Tasks that match all the specified criteria are listed.
|
||||||
void handleList (TDB& tdb, T& task, Config& conf)
|
std::string handleList (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -124,7 +127,6 @@ void handleList (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
handleRecurrence (tdb, tasks);
|
handleRecurrence (tdb, tasks);
|
||||||
|
@ -242,23 +244,27 @@ void handleList (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed. Show a narrow
|
// line. Tasks that match all the specified criteria are listed. Show a narrow
|
||||||
// list that works better on mobile devices.
|
// list that works better on mobile devices.
|
||||||
void handleSmallList (TDB& tdb, T& task, Config& conf)
|
std::string handleSmallList (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -271,7 +277,6 @@ void handleSmallList (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
handleRecurrence (tdb, tasks);
|
handleRecurrence (tdb, tasks);
|
||||||
|
@ -371,22 +376,26 @@ void handleSmallList (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
// line. Tasks that match all the specified criteria are listed.
|
||||||
void handleCompleted (TDB& tdb, T& task, Config& conf)
|
std::string handleCompleted (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -399,7 +408,6 @@ void handleCompleted (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.completedT (tasks);
|
tdb.completedT (tasks);
|
||||||
filter (tasks, task);
|
filter (tasks, task);
|
||||||
|
@ -459,21 +467,25 @@ void handleCompleted (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Display all information for the given task.
|
// Display all information for the given task.
|
||||||
void handleInfo (TDB& tdb, T& task, Config& conf)
|
std::string handleInfo (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -657,18 +669,22 @@ void handleInfo (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches." << std::endl;
|
out << "No matches." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
// line. Tasks that match all the specified criteria are listed.
|
||||||
void handleLongList (TDB& tdb, T& task, Config& conf)
|
std::string handleLongList (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -681,7 +697,6 @@ void handleLongList (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
handleRecurrence (tdb, tasks);
|
handleRecurrence (tdb, tasks);
|
||||||
|
@ -824,24 +839,27 @@ void handleLongList (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches." << std::endl;
|
out << "No matches." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Project Tasks Avg Age Status
|
// Project Tasks Avg Age Status
|
||||||
// A 12 13d XXXXXXXX------
|
// A 12 13d XXXXXXXX------
|
||||||
// B 109 3d 12h XX------------
|
// B 109 3d 12h XX------------
|
||||||
void handleReportSummary (TDB& tdb, T& task, Config& conf)
|
std::string handleReportSummary (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Generate unique list of project names.
|
// Generate unique list of project names.
|
||||||
tdb.gc ();
|
|
||||||
std::map <std::string, bool> allProjects;
|
std::map <std::string, bool> allProjects;
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
@ -981,14 +999,16 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " project" : " projects")
|
<< (table.rowCount () == 1 ? " project" : " projects")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No projects." << std::endl;
|
out << "No projects." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1010,10 +1030,11 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
|
||||||
//
|
//
|
||||||
// Make the "three" tasks a configurable number
|
// Make the "three" tasks a configurable number
|
||||||
//
|
//
|
||||||
void handleReportNext (TDB& tdb, T& task, Config& conf)
|
std::string handleReportNext (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Load all pending.
|
// Load all pending.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
handleRecurrence (tdb, pending);
|
handleRecurrence (tdb, pending);
|
||||||
|
@ -1034,8 +1055,6 @@ void handleReportNext (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
|
@ -1151,15 +1170,17 @@ void handleReportNext (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1184,15 +1205,16 @@ time_t monthlyEpoch (const std::string& date)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleReportHistory (TDB& tdb, T& task, Config& conf)
|
std::string handleReportHistory (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
std::map <time_t, int> groups;
|
std::map <time_t, int> groups;
|
||||||
std::map <time_t, int> addedGroup;
|
std::map <time_t, int> addedGroup;
|
||||||
std::map <time_t, int> completedGroup;
|
std::map <time_t, int> completedGroup;
|
||||||
std::map <time_t, int> deletedGroup;
|
std::map <time_t, int> deletedGroup;
|
||||||
|
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
handleRecurrence (tdb, pending);
|
handleRecurrence (tdb, pending);
|
||||||
|
@ -1360,16 +1382,20 @@ void handleReportHistory (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No tasks." << std::endl;
|
out << "No tasks." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
std::string handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -1388,7 +1414,6 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
||||||
std::map <time_t, int> deletedGroup;
|
std::map <time_t, int> deletedGroup;
|
||||||
|
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
handleRecurrence (tdb, pending);
|
handleRecurrence (tdb, pending);
|
||||||
|
@ -1583,12 +1608,12 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
{
|
{
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (conf.get ("color", true))
|
if (conf.get ("color", true))
|
||||||
std::cout << "Legend: "
|
out << "Legend: "
|
||||||
<< Text::colorize (Text::black, Text::on_red, "added")
|
<< Text::colorize (Text::black, Text::on_red, "added")
|
||||||
<< ", "
|
<< ", "
|
||||||
<< Text::colorize (Text::black, Text::on_green, "completed")
|
<< Text::colorize (Text::black, Text::on_green, "completed")
|
||||||
|
@ -1597,10 +1622,12 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "Legend: + added, X completed, - deleted" << std::endl;
|
out << "Legend: + added, X completed, - deleted" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << "No tasks." << std::endl;
|
out << "No tasks." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1728,10 +1755,11 @@ std::string renderMonths (
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
std::string handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Load all the pending tasks.
|
// Load all the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
handleRecurrence (tdb, pending);
|
handleRecurrence (tdb, pending);
|
||||||
|
@ -1760,7 +1788,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
int mTo = newest.month ();
|
int mTo = newest.month ();
|
||||||
int yTo = newest.year ();
|
int yTo = newest.year ();
|
||||||
|
|
||||||
std::cout << std::endl;
|
out << std::endl;
|
||||||
std::string output;
|
std::string output;
|
||||||
|
|
||||||
int monthsPerLine = (conf.get ("monthsperline", 1));
|
int monthsPerLine = (conf.get ("monthsperline", 1));
|
||||||
|
@ -1777,7 +1805,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
int left = (18 - month.length ()) / 2 + 1;
|
int left = (18 - month.length ()) / 2 + 1;
|
||||||
int right = 18 - left - month.length ();
|
int right = 18 - left - month.length ();
|
||||||
|
|
||||||
std::cout << std::setw (left) << ' '
|
out << std::setw (left) << ' '
|
||||||
<< month
|
<< month
|
||||||
<< ' '
|
<< ' '
|
||||||
<< nextY
|
<< nextY
|
||||||
|
@ -1790,7 +1818,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl
|
out << std::endl
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< renderMonths (mFrom, yFrom, today, pending, conf)
|
<< renderMonths (mFrom, yFrom, today, pending, conf)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -1803,7 +1831,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Legend: "
|
out << "Legend: "
|
||||||
<< Text::colorize (Text::cyan, Text::nocolor, "today")
|
<< Text::colorize (Text::cyan, Text::nocolor, "today")
|
||||||
<< ", "
|
<< ", "
|
||||||
<< Text::colorize (Text::black, Text::on_yellow, "due")
|
<< Text::colorize (Text::black, Text::on_yellow, "due")
|
||||||
|
@ -1812,11 +1840,15 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
||||||
<< "."
|
<< "."
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportActive (TDB& tdb, T& task, Config& conf)
|
std::string handleReportActive (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -1829,7 +1861,6 @@ void handleReportActive (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
filter (tasks, task);
|
filter (tasks, task);
|
||||||
|
@ -1922,19 +1953,23 @@ void handleReportActive (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No active tasks." << std::endl;
|
out << "No active tasks." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportOverdue (TDB& tdb, T& task, Config& conf)
|
std::string handleReportOverdue (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -2029,21 +2064,25 @@ void handleReportOverdue (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No overdue tasks." << std::endl;
|
out << "No overdue tasks." << std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
// line. Tasks that match all the specified criteria are listed.
|
||||||
void handleReportOldest (TDB& tdb, T& task, Config& conf)
|
std::string handleReportOldest (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -2056,7 +2095,6 @@ void handleReportOldest (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
handleRecurrence (tdb, tasks);
|
handleRecurrence (tdb, tasks);
|
||||||
|
@ -2173,22 +2211,26 @@ void handleReportOldest (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Successively apply filters based on the task object built from the command
|
// Successively apply filters based on the task object built from the command
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
// line. Tasks that match all the specified criteria are listed.
|
||||||
void handleReportNewest (TDB& tdb, T& task, Config& conf)
|
std::string handleReportNewest (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Determine window size, and set table accordingly.
|
// Determine window size, and set table accordingly.
|
||||||
int width = conf.get ("defaultwidth", 80);
|
int width = conf.get ("defaultwidth", 80);
|
||||||
#ifdef HAVE_LIBNCURSES
|
#ifdef HAVE_LIBNCURSES
|
||||||
|
@ -2201,7 +2243,6 @@ void handleReportNewest (TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
tdb.gc ();
|
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
handleRecurrence (tdb, tasks);
|
handleRecurrence (tdb, tasks);
|
||||||
|
@ -2319,21 +2360,25 @@ void handleReportNewest (TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.rowCount ())
|
if (table.rowCount ())
|
||||||
std::cout << optionalBlankLine (conf)
|
out << optionalBlankLine (conf)
|
||||||
<< table.render ()
|
<< table.render ()
|
||||||
<< optionalBlankLine (conf)
|
<< optionalBlankLine (conf)
|
||||||
<< table.rowCount ()
|
<< table.rowCount ()
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "No matches."
|
out << "No matches."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportStats (TDB& tdb, T& task, Config& conf)
|
std::string handleReportStats (TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allT (tasks);
|
tdb.allT (tasks);
|
||||||
|
@ -2380,7 +2425,7 @@ void handleReportStats (TDB& tdb, T& task, Config& conf)
|
||||||
if (tags.size ()) ++taggedT;
|
if (tags.size ()) ++taggedT;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Pending " << pendingT << std::endl
|
out << "Pending " << pendingT << std::endl
|
||||||
<< "Recurring " << recurringT << std::endl
|
<< "Recurring " << recurringT << std::endl
|
||||||
<< "Completed " << completedT << std::endl
|
<< "Completed " << completedT << std::endl
|
||||||
<< "Deleted " << deletedT << std::endl
|
<< "Deleted " << deletedT << std::endl
|
||||||
|
@ -2389,31 +2434,33 @@ void handleReportStats (TDB& tdb, T& task, Config& conf)
|
||||||
if (tasks.size ())
|
if (tasks.size ())
|
||||||
{
|
{
|
||||||
Date e (earliest);
|
Date e (earliest);
|
||||||
std::cout << "Oldest task " << e.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
out << "Oldest task " << e.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
||||||
Date l (latest);
|
Date l (latest);
|
||||||
std::cout << "Newest task " << l.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
out << "Newest task " << l.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
|
||||||
std::cout << "Task used for " << formatSeconds (latest - earliest) << std::endl;
|
out << "Task used for " << formatSeconds (latest - earliest) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalT)
|
if (totalT)
|
||||||
std::cout << "Task added every " << formatSeconds ((latest - earliest) / totalT) << std::endl;
|
out << "Task added every " << formatSeconds ((latest - earliest) / totalT) << std::endl;
|
||||||
|
|
||||||
if (completedT)
|
if (completedT)
|
||||||
std::cout << "Task completed every " << formatSeconds ((latest - earliest) / completedT) << std::endl;
|
out << "Task completed every " << formatSeconds ((latest - earliest) / completedT) << std::endl;
|
||||||
|
|
||||||
if (deletedT)
|
if (deletedT)
|
||||||
std::cout << "Task deleted every " << formatSeconds ((latest - earliest) / deletedT) << std::endl;
|
out << "Task deleted every " << formatSeconds ((latest - earliest) / deletedT) << std::endl;
|
||||||
|
|
||||||
if (pendingT || completedT)
|
if (pendingT || completedT)
|
||||||
std::cout << "Average time pending "
|
out << "Average time pending "
|
||||||
<< formatSeconds ((int) ((daysPending / (pendingT + completedT)) * 86400))
|
<< formatSeconds ((int) ((daysPending / (pendingT + completedT)) * 86400))
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
if (totalT)
|
if (totalT)
|
||||||
{
|
{
|
||||||
std::cout << "Average desc length " << (int) (descLength / totalT) << " characters" << std::endl;
|
out << "Average desc length " << (int) (descLength / totalT) << " characters" << std::endl;
|
||||||
std::cout << "Tasks tagged " << std::setprecision (3) << (100.0 * taggedT / totalT) << "%" << std::endl;
|
out << "Tasks tagged " << std::setprecision (3) << (100.0 * taggedT / totalT) << "%" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
113
src/task.cpp
113
src/task.cpp
|
@ -319,18 +319,18 @@ int main (int argc, char** argv)
|
||||||
tdb.onChange (&onChangeCallback);
|
tdb.onChange (&onChangeCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
runTaskCommand (argc, argv, tdb, conf);
|
std::cout << runTaskCommand (argc, argv, tdb, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (std::string& error)
|
catch (std::string& error)
|
||||||
{
|
{
|
||||||
std::cout << error << std::endl;
|
std::cerr << error << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
std::cout << "Unknown error." << std::endl;
|
std::cerr << "Unknown error." << std::endl;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,16 +679,14 @@ void onChangeCallback ()
|
||||||
{
|
{
|
||||||
if (gConf && gTdb)
|
if (gConf && gTdb)
|
||||||
{
|
{
|
||||||
gConf->set ("curses", "off");
|
|
||||||
gConf->set ("color", "off");
|
|
||||||
|
|
||||||
// Determine if shadow file is enabled.
|
// Determine if shadow file is enabled.
|
||||||
std::string shadowFile = expandPath (gConf->get ("shadow.file"));
|
std::string shadowFile = expandPath (gConf->get ("shadow.file"));
|
||||||
if (shadowFile != "")
|
if (shadowFile != "")
|
||||||
{
|
{
|
||||||
// Capture std::cout for the shadow file.
|
std::string oldCurses = gConf->get ("curses");
|
||||||
std::ofstream shadow (shadowFile.c_str ());
|
std::string oldColor = gConf->get ("color");
|
||||||
std::streambuf* original = std::cout.rdbuf (shadow.rdbuf ());
|
gConf->set ("curses", "off");
|
||||||
|
gConf->set ("color", "off");
|
||||||
|
|
||||||
// Run report. Use shadow.command, using default.command as a fallback
|
// Run report. Use shadow.command, using default.command as a fallback
|
||||||
// with "list" as a default.
|
// with "list" as a default.
|
||||||
|
@ -696,13 +694,26 @@ void onChangeCallback ()
|
||||||
gConf->get ("default.command", "list"));
|
gConf->get ("default.command", "list"));
|
||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
split (args, command, ' ');
|
split (args, command, ' ');
|
||||||
runTaskCommand (args, *gTdb, *gConf);
|
std::string result = runTaskCommand (args, *gTdb, *gConf);
|
||||||
|
|
||||||
// Restore std::cout.
|
std::ofstream out (shadowFile.c_str ());
|
||||||
std::cout.rdbuf (original);
|
if (out.good ())
|
||||||
|
{
|
||||||
|
out << result;
|
||||||
|
out.close ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::string ("Could not write to '") + shadowFile + "'.";
|
throw std::string ("Could not write file '") + shadowFile + "'";
|
||||||
|
|
||||||
|
gConf->set ("curses", oldCurses);
|
||||||
|
gConf->set ("color", oldColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("No specified shadow file '") + shadowFile + "'.";
|
||||||
|
|
||||||
|
// Optionally display a notification that the shadow file was updated.
|
||||||
|
if (gConf->get (std::string ("shadow.notify"), false))
|
||||||
|
std::cout << "[Shadow file '" << shadowFile << "' updated]" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::string ("Internal error (TDB/Config).");
|
throw std::string ("Internal error (TDB/Config).");
|
||||||
|
@ -720,24 +731,26 @@ void onChangeCallback ()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void runTaskCommand (
|
std::string runTaskCommand (
|
||||||
int argc,
|
int argc,
|
||||||
char** argv,
|
char** argv,
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf)
|
Config& conf,
|
||||||
|
bool gc /* = true */)
|
||||||
{
|
{
|
||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
args.push_back (argv[i]);
|
args.push_back (argv[i]);
|
||||||
|
|
||||||
runTaskCommand (args, tdb, conf);
|
return runTaskCommand (args, tdb, conf, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void runTaskCommand (
|
std::string runTaskCommand (
|
||||||
std::vector <std::string>& args,
|
std::vector <std::string>& args,
|
||||||
TDB& tdb,
|
TDB& tdb,
|
||||||
Config& conf)
|
Config& conf,
|
||||||
|
bool gc /* = false */)
|
||||||
{
|
{
|
||||||
// If argc == 1 and the default.command configuration variable is set,
|
// If argc == 1 and the default.command configuration variable is set,
|
||||||
// then use that, otherwise stick with argc/argv.
|
// then use that, otherwise stick with argc/argv.
|
||||||
|
@ -754,36 +767,40 @@ void runTaskCommand (
|
||||||
T task;
|
T task;
|
||||||
parse (args, command, task, conf);
|
parse (args, command, task, conf);
|
||||||
|
|
||||||
if (command == "add") handleAdd (tdb, task, conf);
|
std::string out = "";
|
||||||
else if (command == "projects") handleProjects (tdb, task, conf);
|
|
||||||
else if (command == "tags") handleTags (tdb, task, conf);
|
if (command == "" && task.getId ()) { handleModify (tdb, task, conf); }
|
||||||
else if (command == "list") handleList (tdb, task, conf);
|
else if (command == "add") { handleAdd (tdb, task, conf); }
|
||||||
else if (command == "info") handleInfo (tdb, task, conf);
|
else if (command == "done") { handleDone (tdb, task, conf); }
|
||||||
else if (command == "undelete") handleUndelete (tdb, task, conf);
|
else if (command == "export") { handleExport (tdb, task, conf); }
|
||||||
else if (command == "long") handleLongList (tdb, task, conf);
|
else if (command == "projects") { out = handleProjects (tdb, task, conf); }
|
||||||
else if (command == "ls") handleSmallList (tdb, task, conf);
|
else if (command == "tags") { out = handleTags (tdb, task, conf); }
|
||||||
else if (command == "colors") handleColor ( conf);
|
else if (command == "info") { out = handleInfo (tdb, task, conf); }
|
||||||
else if (command == "completed") handleCompleted (tdb, task, conf);
|
else if (command == "undelete") { out = handleUndelete (tdb, task, conf); }
|
||||||
else if (command == "delete") handleDelete (tdb, task, conf);
|
else if (command == "delete") { out = handleDelete (tdb, task, conf); }
|
||||||
else if (command == "start") handleStart (tdb, task, conf);
|
else if (command == "start") { out = handleStart (tdb, task, conf); }
|
||||||
else if (command == "stop") handleStop (tdb, task, conf);
|
else if (command == "stop") { out = handleStop (tdb, task, conf); }
|
||||||
else if (command == "done") handleDone (tdb, task, conf);
|
else if (command == "undo") { out = handleUndo (tdb, task, conf); }
|
||||||
else if (command == "undo") handleUndo (tdb, task, conf);
|
else if (command == "stats") { out = handleReportStats (tdb, task, conf); }
|
||||||
else if (command == "export") handleExport (tdb, task, conf);
|
else if (command == "list") { if (gc) tdb.gc (); out = handleList (tdb, task, conf); }
|
||||||
else if (command == "version") handleVersion ( conf);
|
else if (command == "long") { if (gc) tdb.gc (); out = handleLongList (tdb, task, conf); }
|
||||||
else if (command == "summary") handleReportSummary (tdb, task, conf);
|
else if (command == "ls") { if (gc) tdb.gc (); out = handleSmallList (tdb, task, conf); }
|
||||||
else if (command == "next") handleReportNext (tdb, task, conf);
|
else if (command == "completed") { if (gc) tdb.gc (); out = handleCompleted (tdb, task, conf); }
|
||||||
else if (command == "history") handleReportHistory (tdb, task, conf);
|
else if (command == "summary") { if (gc) tdb.gc (); out = handleReportSummary (tdb, task, conf); }
|
||||||
else if (command == "ghistory") handleReportGHistory (tdb, task, conf);
|
else if (command == "next") { if (gc) tdb.gc (); out = handleReportNext (tdb, task, conf); }
|
||||||
else if (command == "calendar") handleReportCalendar (tdb, task, conf);
|
else if (command == "history") { if (gc) tdb.gc (); out = handleReportHistory (tdb, task, conf); }
|
||||||
else if (command == "active") handleReportActive (tdb, task, conf);
|
else if (command == "ghistory") { if (gc) tdb.gc (); out = handleReportGHistory (tdb, task, conf); }
|
||||||
else if (command == "overdue") handleReportOverdue (tdb, task, conf);
|
else if (command == "calendar") { if (gc) tdb.gc (); out = handleReportCalendar (tdb, task, conf); }
|
||||||
else if (command == "oldest") handleReportOldest (tdb, task, conf);
|
else if (command == "active") { if (gc) tdb.gc (); out = handleReportActive (tdb, task, conf); }
|
||||||
else if (command == "newest") handleReportNewest (tdb, task, conf);
|
else if (command == "overdue") { if (gc) tdb.gc (); out = handleReportOverdue (tdb, task, conf); }
|
||||||
else if (command == "stats") handleReportStats (tdb, task, conf);
|
else if (command == "oldest") { if (gc) tdb.gc (); out = handleReportOldest (tdb, task, conf); }
|
||||||
else if (command == "" && task.getId ()) handleModify (tdb, task, conf);
|
else if (command == "newest") { if (gc) tdb.gc (); out = handleReportNewest (tdb, task, conf); }
|
||||||
else if (command == "help") longUsage (conf);
|
else if (command == "colors") { out = handleColor ( conf); }
|
||||||
else shortUsage (conf);
|
else if (command == "version") { out = handleVersion ( conf); }
|
||||||
|
else if (command == "help") { longUsage ( conf); }
|
||||||
|
else { shortUsage ( conf); }
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
52
src/task.h
52
src/task.h
|
@ -67,41 +67,41 @@ bool generateDueDates (T&, std::vector <Date>&);
|
||||||
Date getNextRecurrence (Date&, std::string&);
|
Date getNextRecurrence (Date&, std::string&);
|
||||||
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
|
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
|
||||||
void onChangeCallback ();
|
void onChangeCallback ();
|
||||||
void runTaskCommand (int, char**, TDB&, Config&);
|
std::string runTaskCommand (int, char**, TDB&, Config&, bool gc = true);
|
||||||
void runTaskCommand (std::vector <std::string>&, TDB&, Config&);
|
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&, bool gc = false);
|
||||||
|
|
||||||
// command.cpp
|
// command.cpp
|
||||||
void handleAdd (TDB&, T&, Config&);
|
void handleAdd (TDB&, T&, Config&);
|
||||||
void handleProjects (TDB&, T&, Config&);
|
|
||||||
void handleTags (TDB&, T&, Config&);
|
|
||||||
void handleUndelete (TDB&, T&, Config&);
|
|
||||||
void handleVersion (Config&);
|
|
||||||
void handleExport (TDB&, T&, Config&);
|
void handleExport (TDB&, T&, Config&);
|
||||||
void handleDelete (TDB&, T&, Config&);
|
|
||||||
void handleStart (TDB&, T&, Config&);
|
|
||||||
void handleStop (TDB&, T&, Config&);
|
|
||||||
void handleDone (TDB&, T&, Config&);
|
void handleDone (TDB&, T&, Config&);
|
||||||
void handleUndo (TDB&, T&, Config&);
|
|
||||||
void handleModify (TDB&, T&, Config&);
|
void handleModify (TDB&, T&, Config&);
|
||||||
void handleColor (Config&);
|
std::string handleProjects (TDB&, T&, Config&);
|
||||||
|
std::string handleTags (TDB&, T&, Config&);
|
||||||
|
std::string handleUndelete (TDB&, T&, Config&);
|
||||||
|
std::string handleVersion (Config&);
|
||||||
|
std::string handleDelete (TDB&, T&, Config&);
|
||||||
|
std::string handleStart (TDB&, T&, Config&);
|
||||||
|
std::string handleStop (TDB&, T&, Config&);
|
||||||
|
std::string handleUndo (TDB&, T&, Config&);
|
||||||
|
std::string handleColor (Config&);
|
||||||
|
|
||||||
// report.cpp
|
// report.cpp
|
||||||
void filter (std::vector<T>&, T&);
|
void filter (std::vector<T>&, T&);
|
||||||
void handleList (TDB&, T&, Config&);
|
std::string handleList (TDB&, T&, Config&);
|
||||||
void handleInfo (TDB&, T&, Config&);
|
std::string handleInfo (TDB&, T&, Config&);
|
||||||
void handleLongList (TDB&, T&, Config&);
|
std::string handleLongList (TDB&, T&, Config&);
|
||||||
void handleSmallList (TDB&, T&, Config&);
|
std::string handleSmallList (TDB&, T&, Config&);
|
||||||
void handleCompleted (TDB&, T&, Config&);
|
std::string handleCompleted (TDB&, T&, Config&);
|
||||||
void handleReportSummary (TDB&, T&, Config&);
|
std::string handleReportSummary (TDB&, T&, Config&);
|
||||||
void handleReportNext (TDB&, T&, Config&);
|
std::string handleReportNext (TDB&, T&, Config&);
|
||||||
void handleReportHistory (TDB&, T&, Config&);
|
std::string handleReportHistory (TDB&, T&, Config&);
|
||||||
void handleReportGHistory (TDB&, T&, Config&);
|
std::string handleReportGHistory (TDB&, T&, Config&);
|
||||||
void handleReportCalendar (TDB&, T&, Config&);
|
std::string handleReportCalendar (TDB&, T&, Config&);
|
||||||
void handleReportActive (TDB&, T&, Config&);
|
std::string handleReportActive (TDB&, T&, Config&);
|
||||||
void handleReportOverdue (TDB&, T&, Config&);
|
std::string handleReportOverdue (TDB&, T&, Config&);
|
||||||
void handleReportStats (TDB&, T&, Config&);
|
std::string handleReportStats (TDB&, T&, Config&);
|
||||||
void handleReportOldest (TDB&, T&, Config&);
|
std::string handleReportOldest (TDB&, T&, Config&);
|
||||||
void handleReportNewest (TDB&, T&, Config&);
|
std::string handleReportNewest (TDB&, T&, Config&);
|
||||||
|
|
||||||
// util.cpp
|
// util.cpp
|
||||||
bool confirm (const std::string&);
|
bool confirm (const std::string&);
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
./task li due:monday
|
|
||||||
./task li due:tuesday
|
|
||||||
./task li due:wednesday
|
|
||||||
./task li due:thursday
|
|
||||||
./task li due:friday
|
|
||||||
./task li due:saturday
|
|
||||||
./task li due:sunday
|
|
||||||
./task li due:yesterday
|
|
||||||
./task li due:today
|
|
||||||
./task li due:tomorrow
|
|
||||||
./task li due:eow
|
|
||||||
./task li due:eom
|
|
||||||
./task li due:eoy
|
|
||||||
./task li due:21st
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue