diff --git a/src/Context.cpp b/src/Context.cpp index 9638fe69b..925c6416e 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -204,7 +204,9 @@ std::string Context::dispatch () else if (cmd.command == "export") { out = handleExport (); } /* else if (cmd.command == "import") { out = handleImport (); } +*/ else if (cmd.command == "duplicate") { out = handleDuplicate (); } +/* else if (cmd.command == "edit") { out = handleEdit (); } */ @@ -449,7 +451,6 @@ void Context::parse () // Anything else is just considered description. else { - header ("parse description '" + *arg + "'"); if (foundSequence) foundSomethingAfterSequence = true; @@ -473,7 +474,10 @@ void Context::parse () } if (descCandidate != "" && noVerticalSpace (descCandidate)) + { + header ("parse description '" + descCandidate + "'"); task.set ("description", descCandidate); + } // TODO task.validate () ? diff --git a/src/command.cpp b/src/command.cpp index 7fee10a02..ab4053fad 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -880,58 +880,72 @@ std::string handleAppend () //////////////////////////////////////////////////////////////////////////////// std::string handleDuplicate () { -/* - int count = 0; -*/ std::stringstream out; -/* - std::vector all; - tdb.allPendingT (all); + int count = 0; - std::vector filtered = all; - filterSequence (filtered, task); - foreach (seq, filtered) + std::vector tasks; + context.tdb.lock (context.config.get ("locking", true)); + context.tdb.loadPending (tasks, context.filter); + + // Filter sequence. + context.filter.applySequence (tasks, context.sequence); + + foreach (task, tasks) { - if (seq->getStatus () != T::recurring && seq->getAttribute ("parent") == "") + Task dup (*task); + dup.set ("uuid", uuid ()); // Needs a new UUID. + dup.setStatus (Task::pending); + dup.remove ("start"); // Does not inherit start date. + dup.remove ("end"); // Does not inherit end date. + + // Recurring tasks are duplicated and downgraded to regular tasks. + if (task->getStatus () == Task::recurring) { - T dup (*seq); - dup.setUUID (uuid ()); // Needs a new UUID. + dup.remove ("parent"); + dup.remove ("recur"); + dup.remove ("until"); + dup.remove ("imak"); + dup.remove ("imask"); - // Apply deltas. - deltaDescription (dup, task); - deltaTags (dup, task); - deltaAttributes (dup, task); - deltaSubstitutions (dup, task); - - // A New task needs a new entry time. - char entryTime[16]; - sprintf (entryTime, "%u", (unsigned int) time (NULL)); - dup.setAttribute ("entry", entryTime); - - if (!tdb.addT (dup)) - throw std::string ("Could not create new task."); - - if (context.config.get ("echo.command", true)) - out << "Duplicated " - << seq->getId () - << " '" - << seq->getDescription () - << "'" - << std::endl; - ++count; - } - else - out << "Task " - << seq->getId () - << " '" - << seq->getDescription () - << "' is a recurring task, and cannot be duplicated." + out << "Note: task " + << task->id + << " was a recurring task. The new task is not." << std::endl; + } + + // Apply deltas. + deltaDescription (dup); + context.task.remove ("description"); + + deltaTags (dup); + context.task.remove ("tags"); + + deltaAttributes (dup); + deltaSubstitutions (dup); + + // A New task needs a new entry time. + char entryTime[16]; + sprintf (entryTime, "%u", (unsigned int) time (NULL)); + dup.set ("entry", entryTime); + + context.tdb.add (dup); + + if (context.config.get ("echo.command", true)) + out << "Duplicated " + << task->id + << " '" + << task->get ("description") + << "'" + << std::endl; + ++count; } + context.tdb.commit (); + context.tdb.unlock (); + if (context.config.get ("echo.command", true)) out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl; -*/ + return out.str (); }