mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
- "task calendar" now lists all months that contain pending due tasks.
This commit is contained in:
parent
86a9f0f6d5
commit
b061ef6191
6 changed files with 86 additions and 135 deletions
|
@ -213,28 +213,28 @@ std::string Date::dayName (int dow)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Date::dayOfWeek ()
|
int Date::dayOfWeek () const
|
||||||
{
|
{
|
||||||
struct tm* t = localtime (&mT);
|
struct tm* t = localtime (&mT);
|
||||||
return t->tm_wday;
|
return t->tm_wday;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Date::month ()
|
int Date::month () const
|
||||||
{
|
{
|
||||||
struct tm* t = localtime (&mT);
|
struct tm* t = localtime (&mT);
|
||||||
return t->tm_mon + 1;
|
return t->tm_mon + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Date::day ()
|
int Date::day () const
|
||||||
{
|
{
|
||||||
struct tm* t = localtime (&mT);
|
struct tm* t = localtime (&mT);
|
||||||
return t->tm_mday;
|
return t->tm_mday;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Date::year ()
|
int Date::year () const
|
||||||
{
|
{
|
||||||
struct tm* t = localtime (&mT);
|
struct tm* t = localtime (&mT);
|
||||||
return t->tm_year + 1900;
|
return t->tm_year + 1900;
|
||||||
|
|
|
@ -32,11 +32,11 @@ public:
|
||||||
static std::string monthName (int);
|
static std::string monthName (int);
|
||||||
static void dayName (int, std::string&);
|
static void dayName (int, std::string&);
|
||||||
static std::string dayName (int);
|
static std::string dayName (int);
|
||||||
int dayOfWeek ();
|
int dayOfWeek () const;
|
||||||
|
|
||||||
int month ();
|
int month () const;
|
||||||
int day ();
|
int day () const;
|
||||||
int year ();
|
int year () const;
|
||||||
|
|
||||||
bool operator== (const Date&);
|
bool operator== (const Date&);
|
||||||
bool operator!= (const Date&);
|
bool operator!= (const Date&);
|
||||||
|
|
38
src/Grid.cpp
38
src/Grid.cpp
|
@ -145,9 +145,9 @@ unsigned int Grid::height () const
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Grid::Cell* Grid::byRow (const unsigned int row, const unsigned int col) const
|
Grid::Cell* Grid::byRow (const unsigned int row, const unsigned int col) const
|
||||||
{
|
{
|
||||||
if (row <= mRows.size () &&
|
if (row < mRows.size () &&
|
||||||
mRows[row] != NULL &&
|
mRows[row] != NULL &&
|
||||||
col <= mRows[row]->size ())
|
col < mRows[row]->size ())
|
||||||
return (*mRows[row])[col];
|
return (*mRows[row])[col];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -155,9 +155,9 @@ Grid::Cell* Grid::byRow (const unsigned int row, const unsigned int col) const
|
||||||
|
|
||||||
Grid::Cell* Grid::byColumn (const unsigned int row, const unsigned int col) const
|
Grid::Cell* Grid::byColumn (const unsigned int row, const unsigned int col) const
|
||||||
{
|
{
|
||||||
if (col <= mColumns.size () &&
|
if (col < mColumns.size () &&
|
||||||
mColumns[col] != NULL &&
|
mColumns[col] != NULL &&
|
||||||
row <= mColumns[col]->size ())
|
row < mColumns[col]->size ())
|
||||||
return (*mColumns[col])[row];
|
return (*mColumns[col])[row];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -166,36 +166,25 @@ Grid::Cell* Grid::byColumn (const unsigned int row, const unsigned int col) cons
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Grid::expandGrid (const unsigned int row, const unsigned int col)
|
void Grid::expandGrid (const unsigned int row, const unsigned int col)
|
||||||
{
|
{
|
||||||
|
|
||||||
// If the new row is outside the bounds of the current grid, add blank rows to
|
// If the new row is outside the bounds of the current grid, add blank rows to
|
||||||
// pad, then a new row vector.
|
// pad, then a new row vector.
|
||||||
if (row >= mRows.size ())
|
if (row >= mRows.size ())
|
||||||
{
|
{
|
||||||
for (unsigned int r = mRows.size (); r <= row; ++r)
|
for (unsigned int r = mRows.size (); r <= row; ++r)
|
||||||
if (r < row)
|
if (r < row)
|
||||||
// {
|
|
||||||
// std::cout << "additional mRows[" << r << "] = NULL" << std::endl;
|
|
||||||
mRows.push_back (NULL);
|
mRows.push_back (NULL);
|
||||||
// }
|
|
||||||
else
|
else
|
||||||
// {
|
|
||||||
// std::cout << "additional mRows[" << r << "] = new std::vector <Cell*>" << std::endl;
|
|
||||||
mRows.push_back (new std::vector <Cell*>);
|
mRows.push_back (new std::vector <Cell*>);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// If the new row is within the bounds of the current grid, ensure that the
|
// If the new row is within the bounds of the current grid, ensure that the
|
||||||
// row points to a vector of cells.
|
// row points to a vector of cells.
|
||||||
else if (mRows[row] == NULL)
|
else if (mRows[row] == NULL)
|
||||||
// {
|
|
||||||
// std::cout << "existing mRows[" << row << "] = new std::vector <Cell*>" << std::endl;
|
|
||||||
mRows[row] = new std::vector <Cell*>;
|
mRows[row] = new std::vector <Cell*>;
|
||||||
// }
|
|
||||||
|
|
||||||
if (col >= mRows[row]->size ())
|
if (col >= mRows[row]->size ())
|
||||||
for (unsigned int c = mRows[row]->size (); c <= col; ++c)
|
for (unsigned int c = mRows[row]->size (); c <= col; ++c)
|
||||||
// {
|
|
||||||
// std::cout << "additional mRows[" << row << "][" << c << "] = NULL" << std::endl;
|
|
||||||
mRows[row]->push_back (NULL);
|
mRows[row]->push_back (NULL);
|
||||||
// }
|
|
||||||
|
|
||||||
// If the new col is outside the bounds of the current grid, add blank cols to
|
// If the new col is outside the bounds of the current grid, add blank cols to
|
||||||
// pad, then a new col vector.
|
// pad, then a new col vector.
|
||||||
|
@ -203,30 +192,18 @@ void Grid::expandGrid (const unsigned int row, const unsigned int col)
|
||||||
{
|
{
|
||||||
for (unsigned int c = mColumns.size (); c <= col; ++c)
|
for (unsigned int c = mColumns.size (); c <= col; ++c)
|
||||||
if (c < col)
|
if (c < col)
|
||||||
// {
|
|
||||||
// std::cout << "additional mColumns[" << c << "] = NULL" << std::endl;
|
|
||||||
mColumns.push_back (NULL);
|
mColumns.push_back (NULL);
|
||||||
// }
|
|
||||||
else
|
else
|
||||||
// {
|
|
||||||
// std::cout << "additional mColumns[" << c << "] = new std::vector <Cell*>" << std::endl;
|
|
||||||
mColumns.push_back (new std::vector <Cell*>);
|
mColumns.push_back (new std::vector <Cell*>);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// If the new col is within the bounds of the current grid, ensure that the
|
// If the new col is within the bounds of the current grid, ensure that the
|
||||||
// col points to a vector of cells.
|
// col points to a vector of cells.
|
||||||
else if (mColumns[col] == NULL)
|
else if (mColumns[col] == NULL)
|
||||||
// {
|
|
||||||
// std::cout << "existing mColumns[" << col << "] = new std::vector <Cell*>" << std::endl;
|
|
||||||
mColumns[col] = new std::vector <Cell*>;
|
mColumns[col] = new std::vector <Cell*>;
|
||||||
// }
|
|
||||||
|
|
||||||
if (row >= mColumns[col]->size ())
|
if (row >= mColumns[col]->size ())
|
||||||
for (unsigned int r = mColumns[col]->size (); r <= row; ++r)
|
for (unsigned int r = mColumns[col]->size (); r <= row; ++r)
|
||||||
// {
|
|
||||||
// std::cout << "additional mColumns[" << col << "][" << r << "] = NULL" << std::endl;
|
|
||||||
mColumns[col]->push_back (NULL);
|
mColumns[col]->push_back (NULL);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -237,15 +214,10 @@ void Grid::insertCell (
|
||||||
{
|
{
|
||||||
// Delete any existing cell, because cells are owned by rows, not columns.
|
// Delete any existing cell, because cells are owned by rows, not columns.
|
||||||
if ((*mRows[row])[col] != NULL)
|
if ((*mRows[row])[col] != NULL)
|
||||||
// {
|
|
||||||
// std::cout << "deleted old cell mRows[" << row << "][" << col << "]" << std::endl;
|
|
||||||
delete (*mRows[row])[col];
|
delete (*mRows[row])[col];
|
||||||
// }
|
|
||||||
|
|
||||||
(*mRows[row])[col] = cell;
|
(*mRows[row])[col] = cell;
|
||||||
(*mColumns[col])[row] = cell;
|
(*mColumns[col])[row] = cell;
|
||||||
// std::cout << "assigned new cell mRows[" << row << "][" << col << "]" << std::endl;
|
|
||||||
// std::cout << "assigned new cell mColumns[" << col << "][" << row << "]" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -632,57 +632,6 @@ void Table::formatCell (
|
||||||
blank = Text::colorize (fg, bg, pad + intraPad);
|
blank = Text::colorize (fg, bg, pad + intraPad);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
const std::string Table::formatCell (
|
|
||||||
const int row,
|
|
||||||
const int col,
|
|
||||||
const int width,
|
|
||||||
const int padding)
|
|
||||||
{
|
|
||||||
assert (width > 0);
|
|
||||||
|
|
||||||
Text::color fg = getFg (row, col);
|
|
||||||
Text::color bg = getBg (row, col);
|
|
||||||
just justification = getJustification (row, col);
|
|
||||||
std::string data = getCell (row, col);
|
|
||||||
|
|
||||||
std::string pad = "";
|
|
||||||
std::string intraPad = "";
|
|
||||||
std::string preJust = "";
|
|
||||||
std::string postJust = "";
|
|
||||||
|
|
||||||
for (int i = 0; i < padding; ++i)
|
|
||||||
pad += " ";
|
|
||||||
|
|
||||||
// Place the data within the available space - justify.
|
|
||||||
int gap = width - data.length ();
|
|
||||||
|
|
||||||
if (justification == left)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < gap; ++i)
|
|
||||||
postJust += " ";
|
|
||||||
}
|
|
||||||
else if (justification == right)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < gap; ++i)
|
|
||||||
preJust += " ";
|
|
||||||
}
|
|
||||||
else if (justification == center)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < gap / 2; ++i)
|
|
||||||
preJust += " ";
|
|
||||||
|
|
||||||
for (size_t i = 0; i < gap - preJust.length (); ++i)
|
|
||||||
postJust += " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col < (signed) mColumns.size () - 1)
|
|
||||||
for (int i = 0; i < getIntraPadding (); ++i)
|
|
||||||
intraPad += " ";
|
|
||||||
|
|
||||||
return Text::colorize (fg, bg, pad + preJust + data + postJust + pad + intraPad);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Table::suppressWS ()
|
void Table::suppressWS ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,6 @@ private:
|
||||||
just getJustification (const int, const int);
|
just getJustification (const int, const int);
|
||||||
just getHeaderJustification (const int);
|
just getHeaderJustification (const int);
|
||||||
const std::string formatHeader (const int, const int, const int);
|
const std::string formatHeader (const int, const int, const int);
|
||||||
const std::string formatCell (const int, const int, const int, const int);
|
|
||||||
void formatCell (const int, const int, const int, const int, std::vector <std::string>&, std::string&);
|
void formatCell (const int, const int, const int, const int, std::vector <std::string>&, std::string&);
|
||||||
void optimize (std::string&);
|
void optimize (std::string&);
|
||||||
void sort (std::vector <int>&);
|
void sort (std::vector <int>&);
|
||||||
|
|
115
src/task.cpp
115
src/task.cpp
|
@ -1824,32 +1824,15 @@ void handleReportUsage (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
std::string renderMonth (
|
||||||
|
int month,
|
||||||
|
int year,
|
||||||
|
const Date& today,
|
||||||
|
std::vector <T>& all,
|
||||||
|
Config& conf)
|
||||||
{
|
{
|
||||||
// Today.
|
|
||||||
Date date;
|
|
||||||
int m = date.month ();
|
|
||||||
int y = date.year ();
|
|
||||||
int today = date.day ();
|
|
||||||
|
|
||||||
// Read all the tasks, filter by those that have a due date.
|
|
||||||
std::vector <int> annotations;
|
|
||||||
std::vector <T> pending;
|
|
||||||
tdb.pendingT (pending);
|
|
||||||
for (unsigned int i = 0; i < pending.size (); ++i)
|
|
||||||
{
|
|
||||||
T task (pending[i]);
|
|
||||||
if (task.getAttribute ("due") != "")
|
|
||||||
{
|
|
||||||
Date d (::atoi (task.getAttribute ("due").c_str ()));
|
|
||||||
if (d.year () == y && d.month () == m)
|
|
||||||
annotations.push_back (d.day ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pending.clear ();
|
|
||||||
|
|
||||||
Table table;
|
Table table;
|
||||||
|
table.addColumn (" ");
|
||||||
table.addColumn ("Su");
|
table.addColumn ("Su");
|
||||||
table.addColumn ("Mo");
|
table.addColumn ("Mo");
|
||||||
table.addColumn ("Tu");
|
table.addColumn ("Tu");
|
||||||
|
@ -1858,13 +1841,13 @@ void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||||
table.addColumn ("Fr");
|
table.addColumn ("Fr");
|
||||||
table.addColumn ("Sa");
|
table.addColumn ("Sa");
|
||||||
|
|
||||||
table.setColumnUnderline (0);
|
|
||||||
table.setColumnUnderline (1);
|
table.setColumnUnderline (1);
|
||||||
table.setColumnUnderline (2);
|
table.setColumnUnderline (2);
|
||||||
table.setColumnUnderline (3);
|
table.setColumnUnderline (3);
|
||||||
table.setColumnUnderline (4);
|
table.setColumnUnderline (4);
|
||||||
table.setColumnUnderline (5);
|
table.setColumnUnderline (5);
|
||||||
table.setColumnUnderline (6);
|
table.setColumnUnderline (6);
|
||||||
|
table.setColumnUnderline (7);
|
||||||
|
|
||||||
table.setColumnJustification (0, Table::right);
|
table.setColumnJustification (0, Table::right);
|
||||||
table.setColumnJustification (1, Table::right);
|
table.setColumnJustification (1, Table::right);
|
||||||
|
@ -1873,25 +1856,35 @@ void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||||
table.setColumnJustification (4, Table::right);
|
table.setColumnJustification (4, Table::right);
|
||||||
table.setColumnJustification (5, Table::right);
|
table.setColumnJustification (5, Table::right);
|
||||||
table.setColumnJustification (6, Table::right);
|
table.setColumnJustification (6, Table::right);
|
||||||
|
table.setColumnJustification (7, Table::right);
|
||||||
|
|
||||||
int days = Date::daysInMonth (m, y);
|
int days = Date::daysInMonth (month, year);
|
||||||
int row = table.addRow ();
|
int row = table.addRow ();
|
||||||
for (int d = 1; d <= days; ++d)
|
for (int d = 1; d <= days; ++d)
|
||||||
{
|
{
|
||||||
Date temp (m, d, y);
|
Date temp (month, d, year);
|
||||||
int dow = temp.dayOfWeek ();
|
int dow = temp.dayOfWeek ();
|
||||||
|
|
||||||
table.addCell (row, dow, d);
|
table.addCell (row, dow + 1, d);
|
||||||
|
|
||||||
if (conf.get ("color", true) && d == today)
|
if (conf.get ("color", true) &&
|
||||||
table.setCellFg (row, dow, Text::cyan);
|
today.day () == d &&
|
||||||
|
today.month () == month &&
|
||||||
|
today.year () == year)
|
||||||
|
table.setCellFg (row, dow + 1, Text::cyan);
|
||||||
|
|
||||||
for (unsigned int a = 0; a < annotations.size (); ++a)
|
std::vector <T>::iterator it;
|
||||||
|
for (it = all.begin (); it != all.end (); ++it)
|
||||||
{
|
{
|
||||||
if (conf.get ("color", true) && annotations[a] == d)
|
Date due (::atoi (it->getAttribute ("due").c_str ()));
|
||||||
|
|
||||||
|
if (conf.get ("color", true) &&
|
||||||
|
due.day () == d &&
|
||||||
|
due.month () == month &&
|
||||||
|
due.year () == year)
|
||||||
{
|
{
|
||||||
table.setCellFg (row, dow, Text::black);
|
table.setCellFg (row, dow + 1, Text::black);
|
||||||
table.setCellBg (row, dow, d < today ? Text::red : Text::yellow);
|
table.setCellBg (row, dow + 1, d < today.day () ? Text::red : Text::yellow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1899,14 +1892,52 @@ void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||||
row = table.addRow ();
|
row = table.addRow ();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl
|
return table.render ();
|
||||||
<< Date::monthName (m)
|
}
|
||||||
<< " "
|
|
||||||
<< y
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
<< std::endl
|
void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||||
<< std::endl
|
{
|
||||||
<< table.render ()
|
// Load all the pending tasks.
|
||||||
<< std::endl;
|
std::vector <T> pending;
|
||||||
|
tdb.pendingT (pending);
|
||||||
|
|
||||||
|
// Find the oldest pending due date.
|
||||||
|
Date oldest;
|
||||||
|
std::vector <T>::iterator it;
|
||||||
|
for (it = pending.begin (); it != pending.end (); ++it)
|
||||||
|
{
|
||||||
|
if (it->getAttribute ("due") != "")
|
||||||
|
{
|
||||||
|
Date d (::atoi (it->getAttribute ("due").c_str ()));
|
||||||
|
if (d < oldest)
|
||||||
|
oldest = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate from oldest due month, year to now.
|
||||||
|
Date today;
|
||||||
|
int m = oldest.month ();
|
||||||
|
int y = oldest.year ();
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::string output;
|
||||||
|
while (y < today.year () || (y == today.year () && m <= today.month ()))
|
||||||
|
{
|
||||||
|
std::cout << Date::monthName (m)
|
||||||
|
<< " "
|
||||||
|
<< y
|
||||||
|
<< std::endl
|
||||||
|
<< std::endl
|
||||||
|
<< renderMonth (m, y, today, pending, conf)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (++m == 13)
|
||||||
|
{
|
||||||
|
m = 1;
|
||||||
|
++y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue