From 57aa2de98cffa51063b9d522c98b886d1cd99705 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Mon, 16 Jul 2012 00:16:36 -0400 Subject: [PATCH] UDA - Implemented UDAs in the 'edit' command for all four UDA data types. --- src/Duration.cpp | 9 ++++ src/Duration.h | 1 + src/commands/CmdEdit.cpp | 101 +++++++++++++++++++++++++++++++++++++-- src/commands/CmdEdit.h | 1 + src/en-US.h | 2 + 5 files changed, 109 insertions(+), 5 deletions(-) diff --git a/src/Duration.cpp b/src/Duration.cpp index 854049342..d82b98bc1 100644 --- a/src/Duration.cpp +++ b/src/Duration.cpp @@ -303,6 +303,15 @@ std::string Duration::formatPrecise () const return std::string (formatted); } + +//////////////////////////////////////////////////////////////////////////////// +std::string Duration::formatSeconds () const +{ + char formatted[24]; + sprintf (formatted, "%s%ldsec", (_negative ? "-" : ""), _secs); + return std::string (formatted); +} + //////////////////////////////////////////////////////////////////////////////// bool Duration::operator< (const Duration& other) { diff --git a/src/Duration.h b/src/Duration.h index 9336d961b..e59d5d8fd 100644 --- a/src/Duration.h +++ b/src/Duration.h @@ -57,6 +57,7 @@ public: std::string format () const; std::string formatCompact () const; std::string formatPrecise () const; + std::string formatSeconds () const; bool negative () const; static bool valid (const std::string&); diff --git a/src/commands/CmdEdit.cpp b/src/commands/CmdEdit.cpp index 6ea3a0566..3a07a7c7b 100644 --- a/src/commands/CmdEdit.cpp +++ b/src/commands/CmdEdit.cpp @@ -97,6 +97,35 @@ std::string CmdEdit::findValue ( return ""; } +//////////////////////////////////////////////////////////////////////////////// +std::vector CmdEdit::findValues ( + const std::string& text, + const std::string& name) +{ + std::vector results; + std::string::size_type found = 0; + + while (found != std::string::npos) + { + found = text.find (name, found + 1); + if (found != std::string::npos) + { + std::string::size_type eol = text.find ("\n", found + 1); + if (eol != std::string::npos) + { + std::string value = text.substr ( + found + name.length (), + eol - (found + name.length ())); + + found = eol - 1; + results.push_back (trim (value, "\t ")); + } + } + } + + return results; +} + //////////////////////////////////////////////////////////////////////////////// std::string CmdEdit::formatDate ( Task& task, @@ -106,7 +135,7 @@ std::string CmdEdit::formatDate ( std::string value = task.get (attribute); if (value.length ()) { - Date dt (strtol (value.c_str (), NULL, 10)); + Date dt (value); value = dt.toString (dateformat); } @@ -121,8 +150,8 @@ std::string CmdEdit::formatDuration ( std::string value = task.get (attribute); if (value.length ()) { - Duration dur (strtol (value.c_str (), NULL, 10)); - value = dur.formatPrecise (); + Duration dur (value); + value = dur.formatSeconds (); } return value; @@ -681,9 +710,71 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string task.addDependency (*id); } - // TODO UDAs + // UDAs + std::map ::iterator col; + for (col = context.columns.begin (); col != context.columns.end (); ++col) + { + std::string type = context.config.get ("uda." + col->first + ".type"); + if (type != "") + { + std::string value = findValue (after, "\n UDA " + col->first + ":"); + if (task.get (col->first) != value) + { + if (value != "") + { + context.footnote (format (STRING_EDIT_UDA_MOD, col->first)); - // TODO UDA orphans + if (type == "string") + { + task.set (col->first, value); + } + else if (type == "numeric") + { + Nibbler n (value); + double d; + if (n.getNumber (d) && + n.depleted ()) + task.set (col->first, value); + else + throw format (STRING_UDA_NUMERIC, value); + } + else if (type == "date") + { + Date d (value, dateformat); + task.set (col->first, d.toEpochString ()); + } + else if (type == "duration") + { + Duration d (value); + task.set (col->first, (time_t) d); + } + } + else + { + context.footnote (format (STRING_EDIT_UDA_DEL, col->first)); + task.remove (col->first); + } + } + } + } + + // UDA orphans + std::vector orphanValues = findValues (after, "\n UDA Orphan "); + std::vector ::iterator orphan; + for (orphan = orphanValues.begin (); orphan != orphanValues.end (); ++orphan) + { + std::string::size_type colon = orphan->find (':'); + if (colon != std::string::npos) + { + std::string name = trim (orphan->substr (0, colon), "\t "); + std::string value = trim (orphan->substr (colon + 1), "\t "); + + if (value != "") + task.set (name, value); + else + task.remove (name); + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdEdit.h b/src/commands/CmdEdit.h index fc4599ccb..0496c61f3 100644 --- a/src/commands/CmdEdit.h +++ b/src/commands/CmdEdit.h @@ -41,6 +41,7 @@ public: private: std::string findValue (const std::string&, const std::string&); + std::vector findValues (const std::string&, const std::string&); std::string formatDate (Task&, const std::string&, const std::string&); std::string formatDuration (Task&, const std::string&); std::string formatTask (Task, const std::string&); diff --git a/src/en-US.h b/src/en-US.h index 1011a7a86..ad38c8b35 100644 --- a/src/en-US.h +++ b/src/en-US.h @@ -654,6 +654,8 @@ #define STRING_EDIT_FG_DEL "Foreground color removed." #define STRING_EDIT_BG_MOD "Background color modified." #define STRING_EDIT_BG_DEL "Background color removed." +#define STRING_EDIT_UDA_MOD "UDA {1} modified." +#define STRING_EDIT_UDA_DEL "UDA {1} deleted." // These four blocks can be replaced, but the number of lines must not change. #define STRING_EDIT_HEADER_1 "The 'task edit' command allows you to modify all aspects of a task"