mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-20 04:13:07 +02:00
Virtual Tag
- Added 'ANNOTATED' virtual tag. This fell out of a change mandated by #1218.
This commit is contained in:
parent
6824fb1527
commit
1de2f9e6f1
4 changed files with 34 additions and 22 deletions
|
@ -30,7 +30,7 @@ Features
|
||||||
+ The 'diagnostics' command now reports libuuid details.
|
+ The 'diagnostics' command now reports libuuid details.
|
||||||
+ New characters for parsing and formating dates ('n', 's' and 'v').
|
+ New characters for parsing and formating dates ('n', 's' and 'v').
|
||||||
+ Virtual tags (BLOCKED, UNBLOCKED, BLOCKING, DUE, DUETODAY, TODAY, OVERDUE,
|
+ 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,
|
+ New 'modified' attribute, which contains the most recent modification date,
|
||||||
if a modification has occurred.
|
if a modification has occurred.
|
||||||
+ Fixed the mechanism used for selecting translations (thanks to Fidel Mato).
|
+ Fixed the mechanism used for selecting translations (thanks to Fidel Mato).
|
||||||
|
|
|
@ -580,6 +580,7 @@ are:
|
||||||
CHILD Matches if the task has a parent
|
CHILD Matches if the task has a parent
|
||||||
UNTIL Matches if the task expires
|
UNTIL Matches if the task expires
|
||||||
WAITING Matches if the task is waiting
|
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.
|
You can use +BLOCKED to filter blocked tasks, or -BLOCKED for unblocked tasks.
|
||||||
Similarly, -BLOCKED is equivalent to +UNBLOCKED.
|
Similarly, -BLOCKED is equivalent to +UNBLOCKED.
|
||||||
|
|
38
src/Task.cpp
38
src/Task.cpp
|
@ -106,6 +106,7 @@ Task::Task ()
|
||||||
, recalc_urgency (true)
|
, recalc_urgency (true)
|
||||||
, is_blocked (false)
|
, is_blocked (false)
|
||||||
, is_blocking (false)
|
, is_blocking (false)
|
||||||
|
, annotation_count (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +128,7 @@ Task& Task::operator= (const Task& other)
|
||||||
recalc_urgency = other.recalc_urgency;
|
recalc_urgency = other.recalc_urgency;
|
||||||
is_blocked = other.is_blocked;
|
is_blocked = other.is_blocked;
|
||||||
is_blocking = other.is_blocking;
|
is_blocking = other.is_blocking;
|
||||||
|
annotation_count = other.annotation_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -156,6 +158,7 @@ Task::Task (const std::string& input)
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
is_blocked = false;
|
is_blocked = false;
|
||||||
is_blocking = false;
|
is_blocking = false;
|
||||||
|
annotation_count = 0;
|
||||||
parse (input);
|
parse (input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,6 +439,9 @@ void Task::parse (const std::string& input)
|
||||||
value[value.length () - 1] == 'm')
|
value[value.length () - 1] == 'm')
|
||||||
value += 'o';
|
value += 'o';
|
||||||
|
|
||||||
|
if (name.substr (0, 11) == "annotation_")
|
||||||
|
++annotation_count;
|
||||||
|
|
||||||
(*this)[name] = decode (json::decode (value));
|
(*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 name = pair.substr (0, colon);
|
||||||
std::string value = pair.substr (colon + 2, pair.length () - colon - 3);
|
std::string value = pair.substr (colon + 2, pair.length () - colon - 3);
|
||||||
set ("annotation_" + name, value);
|
set ("annotation_" + name, value);
|
||||||
|
++annotation_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +683,6 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
|
||||||
|
|
||||||
// First the non-annotations.
|
// First the non-annotations.
|
||||||
int attributes_written = 0;
|
int attributes_written = 0;
|
||||||
int annotation_count = 0;
|
|
||||||
Task::const_iterator i;
|
Task::const_iterator i;
|
||||||
for (i = this->begin (); i != this->end (); ++i)
|
for (i = this->begin (); i != this->end (); ++i)
|
||||||
{
|
{
|
||||||
|
@ -685,14 +691,8 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
|
||||||
|
|
||||||
Column* column = context.columns[i->first];
|
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.
|
// Date fields are written as ISO 8601.
|
||||||
else if (column &&
|
if (column &&
|
||||||
column->type () == "date")
|
column->type () == "date")
|
||||||
{
|
{
|
||||||
Date d (i->second);
|
Date d (i->second);
|
||||||
|
@ -776,6 +776,12 @@ std::string Task::composeJSON (bool include_id /*= false*/) const
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Task::hasAnnotations () const
|
||||||
|
{
|
||||||
|
return annotation_count ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Task::getAnnotations (std::map <std::string, std::string>& annotations) const
|
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)
|
for (ci = annotations.begin (); ci != annotations.end (); ++ci)
|
||||||
this->insert (*ci);
|
this->insert (*ci);
|
||||||
|
|
||||||
|
annotation_count = annotations.size ();
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +826,7 @@ void Task::addAnnotation (const std::string& description)
|
||||||
while (has (key));
|
while (has (key));
|
||||||
|
|
||||||
(*this)[key] = description;
|
(*this)[key] = description;
|
||||||
|
++annotation_count;
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +838,10 @@ void Task::removeAnnotations ()
|
||||||
while (i != this->end ())
|
while (i != this->end ())
|
||||||
{
|
{
|
||||||
if (i->first.substr (0, 11) == "annotation_")
|
if (i->first.substr (0, 11) == "annotation_")
|
||||||
|
{
|
||||||
|
--annotation_count;
|
||||||
this->erase (i++);
|
this->erase (i++);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -960,6 +971,7 @@ bool Task::hasTag (const std::string& tag) const
|
||||||
if (tag == "CHILD") return has ("parent");
|
if (tag == "CHILD") return has ("parent");
|
||||||
if (tag == "UNTIL") return has ("until");
|
if (tag == "UNTIL") return has ("until");
|
||||||
if (tag == "WAITING") return has ("wait");
|
if (tag == "WAITING") return has ("wait");
|
||||||
|
if (tag == "ANNOTATED") return hasAnnotations ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO YESTERDAY - due yesterday
|
TODO YESTERDAY - due yesterday
|
||||||
|
@ -967,7 +979,6 @@ bool Task::hasTag (const std::string& tag) const
|
||||||
TODO WEEK - due this week
|
TODO WEEK - due this week
|
||||||
TODO MONTH - due this month
|
TODO MONTH - due this month
|
||||||
TODO YEAR - due this year
|
TODO YEAR - due this year
|
||||||
TODO ANNOTATED - has any annotations
|
|
||||||
TODO READY - is ready
|
TODO READY - is ready
|
||||||
TODO WAITING - is waiting
|
TODO WAITING - is waiting
|
||||||
TODO PARENT - is a parent
|
TODO PARENT - is a parent
|
||||||
|
@ -1547,12 +1558,9 @@ float Task::urgency_blocked () const
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
float Task::urgency_annotations () const
|
float Task::urgency_annotations () const
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string> annos;
|
if (annotation_count >= 3) return 1.0;
|
||||||
getAnnotations (annos);
|
else if (annotation_count == 2) return 0.9;
|
||||||
|
else if (annotation_count == 1) return 0.8;
|
||||||
if (annos.size () >= 3) return 1.0;
|
|
||||||
else if (annos.size () == 2) return 0.9;
|
|
||||||
else if (annos.size () == 1) return 0.8;
|
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ public:
|
||||||
bool is_blocked;
|
bool is_blocked;
|
||||||
bool is_blocking;
|
bool is_blocking;
|
||||||
|
|
||||||
|
int annotation_count;
|
||||||
|
|
||||||
// Series of helper functions.
|
// Series of helper functions.
|
||||||
static status textToStatus (const std::string&);
|
static status textToStatus (const std::string&);
|
||||||
static std::string statusToText (status);
|
static std::string statusToText (status);
|
||||||
|
@ -96,6 +98,7 @@ public:
|
||||||
void getTags (std::vector<std::string>&) const;
|
void getTags (std::vector<std::string>&) const;
|
||||||
void removeTag (const std::string&);
|
void removeTag (const std::string&);
|
||||||
|
|
||||||
|
bool hasAnnotations () const;
|
||||||
void getAnnotations (std::map <std::string, std::string>&) const;
|
void getAnnotations (std::map <std::string, std::string>&) const;
|
||||||
void setAnnotations (const std::map <std::string, std::string>&);
|
void setAnnotations (const std::map <std::string, std::string>&);
|
||||||
void addAnnotation (const std::string&);
|
void addAnnotation (const std::string&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue