mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
- Merged 1.4.3 to master
This commit is contained in:
parent
a815492111
commit
2cae1df42f
27 changed files with 950 additions and 431 deletions
1
src/.gitignore
vendored
1
src/.gitignore
vendored
|
@ -1,2 +1 @@
|
|||
./Makefile
|
||||
*.o
|
||||
|
|
27
src/TDB.cpp
27
src/TDB.cpp
|
@ -235,7 +235,7 @@ bool TDB::completeT (const T& t)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool TDB::addT (const T& t) const
|
||||
bool TDB::addT (const T& t)
|
||||
{
|
||||
T task (t);
|
||||
std::vector <std::string> tags;
|
||||
|
@ -254,7 +254,9 @@ bool TDB::addT (const T& t) const
|
|||
|
||||
if (task.getStatus () == T::pending ||
|
||||
task.getStatus () == T::recurring)
|
||||
{
|
||||
return writePending (task);
|
||||
}
|
||||
|
||||
return writeCompleted (task);
|
||||
}
|
||||
|
@ -312,6 +314,7 @@ bool TDB::overwritePending (std::vector <T>& all)
|
|||
fputs (it->compose ().c_str (), out);
|
||||
|
||||
fclose (out);
|
||||
dbChanged ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -319,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
|
||||
FILE* out;
|
||||
|
@ -334,6 +337,7 @@ bool TDB::writePending (const T& t) const
|
|||
fputs (t.compose ().c_str (), out);
|
||||
|
||||
fclose (out);
|
||||
dbChanged ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -341,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
|
||||
FILE* out;
|
||||
|
@ -356,6 +360,7 @@ bool TDB::writeCompleted (const T& t) const
|
|||
fputs (t.compose ().c_str (), out);
|
||||
|
||||
fclose (out);
|
||||
dbChanged ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -439,4 +444,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) ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
10
src/TDB.h
10
src/TDB.h
|
@ -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 writePending (const T&);
|
||||
bool writeCompleted (const T&);
|
||||
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
|
||||
|
|
277
src/command.cpp
277
src/command.cpp
|
@ -26,6 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
@ -47,7 +48,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));
|
||||
|
@ -67,7 +68,6 @@ void handleAdd (const 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 (const 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 (const 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,21 +129,25 @@ void handleProjects (TDB& tdb, T& task, Config& conf)
|
|||
table.addCell (row, 1, i->second);
|
||||
}
|
||||
|
||||
std::cout << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " project" : " projects")
|
||||
<< std::endl;
|
||||
out << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " project" : " projects")
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
std::cout << "No projects."
|
||||
<< std::endl;
|
||||
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)
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " tag" : " tags")
|
||||
<< std::endl;
|
||||
out << optionalBlankLine (conf)
|
||||
<< unique.size ()
|
||||
<< (unique.size () == 1 ? " tag" : " tags")
|
||||
<< std::endl;
|
||||
else
|
||||
std::cout << "No tags."
|
||||
<< std::endl;
|
||||
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
|
||||
<< " not found - tasks can only be reliably undeleted if the undelete" << std::endl
|
||||
<< "command is run immediately after the errant delete command." << std::endl;
|
||||
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
|
||||
<< " not found - tasks can only be reliably undone if the undo" << std::endl
|
||||
<< "command is run immediately after the errant done command." << std::endl;
|
||||
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,40 +343,42 @@ void handleVersion (Config& conf)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "Copyright (C) 2006 - 2008, P. Beckingham."
|
||||
<< std::endl
|
||||
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, PACKAGE) : PACKAGE)
|
||||
<< " "
|
||||
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, VERSION) : VERSION)
|
||||
<< std::endl
|
||||
<< disclaimer.render ()
|
||||
<< std::endl
|
||||
<< table.render ()
|
||||
<< link.render ()
|
||||
<< std::endl;
|
||||
out << "Copyright (C) 2006 - 2008, P. Beckingham."
|
||||
<< std::endl
|
||||
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, PACKAGE) : PACKAGE)
|
||||
<< " "
|
||||
<< (conf.get ("color", true) ? Text::colorize (Text::bold, Text::nocolor, VERSION) : VERSION)
|
||||
<< std::endl
|
||||
<< disclaimer.render ()
|
||||
<< std::endl
|
||||
<< table.render ()
|
||||
<< link.render ()
|
||||
<< std::endl;
|
||||
|
||||
// Verify installation. This is mentioned in the documentation as the way to
|
||||
// ensure everything is properly installed.
|
||||
|
||||
if (all.size () == 0)
|
||||
std::cout << "Configuration error: .taskrc contains no entries"
|
||||
<< std::endl;
|
||||
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 "
|
||||
"file."
|
||||
<< std::endl;
|
||||
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"
|
||||
" that doesn't exist, or is unreadable."
|
||||
<< std::endl;
|
||||
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,87 +620,91 @@ 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
|
||||
<< " "
|
||||
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
||||
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
||||
<< Text::colorize (Text::bold_underline, Text::nocolor, "bold_underline") << std::endl
|
||||
out << optionalBlankLine (conf) << "Foreground" << std::endl
|
||||
<< " "
|
||||
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
|
||||
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
|
||||
<< Text::colorize (Text::bold_underline, Text::nocolor, "bold_underline") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::black, Text::nocolor, "black") << " "
|
||||
<< Text::colorize (Text::bold_black, Text::nocolor, "bold_black") << " "
|
||||
<< Text::colorize (Text::underline_black, Text::nocolor, "underline_black") << " "
|
||||
<< Text::colorize (Text::bold_underline_black, Text::nocolor, "bold_underline_black") << std::endl
|
||||
<< " " << Text::colorize (Text::black, Text::nocolor, "black") << " "
|
||||
<< Text::colorize (Text::bold_black, Text::nocolor, "bold_black") << " "
|
||||
<< Text::colorize (Text::underline_black, Text::nocolor, "underline_black") << " "
|
||||
<< Text::colorize (Text::bold_underline_black, Text::nocolor, "bold_underline_black") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::red, Text::nocolor, "red") << " "
|
||||
<< Text::colorize (Text::bold_red, Text::nocolor, "bold_red") << " "
|
||||
<< Text::colorize (Text::underline_red, Text::nocolor, "underline_red") << " "
|
||||
<< Text::colorize (Text::bold_underline_red, Text::nocolor, "bold_underline_red") << std::endl
|
||||
<< " " << Text::colorize (Text::red, Text::nocolor, "red") << " "
|
||||
<< Text::colorize (Text::bold_red, Text::nocolor, "bold_red") << " "
|
||||
<< Text::colorize (Text::underline_red, Text::nocolor, "underline_red") << " "
|
||||
<< Text::colorize (Text::bold_underline_red, Text::nocolor, "bold_underline_red") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::green, Text::nocolor, "green") << " "
|
||||
<< Text::colorize (Text::bold_green, Text::nocolor, "bold_green") << " "
|
||||
<< Text::colorize (Text::underline_green, Text::nocolor, "underline_green") << " "
|
||||
<< Text::colorize (Text::bold_underline_green, Text::nocolor, "bold_underline_green") << std::endl
|
||||
<< " " << Text::colorize (Text::green, Text::nocolor, "green") << " "
|
||||
<< Text::colorize (Text::bold_green, Text::nocolor, "bold_green") << " "
|
||||
<< Text::colorize (Text::underline_green, Text::nocolor, "underline_green") << " "
|
||||
<< Text::colorize (Text::bold_underline_green, Text::nocolor, "bold_underline_green") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::yellow, Text::nocolor, "yellow") << " "
|
||||
<< Text::colorize (Text::bold_yellow, Text::nocolor, "bold_yellow") << " "
|
||||
<< Text::colorize (Text::underline_yellow, Text::nocolor, "underline_yellow") << " "
|
||||
<< Text::colorize (Text::bold_underline_yellow, Text::nocolor, "bold_underline_yellow") << std::endl
|
||||
<< " " << Text::colorize (Text::yellow, Text::nocolor, "yellow") << " "
|
||||
<< Text::colorize (Text::bold_yellow, Text::nocolor, "bold_yellow") << " "
|
||||
<< Text::colorize (Text::underline_yellow, Text::nocolor, "underline_yellow") << " "
|
||||
<< Text::colorize (Text::bold_underline_yellow, Text::nocolor, "bold_underline_yellow") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::blue, Text::nocolor, "blue") << " "
|
||||
<< Text::colorize (Text::bold_blue, Text::nocolor, "bold_blue") << " "
|
||||
<< Text::colorize (Text::underline_blue, Text::nocolor, "underline_blue") << " "
|
||||
<< Text::colorize (Text::bold_underline_blue, Text::nocolor, "bold_underline_blue") << std::endl
|
||||
<< " " << Text::colorize (Text::blue, Text::nocolor, "blue") << " "
|
||||
<< Text::colorize (Text::bold_blue, Text::nocolor, "bold_blue") << " "
|
||||
<< Text::colorize (Text::underline_blue, Text::nocolor, "underline_blue") << " "
|
||||
<< Text::colorize (Text::bold_underline_blue, Text::nocolor, "bold_underline_blue") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::magenta, Text::nocolor, "magenta") << " "
|
||||
<< Text::colorize (Text::bold_magenta, Text::nocolor, "bold_magenta") << " "
|
||||
<< Text::colorize (Text::underline_magenta, Text::nocolor, "underline_magenta") << " "
|
||||
<< Text::colorize (Text::bold_underline_magenta, Text::nocolor, "bold_underline_magenta") << std::endl
|
||||
<< " " << Text::colorize (Text::magenta, Text::nocolor, "magenta") << " "
|
||||
<< Text::colorize (Text::bold_magenta, Text::nocolor, "bold_magenta") << " "
|
||||
<< Text::colorize (Text::underline_magenta, Text::nocolor, "underline_magenta") << " "
|
||||
<< Text::colorize (Text::bold_underline_magenta, Text::nocolor, "bold_underline_magenta") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::cyan, Text::nocolor, "cyan") << " "
|
||||
<< Text::colorize (Text::bold_cyan, Text::nocolor, "bold_cyan") << " "
|
||||
<< Text::colorize (Text::underline_cyan, Text::nocolor, "underline_cyan") << " "
|
||||
<< Text::colorize (Text::bold_underline_cyan, Text::nocolor, "bold_underline_cyan") << std::endl
|
||||
<< " " << Text::colorize (Text::cyan, Text::nocolor, "cyan") << " "
|
||||
<< Text::colorize (Text::bold_cyan, Text::nocolor, "bold_cyan") << " "
|
||||
<< Text::colorize (Text::underline_cyan, Text::nocolor, "underline_cyan") << " "
|
||||
<< Text::colorize (Text::bold_underline_cyan, Text::nocolor, "bold_underline_cyan") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::white, Text::nocolor, "white") << " "
|
||||
<< Text::colorize (Text::bold_white, Text::nocolor, "bold_white") << " "
|
||||
<< Text::colorize (Text::underline_white, Text::nocolor, "underline_white") << " "
|
||||
<< Text::colorize (Text::bold_underline_white, Text::nocolor, "bold_underline_white") << std::endl
|
||||
<< " " << Text::colorize (Text::white, Text::nocolor, "white") << " "
|
||||
<< Text::colorize (Text::bold_white, Text::nocolor, "bold_white") << " "
|
||||
<< Text::colorize (Text::underline_white, Text::nocolor, "underline_white") << " "
|
||||
<< Text::colorize (Text::bold_underline_white, Text::nocolor, "bold_underline_white") << std::endl
|
||||
|
||||
<< std::endl << "Background" << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_black, "on_black") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_black, "on_bright_black") << std::endl
|
||||
<< std::endl << "Background" << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_black, "on_black") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_black, "on_bright_black") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_red, "on_red") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_red, "on_bright_red") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_red, "on_red") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_red, "on_bright_red") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_green, "on_green") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_green, "on_bright_green") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_green, "on_green") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_green, "on_bright_green") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_yellow, "on_yellow") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_yellow, "on_bright_yellow") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_yellow, "on_yellow") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_yellow, "on_bright_yellow") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_blue, "on_blue") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_blue, "on_bright_blue") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_blue, "on_blue") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_blue, "on_bright_blue") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_magenta, "on_magenta") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_magenta, "on_bright_magenta") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_magenta, "on_magenta") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_magenta, "on_bright_magenta") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_cyan, "on_cyan") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_cyan, "on_bright_cyan") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_cyan, "on_cyan") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_cyan, "on_bright_cyan") << std::endl
|
||||
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
|
||||
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
|
||||
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
|
||||
|
||||
<< optionalBlankLine (conf);
|
||||
<< optionalBlankLine (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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
433
src/report.cpp
433
src/report.cpp
|
@ -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)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||
<< std::endl;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||
<< std::endl;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||
<< std::endl;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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,21 +672,22 @@ 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;
|
||||
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
|
||||
|
@ -827,22 +843,26 @@ void handleLongList (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;
|
||||
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;
|
||||
|
@ -984,14 +1004,16 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
|
||||
if (table.rowCount ())
|
||||
std::cout << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< optionalBlankLine (conf)
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " project" : " projects")
|
||||
<< std::endl;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1013,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;
|
||||
|
@ -1154,15 +1178,17 @@ void handleReportNext (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;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1187,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;
|
||||
|
@ -1363,16 +1391,20 @@ void handleReportHistory (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
|
||||
if (table.rowCount ())
|
||||
std::cout << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< std::endl;
|
||||
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
|
||||
|
@ -1574,24 +1606,105 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf)
|
|||
|
||||
if (table.rowCount ())
|
||||
{
|
||||
std::cout << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< std::endl;
|
||||
out << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< std::endl;
|
||||
|
||||
if (conf.get ("color", true))
|
||||
std::cout << "Legend: "
|
||||
<< Text::colorize (Text::black, Text::on_red, "added")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_green, "completed")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_yellow, "deleted")
|
||||
<< optionalBlankLine (conf)
|
||||
<< std::endl;
|
||||
out << "Legend: "
|
||||
<< Text::colorize (Text::black, Text::on_red, "added")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_green, "completed")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_yellow, "deleted")
|
||||
<< 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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// A summary of the command usage. Not useful to users, but used to display
|
||||
// usage statistics for feedback.
|
||||
//
|
||||
// 2006-12-04 19:59:43 "task list"
|
||||
//
|
||||
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;
|
||||
std::vector <std::string> all;
|
||||
tdb.logRead (all);
|
||||
for (unsigned int i = 0; i < all.size (); ++i)
|
||||
{
|
||||
// 0123456789012345678901
|
||||
// v 21
|
||||
// 2006-12-04 19:59:43 "task list"
|
||||
std::string command = all[i].substr (21, all[i].length () - 22);
|
||||
|
||||
// Parse as a command line.
|
||||
std::vector <std::string> args;
|
||||
split (args, command, " ");
|
||||
|
||||
try
|
||||
{
|
||||
T task;
|
||||
std::string commandName;
|
||||
parse (args, commandName, task, conf);
|
||||
|
||||
usage[commandName]++;
|
||||
}
|
||||
|
||||
// Deliberately ignore errors from parsing the command log, as there may
|
||||
// be commands from a prior version of task in there, which were
|
||||
// abbreviated, and are now ambiguous.
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
// Now render the table.
|
||||
Table table;
|
||||
table.addColumn ("Command");
|
||||
table.addColumn ("Frequency");
|
||||
|
||||
if (conf.get ("color", true))
|
||||
{
|
||||
table.setColumnUnderline (0);
|
||||
table.setColumnUnderline (1);
|
||||
}
|
||||
else
|
||||
table.setTableDashedUnderline ();
|
||||
|
||||
table.setColumnJustification (1, Table::right);
|
||||
table.sortOn (1, Table::descendingNumeric);
|
||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
||||
|
||||
foreach (i, usage)
|
||||
{
|
||||
int row = table.addRow ();
|
||||
table.addCell (row, 0, (i->first == "" ? "(modify)" : i->first));
|
||||
table.addCell (row, 1, i->second);
|
||||
}
|
||||
|
||||
if (table.rowCount ())
|
||||
out << optionalBlankLine (conf)
|
||||
<< table.render ()
|
||||
<< std::endl;
|
||||
else
|
||||
out << "No usage." << std::endl;
|
||||
}
|
||||
else
|
||||
out << "Command logging is not enabled, so no history has been kept."
|
||||
<< std::endl;
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1719,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;
|
||||
|
@ -1751,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));
|
||||
|
@ -1768,11 +1883,11 @@ 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) << ' '
|
||||
<< month
|
||||
<< ' '
|
||||
<< nextY
|
||||
<< std::setw (right) << ' ';
|
||||
out << std::setw (left) << ' '
|
||||
<< month
|
||||
<< ' '
|
||||
<< nextY
|
||||
<< std::setw (right) << ' ';
|
||||
|
||||
if (++nextM > 12)
|
||||
{
|
||||
|
@ -1781,10 +1896,10 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< optionalBlankLine (conf)
|
||||
<< renderMonths (mFrom, yFrom, today, pending, conf)
|
||||
<< std::endl;
|
||||
out << std::endl
|
||||
<< optionalBlankLine (conf)
|
||||
<< renderMonths (mFrom, yFrom, today, pending, conf)
|
||||
<< std::endl;
|
||||
|
||||
mFrom += monthsPerLine;
|
||||
if (mFrom > 12)
|
||||
|
@ -1794,20 +1909,24 @@ void handleReportCalendar (TDB& tdb, T& task, Config& conf)
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "Legend: "
|
||||
<< Text::colorize (Text::cyan, Text::nocolor, "today")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_yellow, "due")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_red, "overdue")
|
||||
<< "."
|
||||
<< optionalBlankLine (conf)
|
||||
<< std::endl;
|
||||
out << "Legend: "
|
||||
<< Text::colorize (Text::cyan, Text::nocolor, "today")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_yellow, "due")
|
||||
<< ", "
|
||||
<< Text::colorize (Text::black, Text::on_red, "overdue")
|
||||
<< "."
|
||||
<< 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
|
||||
|
@ -1913,19 +2032,23 @@ void handleReportActive (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;
|
||||
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
|
||||
|
@ -2020,21 +2143,25 @@ void handleReportOverdue (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;
|
||||
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
|
||||
|
@ -2164,22 +2291,26 @@ void handleReportOldest (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;
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
@ -2310,21 +2441,25 @@ void handleReportNewest (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;
|
||||
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 ();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
|
@ -2371,40 +2506,42 @@ void handleReportStats (TDB& tdb, T& task, Config& conf)
|
|||
if (tags.size ()) ++taggedT;
|
||||
}
|
||||
|
||||
std::cout << "Pending " << pendingT << std::endl
|
||||
<< "Recurring " << recurringT << std::endl
|
||||
<< "Completed " << completedT << std::endl
|
||||
<< "Deleted " << deletedT << std::endl
|
||||
<< "Total " << totalT << std::endl;
|
||||
out << "Pending " << pendingT << std::endl
|
||||
<< "Recurring " << recurringT << std::endl
|
||||
<< "Completed " << completedT << std::endl
|
||||
<< "Deleted " << deletedT << std::endl
|
||||
<< "Total " << totalT << std::endl;
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
231
src/task.cpp
231
src/task.cpp
|
@ -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,69 +296,41 @@ int main (int argc, char** argv)
|
|||
}
|
||||
|
||||
TDB tdb;
|
||||
tdb.dataDirectory (expandPath (conf.get ("data.location")));
|
||||
gTdb = &tdb;
|
||||
std::string dataLocation = expandPath (conf.get ("data.location"));
|
||||
tdb.dataDirectory (dataLocation);
|
||||
|
||||
// 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 != "")
|
||||
// Log commands, if desired.
|
||||
if (conf.get ("command.logging") == "on")
|
||||
tdb.logCommand (argc, argv);
|
||||
|
||||
// Set up TDB callback.
|
||||
std::string shadowFile = expandPath (conf.get ("shadow.file"));
|
||||
if (shadowFile != "")
|
||||
{
|
||||
// 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]);
|
||||
if (shadowFile == dataLocation + "/pending.data")
|
||||
throw std::string ("Configuration variable 'shadow.file' is set to "
|
||||
"overwrite your pending tasks. Please change it.");
|
||||
|
||||
if (shadowFile == dataLocation + "/completed.data")
|
||||
throw std::string ("Configuration variable 'shadow.file' is set to "
|
||||
"overwrite your completed tasks. Please change it.");
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -391,12 +369,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 +528,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 +546,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 +561,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 +579,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 +594,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 +609,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 +617,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 +634,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 +641,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 +650,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 +672,129 @@ void updateRecurrenceMask (
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Using gTdb and gConf, generate a report.
|
||||
void onChangeCallback ()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (gConf && gTdb)
|
||||
{
|
||||
// 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");
|
||||
|
||||
// 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, ' ');
|
||||
std::string result = runTaskCommand (args, *gTdb, *gConf);
|
||||
|
||||
std::ofstream out (shadowFile.c_str ());
|
||||
if (out.good ())
|
||||
{
|
||||
out << result;
|
||||
out.close ();
|
||||
}
|
||||
else
|
||||
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 + "'.";
|
||||
}
|
||||
else
|
||||
throw std::string ("Internal error (TDB/Config).");
|
||||
}
|
||||
|
||||
catch (std::string& error)
|
||||
{
|
||||
std::cout << error << std::endl;
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Unknown error." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string 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]);
|
||||
|
||||
return runTaskCommand (args, tdb, conf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string 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);
|
||||
|
||||
std::string out = "";
|
||||
|
||||
if (command == "add") handleAdd (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") out = handleUndo (tdb, task, conf);
|
||||
else if (command == "export") handleExport (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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
52
src/task.h
52
src/task.h
|
@ -66,38 +66,42 @@ 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 ();
|
||||
std::string runTaskCommand (int, char**, TDB&, Config&);
|
||||
std::string runTaskCommand (std::vector <std::string>&, TDB&, Config&);
|
||||
|
||||
// command.cpp
|
||||
void handleAdd (const TDB&, T&, Config&);
|
||||
void handleProjects (TDB&, T&, Config&);
|
||||
void handleTags (TDB&, T&, Config&);
|
||||
void handleUndelete (TDB&, T&, Config&);
|
||||
void handleVersion (Config&);
|
||||
void handleAdd (TDB&, T&, 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 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&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue