diff --git a/ChangeLog b/ChangeLog index a68c9fb16..b55c567dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,12 +4,13 @@ 1.9.0 () + Added feature #292 that permits alternate line coloration in reports (thanks to Richard Querin). - + The 'delete' command is now aliased to 'rm' (thanks to Ivo Jimenez). + + Added feature #307 that provides vim with syntax highlighting for .taskrc. + Added feature #336 which gives task a 'prepend' command for symmetry with the 'append' command. + Added feature #341 that makes explicit references to the task and taskrc man pages, both in the auto-generated .taskrc file and the version command output (thanks to Cory Donnelly). + + The 'delete' command is now aliased to 'rm' (thanks to Ivo Jimenez). + Added new attribute modifiers 'word' and 'noword' which find the existence of whole words, or prove the non-existence of whole words. If a task has the description "Pay the bill", then "description.word:the" will match, but @@ -26,23 +27,25 @@ custom reports. + The new 'priority_long' field can be shown in custom reports, and will display 'High' rather than the abbreviated 'H'. - + Added feature #307 that provides vim with syntax highlighting for .taskrc. + Task now supports .taskrc command line overrides using rc.name:value and the new rc.name=value to accommodate a frequent mistake. + The color rules for projects (color.project.foo) now matches on partial project names, the same way as filters. + The color command now takes a color as an argument, and displays that color with sample text. - + Fixed bug that showed a calendar for the year 2037 when 'task calendar due' - was run, and there are no tasks with due dates. + + Added 2 new configuration variables to display the details of tasks with due + dates when doing a 'task cal' for the corresponding months: + 'calendar.details' and 'calendar.details.report' + Fixed bug #316 which caused the timesheet report to display an oddly sorted list. + Fixed bug #317 which colored tasks in the 'completed' report according to due dates, which are no longer relevant to a completed task (thanks to Cory Donnelly). - + Fixed bug that was causing the 'completed' report to sort incorrectly. + Fixed bug #347 which used only a lowercase "all" to confirm multiple changes instead of an uppercase "All" like the "Yes" answer. + + Fixed bug that was causing the 'completed' report to sort incorrectly. + + Fixed bug that showed a calendar for the year 2037 when 'task calendar due' + was run, and there are no tasks with due dates. ------ old releases ------------------------------ diff --git a/doc/man/taskrc.5 b/doc/man/taskrc.5 index f48cbf072..73f7b334d 100644 --- a/doc/man/taskrc.5 +++ b/doc/man/taskrc.5 @@ -191,6 +191,14 @@ The week number is dependent on the day a week starts. This is the number of days into the future that define when a task is considered due, and is colored accordingly. Defaults to 7. +.TP calendar.details=no +If set to yes running "task calendar" will display the details of tasks with due dates +that fall into the calendar period. + +.TP calendar.details.report=list +The report to run when displaying the details of tasks with due date when running the +"task calendar" command. + .TP .B monthsperline=2 Determines how many months the "task calendar" command renders across the screen. diff --git a/src/Config.cpp b/src/Config.cpp index f871ba89a..6d7da7ba6 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -152,6 +152,8 @@ void Config::createDefaultRC (const std::string& rc, const std::string& data) << "weekstart=Sunday # Sunday or Monday only\n" << "displayweeknumber=yes # Show week numbers on calendar\n" << "due=7 # Task is considered due in 7 days\n" + << "#calendar.details=yes # Calendar shows information for tasks w/due dates\n" + << "#calendar.details.report=list # Report to use when showing task information in cal\n" << "#monthsperline=2 # Number of calendar months on a line\n" << "\n" << "# Color controls.\n" diff --git a/src/command.cpp b/src/command.cpp index ef2f18935..f4394cfa1 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -551,10 +551,10 @@ int handleConfig (std::string &outs) // These are the regular configuration variables. // Note that there is a leading and trailing space, to make searching easier. std::string recognized = - " blanklines bulk color color.active color.due color.overdue color.pri.H " - "color.pri.L color.pri.M color.pri.none color.recurring color.tagged " - "color.footnote color.header color.debug color.alternate confirmation " - "curses data.location dateformat debug default.command default.priority " + " blanklines bulk calendar.details calendar.details.report color color.active " + "color.due color.overdue color.pri.H color.pri.L color.pri.M color.pri.none " + "color.recurring color.tagged color.footnote color.header color.debug color.alternate " + "confirmation curses data.location dateformat debug default.command default.priority " "default.project defaultwidth due locale displayweeknumber echo.command " "locking monthsperline nag next project shadow.command shadow.file " "shadow.notify weekstart editor import.synonym.id import.synonym.uuid " diff --git a/src/report.cpp b/src/report.cpp index c6ee4c776..7b748669a 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -1571,9 +1571,11 @@ int handleReportCalendar (std::string &outs) yTo++; } + int details_yFrom = yFrom; + int details_mFrom = mFrom; + std::stringstream out; out << std::endl; - std::string output; while (yFrom < yTo || (yFrom == yTo && mFrom <= mTo)) { @@ -1645,6 +1647,44 @@ int handleReportCalendar (std::string &outs) << optionalBlankLine () << std::endl; + if (context.config.get (std::string ("calendar.details"), false)) + { + --details_mFrom; + if (details_mFrom == 0) + { + details_mFrom = 12; + --details_yFrom; + } + int details_dFrom = Date::daysInMonth (details_mFrom, details_yFrom); + + ++mTo; + if (mTo == 13) + { + mTo = 1; + ++yTo; + } + + Date date_after (details_mFrom, details_dFrom, details_yFrom); + std::string after = date_after.toString (context.config.get ("dateformat", "m/d/Y")); + + Date date_before (mTo, 1, yTo); + std::string before = date_before.toString (context.config.get ("dateformat", "m/d/Y")); + + std::string report = context.config.get ("calendar.details.report", "list"); + std::string report_filter = context.config.get ("report." + report + ".filter"); + + report_filter += " due.after:" + after + " due.before:" + before; + context.config.set ("report." + report + ".filter", report_filter); + + context.args.clear (); + context.filter.clear (); + context.sequence.clear (); + + std::string output; + handleCustomReport (report, output); + out << output; + } + outs = out.str (); return 0; } diff --git a/src/tests/cal.t b/src/tests/cal.t index cfc037ca7..1bff4ce47 100755 --- a/src/tests/cal.t +++ b/src/tests/cal.t @@ -42,13 +42,15 @@ if (open my $fh, '>', 'cal.rc') close $fh; ok (-r 'cal.rc', 'Created cal.rc'); } + my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); -my ($day, $nmon, $nyear) = (localtime)[3,4,5]; -my $nextmonth = $months[($nmon+1) % 12]; -my $month = $months[($nmon) % 12]; +my ($nday, $nmon, $nyear) = (localtime)[3,4,5]; +my $day = $nday; my $prevmonth = $months[($nmon-1) % 12]; -my $nextyear = $nyear + 1901; -my $year = $nyear + 1900; +my $month = $months[($nmon) % 12]; +my $nextmonth = $months[($nmon+1) % 12]; +my $year = $nyear + 1900; +my $nextyear = $nyear + 1901; if ( $day <= 9) { @@ -123,11 +125,79 @@ unlike ($output, qr/May 2010/, 'May 2010 is not displayed'); # Cleanup. unlink 'pending.data'; ok (!-r 'pending.data', 'Removed pending.data'); - unlink 'undo.data'; ok (!-r 'undo.data', 'Removed undo.data'); - unlink 'cal.rc'; ok (!-r 'cal.rc', 'Removed cal.rc'); +# Create the rc file. +if (open my $fh, '>', 'details.rc') +{ + print $fh "data.location=.\n", + "dateformat=YMD\n", + "calendar.details=yes\n", + "calendar.details.report=list\n", + "color=on\n", + "confirmation=no\n"; + close $fh; + ok (-r 'details.rc', 'Created details.rc'); +} + +# task calendar details +qx{../task rc:details.rc add due:20150105 one}; +qx{../task rc:details.rc add due:20150110 two}; +qx{../task rc:details.rc add due:20150210 three}; +qx{../task rc:details.rc add due:20150410 four}; +qx{../task rc:details.rc add due:20151225 five}; +qx{../task rc:details.rc add due:20141231 six}; +qx{../task rc:details.rc add due:20160101 seven}; +qx{../task rc:details.rc add due:20081231 eight}; + +$output = qx{../task rc:details.rc cal rc.monthsperline:3 1 2015}; +like ($output, qr/January 2015/, 'January 2015 is displayed'); +like ($output, qr/20150105/, 'Due date 20150105 is displayed'); +like ($output, qr/20150110/, 'Due date 20150110 is displayed'); +like ($output, qr/20150210/, 'Due date 20150210 is displayed'); +unlike ($output, qr/20141231/, 'Due date 20141231 is not displayed'); +unlike ($output, qr/20150410/, 'Due date 20150410 is not displayed'); +like ($output, qr/3 tasks/, '3 due tasks are displayed'); + +$output = qx{../task rc:details.rc cal due}; +like ($output, qr/December 2008/, 'December 2008 is displayed'); +like ($output, qr/20081231/, 'Due date 20081231 is displayed'); +like ($output, qr/1 task/, '1 due task is displayed'); + +$output = qx{../task rc:details.rc cal 2015}; +like ($output, qr/January 2015/, 'January 2015 is displayed'); +like ($output, qr/December 2015/, 'December 2015 is displayed'); +unlike ($output, qr/20141231/, 'Due date 20141231 is not displayed'); +unlike ($output, qr/20160101/, 'Due date 20160101 is not displayed'); +like ($output, qr/5 tasks/, '5 due tasks are displayed'); + +$day = $nday; +if ( $day <= 9) +{ + $day = "0".$day; +} +my $mon = $nmon + 1; +if ( $mon <= 9) +{ + $mon = "0".$mon; +} +my $duedate = $year.$mon.$day; + +qx{../task rc:details.rc add due:$duedate rc.monthsperline:1 nine}; +$output = qx{../task rc:details.rc cal}; +like ($output, qr/$month\w+?\s+?$year/, 'Current month and year are displayed'); +like ($output, qr/$duedate/, 'Due date on current day is displayed'); +like ($output, qr/1 task/, '1 due task is displayed'); + +# Cleanup. +unlink 'pending.data'; +ok (!-r 'pending.data', 'Removed pending.data'); +unlink 'undo.data'; +ok (!-r 'undo.data', 'Removed undo.data'); +unlink 'details.rc'; +ok (!-r 'details.rc', 'Removed details.rc'); + exit 0;