- Supports ::isatty call to shut off color, ncurses when stdout is not to a tty

This commit is contained in:
Paul Beckingham 2008-07-06 01:48:48 -04:00
parent 97b120de67
commit 79f6ef075e
4 changed files with 111 additions and 38 deletions

View file

@ -19,6 +19,7 @@ represents a feature release, and the Z represents a patch.
+ Added ability to override ~/.taskrc with rc:<file> + Added ability to override ~/.taskrc with rc:<file>
+ Added bar chart history report "task ghistory" + Added bar chart history report "task ghistory"
+ Added task filtering on all reports + Added task filtering on all reports
+ Automatically shuts off color, curses when output is not a tty
+ Supports relative due: dates (tomorrow, wednesday, 23rd, eom ...) + Supports relative due: dates (tomorrow, wednesday, 23rd, eom ...)
+ Bug: Fixed where Esc[0m sequences were being emitted for no good reason + Bug: Fixed where Esc[0m sequences were being emitted for no good reason
+ Bug: Fixed underlined table headers when color is turned off + Bug: Fixed underlined table headers when color is turned off

View file

@ -57,6 +57,7 @@
<li>Added support for relative due: dates, such as "tomorrow", "friday", <li>Added support for relative due: dates, such as "tomorrow", "friday",
"23rd", "eom" "23rd", "eom"
<li>Added support for task filtering on all reports <li>Added support for task filtering on all reports
<li>Automatically shuts off color, ncurses when output is not to a tty
<li>Fixed bug where Esc[0m sequences were being emitted for no good reason <li>Fixed bug where Esc[0m sequences were being emitted for no good reason
<li>Fixed bug where table headers are underlined when color is turned off <li>Fixed bug where table headers are underlined when color is turned off
<li>Fixed bug where adding a blank priority resulted in an assigned garbage value <li>Fixed bug where adding a blank priority resulted in an assigned garbage value

View file

@ -28,6 +28,7 @@
#include <iomanip> #include <iomanip>
#include <fstream> #include <fstream>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <pwd.h> #include <pwd.h>
@ -275,6 +276,13 @@ int main (int argc, char** argv)
Config conf; Config conf;
loadConfFile (argc, argv, conf); loadConfFile (argc, argv, conf);
// When redirecting output to a file, do not use color, curses.
if (!isatty (fileno (stdout)))
{
conf.set ("curses", "off");
conf.set ("color", "off");
}
TDB tdb; TDB tdb;
tdb.dataDirectory (conf.get ("data.location")); tdb.dataDirectory (conf.get ("data.location"));
@ -585,16 +593,19 @@ void handleList (const TDB& tdb, T& task, Config& conf)
// Now format the matching task. // Now format the matching task.
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string active; std::string active;
@ -605,6 +616,7 @@ void handleList (const TDB& tdb, T& task, Config& conf)
std::string created = refTask.getAttribute ("entry"); std::string created = refTask.getAttribute ("entry");
if (created.length ()) if (created.length ())
{ {
Date now;
Date dt (::atoi (created.c_str ())); Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt)); formatTimeDeltaDays (age, (time_t) (now - dt));
} }
@ -711,16 +723,19 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
// Now format the matching task. // Now format the matching task.
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string active; std::string active;
@ -731,6 +746,7 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
std::string created = refTask.getAttribute ("entry"); std::string created = refTask.getAttribute ("entry");
if (created.length ()) if (created.length ())
{ {
Date now;
Date dt (::atoi (created.c_str ())); Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt)); formatTimeDeltaDays (age, (time_t) (now - dt));
} }
@ -1165,12 +1181,16 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string age; std::string age;
@ -1475,20 +1495,24 @@ void handleReportNext (const TDB& tdb, T& task, Config& conf)
foreach (i, matching) foreach (i, matching)
{ {
T refTask (pending[*i]); T refTask (pending[*i]);
Date now;
// Now format the matching task. // Now format the matching task.
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string active; std::string active;
@ -1932,8 +1956,8 @@ void handleReportGHistory (const TDB& tdb, T& task, Config& conf)
else else
{ {
std::string aBar = ""; while (aBar.length () < addedBar) aBar += "+"; std::string aBar = ""; while (aBar.length () < addedBar) aBar += "+";
std::string cBar = ""; while (cBar.length () < completedBar) cBar += "+"; std::string cBar = ""; while (cBar.length () < completedBar) cBar += "X";
std::string dBar = ""; while (dBar.length () < deletedBar) dBar += "+"; std::string dBar = ""; while (dBar.length () < deletedBar) dBar += "-";
bar = aBar + cBar + dBar; bar = aBar + cBar + dBar;
} }
@ -2301,18 +2325,22 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
T refTask (tasks[i]); T refTask (tasks[i]);
if (refTask.getAttribute ("start") != "") if (refTask.getAttribute ("start") != "")
{ {
Date now;
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
Date now;
overdue = dt < now ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
// All criteria match, so add refTask to the output table. // All criteria match, so add refTask to the output table.
@ -2529,20 +2557,24 @@ void handleReportOldest (const TDB& tdb, T& task, Config& conf)
for (unsigned int i = 0; i < min (quantity, tasks.size ()); ++i) for (unsigned int i = 0; i < min (quantity, tasks.size ()); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
Date now;
// Now format the matching task. // Now format the matching task.
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string active; std::string active;
@ -2669,20 +2701,24 @@ void handleReportNewest (const TDB& tdb, T& task, Config& conf)
for (int i = total - 1; i >= max (0, total - quantity); --i) for (int i = total - 1; i >= max (0, total - quantity); --i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
Date now;
// Now format the matching task. // Now format the matching task.
bool imminent = false; bool imminent = false;
bool overdue = false; bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due"); std::string due = refTask.getAttribute ("due");
if (due.length ()) if (due.length ())
{ {
switch (getDueState (due))
{
case 2: overdue = true; break;
case 1: imminent = true; break;
case 0:
default: break;
}
Date dt (::atoi (due.c_str ())); Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y")); due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
} }
std::string active; std::string active;
@ -3386,12 +3422,35 @@ void decorateRecurringTask (T& task)
task.getAttribute ("recur") != "") task.getAttribute ("recur") != "")
{ {
task.setAttribute ("base", task.getAttribute ("due")); task.setAttribute ("base", task.getAttribute ("due"));
// TODO Create "range".
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Determines whether a task is overdue. Returns
// 0 = not due at all
// 1 = imminent
// 2 = overdue
int getDueState (const std::string& due)
{
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
Date now;
if (dt < now)
return 2;
Date nextweek = now + 7 * 86400;
if (dt < nextweek)
return 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Scan for recurring tasks, and generate any necessary instances of those
// tasks.
void checkRecurring (std::vector <T>& tasks) void checkRecurring (std::vector <T>& tasks)
{ {
std::vector <T>::iterator it; std::vector <T>::iterator it;
@ -3399,7 +3458,18 @@ void checkRecurring (std::vector <T>& tasks)
{ {
if (it->getStatus () == T::recurring) if (it->getStatus () == T::recurring)
{ {
// This task is recurring. While it remains hidden from view, it spawns
// child tasks automatically, here, that are regular tasks, except they
// have a "parent" attribute that contains the UUID of the original.
// Generate a list of child tasks.
std::vector <T> children;
std::vector <T>::iterator them;
for (them = tasks.begin (); them != tasks.end (); ++them)
if (them->getAttribute ("parent") != "")
children.push_back (*them);
// TODO Determine if any new child tasks need to be generated.
} }
} }

View file

@ -111,6 +111,7 @@ std::string formatSeconds (time_t);
const std::string uuid (); const std::string uuid ();
const char* optionalBlankLine (Config&); const char* optionalBlankLine (Config&);
int convertDuration (const std::string&); int convertDuration (const std::string&);
int getDueState (const std::string&);
int addDuration (const Date&, const std::string&); int addDuration (const Date&, const std::string&);
// rules.cpp // rules.cpp