Patch - Support tag exclusion filtering

- Now supports "-tag" in filters to filter out tasks that do not
  have the specified tag (thanks to Chris Pride).
- Added unit tests to prevent regression.
- Updated the filter docs to include examples.
This commit is contained in:
Paul Beckingham 2009-05-28 11:30:30 -04:00
parent 0fcaf85652
commit 7aace1b3db
5 changed files with 55 additions and 4 deletions

View file

@ -14,7 +14,10 @@
part of the description, despite what they otherwise might mean.
+ Removed support for the obsolete task file format 1 (never released).
+ Fixed bug that allowed blank annotations to be added (thanks to Bruce
Dillahunty),
Dillahunty).
+ Supports negative tag filters, so that (task list +foo -bar) now filters
tasks that have the "foo" tag, but do not have the "bar" tag (thanks to
Chris Pride).
------ old releases ------------------------------

View file

@ -76,6 +76,13 @@
<p>
Lists only tasks with the "shopping" tag.
</p>
<code><pre>% task list +shopping -gift</pre></code>
<p>
Lists tasks that have the "shopping" tag, but do not have the
"gift" tag.
</p>
</div>
<br />

View file

@ -144,7 +144,10 @@
part of the description, despite what they otherwise might mean.
<li>Removed support for the obsolete task file format 1 (never released).
<li>Fixed bug that allowed blank annotations to be added (thanks to Bruce
Dillahunty),
Dillahunty).
<li>Supports negative tag filters, so that (task list +foo -bar) now filters
tasks that have the "foo" tag, but do not have the "bar" tag (thanks to
Chris Pride).
</ul>
<p>

View file

@ -108,6 +108,9 @@ void filter (std::vector<T>& all, T& task)
std::vector <std::string> tagList;
task.getTags (tagList);
std::vector <std::string> removeTagList;
task.getRemoveTags (removeTagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
@ -180,7 +183,15 @@ void filter (std::vector<T>& all, T& task)
++matches;
if (matches == tagList.size ())
filtered.push_back (refTask);
{
matches = 0;
for (unsigned int t = 0; t < removeTagList.size (); ++t)
if (refTask.hasTag (removeTagList[t]))
++matches;
if (matches == 0)
filtered.push_back (refTask);
}
}
}
}

View file

@ -28,7 +28,7 @@
use strict;
use warnings;
use Test::More tests => 108;
use Test::More tests => 129;
# Create the rc file.
if (open my $fh, '>', 'filter.rc')
@ -110,6 +110,33 @@ like ($output, qr/five/, 'g5');
unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list -tag};
unlike ($output, qr/one/, 'g1');
like ($output, qr/two/, 'g2');
like ($output, qr/three/, 'g3');
like ($output, qr/four/, 'g4');
unlike ($output, qr/five/, 'g5');
like ($output, qr/six/, 'g6');
like ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list -missing};
like ($output, qr/one/, 'g1');
like ($output, qr/two/, 'g2');
like ($output, qr/three/, 'g3');
like ($output, qr/four/, 'g4');
like ($output, qr/five/, 'g5');
like ($output, qr/six/, 'g6');
like ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list +tag -tag};
unlike ($output, qr/one/, 'g1');
unlike ($output, qr/two/, 'g2');
unlike ($output, qr/three/, 'g3');
unlike ($output, qr/four/, 'g4');
unlike ($output, qr/five/, 'g5');
unlike ($output, qr/six/, 'g6');
unlike ($output, qr/seven/, 'g7');
$output = qx{../task rc:filter.rc list project:A priority:H};
like ($output, qr/one/, 'h1');
like ($output, qr/two/, 'h2');