diff --git a/ChangeLog b/ChangeLog index b01837b96..009c569ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2.4.2 () - +- TW-41 Tasks in subprojects are not counted in project completion (thanks + to Renato Alves). +- TW-1450 Projects command should trigger running garbage collector (thanks to + Tomas Babej). - TW-1535 move default listing-break from list to ls (thanks to David Patrick). - TW-1545 cc1plus: error: unrecognized command line option '-std=c++11' (thanks to Petteri). @@ -17,6 +21,7 @@ - Closed dangling pipes in execute (), resolving problems when a hook script forks (thanks to Jens Erat). - Re-enabled hook script feedback when exiting with 0 exit status. +- The 'info' command now shows virtual tags. ------ current release --------------------------- diff --git a/NEWS b/NEWS index bebc9560c..16224a133 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ New Features in taskwarrior 2.4.2 - Ability to set context, which serves as a permanent user-defined filter. + - The 'info' command now shows virtual tags. New commands in taskwarrior 2.4.2 diff --git a/scripts/bash/task.sh b/scripts/bash/task.sh index 58881ab06..7c37944cc 100644 --- a/scripts/bash/task.sh +++ b/scripts/bash/task.sh @@ -68,7 +68,13 @@ _task_offer_projects() { COMPREPLY=( $(compgen -W "$($taskcommand _projects)" -- ${cur/*:/}) ) } -_task() +_task_offer_contexts() { + COMPREPLY=( $(compgen -W "$($taskcommand _context) define delete list none show" -- $cur) ) +} + +_task_context_alias=$($taskcommand show | grep alias.*context | cut -d' ' -f1 | cut -d. -f2) + +_task() { local cur prev opts base @@ -91,6 +97,10 @@ _task() opts="$commands_aliases $($taskcommand _columns)" case "${prev}" in + $_task_context_alias|cont|conte|contex|context) + _task_offer_contexts + return 0 + ;; :) case "${prev2}" in pri|prior|priori|priorit|priority) diff --git a/src/TDB2.cpp b/src/TDB2.cpp index 555f32150..ff856fb8e 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -572,7 +572,7 @@ void TDB2::add (Task& task, bool add_to_backlog /* = true */) if (add_to_backlog) context.hooks.onAdd (task); - update (uuid, task, add_to_backlog); + update (uuid, task, add_to_backlog, true); } //////////////////////////////////////////////////////////////////////////////// @@ -598,14 +598,15 @@ void TDB2::modify (Task& task, bool add_to_backlog /* = true */) void TDB2::update ( const std::string& uuid, Task& task, - const bool add_to_backlog) + const bool add_to_backlog, + const bool addition) { // Validate to add metadata. task.validate (false); // If the task already exists, it is a modification, else addition. Task original; - if (get (task.get ("uuid"), original)) + if (not addition && get (task.get ("uuid"), original)) { // Update the task, wherever it is. if (!pending.modify_task (task)) diff --git a/src/TDB2.h b/src/TDB2.h index bb3f2cd32..d019fc487 100644 --- a/src/TDB2.h +++ b/src/TDB2.h @@ -128,7 +128,7 @@ public: private: void gather_changes (); - void update (const std::string&, Task&, const bool); + void update (const std::string&, Task&, const bool, const bool addition = false); bool verifyUniqueUUID (const std::string&); void show_diff (const std::string&, const std::string&, const std::string&); void revert_undo (std::vector &, std::string&, std::string&, std::string&, std::string&); diff --git a/src/Task.cpp b/src/Task.cpp index 0a58455b7..268776e01 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -1105,6 +1105,7 @@ int Task::getTagCount () const 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. if (tag == "BLOCKED") return is_blocked; if (tag == "UNBLOCKED") return !is_blocked; if (tag == "BLOCKING") return is_blocking; diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 9097472df..8121dd168 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -314,6 +314,40 @@ int CmdInfo::execute (std::string& output) view.set (row, 1, allTags); } + // Virtual tags. + { + // Note: This list must match that in Task::hasTag. + std::string virtualTags = ""; + if (task->hasTag ("ACTIVE")) virtualTags += "ACTIVE "; + if (task->hasTag ("ANNOTATED")) virtualTags += "ANNOTATED "; + if (task->hasTag ("BLOCKED")) virtualTags += "BLOCKED "; + if (task->hasTag ("BLOCKING")) virtualTags += "BLOCKING "; + if (task->hasTag ("CHILD")) virtualTags += "CHILD "; + if (task->hasTag ("COMPLETED")) virtualTags += "COMPLETED "; + if (task->hasTag ("DELETED")) virtualTags += "DELETED "; + if (task->hasTag ("DUE")) virtualTags += "DUE "; + if (task->hasTag ("DUETODAY")) virtualTags += "DUETODAY "; + if (task->hasTag ("MONTH")) virtualTags += "MONTH "; + if (task->hasTag ("OVERDUE")) virtualTags += "OVERDUE "; + if (task->hasTag ("PARENT")) virtualTags += "PARENT "; + if (task->hasTag ("PENDING")) virtualTags += "PENDING "; + if (task->hasTag ("READY")) virtualTags += "READY "; + if (task->hasTag ("SCHEDULED")) virtualTags += "SCHEDULED "; + if (task->hasTag ("TAGGED")) virtualTags += "TAGGED "; + if (task->hasTag ("TODAY")) virtualTags += "TODAY "; + if (task->hasTag ("TOMORROW")) virtualTags += "TOMORROW "; + if (task->hasTag ("UNBLOCKED")) virtualTags += "UNBLOCKED "; + if (task->hasTag ("UNTIL")) virtualTags += "UNTIL "; + if (task->hasTag ("WAITING")) virtualTags += "WAITING "; + if (task->hasTag ("WEEK")) virtualTags += "WEEK "; + if (task->hasTag ("YEAR")) virtualTags += "YEAR "; + if (task->hasTag ("YESTERDAY")) virtualTags += "YESTERDAY "; + + row = view.addRow (); + view.set (row, 0, STRING_CMD_INFO_VIRTUAL_TAGS); + view.set (row, 1, virtualTags); + } + // uuid row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_UUID); diff --git a/src/commands/CmdProjects.cpp b/src/commands/CmdProjects.cpp index 048ca701b..1c69929cb 100644 --- a/src/commands/CmdProjects.cpp +++ b/src/commands/CmdProjects.cpp @@ -53,6 +53,9 @@ int CmdProjects::execute (std::string& output) { int rc = 0; + // Enforce the garbage collector to show correct task counts + context.tdb2.gc (); + // Get all the tasks. handleRecurrence (); std::vector tasks = context.tdb2.pending.get_tasks (); @@ -89,8 +92,16 @@ int CmdProjects::execute (std::string& output) continue; } + // Increase the count for the project the task belongs to and all + // its super-projects project = task->get ("project"); - unique[project] += 1; + + std::vector projects = extractParents (project); + projects.push_back (project); + + std::vector ::const_iterator parent; + for (parent = projects.begin (); parent != projects.end (); ++parent) + unique[*parent] += 1; if (project == "") no_project = true; diff --git a/src/commands/CmdSummary.cpp b/src/commands/CmdSummary.cpp index d012fb0dd..842948e33 100644 --- a/src/commands/CmdSummary.cpp +++ b/src/commands/CmdSummary.cpp @@ -92,27 +92,34 @@ int CmdSummary::execute (std::string& output) for (task = filtered.begin (); task != filtered.end (); ++task) { std::string project = task->get ("project"); - ++counter[project]; + std::vector projects = extractParents (project); + projects.push_back (project); + + std::vector ::const_iterator parent; + for (parent = projects.begin (); parent != projects.end (); ++parent) + ++counter[*parent]; if (task->getStatus () == Task::pending || task->getStatus () == Task::waiting) - { - ++countPending[project]; + for (parent = projects.begin (); parent != projects.end (); ++parent) + { + ++countPending[*parent]; - time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); - if (entry) - sumEntry[project] = sumEntry[project] + (double) (now - entry); - } + time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); + if (entry) + sumEntry[*parent] = sumEntry[*parent] + (double) (now - entry); + } else if (task->getStatus () == Task::completed) - { - ++countCompleted[project]; + for (parent = projects.begin (); parent != projects.end (); ++parent) + { + ++countCompleted[*parent]; - time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); - time_t end = strtol (task->get ("end").c_str (), NULL, 10); - if (entry && end) - sumEntry[project] = sumEntry[project] + (double) (end - entry); - } + time_t entry = strtol (task->get ("entry").c_str (), NULL, 10); + time_t end = strtol (task->get ("end").c_str (), NULL, 10); + if (entry && end) + sumEntry[*parent] = sumEntry[*parent] + (double) (end - entry); + } } diff --git a/src/l10n/deu-DEU.h b/src/l10n/deu-DEU.h index a374165d1..7d4491b8f 100644 --- a/src/l10n/deu-DEU.h +++ b/src/l10n/deu-DEU.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Bis" #define STRING_CMD_INFO_MODIFICATION "Änderung" #define STRING_CMD_INFO_MODIFIED "Letzte Änderung" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Macht die letzte Änderung an einer Aufgabe Rückgängig" #define STRING_CMD_UNDO_MODS "Der undo-Befehl erlaubt keine weitere Aufgaben-Änderung." #define STRING_CMD_STATS_USAGE "Zeigt Statistiken zur Aufgaben-Datenbank" diff --git a/src/l10n/eng-USA.h b/src/l10n/eng-USA.h index 112db87ae..bbc9393d7 100644 --- a/src/l10n/eng-USA.h +++ b/src/l10n/eng-USA.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Until" #define STRING_CMD_INFO_MODIFICATION "Modification" #define STRING_CMD_INFO_MODIFIED "Last modified" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Reverts the most recent change to a task" #define STRING_CMD_UNDO_MODS "The undo command does not allow further task modification." #define STRING_CMD_STATS_USAGE "Shows task database statistics" diff --git a/src/l10n/epo-RUS.h b/src/l10n/epo-RUS.h index 057946ca3..8b231086e 100644 --- a/src/l10n/epo-RUS.h +++ b/src/l10n/epo-RUS.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Ĝis" #define STRING_CMD_INFO_MODIFICATION "Modifado" #define STRING_CMD_INFO_MODIFIED "Modifado lasta" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Malfaras la plej malfrua modifado al tasko" #define STRING_CMD_UNDO_MODS "La komando 'undo' ne permesos, ke oni pli modifus la taskojn." #define STRING_CMD_STATS_USAGE "Montras statistikon de la taska datumbazo" diff --git a/src/l10n/esp-ESP.h b/src/l10n/esp-ESP.h index d99053429..cba68f585 100644 --- a/src/l10n/esp-ESP.h +++ b/src/l10n/esp-ESP.h @@ -298,6 +298,7 @@ #define STRING_CMD_INFO_UNTIL "Hasta" #define STRING_CMD_INFO_MODIFICATION "Modificación" #define STRING_CMD_INFO_MODIFIED "Modificada por última vez" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Revierte el cambio más reciente a una tarea" #define STRING_CMD_UNDO_MODS "El comando undo no permite más modificación a la tarea." #define STRING_CMD_STATS_USAGE "Muestra estadísticas de la base de datos de tareas" diff --git a/src/l10n/fra-FRA.h b/src/l10n/fra-FRA.h index 11d3b2cb6..f2f1ebe50 100644 --- a/src/l10n/fra-FRA.h +++ b/src/l10n/fra-FRA.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Jusqu'au" #define STRING_CMD_INFO_MODIFICATION "Modification" #define STRING_CMD_INFO_MODIFIED "Dernier modifié" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Annule les changements les plus récents sur une tâche" #define STRING_CMD_UNDO_MODS "The undo command does not allow further task modification." #define STRING_CMD_STATS_USAGE "Affiche les statistiques de la base de donnée" diff --git a/src/l10n/ita-ITA.h b/src/l10n/ita-ITA.h index 5e5255572..358da09a0 100644 --- a/src/l10n/ita-ITA.h +++ b/src/l10n/ita-ITA.h @@ -295,6 +295,7 @@ #define STRING_CMD_INFO_UNTIL "Fino a" #define STRING_CMD_INFO_MODIFICATION "Modifica" #define STRING_CMD_INFO_MODIFIED "Ultima modifica" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Ritorna alla più recente modifica di un task" #define STRING_CMD_UNDO_MODS "Il comando undo non ammette ulteriori modifiche al task." #define STRING_CMD_STATS_USAGE "Mostra le statistiche sul task" diff --git a/src/l10n/pol-POL.h b/src/l10n/pol-POL.h index f3e2a0fcd..e313f2fad 100644 --- a/src/l10n/pol-POL.h +++ b/src/l10n/pol-POL.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Do" #define STRING_CMD_INFO_MODIFICATION "Modyfikacja" #define STRING_CMD_INFO_MODIFIED "Ostatnio zmodyfikowane" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Odwraca ostatnią zmianę w zadaniu" #define STRING_CMD_UNDO_MODS "Polecenie cofnij nie pozwala na późniejsze modyfikacje zadania." #define STRING_CMD_STATS_USAGE "Pokazuje statystyki bazy danych zadań" diff --git a/src/l10n/por-PRT.h b/src/l10n/por-PRT.h index 97d9de571..64c9ca459 100644 --- a/src/l10n/por-PRT.h +++ b/src/l10n/por-PRT.h @@ -296,6 +296,7 @@ #define STRING_CMD_INFO_UNTIL "Até" #define STRING_CMD_INFO_MODIFICATION "Modificação" #define STRING_CMD_INFO_MODIFIED "Última modificação" +#define STRING_CMD_INFO_VIRTUAL_TAGS "Virtual tags" #define STRING_CMD_UNDO_USAGE "Reverte a mais recente modificação a uma tarefa" #define STRING_CMD_UNDO_MODS "O comando undo não permite outras modificações simultâneas." #define STRING_CMD_STATS_USAGE "Exibe estatísticas da base de dados de tarefas"