diff --git a/ChangeLog b/ChangeLog index cfe687e81..a96373114 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,8 @@ + Supports negative tag filters, so that (task list +foo -bar) now filters tasks that have the "foo" tag, but do not have the "bar" tag (thanks to Chris Pride). + + Custom reports now support a more compact form of the "age" column, + called "age_compact" (thanks to T. Charles Yun). ------ old releases ------------------------------ diff --git a/src/report.cpp b/src/report.cpp index cc46dc21d..5bcf94085 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -2669,6 +2669,27 @@ std::string handleCustomReport ( } } + else if (*col == "age_compact") + { + table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Age"); + table.setColumnWidth (columnCount, Table::minimum); + table.setColumnJustification (columnCount, Table::right); + + std::string created; + std::string age; + Date now; + for (unsigned int row = 0; row < tasks.size(); ++row) + { + created = tasks[row].getAttribute ("entry"); + if (created.length ()) + { + Date dt (::atoi (created.c_str ())); + age = formatSecondsCompact ((time_t) (now - dt)); + table.addCell (row, columnCount, age); + } + } + } + else if (*col == "active") { table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Active"); @@ -2899,6 +2920,7 @@ void validReportColumns (const std::vector & columns) *it != "start" && *it != "due" && *it != "age" && + *it != "age_compact" && *it != "active" && *it != "tags" && *it != "recur" && diff --git a/src/util.cpp b/src/util.cpp index 4a09a420f..f839afdee 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -120,6 +120,27 @@ std::string formatSeconds (time_t delta) return std::string (formatted); } +//////////////////////////////////////////////////////////////////////////////// +// Convert a quantity in seconds to a more readable format. +std::string formatSecondsCompact (time_t delta) +{ + char formatted[24]; + float days = (float) delta / 86400.0; + + if (days > 365) sprintf (formatted, "%.1fy", (days / 365.2422)); + else if (days > 84) sprintf (formatted, "%1dmo", (int) (days / 30.6)); + else if (days > 13) sprintf (formatted, "%dwk", (int) (days / 7.0)); + else if (days > 5.0) sprintf (formatted, "%dd", (int) days); + else if (days > 1.0) sprintf (formatted, "%.1fd", days); + else if (days * 24 > 1.0) sprintf (formatted, "%dh", (int) (days * 24.0)); + else if (days * 24 * 60 > 1) sprintf (formatted, "%dm", (int) (days * 24 * 60)); + else if (days * 24 * 3600 > 1) sprintf (formatted, "%ds", (int) (days * 24 * 60 * 60)); + else + strcpy (formatted, "-"); + + return std::string (formatted); +} + //////////////////////////////////////////////////////////////////////////////// int autoComplete ( const std::string& partial, diff --git a/src/util.h b/src/util.h index 101b04afa..350ffac30 100644 --- a/src/util.h +++ b/src/util.h @@ -53,6 +53,7 @@ for (typeof (c) *foreach_p = & (c); \ bool confirm (const std::string&); void delay (float); std::string formatSeconds (time_t); +std::string formatSecondsCompact (time_t); int autoComplete (const std::string&, const std::vector&, std::vector&); const std::string uuid (); int convertDuration (const std::string&);