- Converted reports/command to return strings

This commit is contained in:
Paul Beckingham 2008-10-23 00:44:21 -04:00
parent ce561a6c43
commit b176591261
7 changed files with 466 additions and 368 deletions

View file

@ -19,7 +19,7 @@ AC_CHECK_LIB(ncurses,endwin)
# Checks for header files.
AC_HEADER_STDC
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.
AC_HEADER_STDBOOL

View file

@ -206,9 +206,7 @@ bool TDB::deleteT (const T& t)
sprintf (endTime, "%u", (unsigned int) time (NULL));
it->setAttribute ("end", endTime);
bool status = overwritePending (all);
dbChanged ();
return status;
return overwritePending (all);
}
return false;
@ -232,9 +230,7 @@ bool TDB::completeT (const T& t)
sprintf (endTime, "%u", (unsigned int) time (NULL));
it->setAttribute ("end", endTime);
bool status = overwritePending (all);
dbChanged ();
return status;
return overwritePending (all);
}
return false;
@ -261,14 +257,10 @@ bool TDB::addT (const T& t)
if (task.getStatus () == T::pending ||
task.getStatus () == T::recurring)
{
bool status = writePending (task);
dbChanged ();
return status;
return writePending (task);
}
bool status = writeCompleted (task);
dbChanged ();
return status;
return writeCompleted (task);
}
////////////////////////////////////////////////////////////////////////////////
@ -293,9 +285,7 @@ bool TDB::modifyT (const T& t)
pending.push_back (*it);
}
bool status = overwritePending (pending);
dbChanged ();
return status;
return overwritePending (pending);
}
////////////////////////////////////////////////////////////////////////////////
@ -378,6 +368,7 @@ bool TDB::overwritePending (std::vector <T>& all)
fputs (it->compose ().c_str (), out);
fclose (out);
dbChanged ();
return true;
}
@ -385,7 +376,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
FILE* out;
@ -400,6 +391,7 @@ bool TDB::writePending (const T& t) const
fputs (t.compose ().c_str (), out);
fclose (out);
dbChanged ();
return true;
}
@ -407,7 +399,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
FILE* out;
@ -422,6 +414,7 @@ bool TDB::writeCompleted (const T& t) const
fputs (t.compose ().c_str (), out);
fclose (out);
dbChanged ();
return true;
}

View file

@ -57,8 +57,8 @@ public:
private:
bool lock (FILE*) const;
bool overwritePending (std::vector <T>&);
bool writePending (const T&) const;
bool writeCompleted (const T&) const;
bool writePending (const T&);
bool writeCompleted (const T&);
bool readLockedFile (const std::string&, std::vector <std::string>&) const;
void dbChanged ();

View file

@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <stdio.h>
@ -67,7 +68,6 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
task.setAttribute ("mask", "");
}
/**/
// Override with default.project, if not specified.
if (task.getAttribute ("project") == "")
task.setAttribute ("project", conf.get ("default.project", ""));
@ -79,8 +79,8 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
if (validPriority (defaultPriority))
task.setAttribute ("priority", defaultPriority);
}
/**/
// Disallow blank descriptions.
if (task.getDescription () == "")
throw std::string ("Cannot add a blank task.");
@ -89,8 +89,10 @@ void handleAdd (TDB& tdb, T& task, Config& conf)
}
////////////////////////////////////////////////////////////////////////////////
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.
std::vector <T> tasks;
tdb.pendingT (tasks);
@ -127,7 +129,7 @@ void handleProjects (TDB& tdb, T& task, Config& conf)
table.addCell (row, 1, i->second);
}
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< unique.size ()
@ -135,13 +137,17 @@ void handleProjects (TDB& tdb, T& task, Config& conf)
<< std::endl;
}
else
std::cout << "No projects."
out << "No projects."
<< 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.
std::vector <T> tasks;
tdb.pendingT (tasks);
@ -166,20 +172,23 @@ void handleTags (TDB& tdb, T& task, Config& conf)
std::cout << i->first << std::endl;
if (unique.size ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< unique.size ()
<< (unique.size () == 1 ? " tag" : " tags")
<< std::endl;
else
std::cout << "No tags."
out << "No tags."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// If a task is deleted, but is still in the pending file, then it may be
// 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;
tdb.allPendingT (all);
@ -193,8 +202,8 @@ void handleUndelete (TDB& tdb, T& task, Config& conf)
{
if (it->getAttribute ("recur") != "")
{
std::cout << "Task does not support 'undelete' for recurring tasks." << std::endl;
return;
out << "Task does not support 'undelete' for recurring tasks." << std::endl;
return out.str ();
}
T restored (*it);
@ -202,27 +211,31 @@ void handleUndelete (TDB& tdb, T& task, Config& conf)
restored.removeAttribute ("end");
tdb.modifyT (restored);
std::cout << "Task " << id << " successfully undeleted." << std::endl;
return;
out << "Task " << id << " successfully undeleted." << std::endl;
return out.str ();
}
else
{
std::cout << "Task " << id << " is not deleted - therefore cannot undelete." << std::endl;
return;
out << "Task " << id << " is not deleted - therefore cannot undelete." << std::endl;
return out.str ();
}
}
}
std::cout << "Task " << id
out << "Task " << id
<< " not found - tasks can only be reliably undeleted if the undelete" << 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
// 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;
tdb.allPendingT (all);
@ -235,35 +248,36 @@ void handleUndo (TDB& tdb, T& task, Config& conf)
if (it->getStatus () == T::completed)
{
if (it->getAttribute ("recur") != "")
{
std::cout << "Task does not support 'undo' for recurring tasks." << std::endl;
return;
}
return std::string ("Task does not support 'undo' for recurring tasks.\n");
T restored (*it);
restored.setStatus (T::pending);
restored.removeAttribute ("end");
tdb.modifyT (restored);
std::cout << "Task " << id << " successfully undone." << std::endl;
return;
out << "Task " << id << " successfully undone." << std::endl;
return out.str ();
}
else
{
std::cout << "Task " << id << " is not done - therefore cannot be undone." << std::endl;
return;
out << "Task " << id << " is not done - therefore cannot be undone." << std::endl;
return out.str ();
}
}
}
std::cout << "Task " << id
out << "Task " << id
<< " not found - tasks can only be reliably undone if the undo" << 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.
int width = conf.get ("defaultwidth", 80);
#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
<< (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.
if (all.size () == 0)
std::cout << "Configuration error: .taskrc contains no entries"
out << "Configuration error: .taskrc contains no entries"
<< std::endl;
else
{
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."
<< std::endl;
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."
<< 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?"))
{
@ -386,7 +402,7 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
sibling->getUUID () == parent)
tdb.deleteT (*sibling);
return;
return std::string ("");
}
else
{
@ -394,7 +410,7 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
t->setStatus (T::deleted);
updateRecurrenceMask (tdb, all, *t);
tdb.deleteT (*t);
return;
return std::string ("");
}
}
else
@ -405,11 +421,13 @@ void handleDelete (TDB& tdb, T& task, Config& conf)
}
}
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;
tdb.pendingT (all);
@ -431,14 +449,19 @@ void handleStart (TDB& tdb, T& task, Config& conf)
tdb.modifyT (original);
nag (tdb, task, conf);
return;
return std::string ("");
}
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.");
return std::string (""); // To satisfy gcc.
}
////////////////////////////////////////////////////////////////////////////////
@ -597,11 +620,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))
{
std::cout << optionalBlankLine (conf) << "Foreground" << std::endl
out << optionalBlankLine (conf) << "Foreground" << std::endl
<< " "
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
@ -676,8 +701,10 @@ void handleColor (Config& conf)
}
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 ();
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -26,6 +26,7 @@
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <sys/types.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
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -242,23 +245,27 @@ void handleList (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// 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
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -371,22 +378,26 @@ void handleSmallList (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// Successively apply filters based on the task object built from the command
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -459,21 +470,25 @@ void handleCompleted (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -657,18 +672,22 @@ void handleInfo (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< std::endl;
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
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -824,22 +843,26 @@ void handleLongList (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches." << std::endl;
out << "No matches." << std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// Project Tasks Avg Age Status
// A 12 13d XXXXXXXX------
// 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.
tdb.gc ();
std::map <std::string, bool> allProjects;
@ -981,14 +1004,16 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " project" : " projects")
<< std::endl;
else
std::cout << "No projects." << std::endl;
out << "No projects." << std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@ -1010,8 +1035,10 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
//
// 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.
tdb.gc ();
std::vector <T> pending;
@ -1151,15 +1178,17 @@ void handleReportNext (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@ -1184,8 +1213,10 @@ time_t monthlyEpoch (const std::string& date)
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> addedGroup;
std::map <time_t, int> completedGroup;
@ -1360,16 +1391,20 @@ void handleReportHistory (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< std::endl;
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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -1571,12 +1606,12 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
if (table.rowCount ())
{
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< std::endl;
if (conf.get ("color", true))
std::cout << "Legend: "
out << "Legend: "
<< Text::colorize (Text::black, Text::on_red, "added")
<< ", "
<< Text::colorize (Text::black, Text::on_green, "completed")
@ -1585,10 +1620,12 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
<< optionalBlankLine (conf)
<< std::endl;
else
std::cout << "Legend: + added, X completed, - deleted" << std::endl;
out << "Legend: + added, X completed, - deleted" << std::endl;
}
else
std::cout << "No tasks." << std::endl;
out << "No tasks." << std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@ -1597,8 +1634,10 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
//
// 2006-12-04 19:59:43 "task list"
//
void handleReportUsage (const TDB& tdb, T& task, Config& conf)
std::string handleReportUsage (const TDB& tdb, T& task, Config& conf)
{
std::stringstream out;
if (conf.get ("command.logging") == "on")
{
std::map <std::string, int> usage;
@ -1655,15 +1694,17 @@ void handleReportUsage (const TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< std::endl;
else
std::cout << "No usage." << std::endl;
out << "No usage." << std::endl;
}
else
std::cout << "Command logging is not enabled, so no history has been kept."
out << "Command logging is not enabled, so no history has been kept."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
@ -1791,8 +1832,10 @@ 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.
tdb.gc ();
std::vector <T> pending;
@ -1823,7 +1866,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
int mTo = newest.month ();
int yTo = newest.year ();
std::cout << std::endl;
out << std::endl;
std::string output;
int monthsPerLine = (conf.get ("monthsperline", 1));
@ -1840,7 +1883,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
int left = (18 - month.length ()) / 2 + 1;
int right = 18 - left - month.length ();
std::cout << std::setw (left) << ' '
out << std::setw (left) << ' '
<< month
<< ' '
<< nextY
@ -1853,7 +1896,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
}
}
std::cout << std::endl
out << std::endl
<< optionalBlankLine (conf)
<< renderMonths (mFrom, yFrom, today, pending, conf)
<< std::endl;
@ -1866,7 +1909,7 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
}
}
std::cout << "Legend: "
out << "Legend: "
<< Text::colorize (Text::cyan, Text::nocolor, "today")
<< ", "
<< Text::colorize (Text::black, Text::on_yellow, "due")
@ -1875,11 +1918,15 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
<< "."
<< optionalBlankLine (conf)
<< 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -1985,19 +2032,23 @@ void handleReportActive (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -2092,21 +2143,25 @@ void handleReportOverdue (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
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
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -2236,22 +2291,26 @@ void handleReportOldest (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< std::endl;
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
// Successively apply filters based on the task object built from the command
// 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.
int width = conf.get ("defaultwidth", 80);
#ifdef HAVE_LIBNCURSES
@ -2382,21 +2441,25 @@ void handleReportNewest (TDB& tdb, T& task, Config& conf)
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
out << optionalBlankLine (conf)
<< table.render ()
<< optionalBlankLine (conf)
<< table.rowCount ()
<< (table.rowCount () == 1 ? " task" : " tasks")
<< std::endl;
else
std::cout << "No matches."
out << "No matches."
<< 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.
std::vector <T> tasks;
tdb.allT (tasks);
@ -2443,7 +2506,7 @@ void handleReportStats (TDB& tdb, T& task, Config& conf)
if (tags.size ()) ++taggedT;
}
std::cout << "Pending " << pendingT << std::endl
out << "Pending " << pendingT << std::endl
<< "Recurring " << recurringT << std::endl
<< "Completed " << completedT << std::endl
<< "Deleted " << deletedT << std::endl
@ -2452,31 +2515,33 @@ void handleReportStats (TDB& tdb, T& task, Config& conf)
if (tasks.size ())
{
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);
std::cout << "Newest task " << l.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
std::cout << "Task used for " << formatSeconds (latest - earliest) << std::endl;
out << "Newest task " << l.toString (conf.get ("dateformat", "m/d/Y")) << std::endl;
out << "Task used for " << formatSeconds (latest - earliest) << std::endl;
}
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)
std::cout << "Task completed every " << formatSeconds ((latest - earliest) / completedT) << std::endl;
out << "Task completed every " << formatSeconds ((latest - earliest) / completedT) << std::endl;
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)
std::cout << "Average time pending "
out << "Average time pending "
<< formatSeconds ((int) ((daysPending / (pendingT + completedT)) * 86400))
<< std::endl;
if (totalT)
{
std::cout << "Average desc length " << (int) (descLength / totalT) << " characters" << std::endl;
std::cout << "Tasks tagged " << std::setprecision (3) << (100.0 * taggedT / totalT) << "%" << std::endl;
out << "Average desc length " << (int) (descLength / totalT) << " characters" << std::endl;
out << "Tasks tagged " << std::setprecision (3) << (100.0 * taggedT / totalT) << "%" << std::endl;
}
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -323,18 +323,18 @@ int main (int argc, char** argv)
tdb.onChange (&onChangeCallback);
}
runTaskCommand (argc, argv, tdb, conf);
std::cout << runTaskCommand (argc, argv, tdb, conf);
}
catch (std::string& error)
{
std::cout << error << std::endl;
std::cerr << error << std::endl;
return -1;
}
catch (...)
{
std::cout << "Unknown error." << std::endl;
std::cerr << "Unknown error." << std::endl;
return -2;
}
@ -685,17 +685,17 @@ void onChangeCallback ()
if (gConf && gTdb)
{
std::cout << "--- valid globals" << std::endl;
gConf->set ("curses", "off");
gConf->set ("color", "off");
// Determine if shadow file is enabled.
std::string shadowFile = expandPath (gConf->get ("shadow.file"));
if (shadowFile != "")
{
std::string oldCurses = gConf->get ("curses");
std::string oldColor = gConf->get ("color");
gConf->set ("curses", "off");
gConf->set ("color", "off");
std::cout << "--- shadowFile " << shadowFile<< std::endl;
// 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.
@ -703,15 +703,24 @@ void onChangeCallback ()
gConf->get ("default.command", "list"));
std::vector <std::string> args;
split (args, command, ' ');
runTaskCommand (args, *gTdb, *gConf);
std::string result = runTaskCommand (args, *gTdb, *gConf);
// Restore std::cout.
std::cout.rdbuf (original);
shadow.close ();
std::cout << "--- Complete " << std::endl;
std::ofstream out (shadowFile.c_str ());
if (out.good ())
{
out << result;
out.close ();
}
else
throw std::string ("Could not write to '") + shadowFile + "'.";
throw std::string ("Could not write file '") + shadowFile + "'";
std::cout << "--- Complete " << std::endl;
gConf->set ("curses", oldCurses);
gConf->set ("color", oldColor);
}
else
throw std::string ("No specified shadow file '") + shadowFile + "'.";
}
else
throw std::string ("Internal error (TDB/Config).");
@ -729,7 +738,7 @@ void onChangeCallback ()
}
////////////////////////////////////////////////////////////////////////////////
void runTaskCommand (
std::string runTaskCommand (
int argc,
char** argv,
TDB& tdb,
@ -739,11 +748,11 @@ void runTaskCommand (
for (int i = 1; i < argc; ++i)
args.push_back (argv[i]);
runTaskCommand (args, tdb, conf);
return runTaskCommand (args, tdb, conf);
}
////////////////////////////////////////////////////////////////////////////////
void runTaskCommand (
std::string runTaskCommand (
std::vector <std::string>& args,
TDB& tdb,
Config& conf)
@ -763,36 +772,40 @@ void runTaskCommand (
T task;
parse (args, command, task, conf);
std::string out = "";
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 == "projects") out = handleProjects (tdb, task, conf);
else if (command == "tags") out = handleTags (tdb, task, conf);
else if (command == "list") out = handleList (tdb, task, conf);
else if (command == "info") out = handleInfo (tdb, task, conf);
else if (command == "undelete") out = handleUndelete (tdb, task, conf);
else if (command == "long") out = handleLongList (tdb, task, conf);
else if (command == "ls") out = handleSmallList (tdb, task, conf);
else if (command == "colors") out = handleColor ( conf);
else if (command == "completed") out = handleCompleted (tdb, task, conf);
else if (command == "delete") out = handleDelete (tdb, task, conf);
else if (command == "start") out = handleStart (tdb, task, conf);
else if (command == "done") handleDone (tdb, task, conf);
else if (command == "undo") handleUndo (tdb, task, conf);
else if (command == "undo") out = 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 == "usage") handleReportUsage (tdb, task, conf);
else if (command == "version") out = handleVersion ( conf);
else if (command == "summary") out = handleReportSummary (tdb, task, conf);
else if (command == "next") out = handleReportNext (tdb, task, conf);
else if (command == "history") out = handleReportHistory (tdb, task, conf);
else if (command == "ghistory") out = handleReportGHistory (tdb, task, conf);
else if (command == "calendar") out = handleReportCalendar (tdb, task, conf);
else if (command == "active") out = handleReportActive (tdb, task, conf);
else if (command == "overdue") out = handleReportOverdue (tdb, task, conf);
else if (command == "oldest") out = handleReportOldest (tdb, task, conf);
else if (command == "newest") out = handleReportNewest (tdb, task, conf);
else if (command == "stats") out = handleReportStats (tdb, task, conf);
else if (command == "usage") out = handleReportUsage (tdb, task, conf);
else if (command == "" && task.getId ()) handleModify (tdb, task, conf);
else if (command == "help") longUsage (conf);
else shortUsage (conf);
return out;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -67,41 +67,41 @@ 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&);
std::string runTaskCommand (int, char**, TDB&, Config&);
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&);
// command.cpp
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 handleDelete (TDB&, T&, Config&);
void handleStart (TDB&, T&, Config&);
void handleDone (TDB&, T&, Config&);
void handleUndo (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 handleUndo (TDB&, T&, Config&);
std::string handleColor (Config&);
// report.cpp
void filter (std::vector<T>&, T&);
void handleList (TDB&, T&, Config&);
void handleInfo (TDB&, T&, Config&);
void handleLongList (TDB&, T&, Config&);
void handleSmallList (TDB&, T&, Config&);
void handleCompleted (TDB&, T&, Config&);
void handleReportSummary (TDB&, T&, Config&);
void handleReportNext (TDB&, T&, Config&);
void handleReportHistory (TDB&, T&, Config&);
void handleReportGHistory (TDB&, T&, Config&);
void handleReportUsage (const TDB&, T&, Config&);
void handleReportCalendar (TDB&, T&, Config&);
void handleReportActive (TDB&, T&, Config&);
void handleReportOverdue (TDB&, T&, Config&);
void handleReportStats (TDB&, T&, Config&);
void handleReportOldest (TDB&, T&, Config&);
void handleReportNewest (TDB&, T&, Config&);
std::string handleList (TDB&, T&, Config&);
std::string handleInfo (TDB&, T&, Config&);
std::string handleLongList (TDB&, T&, Config&);
std::string handleSmallList (TDB&, T&, Config&);
std::string handleCompleted (TDB&, T&, Config&);
std::string handleReportSummary (TDB&, T&, Config&);
std::string handleReportNext (TDB&, T&, Config&);
std::string handleReportHistory (TDB&, T&, Config&);
std::string handleReportGHistory (TDB&, T&, Config&);
std::string handleReportUsage (const TDB&, T&, Config&);
std::string handleReportCalendar (TDB&, T&, Config&);
std::string handleReportActive (TDB&, T&, Config&);
std::string handleReportOverdue (TDB&, T&, Config&);
std::string handleReportStats (TDB&, T&, Config&);
std::string handleReportOldest (TDB&, T&, Config&);
std::string handleReportNewest (TDB&, T&, Config&);
// util.cpp
bool confirm (const std::string&);