Virtual Tag

- Added 'ANNOTATED' virtual tag.  This fell out of a change mandated by #1218.
This commit is contained in:
Paul Beckingham 2013-04-01 15:15:10 -04:00
parent 6824fb1527
commit 1de2f9e6f1
4 changed files with 34 additions and 22 deletions

View file

@ -30,7 +30,7 @@ Features
+ The 'diagnostics' command now reports libuuid details.
+ New characters for parsing and formating dates ('n', 's' and 'v').
+ Virtual tags (BLOCKED, UNBLOCKED, BLOCKING, DUE, DUETODAY, TODAY, OVERDUE,
ACTIVE, SCHEDULED, CHILD, UNTIL and WAITING).
ACTIVE, SCHEDULED, CHILD, UNTIL, WAITING and ANNOTATED).
+ New 'modified' attribute, which contains the most recent modification date,
if a modification has occurred.
+ Fixed the mechanism used for selecting translations (thanks to Fidel Mato).

View file

@ -580,6 +580,7 @@ are:
CHILD Matches if the task has a parent
UNTIL Matches if the task expires
WAITING Matches if the task is waiting
ANNOTATED Matches if the task has annotations
You can use +BLOCKED to filter blocked tasks, or -BLOCKED for unblocked tasks.
Similarly, -BLOCKED is equivalent to +UNBLOCKED.

View file

@ -106,6 +106,7 @@ Task::Task ()
, recalc_urgency (true)
, is_blocked (false)
, is_blocking (false)
, annotation_count (0)
{
}
@ -122,11 +123,12 @@ Task& Task::operator= (const Task& other)
{
std::map <std::string, std::string>::operator= (other);
id = other.id;
urgency_value = other.urgency_value;
recalc_urgency = other.recalc_urgency;
is_blocked = other.is_blocked;
is_blocking = other.is_blocking;
id = other.id;
urgency_value = other.urgency_value;
recalc_urgency = other.recalc_urgency;
is_blocked = other.is_blocked;
is_blocking = other.is_blocking;
annotation_count = other.annotation_count;
}
return *this;
@ -156,6 +158,7 @@ Task::Task (const std::string& input)
recalc_urgency = true;
is_blocked = false;
is_blocking = false;
annotation_count = 0;
parse (input);
}
@ -436,6 +439,9 @@ void Task::parse (const std::string& input)
value[value.length () - 1] == 'm')
value += 'o';
if (name.substr (0, 11) == "annotation_")
++annotation_count;
(*this)[name] = decode (json::decode (value));
}
@ -611,6 +617,7 @@ void Task::legacyParse (const std::string& line)
std::string name = pair.substr (0, colon);
std::string value = pair.substr (colon + 2, pair.length () - colon - 3);
set ("annotation_" + name, value);
++annotation_count;
}
}
@ -676,7 +683,6 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
// First the non-annotations.
int attributes_written = 0;
int annotation_count = 0;
Task::const_iterator i;
for (i = this->begin (); i != this->end (); ++i)
{
@ -685,15 +691,9 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
Column* column = context.columns[i->first];
// Annotations are simply counted.
if (i->first.substr (0, 11) == "annotation_")
{
++annotation_count;
}
// Date fields are written as ISO 8601.
else if (column &&
column->type () == "date")
if (column &&
column->type () == "date")
{
Date d (i->second);
out << "\""
@ -776,6 +776,12 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
return out.str ();
}
////////////////////////////////////////////////////////////////////////////////
bool Task::hasAnnotations () const
{
return annotation_count ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void Task::getAnnotations (std::map <std::string, std::string>& annotations) const
{
@ -797,6 +803,7 @@ void Task::setAnnotations (const std::map <std::string, std::string>& annotation
for (ci = annotations.begin (); ci != annotations.end (); ++ci)
this->insert (*ci);
annotation_count = annotations.size ();
recalc_urgency = true;
}
@ -819,6 +826,7 @@ void Task::addAnnotation (const std::string& description)
while (has (key));
(*this)[key] = description;
++annotation_count;
recalc_urgency = true;
}
@ -830,7 +838,10 @@ void Task::removeAnnotations ()
while (i != this->end ())
{
if (i->first.substr (0, 11) == "annotation_")
{
--annotation_count;
this->erase (i++);
}
else
i++;
}
@ -960,6 +971,7 @@ bool Task::hasTag (const std::string& tag) const
if (tag == "CHILD") return has ("parent");
if (tag == "UNTIL") return has ("until");
if (tag == "WAITING") return has ("wait");
if (tag == "ANNOTATED") return hasAnnotations ();
/*
TODO YESTERDAY - due yesterday
@ -967,7 +979,6 @@ bool Task::hasTag (const std::string& tag) const
TODO WEEK - due this week
TODO MONTH - due this month
TODO YEAR - due this year
TODO ANNOTATED - has any annotations
TODO READY - is ready
TODO WAITING - is waiting
TODO PARENT - is a parent
@ -1547,12 +1558,9 @@ float Task::urgency_blocked () const
////////////////////////////////////////////////////////////////////////////////
float Task::urgency_annotations () const
{
std::map <std::string, std::string> annos;
getAnnotations (annos);
if (annos.size () >= 3) return 1.0;
else if (annos.size () == 2) return 0.9;
else if (annos.size () == 1) return 0.8;
if (annotation_count >= 3) return 1.0;
else if (annotation_count == 2) return 0.9;
else if (annotation_count == 1) return 0.8;
return 0.0;
}

View file

@ -62,6 +62,8 @@ public:
bool is_blocked;
bool is_blocking;
int annotation_count;
// Series of helper functions.
static status textToStatus (const std::string&);
static std::string statusToText (status);
@ -96,6 +98,7 @@ public:
void getTags (std::vector<std::string>&) const;
void removeTag (const std::string&);
bool hasAnnotations () const;
void getAnnotations (std::map <std::string, std::string>&) const;
void setAnnotations (const std::map <std::string, std::string>&);
void addAnnotation (const std::string&);