- Factored out filtering code.

This commit is contained in:
Paul Beckingham 2008-06-17 23:40:37 -04:00
parent 7fb3ab0c3d
commit 9bca303113
2 changed files with 298 additions and 483 deletions

View file

@ -12,6 +12,7 @@ Configurable columns in reports
1.3.0 (?)
+ "task calendar" now displays multiple months per line, adjustable by the
"monthsperline" configuration variable. Feature added by Damian Glenny
+ "task export" can now filter tasks like the reports.
+ Bug: Segmentation fault when no "dateformat" configuration variable
specified
+ Bug: Fixed bug whereby if you have more than one task with a due date, 7

View file

@ -285,6 +285,66 @@ int main (int argc, char** argv)
return 0;
}
////////////////////////////////////////////////////////////////////////////////
static void filter (std::vector<T>& all, T& task)
{
std::vector <T> filtered;
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
for (unsigned int i = 0; i < all.size (); ++i)
{
T refTask (all[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
filtered.push_back (refTask);
}
}
}
all = filtered;
}
////////////////////////////////////////////////////////////////////////////////
void handleAdd (const TDB& tdb, T& task, Config& conf)
{
@ -446,56 +506,11 @@ void handleList (const TDB& tdb, T& task, Config& conf)
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
{
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
@ -550,9 +565,6 @@ void handleList (const TDB& tdb, T& task, Config& conf)
}
}
}
}
}
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
@ -616,56 +628,12 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
{
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
@ -717,9 +685,6 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
}
}
}
}
}
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
@ -779,56 +744,12 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
table.sortOn (0, Table::ascendingDate);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
{
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
Date end (::atoi (refTask.getAttribute ("end").c_str ()));
@ -848,9 +769,6 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
table.setRowBg (row, bg);
}
}
}
}
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
@ -1097,56 +1015,12 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
{
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
Date now;
std::string started = refTask.getAttribute ("start");
@ -1220,9 +1094,6 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
}
}
}
}
}
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
@ -1468,56 +1339,11 @@ void handleReportNext (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
foreach (i, matching)
{
T refTask (pending[*i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
{
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
@ -1572,9 +1398,6 @@ void handleReportNext (const TDB& tdb, T& task, Config& conf)
}
}
}
}
}
}
if (table.rowCount ())
std::cout << optionalBlankLine (conf)
@ -2087,15 +1910,8 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter);
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
@ -2202,17 +2018,10 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter);
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
Date now;
// Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i)
{
T refTask (tasks[i]);
@ -2479,7 +2288,11 @@ void handleDone (const TDB& tdb, T& task, Config& conf)
////////////////////////////////////////////////////////////////////////////////
void handleExport (const TDB& tdb, T& task, Config& conf)
{
// Use the description as a file name, then clobber the description so the
// file name isn't used for filtering.
std::string file = trim (task.getDescription ());
task.setDescription ("");
if (file.length () > 0)
{
std::ofstream out (file.c_str ());
@ -2501,6 +2314,7 @@ void handleExport (const TDB& tdb, T& task, Config& conf)
std::vector <T> all;
tdb.allT (all);
filter (all, task);
foreach (t, all)
{
out << t->composeCSV ().c_str ();