Enhancement - Hooks

- Implemented lots of command hooks.
This commit is contained in:
Paul Beckingham 2010-01-30 23:39:51 -05:00
parent 78c7408380
commit dd423d315b
6 changed files with 2818 additions and 2651 deletions

View file

@ -248,7 +248,9 @@ int Context::dispatch (std::string &out)
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); rc = handleCustomReport (cmd.command, out); } else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); rc = handleCustomReport (cmd.command, out); }
// If the command is not recognized, display usage. // If the command is not recognized, display usage.
else { rc = shortUsage (out); } else { hooks.trigger ("pre-usage-command");
rc = shortUsage (out);
hooks.trigger ("post-usage-command"); }
// Only update the shadow file if such an update was not suppressed (shadow), // Only update the shadow file if such an update was not suppressed (shadow),
if (cmd.isWriteCommand () && !inShadow) if (cmd.isWriteCommand () && !inShadow)

View file

@ -53,6 +53,8 @@ extern Context context;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleAdd (std::string &outs) int handleAdd (std::string &outs)
{ {
int rc = 0;
if (context.hooks.trigger ("pre-add-command")) if (context.hooks.trigger ("pre-add-command"))
{ {
std::stringstream out; std::stringstream out;
@ -118,15 +120,17 @@ int handleAdd (std::string &outs)
context.hooks.trigger ("post-add-command"); context.hooks.trigger ("post-add-command");
} }
return 0; return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleProjects (std::string &outs) int handleProjects (std::string &outs)
{ {
int rc = 0; int rc = 0;
std::stringstream out;
if (context.hooks.trigger ("pre-projects-command"))
{
std::stringstream out;
context.filter.push_back (Att ("status", "pending")); context.filter.push_back (Att ("status", "pending"));
std::vector <Task> tasks; std::vector <Task> tasks;
@ -204,13 +208,18 @@ int handleProjects (std::string &outs)
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")" << " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
<< std::endl; << std::endl;
} }
else { else
{
out << "No projects." out << "No projects."
<< std::endl; << std::endl;
rc = 1; rc = 1;
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-projects-command");
}
return rc; return rc;
} }
@ -248,6 +257,9 @@ int handleCompletionProjects (std::string &outs)
int handleTags (std::string &outs) int handleTags (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-tags-command"))
{
std::stringstream out; std::stringstream out;
context.filter.push_back (Att ("status", "pending")); context.filter.push_back (Att ("status", "pending"));
@ -304,13 +316,16 @@ int handleTags (std::string &outs)
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")" << " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
<< std::endl; << std::endl;
} }
else { else
{
out << "No tags." out << "No tags."
<< std::endl; << std::endl;
rc = 1; rc = 1;
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-tags-command");
}
return rc; return rc;
} }
@ -418,18 +433,26 @@ int handleCompletionIDs (std::string &outs)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleUndo () void handleUndo ()
{
if (context.hooks.trigger ("pre-undo-command"))
{ {
context.disallowModification (); context.disallowModification ();
context.tdb.lock (context.config.getBoolean ("locking")); context.tdb.lock (context.config.getBoolean ("locking"));
context.tdb.undo (); context.tdb.undo ();
context.tdb.unlock (); context.tdb.unlock ();
context.hooks.trigger ("post-undo-command");
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleVersion (std::string &outs) int handleVersion (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-version-command"))
{
std::stringstream out; std::stringstream out;
// Create a table for the disclaimer. // Create a table for the disclaimer.
@ -507,6 +530,9 @@ int handleVersion (std::string &outs)
<< std::endl; << std::endl;
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-version-command");
}
return rc; return rc;
} }
@ -514,6 +540,9 @@ int handleVersion (std::string &outs)
int handleConfig (std::string &outs) int handleConfig (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-config-command"))
{
std::stringstream out; std::stringstream out;
// Support: // Support:
@ -806,10 +835,11 @@ int handleConfig (std::string &outs)
<< "'." << "'."
<< std::endl; << std::endl;
// Verify installation. This is mentioned in the documentation as the way to // Verify installation. This is mentioned in the documentation as the way
// ensure everything is properly installed. // to ensure everything is properly installed.
if (all.size () == 0) { if (all.size () == 0)
{
out << "Configuration error: .taskrc contains no entries" out << "Configuration error: .taskrc contains no entries"
<< std::endl; << std::endl;
rc = 1; rc = 1;
@ -830,6 +860,8 @@ int handleConfig (std::string &outs)
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-config-command");
}
return rc; return rc;
} }
@ -954,6 +986,9 @@ int handleDelete (std::string &outs)
int handleStart (std::string &outs) int handleStart (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-start-command"))
{
std::stringstream out; std::stringstream out;
context.disallowModification (); context.disallowModification ();
@ -1003,6 +1038,9 @@ int handleStart (std::string &outs)
context.tdb.unlock (); context.tdb.unlock ();
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-start-command");
}
return rc; return rc;
} }
@ -1010,6 +1048,9 @@ int handleStart (std::string &outs)
int handleStop (std::string &outs) int handleStop (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-stop-command"))
{
std::stringstream out; std::stringstream out;
context.disallowModification (); context.disallowModification ();
@ -1053,6 +1094,9 @@ int handleStop (std::string &outs)
context.tdb.unlock (); context.tdb.unlock ();
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-stop-command");
}
return rc; return rc;
} }
@ -1060,6 +1104,9 @@ int handleStop (std::string &outs)
int handleDone (std::string &outs) int handleDone (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-done-command"))
{
int count = 0; int count = 0;
std::stringstream out; std::stringstream out;
@ -1153,11 +1200,18 @@ int handleDone (std::string &outs)
<< std::endl; << std::endl;
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-done-command");
}
return rc; return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleExport (std::string &outs) int handleExport (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-export-command"))
{ {
std::stringstream out; std::stringstream out;
@ -1197,7 +1251,10 @@ int handleExport (std::string &outs)
} }
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-export-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1297,6 +1354,10 @@ int handleModify (std::string &outs)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleAppend (std::string &outs) int handleAppend (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-append-command"))
{ {
int count = 0; int count = 0;
std::stringstream out; std::stringstream out;
@ -1360,11 +1421,18 @@ int handleAppend (std::string &outs)
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl; out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-append-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handlePrepend (std::string &outs) int handlePrepend (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-prepend-command"))
{ {
int count = 0; int count = 0;
std::stringstream out; std::stringstream out;
@ -1428,11 +1496,18 @@ int handlePrepend (std::string &outs)
out << "Prepended " << count << " task" << (count == 1 ? "" : "s") << std::endl; out << "Prepended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-prepend-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleDuplicate (std::string &outs) int handleDuplicate (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-duplicate-command"))
{ {
std::stringstream out; std::stringstream out;
int count = 0; int count = 0;
@ -1507,12 +1582,17 @@ int handleDuplicate (std::string &outs)
context.tdb.unlock (); context.tdb.unlock ();
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-duplicate-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifdef FEATURE_SHELL #ifdef FEATURE_SHELL
void handleShell () void handleShell ()
{
if (context.hooks.trigger ("pre-shell-command"))
{ {
// Display some kind of welcome message. // Display some kind of welcome message.
Color bold (Color::nocolor, Color::nocolor, false, true, false); Color bold (Color::nocolor, Color::nocolor, false, true, false);
@ -1583,6 +1663,8 @@ void handleShell ()
// No need to repeat any overrides after the shell quits. // No need to repeat any overrides after the shell quits.
context.clearMessages (); context.clearMessages ();
context.hooks.trigger ("post-shell-command");
}
} }
#endif #endif
@ -1590,6 +1672,9 @@ void handleShell ()
int handleColor (std::string &outs) int handleColor (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-color-command"))
{
std::stringstream out; std::stringstream out;
if (context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor")) if (context.config.getBoolean ("color") || context.config.getBoolean ("_forcecolor"))
@ -1725,11 +1810,18 @@ int handleColor (std::string &outs)
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-color-command");
}
return rc; return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleAnnotate (std::string &outs) int handleAnnotate (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-annotate-command"))
{ {
if (!context.task.has ("description")) if (!context.task.has ("description"))
throw std::string ("Cannot apply a blank annotation."); throw std::string ("Cannot apply a blank annotation.");
@ -1774,7 +1866,10 @@ int handleAnnotate (std::string &outs)
context.tdb.unlock (); context.tdb.unlock ();
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-annotate-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -111,6 +111,10 @@ int runCustomReport (
std::string &outs) std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-custom-report-command") &&
context.hooks.trigger (std::string ("pre-") + report + "-command"))
{
// Load report configuration. // Load report configuration.
std::vector <std::string> columns; std::vector <std::string> columns;
split (columns, columnList, ','); split (columns, columnList, ',');
@ -627,6 +631,10 @@ int runCustomReport (
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger (std::string ("post-") + report + "-command");
context.hooks.trigger ("post-custom-report-command");
}
return rc; return rc;
} }

View file

@ -602,6 +602,10 @@ ARE_THESE_REALLY_HARMFUL:
// various other ills. This is like opening up the hood and going in with a // various other ills. This is like opening up the hood and going in with a
// wrench. To be used sparingly. // wrench. To be used sparingly.
int handleEdit (std::string &outs) int handleEdit (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-edit-command"))
{ {
std::stringstream out; std::stringstream out;
@ -646,7 +650,10 @@ int handleEdit (std::string &outs)
context.tdb.unlock (); context.tdb.unlock ();
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-edit-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -1147,6 +1147,10 @@ static std::string importCSV (const std::vector <std::string>& lines)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleImport (std::string &outs) int handleImport (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-import-command"))
{ {
std::stringstream out; std::stringstream out;
@ -1215,7 +1219,10 @@ int handleImport (std::string &outs)
throw std::string ("You must specify a file to import."); throw std::string ("You must specify a file to import.");
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-import-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -223,6 +223,10 @@ int shortUsage (std::string &outs)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int longUsage (std::string &outs) int longUsage (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-usage-command"))
{ {
std::string shortUsageString; std::string shortUsageString;
std::stringstream out; std::stringstream out;
@ -292,7 +296,10 @@ int longUsage (std::string &outs)
<< std::endl; << std::endl;
outs = out.str(); outs = out.str();
return 0; context.hooks.trigger ("post-usage-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -530,6 +537,9 @@ int handleInfo (std::string &outs)
int handleReportSummary (std::string &outs) int handleReportSummary (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-summary-command"))
{
// Scan the pending tasks. // Scan the pending tasks.
std::vector <Task> tasks; std::vector <Task> tasks;
context.tdb.lock (context.config.getBoolean ("locking")); context.tdb.lock (context.config.getBoolean ("locking"));
@ -675,6 +685,9 @@ int handleReportSummary (std::string &outs)
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-summary-command");
}
return rc; return rc;
} }
@ -772,6 +785,9 @@ time_t monthlyEpoch (const std::string& date)
int handleReportHistory (std::string &outs) int handleReportHistory (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-history-command"))
{
std::map <time_t, int> groups; // Represents any month with data std::map <time_t, int> groups; // Represents any month with data
std::map <time_t, int> addedGroup; // Additions by month std::map <time_t, int> addedGroup; // Additions by month
std::map <time_t, int> completedGroup; // Completions by month std::map <time_t, int> completedGroup; // Completions by month
@ -919,12 +935,16 @@ int handleReportHistory (std::string &outs)
out << optionalBlankLine () out << optionalBlankLine ()
<< table.render () << table.render ()
<< std::endl; << std::endl;
else { else
{
out << "No tasks." << std::endl; out << "No tasks." << std::endl;
rc = 1; rc = 1;
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-history-command");
}
return rc; return rc;
} }
@ -932,6 +952,9 @@ int handleReportHistory (std::string &outs)
int handleReportGHistory (std::string &outs) int handleReportGHistory (std::string &outs)
{ {
int rc = 0; int rc = 0;
if (context.hooks.trigger ("pre-ghistory-command"))
{
std::map <time_t, int> groups; // Represents any month with data std::map <time_t, int> groups; // Represents any month with data
std::map <time_t, int> addedGroup; // Additions by month std::map <time_t, int> addedGroup; // Additions by month
std::map <time_t, int> completedGroup; // Completions by month std::map <time_t, int> completedGroup; // Completions by month
@ -1122,17 +1145,25 @@ int handleReportGHistory (std::string &outs)
else else
out << "Legend: + added, X completed, - deleted" << std::endl; out << "Legend: + added, X completed, - deleted" << std::endl;
} }
else { else
{
out << "No tasks." << std::endl; out << "No tasks." << std::endl;
rc = 1; rc = 1;
} }
outs = out.str (); outs = out.str ();
context.hooks.trigger ("post-ghistory-command");
}
return rc; return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleReportTimesheet (std::string &outs) int handleReportTimesheet (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-timesheet-command"))
{ {
// Scan the pending tasks. // Scan the pending tasks.
std::vector <Task> tasks; std::vector <Task> tasks;
@ -1307,7 +1338,10 @@ int handleReportTimesheet (std::string &outs)
} }
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-timesheet-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1511,6 +1545,10 @@ std::string renderMonths (
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleReportCalendar (std::string &outs) int handleReportCalendar (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-calendar-command"))
{ {
// Each month requires 28 text columns width. See how many will actually // Each month requires 28 text columns width. See how many will actually
// fit. But if a preference is specified, and it fits, use it. // fit. But if a preference is specified, and it fits, use it.
@ -1801,11 +1839,18 @@ int handleReportCalendar (std::string &outs)
} }
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-calendar-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleReportStats (std::string &outs) int handleReportStats (std::string &outs)
{
int rc = 0;
if (context.hooks.trigger ("pre-stats-command"))
{ {
std::stringstream out; std::stringstream out;
@ -2030,7 +2075,10 @@ int handleReportStats (std::string &outs)
<< optionalBlankLine (); << optionalBlankLine ();
outs = out.str (); outs = out.str ();
return 0; context.hooks.trigger ("post-stats-command");
}
return rc;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////