mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +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);
|
||||
return t->tm_wday;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::month ()
|
||||
int Date::month () const
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_mon + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::day ()
|
||||
int Date::day () const
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_mday;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Date::year ()
|
||||
int Date::year () const
|
||||
{
|
||||
struct tm* t = localtime (&mT);
|
||||
return t->tm_year + 1900;
|
||||
|
|
|
@ -32,11 +32,11 @@ public:
|
|||
static std::string monthName (int);
|
||||
static void dayName (int, std::string&);
|
||||
static std::string dayName (int);
|
||||
int dayOfWeek ();
|
||||
int dayOfWeek () const;
|
||||
|
||||
int month ();
|
||||
int day ();
|
||||
int year ();
|
||||
int month () const;
|
||||
int day () const;
|
||||
int year () const;
|
||||
|
||||
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
|
||||
{
|
||||
if (row <= mRows.size () &&
|
||||
if (row < mRows.size () &&
|
||||
mRows[row] != NULL &&
|
||||
col <= mRows[row]->size ())
|
||||
col < mRows[row]->size ())
|
||||
return (*mRows[row])[col];
|
||||
|
||||
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
|
||||
{
|
||||
if (col <= mColumns.size () &&
|
||||
if (col < mColumns.size () &&
|
||||
mColumns[col] != NULL &&
|
||||
row <= mColumns[col]->size ())
|
||||
row < mColumns[col]->size ())
|
||||
return (*mColumns[col])[row];
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
// If the new row is outside the bounds of the current grid, add blank rows to
|
||||
// pad, then a new row vector.
|
||||
if (row >= mRows.size ())
|
||||
{
|
||||
for (unsigned int r = mRows.size (); r <= row; ++r)
|
||||
if (r < row)
|
||||
// {
|
||||
// std::cout << "additional mRows[" << r << "] = NULL" << std::endl;
|
||||
mRows.push_back (NULL);
|
||||
// }
|
||||
else
|
||||
// {
|
||||
// std::cout << "additional mRows[" << r << "] = new std::vector <Cell*>" << std::endl;
|
||||
mRows.push_back (new std::vector <Cell*>);
|
||||
// }
|
||||
}
|
||||
// If the new row is within the bounds of the current grid, ensure that the
|
||||
// row points to a vector of cells.
|
||||
else if (mRows[row] == NULL)
|
||||
// {
|
||||
// std::cout << "existing mRows[" << row << "] = new std::vector <Cell*>" << std::endl;
|
||||
mRows[row] = new std::vector <Cell*>;
|
||||
// }
|
||||
|
||||
if (col >= mRows[row]->size ())
|
||||
for (unsigned int c = mRows[row]->size (); c <= col; ++c)
|
||||
// {
|
||||
// std::cout << "additional mRows[" << row << "][" << c << "] = NULL" << std::endl;
|
||||
mRows[row]->push_back (NULL);
|
||||
// }
|
||||
|
||||
// If the new col is outside the bounds of the current grid, add blank cols to
|
||||
// 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)
|
||||
if (c < col)
|
||||
// {
|
||||
// std::cout << "additional mColumns[" << c << "] = NULL" << std::endl;
|
||||
mColumns.push_back (NULL);
|
||||
// }
|
||||
else
|
||||
// {
|
||||
// std::cout << "additional mColumns[" << c << "] = new std::vector <Cell*>" << std::endl;
|
||||
mColumns.push_back (new std::vector <Cell*>);
|
||||
// }
|
||||
}
|
||||
// If the new col is within the bounds of the current grid, ensure that the
|
||||
// col points to a vector of cells.
|
||||
else if (mColumns[col] == NULL)
|
||||
// {
|
||||
// std::cout << "existing mColumns[" << col << "] = new std::vector <Cell*>" << std::endl;
|
||||
mColumns[col] = new std::vector <Cell*>;
|
||||
// }
|
||||
|
||||
if (row >= mColumns[col]->size ())
|
||||
for (unsigned int r = mColumns[col]->size (); r <= row; ++r)
|
||||
// {
|
||||
// std::cout << "additional mColumns[" << col << "][" << r << "] = NULL" << std::endl;
|
||||
mColumns[col]->push_back (NULL);
|
||||
// }
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -237,15 +214,10 @@ void Grid::insertCell (
|
|||
{
|
||||
// Delete any existing cell, because cells are owned by rows, not columns.
|
||||
if ((*mRows[row])[col] != NULL)
|
||||
// {
|
||||
// std::cout << "deleted old cell mRows[" << row << "][" << col << "]" << std::endl;
|
||||
delete (*mRows[row])[col];
|
||||
// }
|
||||
|
||||
(*mRows[row])[col] = 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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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 ()
|
||||
{
|
||||
|
|
|
@ -77,7 +77,6 @@ private:
|
|||
just getJustification (const int, const int);
|
||||
just getHeaderJustification (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 optimize (std::string&);
|
||||
void sort (std::vector <int>&);
|
||||
|
|
105
src/task.cpp
105
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.addColumn (" ");
|
||||
table.addColumn ("Su");
|
||||
table.addColumn ("Mo");
|
||||
table.addColumn ("Tu");
|
||||
|
@ -1858,13 +1841,13 @@ void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
|||
table.addColumn ("Fr");
|
||||
table.addColumn ("Sa");
|
||||
|
||||
table.setColumnUnderline (0);
|
||||
table.setColumnUnderline (1);
|
||||
table.setColumnUnderline (2);
|
||||
table.setColumnUnderline (3);
|
||||
table.setColumnUnderline (4);
|
||||
table.setColumnUnderline (5);
|
||||
table.setColumnUnderline (6);
|
||||
table.setColumnUnderline (7);
|
||||
|
||||
table.setColumnJustification (0, 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 (5, 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 ();
|
||||
for (int d = 1; d <= days; ++d)
|
||||
{
|
||||
Date temp (m, d, y);
|
||||
Date temp (month, d, year);
|
||||
int dow = temp.dayOfWeek ();
|
||||
|
||||
table.addCell (row, dow, d);
|
||||
table.addCell (row, dow + 1, d);
|
||||
|
||||
if (conf.get ("color", true) && d == today)
|
||||
table.setCellFg (row, dow, Text::cyan);
|
||||
if (conf.get ("color", true) &&
|
||||
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.setCellBg (row, dow, d < today ? Text::red : Text::yellow);
|
||||
table.setCellFg (row, dow + 1, Text::black);
|
||||
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 ();
|
||||
}
|
||||
|
||||
std::cout << std::endl
|
||||
<< Date::monthName (m)
|
||||
return table.render ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||
{
|
||||
// Load all the pending tasks.
|
||||
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
|
||||
<< table.render ()
|
||||
<< 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