From 315c70c503863a5fcbe11a3acd664b0321daecd1 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Thu, 18 Jun 2009 20:13:12 -0400 Subject: [PATCH] Enhancement - custom report name collisions - Task now emits an error if a custom report name collides with that of a built-in command. --- src/Cmd.cpp | 9 +++- src/Task.cpp | 124 +++++++++++++++++++++++++-------------------------- 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/src/Cmd.cpp b/src/Cmd.cpp index bd23d21d2..46a9d5ccb 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -147,9 +147,14 @@ void Cmd::load () { report = report.substr (0, columns); + + // Make sure a custom report does not clash with a built-in + // command. + if (std::find (commands.begin (), commands.end (), report) != commands.end ()) + throw std::string ("Custom report '") + report + + "' conflicts with built-in task command."; + // A custom report is also a command. - // TODO Make sure a custom report does not clash with a built-in - // command. customReports.push_back (report); commands.push_back (report); } diff --git a/src/Task.cpp b/src/Task.cpp index d39cd5caf..2159521a6 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -37,7 +37,7 @@ Task::Task () : id (0) { // Each new task gets a uuid. - set ("uuid", uuid ()); + set ("uuid", uuid ()); // No i18n } //////////////////////////////////////////////////////////////////////////////// @@ -89,10 +89,10 @@ Task::~Task () //////////////////////////////////////////////////////////////////////////////// Task::status Task::textToStatus (const std::string& input) { - if (input == "pending") return Task::pending; - else if (input == "completed") return Task::completed; - else if (input == "deleted") return Task::deleted; - else if (input == "recurring") return Task::recurring; + if (input == "pending") return Task::pending; // TODO i18n + else if (input == "completed") return Task::completed; // TODO i18n + else if (input == "deleted") return Task::deleted; // TODO i18n + else if (input == "recurring") return Task::recurring; // TODO i18n return Task::pending; } @@ -100,10 +100,10 @@ Task::status Task::textToStatus (const std::string& input) //////////////////////////////////////////////////////////////////////////////// std::string Task::statusToText (Task::status s) { - if (s == Task::pending) return "pending"; - else if (s == Task::completed) return "completed"; - else if (s == Task::deleted) return "deleted"; - else if (s == Task::recurring) return "recurring"; + if (s == Task::pending) return "pending"; // TODO i18n + else if (s == Task::completed) return "completed"; // TODO i18n + else if (s == Task::deleted) return "deleted"; // TODO i18n + else if (s == Task::recurring) return "recurring"; // TODO i18n return "pending"; } @@ -113,19 +113,19 @@ void Task::setEntry () { char entryTime[16]; sprintf (entryTime, "%u", (unsigned int) time (NULL)); - set ("entry", entryTime); + set ("entry", entryTime); // No i18n } //////////////////////////////////////////////////////////////////////////////// Task::status Task::getStatus () { - return textToStatus (get ("status")); + return textToStatus (get ("status")); // No i18n } //////////////////////////////////////////////////////////////////////////////// void Task::setStatus (Task::status status) { - set ("status", statusToText (status)); + set ("status", statusToText (status)); // No i18n } //////////////////////////////////////////////////////////////////////////////// @@ -158,7 +158,7 @@ void Task::legacyParse (const std::string& line) // File format version 1, from 2006.11.27 - 2007.12.31 case 1: throw std::string ("Task no longer supports file format 1, originally used " - "between 27 November 2006 and 31 December 2007."); + "between 27 November 2006 and 31 December 2007."); // TODO i18n break; // File format version 2, from 2008.1.1 - 2009.3.23 @@ -173,7 +173,7 @@ void Task::legacyParse (const std::string& line) : line[37] == 'r' ? recurring : pending; - set ("status", statusToText (status)); + set ("status", statusToText (status)); // No i18n size_t openTagBracket = line.find ("["); size_t closeTagBracket = line.find ("]", openTagBracket); @@ -203,16 +203,16 @@ void Task::legacyParse (const std::string& line) set (pair[0], pair[1]); } - set ("description", line.substr (closeAttrBracket + 2, std::string::npos)); + set ("description", line.substr (closeAttrBracket + 2, std::string::npos)); // No i18n } else - throw std::string ("Missing attribute brackets"); + throw std::string ("Missing attribute brackets"); // TODO i18n } else - throw std::string ("Missing tag brackets"); + throw std::string ("Missing tag brackets"); // TODO i18n } else - throw std::string ("Line too short"); + throw std::string ("Line too short"); // TODO i18n removeAnnotations (); } @@ -230,7 +230,7 @@ void Task::legacyParse (const std::string& line) : line[37] == 'r' ? recurring : pending; - set ("status", statusToText (status)); + set ("status", statusToText (status)); // No i18n size_t openTagBracket = line.find ("["); size_t closeTagBracket = line.find ("]", openTagBracket); @@ -300,28 +300,28 @@ 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); + set ("annotation_" + name, value); // No i18n } } - set ("description", line.substr (closeAnnoBracket + 2, std::string::npos)); + set ("description", line.substr (closeAnnoBracket + 2, std::string::npos)); // No i18n } else - throw std::string ("Missing annotation brackets."); + throw std::string ("Missing annotation brackets."); // TODO i18n } else - throw std::string ("Missing attribute brackets."); + throw std::string ("Missing attribute brackets."); // TODO i18n } else - throw std::string ("Missing tag brackets."); + throw std::string ("Missing tag brackets."); // TODO i18n } else - throw std::string ("Line too short."); + throw std::string ("Line too short."); // TODO i18n } break; default: - throw std::string ("Unrecognized task file format."); + throw std::string ("Unrecognized task file format."); // TODO i18n break; } } @@ -332,30 +332,30 @@ std::string Task::composeCSV () const std::stringstream out; out << "'" << id << "',"; - out << "'" << get ("uuid") << "',"; - out << "'" << get ("status") << "',"; + out << "'" << get ("uuid") << "',"; // No i18n + out << "'" << get ("status") << "',"; // No i18n // Tags std::vector tags; getTags (tags); std::string allTags; - join (allTags, " ", tags); - out << "'" << allTags << "',"; + join (allTags, " ", tags); // No i18n + out << "'" << allTags << "',"; // No i18n - out << "'" << get ("entry") << "',"; - out << "'" << get ("start") << "',"; - out << "'" << get ("due") << "',"; - out << "'" << get ("recur") << "',"; - out << "'" << get ("end") << "',"; - out << "'" << get ("project") << "',"; - out << "'" << get ("priority") << "',"; - out << "'" << get ("fg") << "',"; - out << "'" << get ("bg") << "',"; + out << "'" << get ("entry") << "',"; // No i18n + out << "'" << get ("start") << "',"; // No i18n + out << "'" << get ("due") << "',"; // No i18n + out << "'" << get ("recur") << "',"; // No i18n + out << "'" << get ("end") << "',"; // No i18n + out << "'" << get ("project") << "',"; // No i18n + out << "'" << get ("priority") << "',"; // No i18n + out << "'" << get ("fg") << "',"; // No i18n + out << "'" << get ("bg") << "',"; // No i18n // Convert single quotes to double quotes, because single quotes are used to // delimit the values that need it. - std::string clean = get ("description"); - std::replace (clean.begin (), clean.end (), '\'', '"'); + std::string clean = get ("description"); // No i18n + std::replace (clean.begin (), clean.end (), '\'', '"'); // No i18n out << "'" << clean << "'\n"; return out.str (); @@ -368,7 +368,7 @@ void Task::getAnnotations (std::vector & annotations) const Record::const_iterator ci; for (ci = this->begin (); ci != this->end (); ++ci) - if (ci->first.substr (0, 11) == "annotation_") + if (ci->first.substr (0, 11) == "annotation_") // No i18n annotations.push_back (ci->second); } @@ -390,7 +390,7 @@ void Task::setAnnotations (const std::vector & annotations) void Task::addAnnotation (const std::string& description) { std::stringstream s; - s << "annotation_" << time (NULL); + s << "annotation_" << time (NULL); // No i18n (*this)[s.str ()] = Att (s.str (), description); } @@ -401,7 +401,7 @@ void Task::removeAnnotations () // Erase old annotations. Record::iterator i; for (i = this->begin (); i != this->end (); ++i) - if (i->first.substr (0, 11) == "annotation_") + if (i->first.substr (0, 11) == "annotation_") // No i18n this->erase (i); } @@ -409,7 +409,7 @@ void Task::removeAnnotations () int Task::getTagCount () { std::vector tags; - split (tags, get ("tags"), ','); + split (tags, get ("tags"), ','); // No i18n return (int) tags.size (); } @@ -418,7 +418,7 @@ int Task::getTagCount () bool Task::hasTag (const std::string& tag) { std::vector tags; - split (tags, get ("tags"), ','); + split (tags, get ("tags"), ','); // No i18n if (std::find (tags.begin (), tags.end (), tag) != tags.end ()) return true; @@ -430,21 +430,21 @@ bool Task::hasTag (const std::string& tag) void Task::addTag (const std::string& tag) { std::vector tags; - split (tags, get ("tags"), ','); + split (tags, get ("tags"), ','); // No i18n if (std::find (tags.begin (), tags.end (), tag) == tags.end ()) { tags.push_back (tag); std::string combined; - join (combined, ",", tags); - set ("tags", combined); + join (combined, ",", tags); // No i18n + set ("tags", combined); // No i18n } } //////////////////////////////////////////////////////////////////////////////// void Task::addTags (const std::vector & tags) { - remove ("tags"); + remove ("tags"); // No i18n std::vector ::const_iterator it; for (it = tags.begin (); it != tags.end (); ++it) @@ -454,14 +454,14 @@ void Task::addTags (const std::vector & tags) //////////////////////////////////////////////////////////////////////////////// void Task::getTags (std::vector& tags) const { - split (tags, get ("tags"), ','); + split (tags, get ("tags"), ','); // No i18n } //////////////////////////////////////////////////////////////////////////////// void Task::removeTag (const std::string& tag) { std::vector tags; - split (tags, get ("tags"), ','); + split (tags, get ("tags"), ','); // No i18n std::vector ::iterator i; i = std::find (tags.begin (), tags.end (), tag); @@ -469,8 +469,8 @@ void Task::removeTag (const std::string& tag) { tags.erase (i); std::string combined; - join (combined, ",", tags); - set ("tags", combined); + join (combined, ",", tags); // No i18n + set ("tags", combined); // No i18n } } @@ -486,8 +486,8 @@ void Task::validate () const // TODO Verify entry < until, due, start, end // TODO If name == "recur", then Duration::valid (value). - if (get ("description") == "") - throw std::string ("Cannot add a task that is blank, or contains or characters."); + if (get ("description") == "") // No i18n + throw std::string ("Cannot add a task that is blank, or contains or characters."); // TODO i18n } //////////////////////////////////////////////////////////////////////////////// @@ -515,9 +515,9 @@ int Task::determineVersion (const std::string& line) // uuid status [tags] [attributes] [annotations] description\n // // Scan for the number of [] pairs. - std::string::size_type tagAtts = line.find ("] [", 0); - std::string::size_type attsAnno = line.find ("] [", tagAtts + 1); - std::string::size_type annoDesc = line.find ("] ", attsAnno + 1); + std::string::size_type tagAtts = line.find ("] [", 0); // No i18n + std::string::size_type attsAnno = line.find ("] [", tagAtts + 1); // No i18n + std::string::size_type annoDesc = line.find ("] ", attsAnno + 1); // No i18n if (tagAtts != std::string::npos && attsAnno != std::string::npos && annoDesc != std::string::npos) @@ -533,7 +533,7 @@ int Task::determineVersion (const std::string& line) // Scan for [, ] and :". else if (line[0] == '[' && line[line.length () - 1] == ']' && - line.find ("uuid:\"") != std::string::npos) + line.find ("uuid:\"") != std::string::npos) // No i18n return 4; // Version 1 looks like: @@ -543,9 +543,9 @@ int Task::determineVersion (const std::string& line) // // Scan for the first character being either the bracket or X. else if (line.find ("X [") == 0 || - line.find ("uuid") == std::string::npos || + line.find ("uuid") == std::string::npos || // No i18n (line[0] == '[' && - line.substr (line.length () - 1, 1) != "]")) + line.substr (line.length () - 1, 1) != "]")) // No i18n return 1; // Version 5?