mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Holidays
- added displaying of holidays in 'task cal' via calendar.holidays - the legend in the calendar can now be turned off - weeknumbers in the calendar can now be color-coded
This commit is contained in:
parent
f6f84aaf42
commit
a7244a999e
5 changed files with 247 additions and 73 deletions
|
@ -167,6 +167,7 @@ according to dateformat.
|
|||
|
||||
The default value is: m/d/Y. The string should contain the characters
|
||||
|
||||
.RS
|
||||
.RS
|
||||
m minimal-digit month, for example 1 or 12
|
||||
.br
|
||||
|
@ -190,10 +191,14 @@ B long name of month, for example January or August
|
|||
.br
|
||||
V weeknumber, for example 03 or 37
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.RS
|
||||
The string may also contain other characters to act as spacers, or formatting. Examples for other
|
||||
values of dateformat:
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.RS
|
||||
.br
|
||||
d/m/Y would use for input and output 24/7/2009
|
||||
|
@ -202,9 +207,13 @@ yMD would use for input and output 090724
|
|||
.br
|
||||
M-D-Y would use for input and output 07-24-2009
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.RS
|
||||
Examples for other values of reportdateformat:
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.RS
|
||||
.br
|
||||
a D b Y (V) would do an output as "Fri 24 Jul 2009 (30)"
|
||||
|
@ -213,6 +222,7 @@ A, B D, Y would do an output as "Friday, July 24, 2009"
|
|||
.br
|
||||
vV a Y-M-D would do an output as "v30 Fri 2009-07.24"
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B weekstart=Sunday
|
||||
|
@ -228,14 +238,48 @@ 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
|
||||
.B calendar.details=sparse
|
||||
If set to full running "task calendar" will display the details of tasks with due dates
|
||||
that fall into the calendar period. The corresponding days will be color-coded in the
|
||||
calendar. If set to sparse only the corresponding days will be color coded and no details
|
||||
will be displayed. The displaying of due dates with details is turned off by setting the
|
||||
variable to none.
|
||||
|
||||
.TP calendar.details.report=list
|
||||
.TP
|
||||
.B 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 calendar.holidays=full
|
||||
If set to full running "task calendar" will display holidays in the calendar by color-coding
|
||||
the corresponding days. A detailed list with the dates and names of the holidays is also shown.
|
||||
If set to sparse only the days are color-coded and no details on the holidays will be
|
||||
displayed. The displaying of holidays is turned off by setting the variable to none.
|
||||
|
||||
.TP
|
||||
.B Holidays
|
||||
Holidays are entered either directly in the .taskrc file or via an include file that is specified
|
||||
in .taskrc. For each holiday the name and the date is required to be given:
|
||||
|
||||
.RS
|
||||
.RS
|
||||
.br
|
||||
holiday.towel.name=Day of the towel
|
||||
.br
|
||||
holiday.towel.date=20100525
|
||||
.br
|
||||
holiday.sysadmin.name=System Administrator Appreciation Day
|
||||
.br
|
||||
holiday.sysadmin.date=20100730
|
||||
.RE
|
||||
.RE
|
||||
|
||||
.RS
|
||||
Dates are to be entered according to the setting in the dateformat variable.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B monthsperline=2
|
||||
Determines how many months the "task calendar" command renders across the screen.
|
||||
|
@ -351,8 +395,16 @@ Color of days with due tasks in calendar.
|
|||
Color of days with overdue tasks in calendar.
|
||||
|
||||
.TP
|
||||
.B color.calendar.weekend=black on white
|
||||
.B color.calendar.weekend=bright white on black
|
||||
Color of weekend days in calendar.
|
||||
|
||||
.TP
|
||||
.B color.calendar.holiday=black on bright yellow
|
||||
Color of holidays in calendar.
|
||||
|
||||
.TP
|
||||
.B color.calendar.weeknumber=black on white
|
||||
Color of weeknumbers in calendar.
|
||||
.RE
|
||||
|
||||
.SS SHADOW FILE
|
||||
|
|
|
@ -70,8 +70,10 @@ std::string Config::defaults =
|
|||
"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.legend=yes # Display the legend on calendar\n"
|
||||
"#calendar.details=full # Calendar shows information for tasks w/due dates\n"
|
||||
"#calendar.details.report=list # Report to use when showing task information in cal\n"
|
||||
"#calendar.holidays=none # Show public holidays on calendar\n"
|
||||
"#monthsperline=3 # Number of calendar months on a line\n" // TODO
|
||||
"\n"
|
||||
"# Color controls.\n"
|
||||
|
@ -94,12 +96,10 @@ std::string Config::defaults =
|
|||
"color.calendar.today=black on cyan # Color of today in calendar\n"
|
||||
"color.calendar.due=black on green # Color of days with due tasks in calendar\n"
|
||||
"color.calendar.overdue=black on red # Color of days with overdue tasks in calendar\n"
|
||||
"color.calendar.weekend=black on white # Color of weekend days in calendar\n"
|
||||
"color.calendar.weekend=bright white on black # Color of weekend days in calendar\n"
|
||||
"color.calendar.holiday=black on bright yellow # Color of public holidays in calendar\n"
|
||||
"color.calendar.weeknumber=black on white # Color of the weeknumbers in calendar\n"
|
||||
"#color.debug=magenta # Color of diagnostic output\n"
|
||||
"color.pri.H=bold # Color of priority:H tasks\n"
|
||||
"color.history.add=on red # Color of added tasks in the history reports\n"
|
||||
"color.history.delete=on yellow # Color of deleted tasks in the history reports\n"
|
||||
"color.history.done=on green # Color of completed tasks in the history reports\n"
|
||||
"\n"
|
||||
"# Shadow file support\n"
|
||||
"#shadow.file=/tmp/shadow.txt # Location of shadow file\n"
|
||||
|
|
|
@ -649,15 +649,15 @@ 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 =
|
||||
" annotations 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 "
|
||||
"color.calendar.today color.calendar.due color.calendar.overdue color.calendar.weekend "
|
||||
"confirmation curses data.location dateformat reportdateformat 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 "
|
||||
"complete.all.projects complete.all.tags "
|
||||
" annotations blanklines bulk calendar.details calendar.details.report calendar.holidays "
|
||||
"calendar.legend 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 color.calendar.today color.calendar.due color.calendar.overdue "
|
||||
"color.calendar.weekend color.calendar.holiday color.calendar.weeknumber confirmation "
|
||||
"curses data.location dateformat reportdateformat debug default.command default.priority "
|
||||
"default.project defaultwidth due locale displayweeknumber echo.command fontunderline "
|
||||
"locking monthsperline nag next project shadow.command shadow.file shadow.notify weekstart "
|
||||
"editor import.synonym.id import.synonym.uuid complete.all.projects complete.all.tags "
|
||||
#ifdef FEATURE_SHELL
|
||||
"shell.prompt "
|
||||
#endif
|
||||
|
@ -684,6 +684,7 @@ int handleConfig (std::string &outs)
|
|||
if (i->substr (0, 14) != "color.keyword." &&
|
||||
i->substr (0, 14) != "color.project." &&
|
||||
i->substr (0, 10) != "color.tag." &&
|
||||
i->substr (0, 8) != "holiday." &&
|
||||
i->substr (0, 7) != "report." &&
|
||||
i->substr (0, 6) != "alias.")
|
||||
{
|
||||
|
|
113
src/report.cpp
113
src/report.cpp
|
@ -1416,6 +1416,13 @@ std::string renderMonths (
|
|||
|
||||
int row = 0;
|
||||
|
||||
Color color_today (context.config.get ("color.calendar.today"));
|
||||
Color color_due (context.config.get ("color.calendar.due"));
|
||||
Color color_overdue (context.config.get ("color.calendar.overdue"));
|
||||
Color color_weekend (context.config.get ("color.calendar.weekend"));
|
||||
Color color_holiday (context.config.get ("color.calendar.holiday"));
|
||||
Color color_weeknumber (context.config.get ("color.calendar.weeknumber"));
|
||||
|
||||
// Loop through months to be added on this line.
|
||||
for (int mpl = 0; mpl < monthsPerLine ; mpl++)
|
||||
{
|
||||
|
@ -1431,7 +1438,11 @@ std::string renderMonths (
|
|||
int woy = temp.weekOfYear (weekStart);
|
||||
|
||||
if (context.config.getBoolean ("displayweeknumber"))
|
||||
{
|
||||
table.addCell (row, (8 * mpl), woy);
|
||||
if (context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor"))
|
||||
table.setCellColor (row, (8 * mpl), color_weeknumber);
|
||||
}
|
||||
|
||||
// Calculate column id.
|
||||
int thisCol = dow + // 0 = Sunday
|
||||
|
@ -1443,22 +1454,39 @@ std::string renderMonths (
|
|||
|
||||
table.addCell (row, thisCol, d);
|
||||
|
||||
Color color_today (context.config.get ("color.calendar.today"));
|
||||
Color color_due (context.config.get ("color.calendar.due"));
|
||||
Color color_overdue (context.config.get ("color.calendar.overdue"));
|
||||
Color color_weekend (context.config.get ("color.calendar.weekend"));
|
||||
|
||||
if (context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor"))
|
||||
{
|
||||
|
||||
// colorize weekends
|
||||
if (dow == 0 || dow == 6)
|
||||
table.setCellColor (row, thisCol, color_weekend);
|
||||
|
||||
// colorize holidays
|
||||
if (context.config.get ("calendar.holidays") != "none")
|
||||
{
|
||||
std::vector <std::string> holidays;
|
||||
context.config.all (holidays);
|
||||
foreach (hol, holidays)
|
||||
if (hol->substr (0, 8) == "holiday.")
|
||||
if (hol->substr (hol->size () - 4) == "date")
|
||||
{
|
||||
std::string value = context.config.get (*hol);
|
||||
Date holDate (value.c_str (), context.config.get ("dateformat"));
|
||||
if (holDate.day () == d &&
|
||||
holDate.month () == months[mpl] &&
|
||||
holDate.year () == years[mpl])
|
||||
table.setCellColor (row, thisCol, color_holiday);
|
||||
}
|
||||
}
|
||||
|
||||
// colorize today
|
||||
if (today.day () == d &&
|
||||
today.month () == months.at (mpl) &&
|
||||
today.year () == years.at (mpl))
|
||||
table.setCellColor (row, thisCol, color_today);
|
||||
}
|
||||
|
||||
// colorize due tasks
|
||||
if (context.config.get ("calendar.details") != "none")
|
||||
foreach (task, all)
|
||||
{
|
||||
if (task->getStatus () == Task::pending &&
|
||||
|
@ -1466,13 +1494,13 @@ std::string renderMonths (
|
|||
{
|
||||
Date due (atoi (task->get ("due").c_str ()));
|
||||
|
||||
if ((context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor")) &&
|
||||
due.day () == d &&
|
||||
if (due.day () == d &&
|
||||
due.month () == months[mpl] &&
|
||||
due.year () == years[mpl])
|
||||
table.setCellColor (row, thisCol, (due < today ? color_overdue : color_due));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for end of week, and...
|
||||
int eow = 6;
|
||||
|
@ -1656,8 +1684,11 @@ int handleReportCalendar (std::string &outs)
|
|||
Color color_due (context.config.get ("color.calendar.due"));
|
||||
Color color_overdue (context.config.get ("color.calendar.overdue"));
|
||||
Color color_weekend (context.config.get ("color.calendar.weekend"));
|
||||
Color color_holiday (context.config.get ("color.calendar.holiday"));
|
||||
Color color_weeknumber (context.config.get ("color.calendar.weeknumber"));
|
||||
|
||||
if (context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor"))
|
||||
if ((context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor")) &&
|
||||
context.config.getBoolean ("calendar.legend"))
|
||||
out << "Legend: "
|
||||
<< color_today.colorize ("today")
|
||||
<< ", "
|
||||
|
@ -1666,11 +1697,15 @@ int handleReportCalendar (std::string &outs)
|
|||
<< color_overdue.colorize ("overdue")
|
||||
<< ", "
|
||||
<< color_weekend.colorize ("weekend")
|
||||
<< ", "
|
||||
<< color_holiday.colorize ("holiday")
|
||||
<< ", "
|
||||
<< color_weeknumber.colorize ("weeknumber")
|
||||
<< "."
|
||||
<< optionalBlankLine ()
|
||||
<< std::endl;
|
||||
|
||||
if (context.config.getBoolean ("calendar.details"))
|
||||
if (context.config.get ("calendar.details") == "full" || context.config.get ("calendar.holidays") == "full")
|
||||
{
|
||||
--details_mFrom;
|
||||
if (details_mFrom == 0)
|
||||
|
@ -1693,6 +1728,9 @@ int handleReportCalendar (std::string &outs)
|
|||
Date date_before (mTo, 1, yTo);
|
||||
std::string before = date_before.toString (context.config.get ("dateformat"));
|
||||
|
||||
// Table with due date information
|
||||
if (context.config.get ("calendar.details") == "full")
|
||||
{
|
||||
std::string report = context.config.get ("calendar.details.report");
|
||||
std::string report_filter = context.config.get ("report." + report + ".filter");
|
||||
|
||||
|
@ -1711,6 +1749,61 @@ int handleReportCalendar (std::string &outs)
|
|||
out << output;
|
||||
}
|
||||
|
||||
// Table with holiday information
|
||||
if (context.config.get ("calendar.holidays") == "full")
|
||||
{
|
||||
std::vector <std::string> holidays;
|
||||
context.config.all (holidays);
|
||||
|
||||
Table holTable;
|
||||
holTable.setTableWidth (context.getWidth ());
|
||||
holTable.addColumn ("Date");
|
||||
holTable.addColumn ("Holiday");
|
||||
|
||||
if ((context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor")) &&
|
||||
context.config.getBoolean ("fontunderline"))
|
||||
{
|
||||
holTable.setColumnUnderline (0);
|
||||
holTable.setColumnUnderline (1);
|
||||
}
|
||||
else
|
||||
holTable.setTableDashedUnderline ();
|
||||
|
||||
holTable.setColumnWidth (0, Table::minimum);
|
||||
holTable.setColumnWidth (1, Table::flexible);
|
||||
|
||||
holTable.setColumnJustification (0, Table::left);
|
||||
holTable.setColumnJustification (1, Table::left);
|
||||
|
||||
foreach (hol, holidays)
|
||||
if (hol->substr (0, 8) == "holiday.")
|
||||
if (hol->substr (hol->size () - 4) == "name")
|
||||
{
|
||||
std::string holName = context.config.get ("holiday." + hol->substr (8, hol->size () - 13) + ".name");
|
||||
std::string holDate = context.config.get ("holiday." + hol->substr (8, hol->size () - 13) + ".date");
|
||||
Date hDate (holDate.c_str (), context.config.get ("dateformat"));
|
||||
|
||||
if (date_after < hDate && hDate < date_before)
|
||||
{
|
||||
std::string format = context.config.get ("report." +
|
||||
context.config.get ("calendar.details.report") +
|
||||
".dateformat");
|
||||
if (format == "")
|
||||
format = context.config.get ("reportdateformat");
|
||||
if (format == "")
|
||||
format = context.config.get ("dateformat");
|
||||
|
||||
int row = holTable.addRow ();
|
||||
holTable.addCell (row, 0, hDate.toString (format));
|
||||
holTable.addCell (row, 1, holName);
|
||||
}
|
||||
}
|
||||
out << optionalBlankLine ()
|
||||
<< holTable.render ()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 60;
|
||||
use Test::More tests => 75;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'cal.rc')
|
||||
|
@ -99,8 +99,9 @@ qx{../task rc:cal.rc add due:20080408 three};
|
|||
$output = qx{../task rc:cal.rc rc._forcecolor:on cal due};
|
||||
like ($output, qr/April 2008/, 'April 2008 is displayed');
|
||||
like ($output, qr/41m 8/, 'Task 3 is color-coded overdue');
|
||||
like ($output, qr/30;47m19/, 'Saturday April 19, 2008 is color-coded');
|
||||
like ($output, qr/30;47m20/, 'Sunday April 20, 2008 is color-coded');
|
||||
like ($output, qr/37;100m19/, 'Saturday April 19, 2008 is color-coded');
|
||||
like ($output, qr/37;100m20/, 'Sunday April 20, 2008 is color-coded');
|
||||
like ($output, qr/30;47m 1/, 'Weeknumbers are color-coded');
|
||||
|
||||
# task cal 2016
|
||||
$output = qx{../task rc:cal.rc rc.weekstart:Monday cal 2016};
|
||||
|
@ -137,10 +138,17 @@ if (open my $fh, '>', 'details.rc')
|
|||
{
|
||||
print $fh "data.location=.\n",
|
||||
"dateformat=YMD\n",
|
||||
"calendar.details=yes\n",
|
||||
"calendar.details=full\n",
|
||||
"calendar.details.report=list\n",
|
||||
"calendar.holidays=full\n",
|
||||
"color=on\n",
|
||||
"confirmation=no\n";
|
||||
"confirmation=no\n",
|
||||
"holiday.AAAA.name=AAAA\n",
|
||||
"holiday.AAAA.date=20150101\n",
|
||||
"holiday.BBBBBB.name=BBBBBB\n",
|
||||
"holiday.BBBBBB.date=20150115\n",
|
||||
"holiday.åäö.name=åäö\n",
|
||||
"holiday.åäö.date=20150125\n";
|
||||
close $fh;
|
||||
ok (-r 'details.rc', 'Created details.rc');
|
||||
}
|
||||
|
@ -155,6 +163,9 @@ 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 rc.calendar.legend:no cal};
|
||||
unlike ($output, qr/Legend:/, 'Legend is not displayed');
|
||||
|
||||
$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');
|
||||
|
@ -194,6 +205,23 @@ 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');
|
||||
|
||||
$output = qx{../task rc:details.rc cal rc.monthsperline:1 1 2015};
|
||||
like ($output, qr/Date/, 'Word Date is displayed');
|
||||
like ($output, qr/Holiday/, 'Word Holiday is displayed');
|
||||
like ($output, qr/20150101/, 'Holiday 20150101 is displayed');
|
||||
like ($output, qr/20150115/, 'Holiday 20150115 is displayed');
|
||||
like ($output, qr/20150125/, 'Holiday 20150125 is displayed');
|
||||
like ($output, qr/AAAA/, 'Holiday name AAAA is displayed');
|
||||
like ($output, qr/BBBBBB/, 'Holiday name BBBBBB is displayed');
|
||||
like ($output, qr/åäö/, 'Holiday name åäö is displayed');
|
||||
|
||||
$output = qx{../task rc:details.rc cal rc._forcecolor:on rc.monthsperline:1 rc.calendar.details:sparse rc.calendar.holidays:sparse 1 2015};
|
||||
unlike ($output, qr/Date/, 'Word Date is not displayed');
|
||||
unlike ($output, qr/Holiday/, 'Word Holiday is not displayed');
|
||||
like ($output, qr/30;103m 1/, 'Holiday AAAA is color-coded');
|
||||
like ($output, qr/30;103m15/, 'Holiday BBBBBB is color-coded');
|
||||
like ($output, qr/30;103m25/, 'Holiday åäö is color-coded');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue