From d44e9363f050c54d19822fe343fa2a3d7e079f9d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 21 Nov 2009 17:39:50 -0500 Subject: [PATCH] Enhancement - better confirmation - Added feature to allow the user to quit when asked to confirm multiple changes. Now task asks "Proceed with change? (Yes/no/all/quit)". --- ChangeLog | 2 ++ src/Permission.cpp | 10 ++++++-- src/Permission.h | 1 + src/command.cpp | 8 +++---- src/tests/confirmation.t | 8 +++---- src/tests/util.t.cpp | 15 ++++++------ src/util.cpp | 50 +++++++++++++++++++++++++++++++++++----- src/util.h | 1 + 8 files changed, 72 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 308690ed6..8dff14de3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ 1.8.5 () + Fixed bug that was causing the 'completed' report to sort incorrectly. + + Added feature to allow the user to quit when asked to confirm multiple + changes. Now task asks "Proceed with change? (Yes/no/all/quit)". ------ old releases ------------------------------ diff --git a/src/Permission.cpp b/src/Permission.cpp index d70c22b1d..2ea8cff7a 100644 --- a/src/Permission.cpp +++ b/src/Permission.cpp @@ -37,6 +37,7 @@ extern Context context; Permission::Permission () : needConfirmation (false) , allConfirmed (false) +, quit (false) { // Turning confirmations off is the same as entering "all". if (context.config.get ("confirmation", true) == false) @@ -46,6 +47,9 @@ Permission::Permission () //////////////////////////////////////////////////////////////////////////////// bool Permission::confirmed (const Task& task, const std::string& question) { + if (quit) + return false; + if (!needConfirmation) return true; @@ -67,13 +71,15 @@ bool Permission::confirmed (const Task& task, const std::string& question) std::cout << std::endl; - int answer = confirm3 (question); + int answer = confirm4 (question); if (answer == 2) allConfirmed = true; - if (answer > 0) + if (answer == 1 || answer == 2) return true; + if (answer == 3) + quit = true; return false; } diff --git a/src/Permission.h b/src/Permission.h index e3755add2..0d94946a7 100644 --- a/src/Permission.h +++ b/src/Permission.h @@ -44,6 +44,7 @@ public: private: bool needConfirmation; bool allConfirmed; + bool quit; }; #endif diff --git a/src/command.cpp b/src/command.cpp index 490a7bac2..7dad0ebbe 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -829,7 +829,7 @@ int handleDone (std::string &outs) if (taskDiff (before, *task)) { - if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?")) + if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?")) { context.tdb.update (*task); @@ -983,7 +983,7 @@ int handleModify (std::string &outs) if (taskDiff (before, *other)) { - if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?")) + if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?")) { context.tdb.update (*other); ++count; @@ -1043,7 +1043,7 @@ int handleAppend (std::string &outs) if (taskDiff (before, *other)) { - if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?")) + if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?")) { context.tdb.update (*other); @@ -1335,7 +1335,7 @@ int handleAnnotate (std::string &outs) if (taskDiff (before, *task)) { - if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?")) + if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?")) { context.tdb.update (*task); diff --git a/src/tests/confirmation.t b/src/tests/confirmation.t index dd9c6bc9e..9ebf21921 100755 --- a/src/tests/confirmation.t +++ b/src/tests/confirmation.t @@ -49,10 +49,10 @@ if (open my $fh, '>', 'response.txt') qx{../task rc:confirm.rc add foo} for 1 .. 10; -# Test the various forms of "yes". -my $output = qx{echo "yes" | ../task rc:confirm.rc del 1}; -like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - yes works'); -unlike ($output, qr/Task not deleted\./, 'confirmation - yes works'); +# Test the various forms of "Yes". +my $output = qx{echo "Yes" | ../task rc:confirm.rc del 1}; +like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works'); +unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works'); $output = qx{echo "ye" | ../task rc:confirm.rc del 2}; like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works'); diff --git a/src/tests/util.t.cpp b/src/tests/util.t.cpp index 56038cef8..cabdc59ec 100644 --- a/src/tests/util.t.cpp +++ b/src/tests/util.t.cpp @@ -38,6 +38,7 @@ int main (int argc, char** argv) // TODO bool confirm (const std::string&); // TODO int confirm3 (const std::string&); + // TODO int confirm4 (const std::string&); // TODO void delay (float); // TODO std::string formatSeconds (time_t); // TODO std::string formatSecondsCompact (time_t); @@ -83,15 +84,15 @@ int main (int argc, char** argv) Task rightAgain (right); std::string output = taskDifferences (left, right); - t.ok (taskDiff (left, right), "Detected changes"); - t.ok (output.find ("zero was changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00"); - t.ok (output.find ("one was deleted") != std::string::npos, "Detected deletion one:1 ->"); - t.ok (output.find ("two") == std::string::npos, "Detected no change two:2 -> two:2"); - t.ok (output.find ("three was set to '3'") != std::string::npos, "Detected addition -> three:3"); + t.ok (taskDiff (left, right), "Detected changes"); + t.ok (output.find ("zero will be changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00"); + t.ok (output.find ("one will be deleted") != std::string::npos, "Detected deletion one:1 ->"); + t.ok (output.find ("two") == std::string::npos, "Detected no change two:2 -> two:2"); + t.ok (output.find ("three will be set to '3'") != std::string::npos, "Detected addition -> three:3"); - t.notok (taskDiff (right, rightAgain), "No changes detected"); + t.notok (taskDiff (right, rightAgain), "No changes detected"); output = taskDifferences (right, rightAgain); - t.ok (output.find ("No changes were made") != std::string::npos, "No changes detected"); + t.ok (output.find ("No changes will be made") != std::string::npos, "No changes detected"); return 0; } diff --git a/src/util.cpp b/src/util.cpp index 75938a318..ba1f6160b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -82,7 +82,7 @@ bool confirm (const std::string& question) int confirm3 (const std::string& question) { std::vector options; - options.push_back ("yes"); + options.push_back ("Yes"); options.push_back ("no"); options.push_back ("all"); @@ -104,11 +104,49 @@ int confirm3 (const std::string& question) } while (matches.size () != 1); - if (matches[0] == "yes") return 1; + if (matches[0] == "Yes") return 1; else if (matches[0] == "all") return 2; else return 0; } +//////////////////////////////////////////////////////////////////////////////// +// 0 = no +// 1 = yes +// 2 = all +// 3 = quit +int confirm4 (const std::string& question) +{ + std::vector options; + options.push_back ("Yes"); + options.push_back ("no"); + options.push_back ("all"); + options.push_back ("quit"); + + std::string answer; + std::vector matches; + + do + { + std::cout << question + << " (" + << options[0] << "/" + << options[1] << "/" + << options[2] << "/" + << options[3] + << ") "; + + std::getline (std::cin, answer); + answer = trim (answer); + autoComplete (answer, options, matches); + } + while (matches.size () != 1); + + if (matches[0] == "Yes") return 1; + else if (matches[0] == "all") return 2; + else if (matches[0] == "quit") return 3; + else return 0; +} + //////////////////////////////////////////////////////////////////////////////// void delay (float f) { @@ -500,12 +538,12 @@ std::string taskDifferences (const Task& before, const Task& after) foreach (name, beforeOnly) out << " - " << *name - << " was deleted\n"; + << " will be deleted\n"; foreach (name, afterOnly) out << " - " << *name - << " was set to '" + << " will be set to '" << renderAttribute (*name, after.get (*name)) << "'\n"; @@ -515,7 +553,7 @@ std::string taskDifferences (const Task& before, const Task& after) before.get (*name) != after.get (*name)) out << " - " << *name - << " was changed from '" + << " will be changed from '" << renderAttribute (*name, before.get (*name)) << "' to '" << renderAttribute (*name, after.get (*name)) @@ -523,7 +561,7 @@ std::string taskDifferences (const Task& before, const Task& after) // Shouldn't just say nothing. if (out.str ().length () == 0) - out << " - No changes were made\n"; + out << " - No changes will be made\n"; return out.str (); } diff --git a/src/util.h b/src/util.h index 2b0b69b01..0a2102abf 100644 --- a/src/util.h +++ b/src/util.h @@ -53,6 +53,7 @@ for (typeof (c) *foreach_p = & (c); \ // util.cpp bool confirm (const std::string&); int confirm3 (const std::string&); +int confirm4 (const std::string&); void delay (float); std::string formatSeconds (time_t); std::string formatSecondsCompact (time_t);