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()) {
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<date::days>(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<date::sys_days>(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<date::sys_days>(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()) {