Commands - delete

- Migrated handleDelete to CmdDelete.
This commit is contained in:
Paul Beckingham 2011-05-30 14:00:34 -04:00
parent 908fbd8ca4
commit abd51e81a3
9 changed files with 236 additions and 150 deletions

View file

@ -129,7 +129,6 @@ void Cmd::load ()
{ {
if (commands.size () == 0) if (commands.size () == 0)
{ {
commands.push_back ("delete");
commands.push_back ("merge"); commands.push_back ("merge");
commands.push_back ("push"); commands.push_back ("push");
commands.push_back ("pull"); commands.push_back ("pull");
@ -201,7 +200,6 @@ bool Cmd::isReadOnlyCommand ()
bool Cmd::isWriteCommand () bool Cmd::isWriteCommand ()
{ {
if (command == "merge" || if (command == "merge" ||
command == "delete" ||
command == "pull") command == "pull")
return true; return true;

View file

@ -249,8 +249,7 @@ int Context::dispatch (std::string &out)
Timer t ("Context::dispatch"); Timer t ("Context::dispatch");
// TODO Chain-of-command pattern dispatch. // TODO Chain-of-command pattern dispatch.
if (cmd.command == "delete") { rc = handleDelete (out); } if (cmd.command == "merge") { tdb.gc ();
else if (cmd.command == "merge") { tdb.gc ();
handleMerge (out); } handleMerge (out); }
else if (cmd.command == "push") { handlePush (out); } else if (cmd.command == "push") { handlePush (out); }
else if (cmd.command == "pull") { handlePull (out); } else if (cmd.command == "pull") { handlePull (out); }

View file

@ -226,147 +226,6 @@ void handlePull (std::string&)
"'pull.default.uri' entry in your .taskrc file."); "'pull.default.uri' entry in your .taskrc file.");
} }
////////////////////////////////////////////////////////////////////////////////
int handleDelete (std::string& outs)
{
int rc = 0;
std::stringstream out;
context.disallowModification ();
std::vector <Task> tasks;
context.tdb.lock (context.config.getBoolean ("locking"));
Filter filter;
context.tdb.loadPending (tasks, filter);
// Filter sequence.
std::vector <Task> all = tasks;
context.filter.applySequence (tasks, context.sequence);
if (tasks.size () == 0)
{
std::cout << "No tasks specified.\n";
return 1;
}
// Determine the end date.
char endTime[16];
sprintf (endTime, "%u", (unsigned int) time (NULL));
foreach (task, tasks)
{
if (task->getStatus () == Task::pending ||
task->getStatus () == Task::waiting)
{
std::stringstream question;
question << "Permanently delete task "
<< task->id
<< " '"
<< task->get ("description")
<< "'?";
if (!context.config.getBoolean ("confirmation") || confirm (question.str ()))
{
// Check for the more complex case of a recurring task. If this is a
// recurring task, get confirmation to delete them all.
std::string parent = task->get ("parent");
if (parent != "")
{
if (confirm ("This is a recurring task. Do you want to delete all pending recurrences of this same task?"))
{
// Scan all pending tasks for siblings of this task, and the parent
// itself, and delete them.
foreach (sibling, all)
{
if (sibling->get ("parent") == parent ||
sibling->get ("uuid") == parent)
{
sibling->setStatus (Task::deleted);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! sibling->has ("end"))
sibling->set ("end", endTime);
context.tdb.update (*sibling);
if (context.config.getBoolean ("echo.command"))
out << "Deleting recurring task "
<< sibling->id
<< " '"
<< sibling->get ("description")
<< "'.\n";
}
}
}
else
{
// Update mask in parent.
task->setStatus (Task::deleted);
updateRecurrenceMask (all, *task);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! task->has ("end"))
task->set ("end", endTime);
context.tdb.update (*task);
out << "Deleting recurring task "
<< task->id
<< " '"
<< task->get ("description")
<< "'.\n";
dependencyChainOnComplete (*task);
context.footnote (onProjectChange (*task));
}
}
else
{
task->setStatus (Task::deleted);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! task->has ("end"))
task->set ("end", endTime);
context.tdb.update (*task);
if (context.config.getBoolean ("echo.command"))
out << "Deleting task "
<< task->id
<< " '"
<< task->get ("description")
<< "'.\n";
dependencyChainOnComplete (*task);
context.footnote (onProjectChange (*task));
}
}
else
{
out << "Task not deleted.\n";
rc = 1;
}
}
else
{
out << "Task "
<< task->id
<< " '"
<< task->get ("description")
<< "' is neither pending nor waiting.\n";
rc = 1;
}
}
context.tdb.commit ();
context.tdb.unlock ();
outs = out.str ();
return rc;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleModify (std::string& outs) int handleModify (std::string& outs)
{ {

View file

@ -16,6 +16,7 @@ set (commands_SRCS Command.cpp Command.h
CmdConfig.cpp CmdConfig.h CmdConfig.cpp CmdConfig.h
CmdCount.cpp CmdCount.h CmdCount.cpp CmdCount.h
CmdCustom.cpp CmdCustom.h CmdCustom.cpp CmdCustom.h
CmdDelete.cpp CmdDelete.h
CmdDenotate.cpp CmdDenotate.h CmdDenotate.cpp CmdDenotate.h
CmdDiagnostics.cpp CmdDiagnostics.h CmdDiagnostics.cpp CmdDiagnostics.h
CmdDone.cpp CmdDone.h CmdDone.cpp CmdDone.h

190
src/commands/CmdDelete.cpp Normal file
View file

@ -0,0 +1,190 @@
////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <sstream>
#include <Context.h>
#include <Permission.h>
#include <util.h>
#include <main.h>
#include <CmdDelete.h>
extern Context context;
////////////////////////////////////////////////////////////////////////////////
CmdDelete::CmdDelete ()
{
_keyword = "delete";
_usage = "task delete ID";
_description = "Deletes the specified task.";
_read_only = false;
_displays_id = false;
}
////////////////////////////////////////////////////////////////////////////////
int CmdDelete::execute (const std::string&, std::string& output)
{
int rc = 0;
std::stringstream out;
context.disallowModification ();
std::vector <Task> tasks;
context.tdb.lock (context.config.getBoolean ("locking"));
Filter filter;
context.tdb.loadPending (tasks, filter);
// Filter sequence.
std::vector <Task> all = tasks;
context.filter.applySequence (tasks, context.sequence);
if (tasks.size () == 0)
{
context.footnote ("No tasks specified.");
return 1;
}
// Determine the end date.
char endTime[16];
sprintf (endTime, "%u", (unsigned int) time (NULL));
std::vector <Task>::iterator task;
for (task = tasks.begin (); task != tasks.end (); ++task)
{
if (task->getStatus () == Task::pending ||
task->getStatus () == Task::waiting)
{
std::stringstream question;
question << "Permanently delete task "
<< task->id
<< " '"
<< task->get ("description")
<< "'?";
if (!context.config.getBoolean ("confirmation") || confirm (question.str ()))
{
// Check for the more complex case of a recurring task. If this is a
// recurring task, get confirmation to delete them all.
std::string parent = task->get ("parent");
if (parent != "")
{
if (confirm ("This is a recurring task. Do you want to delete all pending recurrences of this same task?"))
{
// Scan all pending tasks for siblings of this task, and the parent
// itself, and delete them.
std::vector <Task>::iterator sibling;
for (sibling = all.begin (); sibling != all.end (); ++sibling)
{
if (sibling->get ("parent") == parent ||
sibling->get ("uuid") == parent)
{
sibling->setStatus (Task::deleted);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! sibling->has ("end"))
sibling->set ("end", endTime);
context.tdb.update (*sibling);
if (context.config.getBoolean ("echo.command"))
out << "Deleting recurring task "
<< sibling->id
<< " '"
<< sibling->get ("description")
<< "'.\n";
}
}
}
else
{
// Update mask in parent.
task->setStatus (Task::deleted);
updateRecurrenceMask (all, *task);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! task->has ("end"))
task->set ("end", endTime);
context.tdb.update (*task);
out << "Deleting recurring task "
<< task->id
<< " '"
<< task->get ("description")
<< "'.\n";
dependencyChainOnComplete (*task);
context.footnote (onProjectChange (*task));
}
}
else
{
task->setStatus (Task::deleted);
// Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command.
if (! task->has ("end"))
task->set ("end", endTime);
context.tdb.update (*task);
if (context.config.getBoolean ("echo.command"))
out << "Deleting task "
<< task->id
<< " '"
<< task->get ("description")
<< "'.\n";
dependencyChainOnComplete (*task);
context.footnote (onProjectChange (*task));
}
}
else
{
out << "Task not deleted.\n";
rc = 1;
}
}
else
{
out << "Task "
<< task->id
<< " '"
<< task->get ("description")
<< "' is neither pending nor waiting.\n";
rc = 1;
}
}
context.tdb.commit ();
context.tdb.unlock ();
output = out.str ();
return rc;
}
////////////////////////////////////////////////////////////////////////////////

42
src/commands/CmdDelete.h Normal file
View file

@ -0,0 +1,42 @@
////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_CMDDELETE
#define INCLUDED_CMDDELETE
#define L10N // Localization complete.
#include <string>
#include <Command.h>
class CmdDelete : public Command
{
public:
CmdDelete ();
int execute (const std::string&, std::string&);
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -103,10 +103,6 @@ int CmdHelp::execute (const std::string&, std::string& output)
view.set (row, 1, "task ID"); view.set (row, 1, "task ID");
view.set (row, 2, "Specifying an ID without a command invokes the 'info' command."); view.set (row, 2, "Specifying an ID without a command invokes the 'info' command.");
row = view.addRow ();
view.set (row, 1, "task delete ID");
view.set (row, 2, "Deletes the specified task.");
row = view.addRow (); row = view.addRow ();
view.set (row, 1, "task merge URL"); view.set (row, 1, "task merge URL");
view.set (row, 2, "Merges the specified undo.data file with the local data files."); view.set (row, 2, "Merges the specified undo.data file with the local data files.");

View file

@ -38,6 +38,7 @@
#include <CmdConfig.h> #include <CmdConfig.h>
#include <CmdCount.h> #include <CmdCount.h>
#include <CmdCustom.h> #include <CmdCustom.h>
#include <CmdDelete.h>
#include <CmdDenotate.h> #include <CmdDenotate.h>
#include <CmdDiagnostics.h> #include <CmdDiagnostics.h>
#include <CmdDone.h> #include <CmdDone.h>
@ -93,6 +94,7 @@ void Command::factory (std::map <std::string, Command*>& all)
c = new CmdCompletionVersion (); all[c->keyword ()] = c; c = new CmdCompletionVersion (); all[c->keyword ()] = c;
c = new CmdConfig (); all[c->keyword ()] = c; c = new CmdConfig (); all[c->keyword ()] = c;
c = new CmdCount (); all[c->keyword ()] = c; c = new CmdCount (); all[c->keyword ()] = c;
c = new CmdDelete (); all[c->keyword ()] = c;
c = new CmdDenotate (); all[c->keyword ()] = c; c = new CmdDenotate (); all[c->keyword ()] = c;
c = new CmdDiagnostics (); all[c->keyword ()] = c; c = new CmdDiagnostics (); all[c->keyword ()] = c;
c = new CmdDone (); all[c->keyword ()] = c; c = new CmdDone (); all[c->keyword ()] = c;

View file

@ -51,7 +51,6 @@ bool nag (Task&);
// command.cpp // command.cpp
int handleModify (std::string&); int handleModify (std::string&);
int handleDelete (std::string&);
void handleMerge (std::string&); void handleMerge (std::string&);
void handlePush (std::string&); void handlePush (std::string&);
void handlePull (std::string&); void handlePull (std::string&);