Merge pull request #1868 from prohornikitin/calendar-week-numbers

Fix https://github.com/Alexays/Waybar/issues/1802
This commit is contained in:
Alex 2022-12-06 09:01:18 +01:00 committed by GitHub
commit c5babb4c44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 56 additions and 44 deletions

View File

@ -113,8 +113,12 @@ auto waybar::modules::Clock::update() -> void {
if (config_["tooltip-format"].isString()) { if (config_["tooltip-format"].isString()) {
std::string calendar_lines{""}; std::string calendar_lines{""};
std::string timezoned_time_lines{""}; std::string timezoned_time_lines{""};
if (is_calendar_in_tooltip_) calendar_lines = calendar_text(wtime); if (is_calendar_in_tooltip_) {
if (is_timezoned_list_in_tooltip_) timezoned_time_lines = timezones_text(&now); calendar_lines = calendar_text(wtime);
}
if (is_timezoned_list_in_tooltip_) {
timezoned_time_lines = timezones_text(&now);
}
auto tooltip_format = config_["tooltip-format"].asString(); auto tooltip_format = config_["tooltip-format"].asString();
text = text =
fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines), 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<date::days>(wtime.ztime.get_local_time()); const auto daypoint = date::floor<date::days>(wtime.ztime.get_local_time());
const auto ymd{date::year_month_day{daypoint}}; 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) const auto curr_day{(calendar_shift_init_.count() != 0 && calendar_shift_.count() != 0)
? date::day{0} ? date::day{0}
: ymd.day()}; : ymd.day()};
const date::year_month ym{ymd.year(), ymd.month()}; const date::year_month ym{ymd.year(), ymd.month()};
const auto week_format{config_["format-calendar-weekdays"].isString() const auto weeks_format{config_["format-calendar-weeks"].isString()
? config_["format-calendar-weekdays"].asString() ? config_["format-calendar-weeks"].asString()
: ""}; : ""};
const auto wn_format{config_["format-calendar-weeks"].isString()
? config_["format-calendar-weeks"].asString()
: ""};
std::stringstream os; std::stringstream os;
const auto first_dow = first_day_of_week(); const date::weekday first_week_day = first_day_of_week();
int ws{0}; // weeks-pos: side(1 - left, 2 - right)
enum class WeeksPlacement {
LEFT,
RIGHT,
HIDDEN,
};
WeeksPlacement weeks_pos = WeeksPlacement::HIDDEN;
if (config_["calendar-weeks-pos"].isString()) { if (config_["calendar-weeks-pos"].isString()) {
if (config_["calendar-weeks-pos"].asString() == "left") { if (config_["calendar-weeks-pos"].asString() == "left") {
ws = 1; weeks_pos = WeeksPlacement::LEFT;
// Add paddings before the header // Add paddings before the header
os << std::string(4, ' '); os << std::string(4, ' ');
} else if (config_["calendar-weeks-pos"].asString() == "right") { } 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. // First week prefixed with spaces if needed.
auto wd = date::weekday(ym / 1); auto first_month_day = date::weekday(ym / 1);
auto empty_days = (wd - first_dow).count(); int empty_days = (first_week_day - first_month_day).count() + 1;
date::sys_days lwd{static_cast<date::sys_days>(ym / 1) + date::days{7 - empty_days}}; date::sys_days last_week_day{static_cast<date::sys_days>(ym / 1) + date::days{7 - empty_days}};
if (first_dow == date::Monday) { if (first_week_day == date::Monday) {
lwd -= date::days{1}; last_week_day -= date::days{1};
} }
/* Print weeknumber on the left for the first row*/ /* Print weeknumber on the left for the first row*/
if (ws == 1) { if (weeks_pos == WeeksPlacement::LEFT) {
os << fmt::format(wn_format, lwd); os << fmt::format(weeks_format, date::format("%U", last_week_day)) << ' ';
os << ' '; last_week_day += date::weeks{1};
lwd += date::weeks{1};
} }
if (empty_days > 0) { if (empty_days > 0) {
os << std::string(empty_days * 3 - 1, ' '); os << std::string(empty_days * 3 - 1, ' ');
} }
auto last_day = (ym / date::literals::last).day(); const auto last_day = (ym / date::literals::last).day();
for (auto d = date::day(1); d <= last_day; ++d, ++wd) { auto weekday = first_month_day;
if (wd != first_dow) { for (auto d = date::day(1); d <= last_day; ++d, ++weekday) {
if (weekday != first_week_day) {
os << ' '; os << ' ';
} else if (unsigned(d) != 1) { } else if (unsigned(d) != 1) {
if (ws == 2) { last_week_day -= date::days{1};
if (weeks_pos == WeeksPlacement::RIGHT) {
os << ' '; os << ' ';
os << fmt::format(wn_format, lwd); os << fmt::format(weeks_format, date::format("%U", last_week_day));
lwd += date::weeks{1};
} }
os << '\n'; os << "\n";
if (ws == 1) { if (weeks_pos == WeeksPlacement::LEFT) {
os << fmt::format(wn_format, lwd); os << fmt::format(weeks_format, date::format("%U", last_week_day));
os << ' '; os << ' ';
lwd += date::weeks{1};
} }
last_week_day += date::weeks{1} + date::days{1};
} }
if (d == curr_day) { if (d == curr_day) {
if (config_["today-format"].isString()) { 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()) { } else if (config_["format-calendar"].isString()) {
os << fmt::format(config_["format-calendar"].asString(), date::format("%e", d)); os << fmt::format(config_["format-calendar"].asString(), date::format("%e", d));
} else } else {
os << date::format("%e", d); os << date::format("%e", d);
}
/*Print weeks on the right when the endings with spaces*/ /*Print weeks on the right when the endings with spaces*/
if (ws == 2 && d == last_day) { if (weeks_pos == WeeksPlacement::RIGHT && d == last_day) {
empty_days = 6 - (wd.c_encoding() - first_dow.c_encoding()); last_week_day -= date::days{1};
if (empty_days > 0) { empty_days = 6 - (weekday - first_week_day).count();
os << std::string(empty_days * 3 + 1, ' '); os << std::string(empty_days * 3 + 1, ' ');
os << fmt::format(wn_format, lwd); 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; 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 { -> void {
std::stringstream res; std::stringstream res;
auto wd = first_dow; auto wd = first_week_day;
do { do {
if (wd != first_dow) res << ' '; if (wd != first_week_day) {
res << ' ';
}
Glib::ustring wd_ustring(date::format(locale_, "%a", wd)); Glib::ustring wd_ustring(date::format(locale_, "%a", wd));
auto clen = ustring_clen(wd_ustring); auto clen = ustring_clen(wd_ustring);
auto wd_len = wd_ustring.length(); 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, ' '); const std::string pad(2 - clen, ' ');
res << pad << wd_ustring; res << pad << wd_ustring;
} while (++wd != first_dow); } while (++wd != first_week_day);
res << "\n"; res << "\n";
if (config_["format-calendar-weekdays"].isString()) { if (config_["format-calendar-weekdays"].isString()) {