mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
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:
parent
549e700bc8
commit
d44e9363f0
8 changed files with 72 additions and 23 deletions
|
@ -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 ------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool needConfirmation;
|
bool needConfirmation;
|
||||||
bool allConfirmed;
|
bool allConfirmed;
|
||||||
|
bool quit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
50
src/util.cpp
50
src/util.cpp
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue