mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Enhancement - undo
- Implemented new undo command. - Removed old undelete command. - Does not work yet.
This commit is contained in:
parent
b7a0883212
commit
0891d3ea63
4 changed files with 124 additions and 15 deletions
|
@ -132,7 +132,6 @@ void Cmd::load ()
|
||||||
commands.push_back (context.stringtable.get (CMD_SUMMARY, "summary"));
|
commands.push_back (context.stringtable.get (CMD_SUMMARY, "summary"));
|
||||||
commands.push_back (context.stringtable.get (CMD_TAGS, "tags"));
|
commands.push_back (context.stringtable.get (CMD_TAGS, "tags"));
|
||||||
commands.push_back (context.stringtable.get (CMD_TIMESHEET, "timesheet"));
|
commands.push_back (context.stringtable.get (CMD_TIMESHEET, "timesheet"));
|
||||||
commands.push_back (context.stringtable.get (CMD_UNDELETE, "undelete"));
|
|
||||||
commands.push_back (context.stringtable.get (CMD_UNDO, "undo"));
|
commands.push_back (context.stringtable.get (CMD_UNDO, "undo"));
|
||||||
commands.push_back (context.stringtable.get (CMD_VERSION, "version"));
|
commands.push_back (context.stringtable.get (CMD_VERSION, "version"));
|
||||||
|
|
||||||
|
@ -218,7 +217,6 @@ bool Cmd::isWriteCommand ()
|
||||||
command == context.stringtable.get (CMD_IMPORT, "import") ||
|
command == context.stringtable.get (CMD_IMPORT, "import") ||
|
||||||
command == context.stringtable.get (CMD_START, "start") ||
|
command == context.stringtable.get (CMD_START, "start") ||
|
||||||
command == context.stringtable.get (CMD_STOP, "stop") ||
|
command == context.stringtable.get (CMD_STOP, "stop") ||
|
||||||
command == context.stringtable.get (CMD_UNDELETE, "undelete") ||
|
|
||||||
command == context.stringtable.get (CMD_UNDO, "undo"))
|
command == context.stringtable.get (CMD_UNDO, "undo"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
132
src/TDB.cpp
132
src/TDB.cpp
|
@ -493,23 +493,131 @@ int TDB::nextId ()
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void TDB::undo ()
|
void TDB::undo ()
|
||||||
{
|
{
|
||||||
// TODO Load all undo.data
|
std::string location = expandPath (context.config.get ("data.location"));
|
||||||
|
|
||||||
// TODO Load all pending.data
|
std::string undoFile = location + "/undo.data";
|
||||||
std::vector <Task> allPending;
|
std::string pendingFile = location + "/pending.data";
|
||||||
|
std::string completedFile = location + "/completed.data";
|
||||||
|
|
||||||
// TODO Load all completed.data
|
// load undo.data
|
||||||
std::vector <Task> allCompleted;
|
std::vector <std::string> u;
|
||||||
|
slurp (undoFile, u);
|
||||||
|
|
||||||
// TODO 'pop' last transaction
|
if (u.size () < 3)
|
||||||
// TODO Locate 'new' task
|
throw std::string ("There are no recorded transactions to undo.");
|
||||||
|
|
||||||
// TODO Confirm
|
// pop last tx
|
||||||
// TODO Overwrite 'old' task, or delete
|
u.pop_back ();
|
||||||
|
|
||||||
// TODO Write all pending.data
|
std::string current = u.back ().substr (4, std::string::npos);
|
||||||
// TODO Write all completed.data
|
u.pop_back ();
|
||||||
// TODO Write all undo.data
|
|
||||||
|
std::string prior;
|
||||||
|
std::string when;
|
||||||
|
if (u.back ().substr (0, 5) == "time ")
|
||||||
|
{
|
||||||
|
when = u.back ().substr (5, std::string::npos);
|
||||||
|
prior = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prior = u.back ().substr (4, std::string::npos);
|
||||||
|
u.pop_back ();
|
||||||
|
when = u.back ().substr (5, std::string::npos);
|
||||||
|
u.pop_back ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// confirm
|
||||||
|
Task priorTask (prior);
|
||||||
|
Task currentTask (current);
|
||||||
|
std::cout << "The last modification was that "
|
||||||
|
<< taskDifferences (prior, current)
|
||||||
|
<< std::endl
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
if (!confirm ("Are you sure you want to undo the last update?"))
|
||||||
|
throw std::string ("No changes made.");
|
||||||
|
|
||||||
|
// Extract identifying uuid.
|
||||||
|
std::string uuid;
|
||||||
|
std::string::size_type uuidAtt = current.find ("uuid:\"");
|
||||||
|
if (uuidAtt != std::string::npos)
|
||||||
|
uuid = current.substr (uuidAtt, 43); // 43 = uuid:"..."
|
||||||
|
else
|
||||||
|
throw std::string ("Cannot locate UUID in task to undo.");
|
||||||
|
|
||||||
|
std::cout << "# " << uuid << std::endl;
|
||||||
|
|
||||||
|
// load pending.data
|
||||||
|
std::vector <std::string> p;
|
||||||
|
slurp (pendingFile, p);
|
||||||
|
|
||||||
|
// is 'current' in pending?
|
||||||
|
foreach (task, p)
|
||||||
|
{
|
||||||
|
if (task->find (uuid) != std::string::npos)
|
||||||
|
{
|
||||||
|
// Either revert if there was a prior state, or remove the task.
|
||||||
|
if (prior != "")
|
||||||
|
{
|
||||||
|
*task = prior;
|
||||||
|
std::cout << "Modified task reverted." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.erase (task);
|
||||||
|
std::cout << "Task removed." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rewrite files.
|
||||||
|
spit (pendingFile, p);
|
||||||
|
spit (undoFile, u);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load completed.data
|
||||||
|
std::vector <std::string> c;
|
||||||
|
slurp (pendingFile, p);
|
||||||
|
|
||||||
|
// is 'current' in completed?
|
||||||
|
foreach (task, c)
|
||||||
|
{
|
||||||
|
if (task->find (uuid) != std::string::npos)
|
||||||
|
{
|
||||||
|
// If task now belongs back in pending.data
|
||||||
|
if (prior.find ("status:\"pending\"") != std::string::npos ||
|
||||||
|
prior.find ("status:\"waiting\"") != std::string::npos ||
|
||||||
|
prior.find ("status:\"recurring\"") != std::string::npos)
|
||||||
|
{
|
||||||
|
c.erase (task);
|
||||||
|
p.push_back (prior);
|
||||||
|
spit (completedFile, c);
|
||||||
|
spit (pendingFile, p);
|
||||||
|
spit (undoFile, u);
|
||||||
|
std::cout << "Modified task reverted." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*task = prior;
|
||||||
|
spit (completedFile, c);
|
||||||
|
spit (undoFile, u);
|
||||||
|
std::cout << "Modified task reverted." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Undo complete." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perhaps user hand-edited the data files?
|
||||||
|
// Perhaps the task was in completed.data, which was still in file format 3?
|
||||||
|
std::cout << "Task with UUID "
|
||||||
|
<< uuid.substr (6, 36)
|
||||||
|
<< " not found in data."
|
||||||
|
<< std::endl
|
||||||
|
<< "No undo possible."
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
#define CMD_SUMMARY 223
|
#define CMD_SUMMARY 223
|
||||||
#define CMD_TAGS 224
|
#define CMD_TAGS 224
|
||||||
#define CMD_TIMESHEET 225
|
#define CMD_TIMESHEET 225
|
||||||
#define CMD_UNDELETE 226
|
|
||||||
#define CMD_UNDO 227
|
#define CMD_UNDO 227
|
||||||
#define CMD_VERSION 228
|
#define CMD_VERSION 228
|
||||||
#define CMD_SHELL 229
|
#define CMD_SHELL 229
|
||||||
|
|
|
@ -513,9 +513,12 @@ std::string taskDifferences (const Task& before, const Task& after)
|
||||||
if (out.str ().length () == 0)
|
if (out.str ().length () == 0)
|
||||||
out << "No changes were made. ";
|
out << "No changes were made. ";
|
||||||
|
|
||||||
|
/*
|
||||||
std::stringstream decorated;
|
std::stringstream decorated;
|
||||||
decorated << "Task " << before.id << " was modified. " << out.str ();
|
decorated << "Task " << before.id << " was modified. " << out.str ();
|
||||||
return decorated.str ();
|
return decorated.str ();
|
||||||
|
*/
|
||||||
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue