diff --git a/lib/json b/lib/json index 199dea1..377c767 160000 --- a/lib/json +++ b/lib/json @@ -1 +1 @@ -Subproject commit 199dea11b17c533721b26249e2dcaee6ca1d51d3 +Subproject commit 377c767aa19da7159cf537490bc33da96edf8803 diff --git a/lib/libxlsxwriter b/lib/libxlsxwriter index f6d73b0..7548faa 160000 --- a/lib/libxlsxwriter +++ b/lib/libxlsxwriter @@ -1 +1 @@ -Subproject commit f6d73b0ae13de14e8f23afab76ee188d4b18e71d +Subproject commit 7548faa95afdf8ac321136d10eda931683fbf7c6 diff --git a/src/common/Symbols.h b/src/common/Symbols.h index 72ef55f..0db13b3 100644 --- a/src/common/Symbols.h +++ b/src/common/Symbols.h @@ -9,8 +9,9 @@ namespace platform { inline static const std::string black_star{ "\u2605" }; inline static const std::string cross{ "\u2717" }; inline static const std::string upward_arrow{ "\u27B6" }; - inline static const std::string down_arrow{ "\u27B4" }; - inline static const std::string downward_arrow{ "\u2B07" }; + inline static const std::string downward_arrow{ "\u27B4" }; + inline static const std::string up_arrow{ "\u2B06" }; + inline static const std::string down_arrow{ "\u2B07" }; inline static const std::string equal_best{ check_mark }; inline static const std::string better_best{ black_star }; inline static const std::string notebook{ "\U0001F5C8" }; diff --git a/src/manage/ManageScreen.cpp b/src/manage/ManageScreen.cpp index 7f089fb..16151d2 100644 --- a/src/manage/ManageScreen.cpp +++ b/src/manage/ManageScreen.cpp @@ -22,8 +22,6 @@ namespace platform { rows{ rows }, cols{ cols }, complete{ complete }, partial{ partial }, compare{ compare }, didExcel(false), results(ResultsManager(model, score, complete, partial)) { results.load(); - results.sortDate(); - sort_field = "Date"; openExcel = false; workbook = NULL; this->rows = std::max(0, rows - 6); // 6 is the number of lines used by the menu & header @@ -44,7 +42,7 @@ namespace platform { std::cout << Colors::MAGENTA() << "No results found!" << Colors::RESET() << std::endl; return; } - results.sortDate(); + results.sortResults(sort_field, sort_type); list(STATUS_OK, STATUS_COLOR); menu(); if (openExcel) { @@ -209,17 +207,18 @@ namespace platform { int maxModel = results.maxModelSize(); int maxTitle = results.maxTitleSize(); std::vector header_lengths = { 3, 10, maxModel, 10, 9, 3, 7, maxTitle }; - // std::cout << Colors::RESET(); - std::string arrow = Symbols::downward_arrow + " "; + std::string arrow_dn = Symbols::down_arrow + " "; + std::string arrow_up = Symbols::up_arrow + " "; std::vector header_labels = { " #", "Date", "Model", "Score Name", "Score", "C/P", "Time", "Title" }; + std::vector sort_fields = { "Date", "Model", "Score", "Time" }; for (int i = 0; i < header_labels.size(); i++) { std::string suffix = "", color = Colors::GREEN(); int diff = 0; - if (header_labels[i] == sort_field) { + if (header_labels[i] == sort_fields[static_cast(sort_field)]) { color = Colors::YELLOW(); diff = 2; - suffix = arrow; + suffix = sort_type == SortType::ASC ? arrow_up : arrow_dn; } std::cout << color << std::setw(header_lengths[i] + diff) << std::left << std::string(header_labels[i] + suffix) << " "; } @@ -290,34 +289,40 @@ namespace platform { } std::pair ManageScreen::sortList() { - std::cout << Colors::YELLOW() << "Choose sorting field (date='d', score='s', time='t', model='m'): "; + std::cout << Colors::YELLOW() << "Choose sorting field (date='d', score='s', time='t', model='m', ascending='+', descending='-'): "; + std::vector fields = { "Date", "Model", "Score", "Time" }; + std::string invalid_option = "Invalid sorting option"; std::string line; char option; getline(std::cin, line); if (line.size() == 0 || line.size() > 1) { - return { Colors::RED(), "Invalid sorting option" }; + return { Colors::RED(), invalid_option }; } option = line[0]; switch (option) { case 'd': - results.sortDate(); - sort_field = "Date"; - return { Colors::GREEN(), "Sorted by date" }; + sort_field = SortField::DATE; + break; case 's': - results.sortScore(); - sort_field = "Score"; - return { Colors::GREEN(), "Sorted by score" }; + sort_field = SortField::SCORE; + break; case 't': - results.sortDuration(); - sort_field = "Time"; - return { Colors::GREEN(), "Sorted by time" }; + sort_field = SortField::DURATION; + break; case 'm': - results.sortModel(); - sort_field = "Model"; - return { Colors::GREEN(), "Sorted by model" }; + sort_field = SortField::MODEL; + break; + case '+': + sort_type = SortType::ASC; + break; + case '-': + sort_type = SortType::DESC; + break; default: - return { Colors::RED(), "Invalid sorting option" }; + return { Colors::RED(), invalid_option }; } + results.sortResults(sort_field, sort_type); + return { Colors::GREEN(), "Sorted by " + fields[static_cast(sort_field)] + " " + (sort_type == SortType::ASC ? "ascending" : "descending") }; } void ManageScreen::menu() { diff --git a/src/manage/ManageScreen.h b/src/manage/ManageScreen.h index 2958af6..9024028 100644 --- a/src/manage/ManageScreen.h +++ b/src/manage/ManageScreen.h @@ -43,7 +43,8 @@ namespace platform { bool complete; bool partial; bool compare; - std::string sort_field; + SortField sort_field = SortField::DATE; + SortType sort_type = SortType::DESC; std::vector paginator; ResultsManager results; lxw_workbook* workbook; diff --git a/src/manage/ResultsManager.cpp b/src/manage/ResultsManager.cpp index 0f3c7fa..69cf92f 100644 --- a/src/manage/ResultsManager.cpp +++ b/src/manage/ResultsManager.cpp @@ -46,47 +46,79 @@ namespace platform { { return files.size(); } - void ResultsManager::sortDate() + void ResultsManager::sortDate(SortType type) { if (empty()) return; - sort(files.begin(), files.end(), [](const Result& a, const Result& b) { + sort(files.begin(), files.end(), [type](const Result& a, const Result& b) { if (a.getDate() == b.getDate()) { - return a.getModel() < b.getModel(); + if (type == SortType::ASC) + return a.getModel() < b.getModel(); + return a.getModel() > b.getModel(); } + if (type == SortType::ASC) + return a.getDate() < b.getDate(); return a.getDate() > b.getDate(); }); } - void ResultsManager::sortModel() + void ResultsManager::sortModel(SortType type) { if (empty()) return; - sort(files.begin(), files.end(), [](const Result& a, const Result& b) { + sort(files.begin(), files.end(), [type](const Result& a, const Result& b) { if (a.getModel() == b.getModel()) { + if (type == SortType::ASC) + return a.getDate() < b.getDate(); return a.getDate() > b.getDate(); } + if (type == SortType::ASC) + return a.getModel() < b.getModel(); return a.getModel() > b.getModel(); }); } - void ResultsManager::sortDuration() + void ResultsManager::sortDuration(SortType type) { if (empty()) return; - sort(files.begin(), files.end(), [](const Result& a, const Result& b) { + sort(files.begin(), files.end(), [type](const Result& a, const Result& b) { + if (type == SortType::ASC) + return a.getDuration() < b.getDuration(); return a.getDuration() > b.getDuration(); }); } - void ResultsManager::sortScore() + void ResultsManager::sortScore(SortType type) { - if (files.empty()) + if (empty()) return; - sort(files.begin(), files.end(), [](const Result& a, const Result& b) { + sort(files.begin(), files.end(), [type](const Result& a, const Result& b) { if (a.getScore() == b.getScore()) { + if (type == SortType::ASC) + return a.getDate() < b.getDate(); return a.getDate() > b.getDate(); } + if (type == SortType::ASC) + return a.getScore() < b.getScore(); return a.getScore() > b.getScore(); }); } + + void ResultsManager::sortResults(SortField field, SortType type) + { + switch (field) { + case SortField::DATE: + sortDate(type); + break; + case SortField::MODEL: + sortModel(type); + break; + case SortField::SCORE: + sortScore(type); + break; + case SortField::DURATION: + sortDuration(type); + break; + } + } bool ResultsManager::empty() const { return files.empty(); diff --git a/src/manage/ResultsManager.h b/src/manage/ResultsManager.h index 308259d..a49cb71 100644 --- a/src/manage/ResultsManager.h +++ b/src/manage/ResultsManager.h @@ -6,14 +6,25 @@ #include "results/Result.h" namespace platform { using json = nlohmann::json; + enum class SortType { + ASC = 0, + DESC = 1, + }; + enum class SortField { + DATE = 0, + MODEL = 1, + SCORE = 2, + DURATION = 3, + }; class ResultsManager { public: ResultsManager(const std::string& model, const std::string& score, bool complete, bool partial); void load(); // Loads the list of results - void sortDate(); - void sortScore(); - void sortModel(); - void sortDuration(); + void sortResults(SortField field, SortType type); // Sorts the list of results + void sortDate(SortType type); + void sortScore(SortType type); + void sortModel(SortType type); + void sortDuration(SortType type); int maxModelSize() const { return maxModel; }; int maxTitleSize() const { return maxTitle; }; void hideResult(int index, const std::string& pathHidden);