diff --git a/src/Context.cpp b/src/Context.cpp index e1347f350..d8ee873ea 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -138,10 +138,6 @@ int Context::initialize (int argc, const char** argv) // Apply rc overrides to Context::config, capturing raw args for later use. a3.apply_overrides (); - // Now that the final RC is in place, initialize the urgency coefficients - // to speed the 'next' report. - initializeUrgencyCoefficients (); - // Initialize the color rules, if necessary. if (color ()) initializeColorRules (); @@ -152,6 +148,9 @@ int Context::initialize (int argc, const char** argv) // Instantiate built-in column objects. Column::factory (columns); + // Static initialization to decouple code. + staticInitialization (); + // Categorize all arguments one more time. THIS IS NECESSARY - it helps the // following inject_defaults method determine whether there needs to be a // default command assumed. @@ -571,6 +570,47 @@ const std::vector Context::getCommands () const return output; } +//////////////////////////////////////////////////////////////////////////////// +// The 'Task' object, among others, is shared between projects. To make this +// easier, it has been decoupled from Context. +void Context::staticInitialization () +{ + Task::defaultProject = config.get ("default.project"); + Task::defaultPriority = config.get ("default.priority"); + Task::defaultDue = config.get ("default.due"); + Task::searchCaseSensitive = config.getBoolean ("search.case.sensitive"); + Task::regex = config.getBoolean ("regex"); + + std::map ::iterator i; + for (i = columns.begin (); i != columns.end (); ++i) + Task::attributes[i->first] = i->second->type (); + + Task::urgencyPriorityCoefficient = config.getReal ("urgency.priority.coefficient"); + Task::urgencyProjectCoefficient = config.getReal ("urgency.project.coefficient"); + Task::urgencyActiveCoefficient = config.getReal ("urgency.active.coefficient"); + Task::urgencyScheduledCoefficient = config.getReal ("urgency.scheduled.coefficient"); + Task::urgencyWaitingCoefficient = config.getReal ("urgency.waiting.coefficient"); + Task::urgencyBlockedCoefficient = config.getReal ("urgency.blocked.coefficient"); + Task::urgencyAnnotationsCoefficient = config.getReal ("urgency.annotations.coefficient"); + Task::urgencyTagsCoefficient = config.getReal ("urgency.tags.coefficient"); + Task::urgencyNextCoefficient = config.getReal ("urgency.next.coefficient"); + Task::urgencyDueCoefficient = config.getReal ("urgency.due.coefficient"); + Task::urgencyBlockingCoefficient = config.getReal ("urgency.blocking.coefficient"); + Task::urgencyAgeCoefficient = config.getReal ("urgency.age.coefficient"); + + // Tag- and project-specific coefficients. + std::vector all; + config.all (all); + + std::vector ::iterator var; + for (var = all.begin (); var != all.end (); ++var) + { + if (var->substr (0, 13) == "urgency.user." || + var->substr (0, 12) == "urgency.uda.") + Task::coefficients[*var] = config.getReal (*var); + } +} + //////////////////////////////////////////////////////////////////////////////// void Context::assumeLocations () { diff --git a/src/Context.h b/src/Context.h index 7ebb1013b..c93eaaa18 100644 --- a/src/Context.h +++ b/src/Context.h @@ -74,6 +74,7 @@ public: void decomposeSortField (const std::string&, std::string&, bool&); private: + void staticInitialization (); void assumeLocations (); void createDefaultConfig (); void loadAliases (); diff --git a/src/Task.cpp b/src/Task.cpp index be19ff7d6..03b496092 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -59,58 +59,30 @@ extern Context context; static const float epsilon = 0.000001; -static std::map coefficients; -float urgencyPriorityCoefficient = 0.0; -float urgencyProjectCoefficient = 0.0; -float urgencyActiveCoefficient = 0.0; -float urgencyScheduledCoefficient = 0.0; -float urgencyWaitingCoefficient = 0.0; -float urgencyBlockedCoefficient = 0.0; -float urgencyAnnotationsCoefficient = 0.0; -float urgencyTagsCoefficient = 0.0; -float urgencyNextCoefficient = 0.0; -float urgencyDueCoefficient = 0.0; -float urgencyBlockingCoefficient = 0.0; -float urgencyAgeCoefficient = 0.0; +std::string Task::defaultProject = ""; +std::string Task::defaultPriority = ""; +std::string Task::defaultDue = ""; +bool Task::searchCaseSensitive = true; +bool Task::regex = false; +std::map Task::attributes; + +std::map Task::coefficients; +float Task::urgencyPriorityCoefficient = 0.0; +float Task::urgencyProjectCoefficient = 0.0; +float Task::urgencyActiveCoefficient = 0.0; +float Task::urgencyScheduledCoefficient = 0.0; +float Task::urgencyWaitingCoefficient = 0.0; +float Task::urgencyBlockedCoefficient = 0.0; +float Task::urgencyAnnotationsCoefficient = 0.0; +float Task::urgencyTagsCoefficient = 0.0; +float Task::urgencyNextCoefficient = 0.0; +float Task::urgencyDueCoefficient = 0.0; +float Task::urgencyBlockingCoefficient = 0.0; +float Task::urgencyAgeCoefficient = 0.0; #endif static const std::string dummy (""); -#ifdef PRODUCT_TASKWARRIOR -//////////////////////////////////////////////////////////////////////////////// -// Non-method. -// -// This is essentialy a cache of float values to save iteration and hash lookup -// in the whole config at time of Task::urgency_C. -void initializeUrgencyCoefficients () -{ - urgencyPriorityCoefficient = context.config.getReal ("urgency.priority.coefficient"); - urgencyProjectCoefficient = context.config.getReal ("urgency.project.coefficient"); - urgencyActiveCoefficient = context.config.getReal ("urgency.active.coefficient"); - urgencyScheduledCoefficient = context.config.getReal ("urgency.scheduled.coefficient"); - urgencyWaitingCoefficient = context.config.getReal ("urgency.waiting.coefficient"); - urgencyBlockedCoefficient = context.config.getReal ("urgency.blocked.coefficient"); - urgencyAnnotationsCoefficient = context.config.getReal ("urgency.annotations.coefficient"); - urgencyTagsCoefficient = context.config.getReal ("urgency.tags.coefficient"); - urgencyNextCoefficient = context.config.getReal ("urgency.next.coefficient"); - urgencyDueCoefficient = context.config.getReal ("urgency.due.coefficient"); - urgencyBlockingCoefficient = context.config.getReal ("urgency.blocking.coefficient"); - urgencyAgeCoefficient = context.config.getReal ("urgency.age.coefficient"); - - // Tag- and project-specific coefficients. - std::vector all; - context.config.all (all); - - std::vector ::iterator var; - for (var = all.begin (); var != all.end (); ++var) - { - if (var->substr (0, 13) == "urgency.user." || - var->substr (0, 12) == "urgency.uda.") - coefficients[*var] = context.config.getReal (*var); - } -} -#endif - //////////////////////////////////////////////////////////////////////////////// Task::Task () : id (0) @@ -502,10 +474,9 @@ void Task::parseJSON (const std::string& line) i != root_obj->_data.end (); ++i) { -#ifdef PRODUCT_TASKWARRIOR // If the attribute is a recognized column. - Column* col = context.columns[i->first]; - if (col) + std::string type = Task::attributes[i->first]; + if (type != "") { // Any specified id is ignored. if (i->first == "id") @@ -516,7 +487,7 @@ void Task::parseJSON (const std::string& line) ; // Dates are converted from ISO to epoch. - else if (col->type () == "date") + else if (type == "date") { Date d (unquoteText (i->second->dump ())); set (i->first, d.toEpochString ()); @@ -540,20 +511,6 @@ void Task::parseJSON (const std::string& line) else set (i->first, unquoteText (i->second->dump ())); } -#else - if (i->first == "tags") - { - json::array* tags = (json::array*)i->second; - json_array_iter t; - for (t = tags->_data.begin (); - t != tags->_data.end (); - ++t) - { - json::string* tag = (json::string*)*t; - addTag (tag->_data); - } - } -#endif // UDA orphans and annotations do not have columns. else @@ -1175,18 +1132,16 @@ void Task::substitute ( std::map annotations; getAnnotations (annotations); - bool sensitive = context.config.getBoolean ("search.case.sensitive"); - // Count the changes, so we know whether to proceed to annotations, after // modifying description. int changes = 0; bool done = false; // Regex support is optional. - if (context.config.getBoolean ("regex")) + if (Task::regex) { // Create the regex. - RX rx (from, sensitive); + RX rx (from, Task::searchCaseSensitive); std::vector start; std::vector end; @@ -1236,7 +1191,7 @@ void Task::substitute ( std::string::size_type pos = 0; int skew = 0; - while ((pos = ::find (description, from, pos, sensitive)) != std::string::npos && !done) + while ((pos = ::find (description, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done) { description.replace (pos + skew, from.length (), to); skew += to.length () - from.length (); @@ -1260,7 +1215,7 @@ void Task::substitute ( { pos = 0; skew = 0; - while ((pos = ::find (i->second, from, pos, sensitive)) != std::string::npos && !done) + while ((pos = ::find (i->second, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done) { i->second.replace (pos + skew, from.length (), to); skew += to.length () - from.length (); @@ -1335,28 +1290,25 @@ void Task::validate (bool applyDefault /* = true */) // Override with default.project, if not specified. if (applyDefault && ! has ("project")) { - std::string defaultProject = context.config.get ("default.project"); - if (defaultProject != "" && - context.columns["project"]->validate (defaultProject)) - set ("project", defaultProject); + if (Task::defaultProject != "" && + context.columns["project"]->validate (Task::defaultProject)) + set ("project", Task::defaultProject); } // Override with default.priority, if not specified. if (applyDefault && get ("priority") == "") { - std::string defaultPriority = context.config.get ("default.priority"); - if (defaultPriority != "" && - context.columns["priority"]->validate (defaultPriority)) - set ("priority", defaultPriority); + if (Task::defaultPriority != "" && + context.columns["priority"]->validate (Task::defaultPriority)) + set ("priority", Task::defaultPriority); } // Override with default.due, if not specified. if (applyDefault && get ("due") == "") { - std::string defaultDue = context.config.get ("default.due"); - if (defaultDue != "" && - context.columns["due"]->validate (defaultDue)) - set ("due", Date (defaultDue).toEpoch ()); + if (Task::defaultDue != "" && + context.columns["due"]->validate (Task::defaultDue)) + set ("due", Date (Task::defaultDue).toEpoch ()); } // If a UDA has a default value in the configuration, @@ -1548,39 +1500,39 @@ int Task::determineVersion (const std::string& line) float Task::urgency_c () const { float value = 0.0; - value += fabsf (urgencyPriorityCoefficient) > epsilon ? (urgency_priority () * urgencyPriorityCoefficient) : 0.0; - value += fabsf (urgencyProjectCoefficient) > epsilon ? (urgency_project () * urgencyProjectCoefficient) : 0.0; - value += fabsf (urgencyActiveCoefficient) > epsilon ? (urgency_active () * urgencyActiveCoefficient) : 0.0; - value += fabsf (urgencyScheduledCoefficient) > epsilon ? (urgency_scheduled () * urgencyScheduledCoefficient) : 0.0; - value += fabsf (urgencyWaitingCoefficient) > epsilon ? (urgency_waiting () * urgencyWaitingCoefficient) : 0.0; - value += fabsf (urgencyBlockedCoefficient) > epsilon ? (urgency_blocked () * urgencyBlockedCoefficient) : 0.0; - value += fabsf (urgencyAnnotationsCoefficient) > epsilon ? (urgency_annotations () * urgencyAnnotationsCoefficient) : 0.0; - value += fabsf (urgencyTagsCoefficient) > epsilon ? (urgency_tags () * urgencyTagsCoefficient) : 0.0; - value += fabsf (urgencyNextCoefficient) > epsilon ? (urgency_next () * urgencyNextCoefficient) : 0.0; - value += fabsf (urgencyDueCoefficient) > epsilon ? (urgency_due () * urgencyDueCoefficient) : 0.0; - value += fabsf (urgencyBlockingCoefficient) > epsilon ? (urgency_blocking () * urgencyBlockingCoefficient) : 0.0; - value += fabsf (urgencyAgeCoefficient) > epsilon ? (urgency_age () * urgencyAgeCoefficient) : 0.0; + value += fabsf (Task::urgencyPriorityCoefficient) > epsilon ? (urgency_priority () * Task::urgencyPriorityCoefficient) : 0.0; + value += fabsf (Task::urgencyProjectCoefficient) > epsilon ? (urgency_project () * Task::urgencyProjectCoefficient) : 0.0; + value += fabsf (Task::urgencyActiveCoefficient) > epsilon ? (urgency_active () * Task::urgencyActiveCoefficient) : 0.0; + value += fabsf (Task::urgencyScheduledCoefficient) > epsilon ? (urgency_scheduled () * Task::urgencyScheduledCoefficient) : 0.0; + value += fabsf (Task::urgencyWaitingCoefficient) > epsilon ? (urgency_waiting () * Task::urgencyWaitingCoefficient) : 0.0; + value += fabsf (Task::urgencyBlockedCoefficient) > epsilon ? (urgency_blocked () * Task::urgencyBlockedCoefficient) : 0.0; + value += fabsf (Task::urgencyAnnotationsCoefficient) > epsilon ? (urgency_annotations () * Task::urgencyAnnotationsCoefficient) : 0.0; + value += fabsf (Task::urgencyTagsCoefficient) > epsilon ? (urgency_tags () * Task::urgencyTagsCoefficient) : 0.0; + value += fabsf (Task::urgencyNextCoefficient) > epsilon ? (urgency_next () * Task::urgencyNextCoefficient) : 0.0; + value += fabsf (Task::urgencyDueCoefficient) > epsilon ? (urgency_due () * Task::urgencyDueCoefficient) : 0.0; + value += fabsf (Task::urgencyBlockingCoefficient) > epsilon ? (urgency_blocking () * Task::urgencyBlockingCoefficient) : 0.0; + value += fabsf (Task::urgencyAgeCoefficient) > epsilon ? (urgency_age () * Task::urgencyAgeCoefficient) : 0.0; /* // Very useful for debugging urgency problems. std::cout << "# Urgency for " << get ("uuid") << ":\n" - << "# pri " << (urgency_priority () * urgencyPriorityCoefficient) << "\n" - << "# pro " << (urgency_project () * urgencyProjectCoefficient) << "\n" - << "# act " << (urgency_active () * urgencyActiveCoefficient) << "\n" - << "# sch " << (urgency_scheduled () * urgencyScheduledCoefficient) << "\n" - << "# wai " << (urgency_waiting () * urgencyWaitingCoefficient) << "\n" - << "# blk " << (urgency_blocked () * urgencyBlockedCoefficient) << "\n" - << "# ann " << (urgency_annotations () * urgencyAnnotationsCoefficient) << "\n" - << "# tag " << (urgency_tags () * urgencyTagsCoefficient) << "\n" - << "# nex " << (urgency_next () * urgencyNextCoefficient) << "\n" - << "# due " << (urgency_due () * urgencyDueCoefficient) << "\n" - << "# bkg " << (urgency_blocking () * urgencyBlockingCoefficient) << "\n" - << "# age " << (urgency_age () * urgencyAgeCoefficient) << "\n"; + << "# pri " << (urgency_priority () * Task::urgencyPriorityCoefficient) << "\n" + << "# pro " << (urgency_project () * Task::urgencyProjectCoefficient) << "\n" + << "# act " << (urgency_active () * Task::urgencyActiveCoefficient) << "\n" + << "# sch " << (urgency_scheduled () * Task::urgencyScheduledCoefficient) << "\n" + << "# wai " << (urgency_waiting () * Task::urgencyWaitingCoefficient) << "\n" + << "# blk " << (urgency_blocked () * Task::urgencyBlockedCoefficient) << "\n" + << "# ann " << (urgency_annotations () * Task::urgencyAnnotationsCoefficient) << "\n" + << "# tag " << (urgency_tags () * Task::urgencyTagsCoefficient) << "\n" + << "# nex " << (urgency_next () * Task::urgencyNextCoefficient) << "\n" + << "# due " << (urgency_due () * Task::urgencyDueCoefficient) << "\n" + << "# bkg " << (urgency_blocking () * Task::urgencyBlockingCoefficient) << "\n" + << "# age " << (urgency_age () * Task::urgencyAgeCoefficient) << "\n"; */ // Tag- and project-specific coefficients. std::map ::iterator var; - for (var = coefficients.begin (); var != coefficients.end (); ++var) + for (var = Task::coefficients.begin (); var != Task::coefficients.end (); ++var) { if (fabs (var->second) > epsilon) { diff --git a/src/Task.h b/src/Task.h index e2d8a274b..6e0695f61 100644 --- a/src/Task.h +++ b/src/Task.h @@ -34,12 +34,29 @@ #include #include -#ifdef PRODUCT_TASKWARRIOR -void initializeUrgencyCoefficients (); -#endif - class Task : public std::map { +public: + static std::string defaultProject; + static std::string defaultPriority; + static std::string defaultDue; + static bool searchCaseSensitive; + static bool regex; + static std::map attributes; // name -> type + static std::map coefficients; + static float urgencyPriorityCoefficient; + static float urgencyProjectCoefficient; + static float urgencyActiveCoefficient; + static float urgencyScheduledCoefficient; + static float urgencyWaitingCoefficient; + static float urgencyBlockedCoefficient; + static float urgencyAnnotationsCoefficient; + static float urgencyTagsCoefficient; + static float urgencyNextCoefficient; + static float urgencyDueCoefficient; + static float urgencyBlockingCoefficient; + static float urgencyAgeCoefficient; + public: Task (); // Default constructor Task (const Task&); // Copy constructor