feat: Add ISO 8601 calendar to clock module
This commit is contained in:
@ -50,6 +50,7 @@ class Clock final : public ALabel {
|
|||||||
std::string cldMonCached_; // calendar Month mode. Cached calendar
|
std::string cldMonCached_; // calendar Month mode. Cached calendar
|
||||||
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
||||||
std::string cldText_{""}; // calendar text to print
|
std::string cldText_{""}; // calendar text to print
|
||||||
|
bool iso8601Calendar_{false}; // whether the calendar is in ISO8601
|
||||||
CldMode cldMode_{CldMode::MONTH};
|
CldMode cldMode_{CldMode::MONTH};
|
||||||
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
|
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
|
||||||
const date::time_zone* tz) -> const std::string;
|
const date::time_zone* tz) -> const std::string;
|
||||||
|
@ -126,6 +126,12 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
|
|||||||
:[ 1
|
:[ 1
|
||||||
:[ Value to scroll months/years forward/backward. Can be negative. Is
|
:[ Value to scroll months/years forward/backward. Can be negative. Is
|
||||||
configured under *on-scroll* option
|
configured under *on-scroll* option
|
||||||
|
|[ *iso8601*
|
||||||
|
:[ bool
|
||||||
|
:[ false
|
||||||
|
:[ When enabled, the calendar follows the ISO 8601 standard: weeks begin on
|
||||||
|
Monday, and the first week of the year is numbered 1. The default week format is
|
||||||
|
'{:%V}'.
|
||||||
|
|
||||||
3. Addressed by *clock: calendar: format*
|
3. Addressed by *clock: calendar: format*
|
||||||
[- *Option*
|
[- *Option*
|
||||||
|
@ -73,6 +73,11 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
|||||||
"using instead",
|
"using instead",
|
||||||
cfgMode);
|
cfgMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_[kCldPlaceholder]["iso"].isBool()) {
|
||||||
|
iso8601Calendar_ = config_[kCldPlaceholder]["iso"].asBool();
|
||||||
|
}
|
||||||
|
|
||||||
if (config_[kCldPlaceholder]["weeks-pos"].isString()) {
|
if (config_[kCldPlaceholder]["weeks-pos"].isString()) {
|
||||||
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "left") cldWPos_ = WS::LEFT;
|
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "left") cldWPos_ = WS::LEFT;
|
||||||
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "right") cldWPos_ = WS::RIGHT;
|
if (config_[kCldPlaceholder]["weeks-pos"].asString() == "right") cldWPos_ = WS::RIGHT;
|
||||||
@ -99,17 +104,21 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
|||||||
} else
|
} else
|
||||||
fmtMap_.insert({3, "{}"});
|
fmtMap_.insert({3, "{}"});
|
||||||
if (config_[kCldPlaceholder]["format"]["weeks"].isString() && cldWPos_ != WS::HIDDEN) {
|
if (config_[kCldPlaceholder]["format"]["weeks"].isString() && cldWPos_ != WS::HIDDEN) {
|
||||||
|
const auto defaultFmt =
|
||||||
|
iso8601Calendar_ ? "{:%V}" : ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
|
||||||
fmtMap_.insert({4, std::regex_replace(config_[kCldPlaceholder]["format"]["weeks"].asString(),
|
fmtMap_.insert({4, std::regex_replace(config_[kCldPlaceholder]["format"]["weeks"].asString(),
|
||||||
std::regex("\\{\\}"),
|
std::regex("\\{\\}"), defaultFmt)});
|
||||||
(first_day_of_week() == Monday) ? "{:%W}" : "{:%U}")});
|
|
||||||
Glib::ustring tmp{std::regex_replace(fmtMap_[4], std::regex("</?[^>]+>|\\{.*\\}"), "")};
|
Glib::ustring tmp{std::regex_replace(fmtMap_[4], std::regex("</?[^>]+>|\\{.*\\}"), "")};
|
||||||
cldWnLen_ += tmp.size();
|
cldWnLen_ += tmp.size();
|
||||||
} else {
|
} else {
|
||||||
if (cldWPos_ != WS::HIDDEN)
|
if (cldWPos_ != WS::HIDDEN) {
|
||||||
fmtMap_.insert({4, (first_day_of_week() == Monday) ? "{:%W}" : "{:%U}"});
|
const auto defaultFmt =
|
||||||
else
|
iso8601Calendar_ ? "{:%V}" : ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
|
||||||
|
fmtMap_.insert({4, defaultFmt});
|
||||||
|
} else {
|
||||||
cldWnLen_ = 0;
|
cldWnLen_ = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (config_[kCldPlaceholder]["mode-mon-col"].isInt()) {
|
if (config_[kCldPlaceholder]["mode-mon-col"].isInt()) {
|
||||||
cldMonCols_ = config_[kCldPlaceholder]["mode-mon-col"].asInt();
|
cldMonCols_ = config_[kCldPlaceholder]["mode-mon-col"].asInt();
|
||||||
if (cldMonCols_ == 0u || (12 % cldMonCols_) != 0u) {
|
if (cldMonCols_ == 0u || (12 % cldMonCols_) != 0u) {
|
||||||
@ -204,9 +213,11 @@ const unsigned cldRowsInMonth(const year_month& ym, const weekday& firstdow) {
|
|||||||
|
|
||||||
auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow, const unsigned line)
|
auto cldGetWeekForLine(const year_month& ym, const weekday& firstdow, const unsigned line)
|
||||||
-> const year_month_weekday {
|
-> const year_month_weekday {
|
||||||
unsigned index{line - 2};
|
const unsigned idx = line - 2;
|
||||||
if (weekday{ym / 1} == firstdow) ++index;
|
const std::chrono::weekday_indexed indexed_first_day_of_week =
|
||||||
return ym / firstdow[index];
|
weekday{ym / 1} == firstdow ? firstdow[idx + 1] : firstdow[idx];
|
||||||
|
|
||||||
|
return ym / indexed_first_day_of_week;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getCalendarLine(const year_month_day& currDate, const year_month ym, const unsigned line,
|
auto getCalendarLine(const year_month_day& currDate, const year_month ym, const unsigned line,
|
||||||
@ -265,7 +276,7 @@ auto getCalendarLine(const year_month_day& currDate, const year_month ym, const
|
|||||||
}
|
}
|
||||||
// Print non-first week
|
// Print non-first week
|
||||||
default: {
|
default: {
|
||||||
auto ymdTmp{cldGetWeekForLine(ym, firstdow, line)};
|
const auto ymdTmp{cldGetWeekForLine(ym, firstdow, line)};
|
||||||
if (ymdTmp.ok()) {
|
if (ymdTmp.ok()) {
|
||||||
auto d{year_month_day{ymdTmp}.day()};
|
auto d{year_month_day{ymdTmp}.day()};
|
||||||
const auto dlast{(ym / last).day()};
|
const auto dlast{(ym / last).day()};
|
||||||
@ -356,10 +367,11 @@ auto waybar::modules::Clock::get_calendar(const year_month_day& today, const yea
|
|||||||
: static_cast<const zoned_seconds&&>(zoned_seconds{
|
: static_cast<const zoned_seconds&&>(zoned_seconds{
|
||||||
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)}})))
|
tz, local_days{cldGetWeekForLine(ymTmp, firstdow, line)}})))
|
||||||
<< ' ';
|
<< ' ';
|
||||||
} else
|
} else {
|
||||||
os << pads;
|
os << pads;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Count wide characters to avoid extra padding
|
// Count wide characters to avoid extra padding
|
||||||
size_t wideCharCount = 0;
|
size_t wideCharCount = 0;
|
||||||
@ -481,6 +493,9 @@ using deleting_unique_ptr = std::unique_ptr<T, deleter_from_fn<fn>>;
|
|||||||
|
|
||||||
// Computations done similarly to Linux cal utility.
|
// Computations done similarly to Linux cal utility.
|
||||||
auto waybar::modules::Clock::first_day_of_week() -> weekday {
|
auto waybar::modules::Clock::first_day_of_week() -> weekday {
|
||||||
|
if (iso8601Calendar_) {
|
||||||
|
return Monday;
|
||||||
|
}
|
||||||
#ifdef HAVE_LANGINFO_1STDAY
|
#ifdef HAVE_LANGINFO_1STDAY
|
||||||
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale> posix_locale{
|
deleting_unique_ptr<std::remove_pointer<locale_t>::type, freelocale> posix_locale{
|
||||||
newlocale(LC_ALL, m_locale_.name().c_str(), nullptr)};
|
newlocale(LC_ALL, m_locale_.name().c_str(), nullptr)};
|
||||||
|
Reference in New Issue
Block a user