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)".
This commit is contained in:
Paul Beckingham 2009-11-21 17:39:50 -05:00
parent 549e700bc8
commit d44e9363f0
8 changed files with 72 additions and 23 deletions

View file

@ -3,6 +3,8 @@
1.8.5 () 1.8.5 ()
+ Fixed bug that was causing the 'completed' report to sort incorrectly. + 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 ------------------------------ ------ old releases ------------------------------

View file

@ -37,6 +37,7 @@ extern Context context;
Permission::Permission () Permission::Permission ()
: needConfirmation (false) : needConfirmation (false)
, allConfirmed (false) , allConfirmed (false)
, quit (false)
{ {
// Turning confirmations off is the same as entering "all". // Turning confirmations off is the same as entering "all".
if (context.config.get ("confirmation", true) == false) if (context.config.get ("confirmation", true) == false)
@ -46,6 +47,9 @@ Permission::Permission ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Permission::confirmed (const Task& task, const std::string& question) bool Permission::confirmed (const Task& task, const std::string& question)
{ {
if (quit)
return false;
if (!needConfirmation) if (!needConfirmation)
return true; return true;
@ -67,13 +71,15 @@ bool Permission::confirmed (const Task& task, const std::string& question)
std::cout << std::endl; std::cout << std::endl;
int answer = confirm3 (question); int answer = confirm4 (question);
if (answer == 2) if (answer == 2)
allConfirmed = true; allConfirmed = true;
if (answer > 0) if (answer == 1 || answer == 2)
return true; return true;
if (answer == 3)
quit = true;
return false; return false;
} }

View file

@ -44,6 +44,7 @@ public:
private: private:
bool needConfirmation; bool needConfirmation;
bool allConfirmed; bool allConfirmed;
bool quit;
}; };
#endif #endif

View file

@ -829,7 +829,7 @@ int handleDone (std::string &outs)
if (taskDiff (before, *task)) 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); context.tdb.update (*task);
@ -983,7 +983,7 @@ int handleModify (std::string &outs)
if (taskDiff (before, *other)) 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); context.tdb.update (*other);
++count; ++count;
@ -1043,7 +1043,7 @@ int handleAppend (std::string &outs)
if (taskDiff (before, *other)) 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); context.tdb.update (*other);
@ -1335,7 +1335,7 @@ int handleAnnotate (std::string &outs)
if (taskDiff (before, *task)) 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); context.tdb.update (*task);

View file

@ -49,10 +49,10 @@ if (open my $fh, '>', 'response.txt')
qx{../task rc:confirm.rc add foo} for 1 .. 10; qx{../task rc:confirm.rc add foo} for 1 .. 10;
# Test the various forms of "yes". # Test the various forms of "Yes".
my $output = qx{echo "yes" | ../task rc:confirm.rc del 1}; my $output = qx{echo "Yes" | ../task rc:confirm.rc del 1};
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - yes works'); like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works');
unlike ($output, qr/Task not deleted\./, 'confirmation - yes works'); unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works');
$output = qx{echo "ye" | ../task rc:confirm.rc del 2}; $output = qx{echo "ye" | ../task rc:confirm.rc del 2};
like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works'); like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works');

View file

@ -38,6 +38,7 @@ int main (int argc, char** argv)
// TODO bool confirm (const std::string&); // TODO bool confirm (const std::string&);
// TODO int confirm3 (const std::string&); // TODO int confirm3 (const std::string&);
// TODO int confirm4 (const std::string&);
// TODO void delay (float); // TODO void delay (float);
// TODO std::string formatSeconds (time_t); // TODO std::string formatSeconds (time_t);
// TODO std::string formatSecondsCompact (time_t); // TODO std::string formatSecondsCompact (time_t);
@ -83,15 +84,15 @@ int main (int argc, char** argv)
Task rightAgain (right); Task rightAgain (right);
std::string output = taskDifferences (left, right); std::string output = taskDifferences (left, right);
t.ok (taskDiff (left, right), "Detected changes"); 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 ("zero will be 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 ("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 ("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 (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); 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; return 0;
} }

View file

@ -82,7 +82,7 @@ bool confirm (const std::string& question)
int confirm3 (const std::string& question) int confirm3 (const std::string& question)
{ {
std::vector <std::string> options; std::vector <std::string> options;
options.push_back ("yes"); options.push_back ("Yes");
options.push_back ("no"); options.push_back ("no");
options.push_back ("all"); options.push_back ("all");
@ -104,11 +104,49 @@ int confirm3 (const std::string& question)
} }
while (matches.size () != 1); while (matches.size () != 1);
if (matches[0] == "yes") return 1; if (matches[0] == "Yes") return 1;
else if (matches[0] == "all") return 2; else if (matches[0] == "all") return 2;
else return 0; else return 0;
} }
////////////////////////////////////////////////////////////////////////////////
// 0 = no
// 1 = yes
// 2 = all
// 3 = quit
int confirm4 (const std::string& question)
{
std::vector <std::string> options;
options.push_back ("Yes");
options.push_back ("no");
options.push_back ("all");
options.push_back ("quit");
std::string answer;
std::vector <std::string> 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) void delay (float f)
{ {
@ -500,12 +538,12 @@ std::string taskDifferences (const Task& before, const Task& after)
foreach (name, beforeOnly) foreach (name, beforeOnly)
out << " - " out << " - "
<< *name << *name
<< " was deleted\n"; << " will be deleted\n";
foreach (name, afterOnly) foreach (name, afterOnly)
out << " - " out << " - "
<< *name << *name
<< " was set to '" << " will be set to '"
<< renderAttribute (*name, after.get (*name)) << renderAttribute (*name, after.get (*name))
<< "'\n"; << "'\n";
@ -515,7 +553,7 @@ std::string taskDifferences (const Task& before, const Task& after)
before.get (*name) != after.get (*name)) before.get (*name) != after.get (*name))
out << " - " out << " - "
<< *name << *name
<< " was changed from '" << " will be changed from '"
<< renderAttribute (*name, before.get (*name)) << renderAttribute (*name, before.get (*name))
<< "' to '" << "' to '"
<< renderAttribute (*name, after.get (*name)) << renderAttribute (*name, after.get (*name))
@ -523,7 +561,7 @@ std::string taskDifferences (const Task& before, const Task& after)
// Shouldn't just say nothing. // Shouldn't just say nothing.
if (out.str ().length () == 0) if (out.str ().length () == 0)
out << " - No changes were made\n"; out << " - No changes will be made\n";
return out.str (); return out.str ();
} }

View file

@ -53,6 +53,7 @@ for (typeof (c) *foreach_p = & (c); \
// util.cpp // util.cpp
bool confirm (const std::string&); bool confirm (const std::string&);
int confirm3 (const std::string&); int confirm3 (const std::string&);
int confirm4 (const std::string&);
void delay (float); void delay (float);
std::string formatSeconds (time_t); std::string formatSeconds (time_t);
std::string formatSecondsCompact (time_t); std::string formatSecondsCompact (time_t);