Enhancement - New columns for custom reports

- Added 'entry_time', 'start_time' and 'end_time' columns that include
  the time as well as the date.
This commit is contained in:
Paul Beckingham 2009-12-11 19:08:45 -05:00
parent 81ce844d79
commit 4ea71c939a
5 changed files with 105 additions and 0 deletions

View file

@ -18,6 +18,9 @@
+ The 'version' command now complains about use of deprecated color names and
duplicate entries.
+ Task now supports nested .taskrc files using the "include /path" directive.
+ The 'entry', 'start' and 'end' columns now have equivalents that include the
time, and are called 'entry_time', 'start_time', and 'end_time', for use in
custom reports.
+ Fixed bug that showed a calendar for the year 2037 when 'task calendar due'
was run, and there are no tasks with due dates.
+ Fixed bug #316 which caused the timesheet report to display an oddly sorted

4
NEWS
View file

@ -4,6 +4,10 @@ New Features in task 1.9
- 256-color support
- Support for coloring alternate lines of output. Remember that old green
and white fan-fold printer paper?
- Supports nested .taskrc files with the new "include" statement"
- New columns that include the time as well as date
- New attribute modifiers
- Improved .taskrc validation
Please refer to the ChangeLog file for full details. There are too many to
list here.

View file

@ -271,6 +271,19 @@ const std::string Date::toString (const std::string& format /*= "m/d/Y" */) cons
return formatted;
}
////////////////////////////////////////////////////////////////////////////////
const std::string Date::toStringWithTime (const std::string& format /*= "m/d/Y" */) const
{
// Format as above.
std::string formatted = toString (format);
char buffer[12];
sprintf (buffer, " %d:%02d:%02d", hour (), minute (), second ());
formatted += buffer;
return formatted;
}
////////////////////////////////////////////////////////////////////////////////
bool Date::valid (const std::string& input, const std::string& format)
{
@ -456,6 +469,27 @@ int Date::year () const
return t->tm_year + 1900;
}
////////////////////////////////////////////////////////////////////////////////
int Date::hour () const
{
struct tm* t = localtime (&mT);
return t->tm_hour;
}
////////////////////////////////////////////////////////////////////////////////
int Date::minute () const
{
struct tm* t = localtime (&mT);
return t->tm_min;
}
////////////////////////////////////////////////////////////////////////////////
int Date::second () const
{
struct tm* t = localtime (&mT);
return t->tm_sec;
}
////////////////////////////////////////////////////////////////////////////////
bool Date::operator== (const Date& rhs)
{

View file

@ -47,6 +47,7 @@ public:
std::string toEpochString ();
void toMDY (int&, int&, int&);
const std::string toString (const std::string& format = "m/d/Y") const;
const std::string toStringWithTime (const std::string& format = "m/d/Y") const;
static bool valid (const std::string&, const std::string& format = "m/d/Y");
static bool valid (const int, const int, const int);
@ -63,6 +64,9 @@ public:
int year () const;
int weekOfYear (int) const;
int dayOfWeek () const;
int hour () const;
int minute () const;
int second () const;
bool operator== (const Date&);
bool operator!= (const Date&);

View file

@ -237,6 +237,25 @@ int runCustomReport (
}
}
else if (*col == "entry_time")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Added");
table.setColumnWidth (columnCount, Table::minimum);
table.setColumnJustification (columnCount, Table::right);
std::string entered;
for (unsigned int row = 0; row < tasks.size(); ++row)
{
entered = tasks[row].get ("entry");
if (entered.length ())
{
Date dt (::atoi (entered.c_str ()));
entered = dt.toStringWithTime (context.config.get ("dateformat", "m/d/Y"));
table.addCell (row, columnCount, entered);
}
}
}
else if (*col == "start")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Started");
@ -256,6 +275,25 @@ int runCustomReport (
}
}
else if (*col == "start_time")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Started");
table.setColumnWidth (columnCount, Table::minimum);
table.setColumnJustification (columnCount, Table::right);
std::string started;
for (unsigned int row = 0; row < tasks.size(); ++row)
{
started = tasks[row].get ("start");
if (started.length ())
{
Date dt (::atoi (started.c_str ()));
started = dt.toStringWithTime (context.config.get ("dateformat", "m/d/Y"));
table.addCell (row, columnCount, started);
}
}
}
else if (*col == "end")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Completed");
@ -275,6 +313,25 @@ int runCustomReport (
}
}
else if (*col == "end_time")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Completed");
table.setColumnWidth (columnCount, Table::minimum);
table.setColumnJustification (columnCount, Table::right);
std::string started;
for (unsigned int row = 0; row < tasks.size(); ++row)
{
started = tasks[row].get ("end");
if (started.length ())
{
Date dt (::atoi (started.c_str ()));
started = dt.toStringWithTime (context.config.get ("dateformat", "m/d/Y"));
table.addCell (row, columnCount, started);
}
}
}
else if (*col == "due")
{
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Due");
@ -576,8 +633,11 @@ void validReportColumns (const std::vector <std::string>& columns)
*it != "project" &&
*it != "priority" &&
*it != "entry" &&
*it != "entry_time" &&
*it != "start" &&
*it != "start_time" &&
*it != "end" &&
*it != "end_time" &&
*it != "due" &&
*it != "age" &&
*it != "age_compact" &&