From 328575a721dec88604a20e070c4a10d17803de0d Mon Sep 17 00:00:00 2001 From: Prokhor40 Date: Tue, 6 Dec 2022 03:47:28 +0300 Subject: [PATCH] fix: calendar week numbers fix their format to correct fix last number hide if the last day of the month is the last day of the week some refactoring(mostly renaming abbreviations to the full phrases) --- src/modules/clock.cpp | 100 +++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index e0d63e2..a40d412 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -113,8 +113,12 @@ auto waybar::modules::Clock::update() -> void { if (config_["tooltip-format"].isString()) { std::string calendar_lines{""}; std::string timezoned_time_lines{""}; - if (is_calendar_in_tooltip_) calendar_lines = calendar_text(wtime); - if (is_timezoned_list_in_tooltip_) timezoned_time_lines = timezones_text(&now); + if (is_calendar_in_tooltip_) { + calendar_lines = calendar_text(wtime); + } + if (is_timezoned_list_in_tooltip_) { + timezoned_time_lines = timezones_text(&now); + } auto tooltip_format = config_["tooltip-format"].asString(); text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines), @@ -168,72 +172,77 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str const auto daypoint = date::floor(wtime.ztime.get_local_time()); const auto ymd{date::year_month_day{daypoint}}; - if (calendar_cached_ymd_ == ymd) return calendar_cached_text_; + if (calendar_cached_ymd_ == ymd) { + return calendar_cached_text_; + } const auto curr_day{(calendar_shift_init_.count() != 0 && calendar_shift_.count() != 0) ? date::day{0} : ymd.day()}; const date::year_month ym{ymd.year(), ymd.month()}; - const auto week_format{config_["format-calendar-weekdays"].isString() - ? config_["format-calendar-weekdays"].asString() - : ""}; - const auto wn_format{config_["format-calendar-weeks"].isString() - ? config_["format-calendar-weeks"].asString() - : ""}; + const auto weeks_format{config_["format-calendar-weeks"].isString() + ? config_["format-calendar-weeks"].asString() + : ""}; std::stringstream os; - const auto first_dow = first_day_of_week(); - int ws{0}; // weeks-pos: side(1 - left, 2 - right) + const date::weekday first_week_day = first_day_of_week(); + + enum class WeeksPlacement { + LEFT, + RIGHT, + HIDDEN, + }; + WeeksPlacement weeks_pos = WeeksPlacement::HIDDEN; if (config_["calendar-weeks-pos"].isString()) { if (config_["calendar-weeks-pos"].asString() == "left") { - ws = 1; + weeks_pos = WeeksPlacement::LEFT; // Add paddings before the header os << std::string(4, ' '); } else if (config_["calendar-weeks-pos"].asString() == "right") { - ws = 2; + weeks_pos = WeeksPlacement::RIGHT; } } - weekdays_header(first_dow, os); + weekdays_header(first_week_day, os); // First week prefixed with spaces if needed. - auto wd = date::weekday(ym / 1); - auto empty_days = (wd - first_dow).count(); - date::sys_days lwd{static_cast(ym / 1) + date::days{7 - empty_days}}; + auto first_month_day = date::weekday(ym / 1); + int empty_days = (first_week_day - first_month_day).count() + 1; + date::sys_days last_week_day{static_cast(ym / 1) + date::days{7 - empty_days}}; - if (first_dow == date::Monday) { - lwd -= date::days{1}; + if (first_week_day == date::Monday) { + last_week_day -= date::days{1}; } /* Print weeknumber on the left for the first row*/ - if (ws == 1) { - os << fmt::format(wn_format, lwd); - os << ' '; - lwd += date::weeks{1}; + if (weeks_pos == WeeksPlacement::LEFT) { + os << fmt::format(weeks_format, date::format("%U", last_week_day)) << ' '; + last_week_day += date::weeks{1}; } if (empty_days > 0) { os << std::string(empty_days * 3 - 1, ' '); } - auto last_day = (ym / date::literals::last).day(); - for (auto d = date::day(1); d <= last_day; ++d, ++wd) { - if (wd != first_dow) { + const auto last_day = (ym / date::literals::last).day(); + auto weekday = first_month_day; + for (auto d = date::day(1); d <= last_day; ++d, ++weekday) { + if (weekday != first_week_day) { os << ' '; } else if (unsigned(d) != 1) { - if (ws == 2) { + last_week_day -= date::days{1}; + if (weeks_pos == WeeksPlacement::RIGHT) { os << ' '; - os << fmt::format(wn_format, lwd); - lwd += date::weeks{1}; + os << fmt::format(weeks_format, date::format("%U", last_week_day)); } - os << '\n'; + os << "\n"; - if (ws == 1) { - os << fmt::format(wn_format, lwd); + if (weeks_pos == WeeksPlacement::LEFT) { + os << fmt::format(weeks_format, date::format("%U", last_week_day)); os << ' '; - lwd += date::weeks{1}; } + last_week_day += date::weeks{1} + date::days{1}; } if (d == curr_day) { if (config_["today-format"].isString()) { @@ -244,15 +253,16 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str } } else if (config_["format-calendar"].isString()) { os << fmt::format(config_["format-calendar"].asString(), date::format("%e", d)); - } else + } else { os << date::format("%e", d); + } /*Print weeks on the right when the endings with spaces*/ - if (ws == 2 && d == last_day) { - empty_days = 6 - (wd.c_encoding() - first_dow.c_encoding()); - if (empty_days > 0) { - os << std::string(empty_days * 3 + 1, ' '); - os << fmt::format(wn_format, lwd); - } + if (weeks_pos == WeeksPlacement::RIGHT && d == last_day) { + last_week_day -= date::days{1}; + empty_days = 6 - (weekday - first_week_day).count(); + os << std::string(empty_days * 3 + 1, ' '); + os << fmt::format(weeks_format, date::format("%U", last_week_day)); + last_week_day += date::days{1}; } } @@ -262,12 +272,14 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str return result; } -auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std::ostream& os) +auto waybar::modules::Clock::weekdays_header(const date::weekday& first_week_day, std::ostream& os) -> void { std::stringstream res; - auto wd = first_dow; + auto wd = first_week_day; do { - if (wd != first_dow) res << ' '; + if (wd != first_week_day) { + res << ' '; + } Glib::ustring wd_ustring(date::format(locale_, "%a", wd)); auto clen = ustring_clen(wd_ustring); auto wd_len = wd_ustring.length(); @@ -278,7 +290,7 @@ auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std } const std::string pad(2 - clen, ' '); res << pad << wd_ustring; - } while (++wd != first_dow); + } while (++wd != first_week_day); res << "\n"; if (config_["format-calendar-weekdays"].isString()) {