diff --git a/src/Config.cpp b/src/Config.cpp index 094f95caa..822f40972 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -45,32 +45,59 @@ // upgrade program to make the change, or c) this. Config::Config () { - (*this)["report.long.description"] = "Lists all task, all data, matching the specified criteria"; // TODO i18n - (*this)["report.long.columns"] = "id,project,priority,entry,start,due,recur,age,tags,description"; // TODO i18n - (*this)["report.long.labels"] = "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description"; // TODO i18n - (*this)["report.long.sort"] = "due+,priority-,project+"; // TODO i18n + set ("report.long.description", "Lists all task, all data, matching the specified criteria"); // TODO i18n + set ("report.long.columns", "id,project,priority,entry,start,due,recur,age,tags,description"); // TODO i18n + set ("report.long.labels", "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description"); // TODO i18n + set ("report.long.sort", "due+,priority-,project+"); // TODO i18n + set ("report.long.filter", "status:pending"); // TODO i18n - (*this)["report.list.description"] = "Lists all tasks matching the specified criteria"; // TODO i18n - (*this)["report.list.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n - (*this)["report.list.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n - (*this)["report.list.sort"] = "due+,priority-,project+"; // TODO i18n + set ("report.list.description", "Lists all tasks matching the specified criteria"); // TODO i18n + set ("report.list.columns", "id,project,priority,due,active,age,description"); // TODO i18n + set ("report.list.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n + set ("report.list.sort", "due+,priority-,project+"); // TODO i18n + set ("report.list.filter", "status:pending"); // TODO i18n - (*this)["report.ls.description"] = "Minimal listing of all tasks matching the specified criteria"; // TODO i18n - (*this)["report.ls.columns"] = "id,project,priority,description"; // TODO i18n - (*this)["report.ls.labels"] = "ID,Project,Pri,Description"; // TODO i18n - (*this)["report.ls.sort"] = "priority-,project+"; // TODO i18n + set ("report.ls.description", "Minimal listing of all tasks matching the specified criteria"); // TODO i18n + set ("report.ls.columns", "id,project,priority,description"); // TODO i18n + set ("report.ls.labels", "ID,Project,Pri,Description"); // TODO i18n + set ("report.ls.sort", "priority-,project+"); // TODO i18n + set ("report.ls.filter", "status:pending"); // TODO i18n - (*this)["report.newest.description"] = "Shows the newest tasks"; // TODO i18n - (*this)["report.newest.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n - (*this)["report.newest.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n - (*this)["report.newest.sort"] = "id-"; // TODO i18n - (*this)["report.newest.limit"] = "10"; // no i18n + set ("report.newest.description", "Shows the newest tasks"); // TODO i18n + set ("report.newest.columns", "id,project,priority,due,active,age,description"); // TODO i18n + set ("report.newest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n + set ("report.newest.sort", "id-"); // TODO i18n + set ("report.newest.filter", "status:pending limit:10"); // TODO i18n - (*this)["report.oldest.description"] = "Shows the oldest tasks"; // TODO i18n - (*this)["report.oldest.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n - (*this)["report.oldest.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n - (*this)["report.oldest.sort"] = "id+"; // TODO i18n - (*this)["report.oldest.limit"] = "10"; // no i18n + set ("report.oldest.description", "Shows the oldest tasks"); // TODO i18n + set ("report.oldest.columns", "id,project,priority,due,active,age,description"); // TODO i18n + set ("report.oldest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n + set ("report.oldest.sort", "id+"); // TODO i18n + set ("report.oldest.filter", "status:pending limit:10"); // TODO i18n + + set ("report.overdue.description", "Lists overdue tasks matching the specified criteria"); // TODO i18n + set ("report.overdue.columns", "id,project,priority,due,active,age,description"); // TODO i18n + set ("report.overdue.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n + set ("report.overdue.sort", "due+,priority-,project+"); // TODO i18n + set ("report.overdue.filter", "status:pending due.before:today"); // TODO i18n + + set ("report.active.description", "Lists active tasks matching the specified criteria"); // TODO i18n + set ("report.active.columns", "id,project,priority,due,active,age,description"); // TODO i18n + set ("report.active.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n + set ("report.active.sort", "due+,priority-,project+"); // TODO i18n + set ("report.active.filter", "status:pending start.any:"); // TODO i18n + + set ("report.completed.description", "Lists completed tasks matching the specified criteria"); // TODO i18n + set ("report.completed.columns", "end,project,priority,age,description"); // TODO i18n + set ("report.completed.labels", "Complete,Project,Pri,Age,Description"); // TODO i18n + set ("report.completed.sort", "end+,priority-,project+"); // TODO i18n + set ("report.completed.filter", "status:completed"); // TODO i18n + + set ("report.recurring.description", "Lists recurring tasks matching the specified criteria"); // TODO i18n + set ("report.recurring.columns", "id,project,priority,due,recur,active,age,description"); // TODO i18n + set ("report.recurring.labels", "ID,Project,Pri,Due,Recur,Active,Age,Description"); // TODO i18n + set ("report.recurring.sort", "due+,priority-,project+"); // TODO i18n + set ("report.recurring.filter", "status:pending parent.any:"); // TODO i18n } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Context.cpp b/src/Context.cpp index 1b1671d7d..39cb46338 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -202,10 +202,7 @@ std::string Context::dispatch () // Command that display IDs and therefore need TDB::gc first. /* - else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (); } // TODO OBSOLETE else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (); } - else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (); } // TODO OBSOLETE - else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (); } // TODO OBSOLETE */ else if (cmd.validCustom (cmd.command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (cmd.command); } diff --git a/src/custom.cpp b/src/custom.cpp index afc038128..06d2cf0af 100644 --- a/src/custom.cpp +++ b/src/custom.cpp @@ -199,6 +199,25 @@ std::string handleCustomReport (const std::string& report) } } + else if (*col == "end") + { + table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Completed"); + table.setColumnWidth (columnCount, Table::minimum); + table.setColumnJustification (columnCount, Table::right); + + std::string started; + for (unsigned int row = 0; row < tasks.size(); ++row) + { + started = tasks[row].get ("end"); + if (started.length ()) + { + Date dt (::atoi (started.c_str ())); + started = dt.toString (context.config.get ("dateformat", "m/d/Y")); + table.addCell (row, columnCount, started); + } + } + } + else if (*col == "due") { table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Due"); diff --git a/src/main.h b/src/main.h index cf903f64d..17e1507cc 100644 --- a/src/main.h +++ b/src/main.h @@ -93,14 +93,11 @@ std::string longUsage (); void filterSequence (std::vector&, T&); void filter (std::vector&, T&); std::string handleInfo (); -std::string handleCompleted (); std::string handleReportSummary (); std::string handleReportNext (); std::string handleReportHistory (); std::string handleReportGHistory (); std::string handleReportCalendar (); -std::string handleReportActive (); -std::string handleReportOverdue (); std::string handleReportStats (); std::string handleReportTimesheet (); diff --git a/src/report.cpp b/src/report.cpp index 9c7d83145..a8e0d81a1 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -85,10 +85,6 @@ std::string shortUsage () table.addCell (row, 1, "task annotate ID desc..."); table.addCell (row, 2, "Adds an annotation to an existing task"); - row = table.addRow (); - table.addCell (row, 1, "task completed [tags] [attrs] desc..."); - table.addCell (row, 2, "Chronological listing of all completed tasks matching the specified criteria"); - row = table.addRow (); table.addCell (row, 1, "task ID [tags] [attrs] [desc...]"); table.addCell (row, 2, "Modifies the existing task with provided arguments"); @@ -169,14 +165,6 @@ std::string shortUsage () table.addCell (row, 1, "task calendar"); table.addCell (row, 2, "Shows a monthly calendar, with due tasks marked"); - row = table.addRow (); - table.addCell (row, 1, "task active"); - table.addCell (row, 2, "Shows all task that are started, but not completed"); - - row = table.addRow (); - table.addCell (row, 1, "task overdue"); - table.addCell (row, 2, "Shows all incomplete tasks that are beyond their due date"); - row = table.addRow (); table.addCell (row, 1, "task stats"); table.addCell (row, 2, "Shows task database statistics"); @@ -429,103 +417,6 @@ void filter (std::vector& all, T& task) all = filtered; } -//////////////////////////////////////////////////////////////////////////////// -// Successively apply filters based on the task object built from the command -// line. Tasks that match all the specified criteria are listed. -std::string handleCompleted () -{ - std::stringstream out; - -/* - // Get the pending tasks. - std::vector tasks; - tdb.completedT (tasks); - filter (tasks, task); - - initializeColorRules (); - - // Create a table for output. - Table table; - table.setTableWidth (context.getWidth ()); - table.setDateFormat (context.config.get ("dateformat", "m/d/Y")); - table.addColumn ("Done"); - table.addColumn ("Project"); - table.addColumn ("Description"); - - if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) && - context.config.get (std::string ("fontunderline"), "true")) - { - table.setColumnUnderline (0); - table.setColumnUnderline (1); - table.setColumnUnderline (2); - } - else - table.setTableDashedUnderline (); - - table.setColumnWidth (0, Table::minimum); - table.setColumnWidth (1, Table::minimum); - table.setColumnWidth (2, Table::flexible); - - table.setColumnJustification (0, Table::right); - table.setColumnJustification (1, Table::left); - table.setColumnJustification (2, Table::left); - - // Note: There is deliberately no sorting. The original sorting was on the - // end date. Tasks are appended to completed.data naturally sorted by - // the end date, so that sequence is assumed to remain unchanged, and - // relied upon here. - - // Iterate over each task, and apply selection criteria. - for (unsigned int i = 0; i < tasks.size (); ++i) - { - T refTask (tasks[i]); - - // Now format the matching task. - Date end (::atoi (refTask.getAttribute ("end").c_str ())); - - // All criteria match, so add refTask to the output table. - int row = table.addRow (); - - table.addCell (row, 0, end.toString (context.config.get ("dateformat", "m/d/Y"))); - table.addCell (row, 1, refTask.getAttribute ("project")); - - std::string description = refTask.getDescription (); - std::string when; - std::map annotations; - refTask.getAnnotations (annotations); - foreach (anno, annotations) - { - Date dt (anno->first); - when = dt.toString (context.config.get ("dateformat", "m/d/Y")); - description += "\n" + when + " " + anno->second; - } - table.addCell (row, 2, description); - - if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) - { - Text::color fg = Text::colorCode (refTask.getAttribute ("fg")); - Text::color bg = Text::colorCode (refTask.getAttribute ("bg")); - autoColorize (refTask, fg, bg); - table.setRowFg (row, fg); - table.setRowBg (row, bg); - } - } - - if (table.rowCount ()) - out << optionalBlankLine () - << table.render () - << optionalBlankLine () - << table.rowCount () - << (table.rowCount () == 1 ? " task" : " tasks") - << std::endl; - else - out << "No matches." - << std::endl; -*/ - - return out.str (); -} - //////////////////////////////////////////////////////////////////////////////// // Display all information for the given task. std::string handleInfo () @@ -1998,244 +1889,6 @@ std::string handleReportCalendar () return out.str (); } -//////////////////////////////////////////////////////////////////////////////// -std::string handleReportActive () -{ - std::stringstream out; - -/* - // Get all the tasks. - std::vector tasks; - tdb.pendingT (tasks); - filter (tasks, task); - - initializeColorRules (); - - // Create a table for output. - Table table; - table.setTableWidth (context.getWidth ()); - table.setDateFormat (context.config.get ("dateformat", "m/d/Y")); - table.addColumn ("ID"); - table.addColumn ("Project"); - table.addColumn ("Pri"); - table.addColumn ("Due"); - table.addColumn ("Description"); - - if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) && - context.config.get (std::string ("fontunderline"), "true")) - { - table.setColumnUnderline (0); - table.setColumnUnderline (1); - table.setColumnUnderline (2); - table.setColumnUnderline (3); - table.setColumnUnderline (4); - } - else - table.setTableDashedUnderline (); - - table.setColumnWidth (0, Table::minimum); - table.setColumnWidth (1, Table::minimum); - table.setColumnWidth (2, Table::minimum); - table.setColumnWidth (3, Table::minimum); - table.setColumnWidth (4, Table::flexible); - - table.setColumnJustification (0, Table::right); - table.setColumnJustification (3, Table::right); - - table.sortOn (3, Table::ascendingDate); - table.sortOn (2, Table::descendingPriority); - table.sortOn (1, Table::ascendingCharacter); - - // Iterate over each task, and apply selection criteria. - for (unsigned int i = 0; i < tasks.size (); ++i) - { - T refTask (tasks[i]); - if (refTask.has ("start")) - { - Date now; - bool imminent = false; - bool overdue = false; - std::string due = refTask.getAttribute ("due"); - if (due.length ()) - { - switch (getDueState (due)) - { - case 2: overdue = true; break; - case 1: imminent = true; break; - case 0: - default: break; - } - - Date dt (::atoi (due.c_str ())); - due = dt.toString (context.config.get ("dateformat", "m/d/Y")); - } - - // All criteria match, so add refTask to the output table. - int row = table.addRow (); - table.addCell (row, 0, refTask.getId ()); - table.addCell (row, 1, refTask.getAttribute ("project")); - table.addCell (row, 2, refTask.getAttribute ("priority")); - table.addCell (row, 3, due); - - std::string description = refTask.getDescription (); - std::string when; - std::map annotations; - refTask.getAnnotations (annotations); - foreach (anno, annotations) - { - Date dt (anno->first); - when = dt.toString (context.config.get ("dateformat", "m/d/Y")); - description += "\n" + when + " " + anno->second; - } - - table.addCell (row, 4, description); - - if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) - { - Text::color fg = Text::colorCode (refTask.getAttribute ("fg")); - Text::color bg = Text::colorCode (refTask.getAttribute ("bg")); - autoColorize (refTask, fg, bg); - table.setRowFg (row, fg); - table.setRowBg (row, bg); - - if (fg == Text::nocolor) - { - if (overdue) - table.setCellFg (row, 3, Text::colorCode (context.config.get ("color.overdue", "red"))); - else if (imminent) - table.setCellFg (row, 3, Text::colorCode (context.config.get ("color.due", "yellow"))); - } - } - } - } - - if (table.rowCount ()) - out << optionalBlankLine () - << table.render () - << optionalBlankLine () - << table.rowCount () - << (table.rowCount () == 1 ? " task" : " tasks") - << std::endl; - else - out << "No active tasks." << std::endl; -*/ - return out.str (); -} - -//////////////////////////////////////////////////////////////////////////////// -std::string handleReportOverdue () -{ - std::stringstream out; - -/* - // Get all the tasks. - std::vector tasks; - tdb.pendingT (tasks); - filter (tasks, task); - - initializeColorRules (); - - // Create a table for output. - Table table; - table.setTableWidth (context.getWidth ()); - table.setDateFormat (context.config.get ("dateformat", "m/d/Y")); - table.addColumn ("ID"); - table.addColumn ("Project"); - table.addColumn ("Pri"); - table.addColumn ("Due"); - table.addColumn ("Description"); - - if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) && - context.config.get (std::string ("fontunderline"), "true")) - { - table.setColumnUnderline (0); - table.setColumnUnderline (1); - table.setColumnUnderline (2); - table.setColumnUnderline (3); - table.setColumnUnderline (4); - } - else - table.setTableDashedUnderline (); - - table.setColumnWidth (0, Table::minimum); - table.setColumnWidth (1, Table::minimum); - table.setColumnWidth (2, Table::minimum); - table.setColumnWidth (3, Table::minimum); - table.setColumnWidth (4, Table::flexible); - - table.setColumnJustification (0, Table::right); - table.setColumnJustification (3, Table::right); - - table.sortOn (3, Table::ascendingDate); - table.sortOn (2, Table::descendingPriority); - table.sortOn (1, Table::ascendingCharacter); - - Date now; - - // Iterate over each task, and apply selection criteria. - for (unsigned int i = 0; i < tasks.size (); ++i) - { - T refTask (tasks[i]); - std::string due; - if ((due = refTask.has ("due"))) - { - if (due.length ()) - { - Date dt (::atoi (due.c_str ())); - due = dt.toString (context.config.get ("dateformat", "m/d/Y")); - - // If overdue. - if (dt < now) - { - // All criteria match, so add refTask to the output table. - int row = table.addRow (); - table.addCell (row, 0, refTask.getId ()); - table.addCell (row, 1, refTask.getAttribute ("project")); - table.addCell (row, 2, refTask.getAttribute ("priority")); - table.addCell (row, 3, due); - - std::string description = refTask.getDescription (); - std::string when; - std::map annotations; - refTask.getAnnotations (annotations); - foreach (anno, annotations) - { - Date dt (anno->first); - when = dt.toString (context.config.get ("dateformat", "m/d/Y")); - description += "\n" + when + " " + anno->second; - } - - table.addCell (row, 4, description); - - if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) - { - Text::color fg = Text::colorCode (refTask.getAttribute ("fg")); - Text::color bg = Text::colorCode (refTask.getAttribute ("bg")); - autoColorize (refTask, fg, bg); - table.setRowFg (row, fg); - table.setRowBg (row, bg); - - if (fg == Text::nocolor) - table.setCellFg (row, 3, Text::red); - } - } - } - } - } - - if (table.rowCount ()) - out << optionalBlankLine () - << table.render () - << optionalBlankLine () - << table.rowCount () - << (table.rowCount () == 1 ? " task" : " tasks") - << std::endl; - else - out << "No overdue tasks." << std::endl; -*/ - return out.str (); -} - //////////////////////////////////////////////////////////////////////////////// std::string handleReportStats () { diff --git a/src/valid.cpp b/src/valid.cpp index 69b2addea..45f54f453 100644 --- a/src/valid.cpp +++ b/src/valid.cpp @@ -290,6 +290,7 @@ void validReportColumns (const std::vector & columns) *it != "priority" && *it != "entry" && *it != "start" && + *it != "end" && *it != "due" && *it != "age" && *it != "age_compact" &&