diff --git a/src/sort.cpp b/src/sort.cpp index 3ee64f503..f99ada61c 100644 --- a/src/sort.cpp +++ b/src/sort.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -68,7 +67,6 @@ void sort_tasks ( // require re-parsing. // // Essentially a static implementation of a dynamic operator<. -// UDA string values delegate to Variant::operator<. static bool sort_compare (int left, int right) { std::string field; @@ -213,20 +211,36 @@ static bool sort_compare (int left, int right) return ascending ? (left_real < right_real) : (left_real > right_real); } - // UDA values of type 'string' are sorted by Variant::operator<. - // By setting 'source' to the UDA name, the comparison operator can use - // the custom sort order, if defined. else if (type == "string") { - Variant l ((*global_data)[left].get_ref (field)); - Variant r ((*global_data)[right].get_ref (field)); - if (l == r) + const std::string left_string = (*global_data)[left].get_ref (field); + const std::string right_string = (*global_data)[right].get_ref (field); + + if (left_string == right_string) continue; - l.source (field); - r.source (field); - return ascending ? (l < r) : (r < l); + // UDAs of the type string can have custom sort orders, which need to be considered. + auto order = Task::customOrder.find (field); + if (order != Task::customOrder.end ()) + { + // Guaranteed to be found, because of ColUDA::validate (). + auto posLeft = std::find (order->second.begin (), order->second.end (), left_string); + auto posRight = std::find (order->second.begin (), order->second.end (), right_string); + return ascending ? (posLeft < posRight) : (posLeft > posRight); + } + else + { + // Empty values are unconditionally last, if no custom order was specified. + if (left_string == "") + return false; + else if (right_string == "") + return true; + + return ascending ? (left_string < right_string) + : (left_string > right_string); + } } + else if (type == "date") { const std::string& left_string = (*global_data)[left].get_ref (field);