Feature: Error on virtual tag modification attempt

- An attempt to add or remove a virtual tag is now an error (thanks to Scott M).
This commit is contained in:
Paul Beckingham 2015-06-27 18:38:24 -04:00
parent 1824a542f6
commit f96a42d8b0
16 changed files with 57 additions and 5 deletions

View file

@ -24,7 +24,7 @@
and enabling more flexible use of the function.
- Enable "task sync" support by default. "cmake -DENABLE_SYNC=OFF" allows
disabling it and building Taskwarrior without libgnutls available.
- An attempt to add or remove a virtual tag is now an error (thanks to Scott M).
------ current release ---------------------------

1
NEWS
View file

@ -2,6 +2,7 @@
New Features in Taskwarrior 2.4.5
- The active context, if one is set, is now identified in "task context list"
- It is an error to attempt and add or remove of a virtual tag.
New commands in Taskwarrior 2.4.5

View file

@ -504,9 +504,10 @@ Shows a report of aggregated task status by project.
.TP
.B task <filter> tags
Show a list of all tags used. Any special tags used are highlighted. Note that
Show a list of all tags used. Any special tags used are highlighted. Note that
virtual tags are not listed - they don't really exist, and are just a convenient
notation for other task metadata.
notation for other task metadata. It is an error to attempt to add or remove a
virtual tag.
.TP
.B task timesheet [weeks]
@ -666,7 +667,8 @@ are:
DELETED Matches if the task has deleted status
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. It is an error to attempt to
add or remove a virtual tag.
.TP
.B project:<project-name>

View file

@ -1092,6 +1092,7 @@ bool Task::hasTag (const std::string& tag) const
{
// Synthetic tags - dynamically generated, but do not occupy storage space.
// Note: This list must match that in CmdInfo::execute.
// Note: This list must match that in ::feedback_reserved_tags.
if (tag == "BLOCKED") return is_blocked;
if (tag == "UNBLOCKED") return !is_blocked;
if (tag == "BLOCKING") return is_blocking;
@ -2094,11 +2095,13 @@ void Task::modify (modType type, bool text_required /* = false */)
else if (a._lextype == Lexer::Type::tag)
{
std::string tag = a.attribute ("name");
feedback_reserved_tags (tag);
if (a.attribute ("sign") == "+")
{
context.debug (label + "tags <-- add '" + tag + "'");
addTag (tag);
feedback_special_tags ((*this), tag);
feedback_special_tags (*this, tag);
}
else
{

View file

@ -303,6 +303,7 @@ int CmdInfo::execute (std::string& output)
// Virtual tags.
{
// Note: This list must match that in Task::hasTag.
// Note: This list must match that in ::feedback_reserved_tags.
std::string virtualTags = "";
if (task.hasTag ("ACTIVE")) virtualTags += "ACTIVE ";
if (task.hasTag ("ANNOTATED")) virtualTags += "ANNOTATED ";

View file

@ -351,6 +351,41 @@ void feedback_affected (const std::string& effect, const Task& task)
}
}
////////////////////////////////////////////////////////////////////////////////
// Implements feedback and error when adding a reserved tag name.
void feedback_reserved_tags (const std::string& tag)
{
// Note: This list must match that in Task::hasTag.
// Note: This list must match that in CmdInfo::execute.
if (tag == "BLOCKED" ||
tag == "UNBLOCKED" ||
tag == "BLOCKING" ||
tag == "READY" ||
tag == "DUE" ||
tag == "DUETODAY" ||
tag == "TODAY" ||
tag == "YESTERDAY" ||
tag == "TOMORROW" ||
tag == "OVERDUE" ||
tag == "WEEK" ||
tag == "MONTH" ||
tag == "YEAR" ||
tag == "ACTIVE" ||
tag == "SCHEDULED" ||
tag == "CHILD" ||
tag == "UNTIL" ||
tag == "ANNOTATED" ||
tag == "TAGGED" ||
tag == "PARENT" ||
tag == "WAITING" ||
tag == "PENDING" ||
tag == "COMPLETED" ||
tag == "DELETED")
{
throw format (STRING_FEEDBACK_TAG_VIRTUAL, tag);
}
}
////////////////////////////////////////////////////////////////////////////////
// Implements feedback when adding special tags to a task.
void feedback_special_tags (const Task& task, const std::string& tag)

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "Das besondere Schlagwort 'nonag' verhindert Nachfragen, wenn diese Aufgabe geändert wird."
#define STRING_FEEDBACK_TAG_NOCAL "Das besondere Schlagwort 'nocal' verhindert, dass diese Aufgabe im 'calendar'-Report erscheint."
#define STRING_FEEDBACK_TAG_NEXT "Das besondere Schlagwort 'next' erhöht die Dringlichkeit dieser Aufgabe, sodass sie im 'next'-Report erscheint."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Aufgabe {1} '{2}' entsperrt."
#define STRING_FEEDBACK_EXPIRED "Aufgabe {1} '{2}' ist abgelaufen und wurde gelöscht."
#define STRING_FEEDBACK_BACKLOG "Lokale Änderungen. Datenabgleich erforderlich."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "The 'nonag' special tag will prevent nagging when this task is modified."
#define STRING_FEEDBACK_TAG_NOCAL "The 'nocal' special tag will keep this task off the 'calendar' report."
#define STRING_FEEDBACK_TAG_NEXT "The 'next' special tag will boost the urgency of this task so it appears on the 'next' report."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Unblocked {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Task {1} '{2}' expired and was deleted."
#define STRING_FEEDBACK_BACKLOG "There are local changes. Sync required."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "Speciala etikedo 'nonag' antaŭmalebligitos molestojn, kiam oni modifus tiun taskon."
#define STRING_FEEDBACK_TAG_NOCAL "Speciala etikedo 'nocal' ekskluzivos tiun taskon ĉe raporto 'calendar'."
#define STRING_FEEDBACK_TAG_NEXT "Speciala etikedo 'next' pligrandigos la urĝecon de tiu tasko por ke ĝi aperus ĉe raporto 'next'."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Malblokis {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Tasko {1} '{2}' fortempiĝis do estis viŝata."
#define STRING_FEEDBACK_BACKLOG "Estas lokaj ŝanĝoj. Sinkronigo devita."

View file

@ -804,6 +804,7 @@
#define STRING_FEEDBACK_TAG_NONAG "La marca especial 'nonag' evitará el recuerdo fastidioso cuando la tarea sea modificada."
#define STRING_FEEDBACK_TAG_NOCAL "La marca especial 'nocal' mantendrá esta tarea fuera del informe 'calendar'."
#define STRING_FEEDBACK_TAG_NEXT "La etiqueta especial 'next' aumentará la urgencia de esta tarea para que aparezca en el informe 'next'."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Desbloqueada {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "La tarea {1} '{2}' caducó y fue eliminada."
#define STRING_FEEDBACK_BACKLOG "Hay modificaciones locales. Se require una sincronización."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "The 'nonag' special tag will prevent nagging when this task is modified."
#define STRING_FEEDBACK_TAG_NOCAL "The 'nocal' special tag will keep this task off the 'calendar' report."
#define STRING_FEEDBACK_TAG_NEXT "The 'next' special tag will boost the urgency of this task so it appears on the 'next' report."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Unblocked {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Tâche {1} '{2}' a expiré et a été supprimée."
#define STRING_FEEDBACK_BACKLOG "Il y a des changements locaux. Synchronisation requise."

View file

@ -791,6 +791,7 @@
#define STRING_FEEDBACK_TAG_NONAG "Il tag speciale 'nonag' eviterà problemi quando il task è modificato."
#define STRING_FEEDBACK_TAG_NOCAL "Il tag speciale 'nocal' manterrà il task fuori dal report 'calendar'."
#define STRING_FEEDBACK_TAG_NEXT "Il tag speciale 'next' aumenterà l'urgenza di questo task in modo che appaia nel report 'next'."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Sbloccato {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Il task {1} '{2}' è scaduto ed è stato eliminato"
#define STRING_FEEDBACK_BACKLOG "There are local changes. Sync required."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "The 'nonag' special tag will prevent nagging when this task is modified."
#define STRING_FEEDBACK_TAG_NOCAL "The 'nocal' special tag will keep this task off the 'calendar' report."
#define STRING_FEEDBACK_TAG_NEXT "The 'next' special tag will boost the urgency of this task so it appears on the 'next' report."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Unblocked {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Task {1} '{2}' expired and was deleted."
#define STRING_FEEDBACK_BACKLOG "There are local changes. Sync required."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "Specjalny tag 'nonag' uchroni przed upierdliwością kiedy zadanie jest modyfikowane."
#define STRING_FEEDBACK_TAG_NOCAL "Specjalny tag 'nocal' spowoduje nie dodawanie zadania do kalendarza."
#define STRING_FEEDBACK_TAG_NEXT "Specjalny tag 'next' podniesie pilność tego zadania co spowoduje wyświetlenie go w raporcie 'next'."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Odblokowane {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Zadanie {1} '{2}' jest przedawnione i zostało usunięte."
#define STRING_FEEDBACK_BACKLOG "Wykryto lokalne zmiany. Wymagana synchronizacja."

View file

@ -792,6 +792,7 @@
#define STRING_FEEDBACK_TAG_NONAG "A marca especial 'nonag' irá prevenir avisos quando a tarefa é modificada."
#define STRING_FEEDBACK_TAG_NOCAL "A marca especial 'nocal' irá manter esta tarefa ausente do relatório de 'calendário'."
#define STRING_FEEDBACK_TAG_NEXT "A marca especial 'next' irá aumentar a urgência desta tarefa de modo a que apareça no relatório 'next'."
#define STRING_FEEDBACK_TAG_VIRTUAL "Virtual tags (including '{1}') are reserved and may not be added or removed."
#define STRING_FEEDBACK_UNBLOCKED "Desbloqueada {1} '{2}'."
#define STRING_FEEDBACK_EXPIRED "Tarefa {1} '{2}' expirou e foi eliminada."
#define STRING_FEEDBACK_BACKLOG "Há modificações locais. Necessário sincronizar (sync)."

View file

@ -67,6 +67,7 @@ std::string renderAttribute (const std::string&, const std::string&, const std::
void feedback_affected (const std::string&);
void feedback_affected (const std::string&, int);
void feedback_affected (const std::string&, const Task&);
void feedback_reserved_tags (const std::string&);
void feedback_special_tags (const Task&, const std::string&);
void feedback_unblocked (const Task&);
void feedback_backlog ();