Merge branch '1.4.3' into 1.5.0

Conflicts:
	NEWS
	TUTORIAL
	configure.ac
	html/advanced.html
	html/task.html
	html/versions.html
	src/task.cpp
This commit is contained in:
Paul Beckingham 2008-10-09 21:03:29 -04:00
commit 437c85da39
23 changed files with 434 additions and 92 deletions

View file

@ -17,4 +17,5 @@ With thanks to:
Stas Antons
Vincent Fleuranceau
T. Charles Yun
ArchiMark

View file

@ -8,6 +8,15 @@
------ old releases ------------------------------
1.4.3 (10/9/2008)
+ Fixed misleading task count at bottom on "info" report.
+ 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".
------ old releases ------------------------------
1.4.2 (9/18/2008)
+ "task undo" can now retract a "task done" command, provided no reports
have been run (and therefore TDB::gc run)

6
TUTORIAL Normal file
View file

@ -0,0 +1,6 @@
This TUTORIAL file has been deprecated. It is superseded by a richer and more
extensive online version that can be found at:
http://www.beckingham.net/task.html

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>30-Second Tutorial</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Advanced Usage</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Color Usage</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Task Configuration</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>
@ -279,6 +279,42 @@ ID Project Pri Description
preceding "task" program name.
</p>
</dd>
<dt>shadow.file</dt>
<dd>
<p>
If specified, designates a file path that will be autoamtically
written to by task, whenever the task database changes. In other
words, it is automatically kept up to date.
</p>
<p>
The shadow.command configuration variable is used to determine
which report is written to the shadow file. There is no color
used in the shadow file.
</p>
<p>
This feature can be useful in maintaining a current file for
use by the "Samurize" program.
</p>
</dd>
<dt>shadow.command</dt>
<dd>
<p>
This is the command that is run to maintain the shadow file,
determined by the shadow.file configuration variable. The
format is identical to that of default.command - please see
the documentation for default.command.
</p>
<p>
If this command is not specified, task will use the default.command
value instead. If that is not specified, the command "list" is used.
</p>
</dd>
</div>
<br />

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Date Handling</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

93
html/filter.html Normal file
View file

@ -0,0 +1,93 @@
<!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 Filters</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>
</div>
<div id="content">
<br />
<br />
<br />
<h2 class="title">Task Filters</h2>
<div class="content">
<p>
</p>
</div>
<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>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Recurring Tasks</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Task Setup</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

93
html/shadow.html Normal file
View file

@ -0,0 +1,93 @@
<!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 Shadow Files</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>
</div>
<div id="content">
<br />
<br />
<br />
<h2 class="title">Task Shadow Files</h2>
<div class="content">
<p>
</p>
</div>
<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>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Interacting with the Shell</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Simple Usage</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -1,7 +1,7 @@
<!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 1.5.0</title>
<title>Latest Release</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>
@ -54,8 +54,8 @@
<li><a href="date.html">Date Handling</a>
<li><a href="troubleshooting.html">Troubleshooting</a>
<li><a href="versions.html">Old Versions</a>
<li>Filters (coming soon)
<li><a href="filter.html">Filters (coming soon)</a>
<li><a href="shadow.html">Shadow Files (coming soon)</a>
</ul>
<p>

View file

@ -1,7 +1,7 @@
<!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 1.4.1</title>
<title>Task Usage</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="task.css" type="text/css" />
</head>

View file

@ -38,6 +38,12 @@
<p>
<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>
<br />
Mac OS X 10.5 (Leopard) Intel-only:
<a href="http://www.beckingham.net/task-1.4.2.pkg">task-1.4.2.pkg</a>
<br />
Debian package: <a href="http://www.beckingham.net/task_1.4.2-1_i386.deb">task_1.4.2-1_i386.deb</a>
(Thanks to <a href="http://blog.rfquerin.org">Richard Querin</a>)
</p>
<ul>

View file

@ -204,7 +204,9 @@ bool TDB::deleteT (const T& t)
sprintf (endTime, "%u", (unsigned int) time (NULL));
it->setAttribute ("end", endTime);
return overwritePending (all);
bool status = overwritePending (all);
dbChanged ();
return status;
}
return false;
@ -228,14 +230,16 @@ bool TDB::completeT (const T& t)
sprintf (endTime, "%u", (unsigned int) time (NULL));
it->setAttribute ("end", endTime);
return overwritePending (all);
bool status = overwritePending (all);
dbChanged ();
return status;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool TDB::addT (const T& t) const
bool TDB::addT (const T& t)
{
T task (t);
std::vector <std::string> tags;
@ -254,9 +258,15 @@ bool TDB::addT (const T& t) const
if (task.getStatus () == T::pending ||
task.getStatus () == T::recurring)
return writePending (task);
{
bool status = writePending (task);
dbChanged ();
return status;
}
return writeCompleted (task);
bool status = writeCompleted (task);
dbChanged ();
return status;
}
////////////////////////////////////////////////////////////////////////////////
@ -281,7 +291,9 @@ bool TDB::modifyT (const T& t)
pending.push_back (*it);
}
return overwritePending (pending);
bool status = overwritePending (pending);
dbChanged ();
return status;
}
////////////////////////////////////////////////////////////////////////////////
@ -439,4 +451,20 @@ int TDB::nextId ()
}
////////////////////////////////////////////////////////////////////////////////
void TDB::onChange (void (*callback)())
{
if (callback)
mOnChange.push_back (callback);
}
////////////////////////////////////////////////////////////////////////////////
// Iterate over callbacks.
void TDB::dbChanged ()
{
foreach (i, mOnChange)
if (*i)
(**i) ();
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -45,23 +45,27 @@ public:
bool allCompletedT (std::vector <T>&) const;
bool deleteT (const T&);
bool completeT (const T&);
bool addT (const T&) const;
bool addT (const T&);
bool modifyT (const T&);
bool logRead (std::vector <std::string>&) const;
int gc ();
int nextId ();
void onChange (void (*)());
private:
bool lock (FILE*) const;
bool overwritePending (std::vector <T>&);
bool writePending (const T&) const;
bool writeCompleted (const T&) const;
bool readLockedFile (const std::string&, std::vector <std::string>&) const;
void dbChanged ();
private:
std::string mPendingFile;
std::string mCompletedFile;
int mId;
std::vector <void (*)()> mOnChange;
};
#endif

View file

@ -47,7 +47,7 @@
#endif
////////////////////////////////////////////////////////////////////////////////
void handleAdd (const TDB& tdb, T& task, Config& conf)
void handleAdd (TDB& tdb, T& task, Config& conf)
{
char entryTime[16];
sprintf (entryTime, "%u", (unsigned int) time (NULL));

View file

@ -659,9 +659,6 @@ void handleInfo (TDB& tdb, T& task, Config& conf)
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches." << std::endl;

View file

@ -46,6 +46,11 @@
#include <ncurses.h>
#endif
////////////////////////////////////////////////////////////////////////////////
// Globals for exclusive use by callback function.
static TDB* gTdb = NULL;
static Config* gConf = NULL;
////////////////////////////////////////////////////////////////////////////////
static void shortUsage (Config& conf)
{
@ -280,6 +285,7 @@ int main (int argc, char** argv)
// Load the config file from the home directory. If the file cannot be
// found, offer to create a sample one.
Config conf;
gConf = &conf;
loadConfFile (argc, argv, conf);
// When redirecting output to a file, do not use color, curses.
@ -290,58 +296,13 @@ int main (int argc, char** argv)
}
TDB tdb;
gTdb = &tdb;
tdb.dataDirectory (expandPath (conf.get ("data.location")));
// If argc == 1 and the default.command configuration variable is set,
// then use that, otherwise stick with argc/argv.
std::vector <std::string> args;
std::string defaultCommand = conf.get ("default.command");
if (argc == 1 && defaultCommand != "")
{
// Stuff the command line.
split (args, defaultCommand, ' ');
std::cout << "[task " << defaultCommand << "]" << std::endl;
}
else
{
// Parse the command line.
for (int i = 1; i < argc; ++i)
args.push_back (argv[i]);
}
// Set up TDB callback.
tdb.onChange (&onChangeCallback);
std::string command;
T task;
parse (args, command, task, conf);
if (command == "add") handleAdd (tdb, task, conf);
else if (command == "projects") handleProjects (tdb, task, conf);
else if (command == "tags") handleTags (tdb, task, conf);
else if (command == "list") handleList (tdb, task, conf);
else if (command == "info") handleInfo (tdb, task, conf);
else if (command == "undelete") handleUndelete (tdb, task, conf);
else if (command == "long") handleLongList (tdb, task, conf);
else if (command == "ls") handleSmallList (tdb, task, conf);
else if (command == "colors") handleColor ( conf);
else if (command == "completed") handleCompleted (tdb, task, conf);
else if (command == "delete") handleDelete (tdb, task, conf);
else if (command == "start") handleStart (tdb, task, conf);
else if (command == "done") handleDone (tdb, task, conf);
else if (command == "undo") handleUndo (tdb, task, conf);
else if (command == "export") handleExport (tdb, task, conf);
else if (command == "version") handleVersion ( conf);
else if (command == "summary") handleReportSummary (tdb, task, conf);
else if (command == "next") handleReportNext (tdb, task, conf);
else if (command == "history") handleReportHistory (tdb, task, conf);
else if (command == "ghistory") handleReportGHistory (tdb, task, conf);
else if (command == "calendar") handleReportCalendar (tdb, task, conf);
else if (command == "active") handleReportActive (tdb, task, conf);
else if (command == "overdue") handleReportOverdue (tdb, task, conf);
else if (command == "oldest") handleReportOldest (tdb, task, conf);
else if (command == "newest") handleReportNewest (tdb, task, conf);
else if (command == "stats") handleReportStats (tdb, task, conf);
else if (command == "" && task.getId ()) handleModify (tdb, task, conf);
else if (command == "help") longUsage (conf);
else shortUsage (conf);
runTaskCommand (argc, argv, tdb, conf);
}
catch (std::string& error)
@ -391,12 +352,18 @@ int getDueState (const std::string& due)
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
Date now;
if (dt < now)
// rightNow is the current date + time.
Date rightNow;
// By performing this conversion, today is set up as the same date, but
// midnight.
Date today (rightNow.month (), rightNow.day (), rightNow.year ());
if (dt < today)
return 2;
Date nextweek = now + 7 * 86400;
Date nextweek = today + 7 * 86400;
if (dt < nextweek)
return 1;
}
@ -544,7 +511,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -563,7 +529,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -579,7 +544,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -598,7 +562,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -614,7 +577,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -630,7 +592,6 @@ Date getNextRecurrence (Date& current, std::string& period)
while (! Date::valid (m, d, y))
--d;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -639,7 +600,6 @@ Date getNextRecurrence (Date& current, std::string& period)
{
y += 2;
// std::cout << "# next " << current.toString () << " + " << period << " = " << m << "/" << d << "/" << y << std::endl;
return Date (m, d, y);
}
@ -657,7 +617,6 @@ void updateRecurrenceMask (
T& task)
{
std::string parent = task.getAttribute ("parent");
// std::cout << "# updateRecurrenceMask of " << parent << std::endl;
if (parent != "")
{
std::vector <T>::iterator it;
@ -665,11 +624,8 @@ void updateRecurrenceMask (
{
if (it->getUUID () == parent)
{
// std::cout << "# located parent task" << std::endl;
unsigned int index = atoi (task.getAttribute ("imask").c_str ());
// std::cout << "# child imask=" << index << std::endl;
std::string mask = it->getAttribute ("mask");
// std::cout << "# parent mask=" << mask << std::endl;
if (mask.length () > index)
{
mask[index] = (task.getStatus () == T::pending) ? '-'
@ -677,15 +633,11 @@ void updateRecurrenceMask (
: (task.getStatus () == T::deleted) ? 'X'
: '?';
// std::cout << "# setting parent mask to=" << mask << std::endl;
it->setAttribute ("mask", mask);
// std::cout << "# tdb.modifyT (parent)" << std::endl;
tdb.modifyT (*it);
}
else
{
// std::cout << "# mask of insufficient length" << std::endl;
// std::cout << "# should never occur" << std::endl;
std::string mask;
for (unsigned int i = 0; i < index; ++i)
mask += "?";
@ -703,3 +655,117 @@ void updateRecurrenceMask (
}
////////////////////////////////////////////////////////////////////////////////
// Using gTdb and gConf, generate a report.
void onChangeCallback ()
{
try
{
if (gConf && gTdb)
{
gConf->set ("curses", "off");
gConf->set ("color", "off");
// Determine if shadow file is enabled.
std::string shadowFile = expandPath (gConf->get ("shadow.file"));
if (shadowFile != "")
{
// Capture std::cout for the shadow file.
std::ofstream shadow (shadowFile.c_str ());
std::streambuf* original = std::cout.rdbuf (shadow.rdbuf ());
// Run report. Use shadow.command, using default.command as a fallback
// with "list" as a default.
std::string command = gConf->get ("shadow.command",
gConf->get ("default.command", "list"));
std::vector <std::string> args;
split (args, command, ' ');
runTaskCommand (args, *gTdb, *gConf);
// Restore std::cout.
std::cout.rdbuf (original);
}
else
throw std::string ("Could not write to '") + shadowFile + "'.";
}
else
throw std::string ("Internal error (TDB/Config).");
}
catch (std::string& error)
{
std::cout << error << std::endl;
}
catch (...)
{
std::cout << "Unknown error." << std::endl;
}
}
////////////////////////////////////////////////////////////////////////////////
void runTaskCommand (
int argc,
char** argv,
TDB& tdb,
Config& conf)
{
std::vector <std::string> args;
for (int i = 1; i < argc; ++i)
args.push_back (argv[i]);
runTaskCommand (args, tdb, conf);
}
////////////////////////////////////////////////////////////////////////////////
void runTaskCommand (
std::vector <std::string>& args,
TDB& tdb,
Config& conf)
{
// If argc == 1 and the default.command configuration variable is set,
// then use that, otherwise stick with argc/argv.
std::string defaultCommand = conf.get ("default.command");
if (args.size () == 0 && defaultCommand != "")
{
// Stuff the command line.
args.clear ();
split (args, defaultCommand, ' ');
std::cout << "[task " << defaultCommand << "]" << std::endl;
}
std::string command;
T task;
parse (args, command, task, conf);
if (command == "add") handleAdd (tdb, task, conf);
else if (command == "projects") handleProjects (tdb, task, conf);
else if (command == "tags") handleTags (tdb, task, conf);
else if (command == "list") handleList (tdb, task, conf);
else if (command == "info") handleInfo (tdb, task, conf);
else if (command == "undelete") handleUndelete (tdb, task, conf);
else if (command == "long") handleLongList (tdb, task, conf);
else if (command == "ls") handleSmallList (tdb, task, conf);
else if (command == "colors") handleColor ( conf);
else if (command == "completed") handleCompleted (tdb, task, conf);
else if (command == "delete") handleDelete (tdb, task, conf);
else if (command == "start") handleStart (tdb, task, conf);
else if (command == "done") handleDone (tdb, task, conf);
else if (command == "undo") handleUndo (tdb, task, conf);
else if (command == "export") handleExport (tdb, task, conf);
else if (command == "version") handleVersion ( conf);
else if (command == "summary") handleReportSummary (tdb, task, conf);
else if (command == "next") handleReportNext (tdb, task, conf);
else if (command == "history") handleReportHistory (tdb, task, conf);
else if (command == "ghistory") handleReportGHistory (tdb, task, conf);
else if (command == "calendar") handleReportCalendar (tdb, task, conf);
else if (command == "active") handleReportActive (tdb, task, conf);
else if (command == "overdue") handleReportOverdue (tdb, task, conf);
else if (command == "oldest") handleReportOldest (tdb, task, conf);
else if (command == "newest") handleReportNewest (tdb, task, conf);
else if (command == "stats") handleReportStats (tdb, task, conf);
else if (command == "" && task.getId ()) handleModify (tdb, task, conf);
else if (command == "help") longUsage (conf);
else shortUsage (conf);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -66,9 +66,12 @@ void handleRecurrence (TDB&, std::vector <T>&);
bool generateDueDates (T&, std::vector <Date>&);
Date getNextRecurrence (Date&, std::string&);
void updateRecurrenceMask (TDB&, std::vector <T>&, T&);
void onChangeCallback ();
void runTaskCommand (int, char**, TDB&, Config&);
void runTaskCommand (std::vector <std::string>&, TDB&, Config&);
// command.cpp
void handleAdd (const TDB&, T&, Config&);
void handleAdd (TDB&, T&, Config&);
void handleProjects (TDB&, T&, Config&);
void handleTags (TDB&, T&, Config&);
void handleUndelete (TDB&, T&, Config&);