clock: add weeks-numbering option for configurable CW calculation
The iso8601 flag previously controlled both the calendar grid layout and the week number format as a coupled boolean. This adds a new weeks-numbering option (iso/monday/sunday) that explicitly overrides just the week number calculation method, independent of iso8601 and locale settings. Existing behaviour is fully preserved when the option is not set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ab7bfdb297
commit
86d516c74d
@@ -12,6 +12,7 @@ const std::string kOrdPlaceholder{"ordinal_date"};
|
|||||||
|
|
||||||
enum class CldMode { MONTH, YEAR };
|
enum class CldMode { MONTH, YEAR };
|
||||||
enum class WS { LEFT, RIGHT, HIDDEN };
|
enum class WS { LEFT, RIGHT, HIDDEN };
|
||||||
|
enum class WeekNumbering { LOCALE, ISO, MONDAY, SUNDAY };
|
||||||
|
|
||||||
class Clock final : public ALabel {
|
class Clock final : public ALabel {
|
||||||
public:
|
public:
|
||||||
@@ -51,6 +52,7 @@ class Clock final : public ALabel {
|
|||||||
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
|
bool iso8601Calendar_{false}; // whether the calendar is in ISO8601
|
||||||
|
WeekNumbering weekNumbering_{WeekNumbering::LOCALE}; // week number calculation method
|
||||||
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;
|
||||||
|
|||||||
+10
-2
@@ -138,6 +138,13 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
|
|||||||
:[ When enabled, the calendar follows the ISO 8601 standard: weeks begin on
|
:[ 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
|
Monday, and the first week of the year is numbered 1. The default week format is
|
||||||
'{:%V}'.
|
'{:%V}'.
|
||||||
|
|[ *weeks-numbering*
|
||||||
|
:[ string
|
||||||
|
:[
|
||||||
|
:[ Override the week number calculation method, independent of *iso8601* and
|
||||||
|
locale settings. Possible values: *iso* (ISO 8601, {:%V}), *monday*
|
||||||
|
(Monday-based, {:%W}), *sunday* (Sunday-based, {:%U}). When not set, the
|
||||||
|
method is derived from *iso8601* or the locale.
|
||||||
|
|
||||||
3. Addressed by *clock: calendar: format*
|
3. Addressed by *clock: calendar: format*
|
||||||
[- *Option*
|
[- *Option*
|
||||||
@@ -155,8 +162,9 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
|
|||||||
|[ *weeks*
|
|[ *weeks*
|
||||||
:[ string
|
:[ string
|
||||||
:[ *{:%U}*
|
:[ *{:%U}*
|
||||||
:[ Format is applied to week numbers. When weekday format is not provided then
|
:[ Format is applied to week numbers. The *{}* placeholder is replaced with the
|
||||||
is used default format: '{:%W}' when week starts with Monday, '{:%U}' otherwise
|
format determined by *weeks-numbering* (if set), otherwise by *iso8601* or the
|
||||||
|
locale: '{:%V}' for ISO 8601, '{:%W}' when week starts with Monday, '{:%U}' otherwise
|
||||||
|[ *weekdays*
|
|[ *weekdays*
|
||||||
:[ string
|
:[ string
|
||||||
:[
|
:[
|
||||||
|
|||||||
+29
-6
@@ -81,6 +81,20 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
|||||||
iso8601Calendar_ = config_[kCldPlaceholder]["iso8601"].asBool();
|
iso8601Calendar_ = config_[kCldPlaceholder]["iso8601"].asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config_[kCldPlaceholder]["weeks-numbering"].isString()) {
|
||||||
|
const std::string wn{config_[kCldPlaceholder]["weeks-numbering"].asString()};
|
||||||
|
const std::map<std::string, WeekNumbering> wnModes{{"iso", WeekNumbering::ISO},
|
||||||
|
{"monday", WeekNumbering::MONDAY},
|
||||||
|
{"sunday", WeekNumbering::SUNDAY}};
|
||||||
|
if (wnModes.find(wn) != wnModes.end())
|
||||||
|
weekNumbering_ = wnModes.at(wn);
|
||||||
|
else
|
||||||
|
spdlog::warn(
|
||||||
|
"Clock calendar configuration weeks-numbering \"{}\" is not recognized. "
|
||||||
|
"Locale default is used instead",
|
||||||
|
wn);
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@@ -104,18 +118,27 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config)
|
|||||||
cldBaseDay_ = year_month_day{floor<days>(local_time)}.day();
|
cldBaseDay_ = year_month_day{floor<days>(local_time)}.day();
|
||||||
} else
|
} else
|
||||||
fmtMap_.insert({3, "{}"});
|
fmtMap_.insert({3, "{}"});
|
||||||
|
const auto weekFmt = [this]() -> std::string {
|
||||||
|
switch (weekNumbering_) {
|
||||||
|
case WeekNumbering::ISO:
|
||||||
|
return "{:%V}";
|
||||||
|
case WeekNumbering::MONDAY:
|
||||||
|
return "{:%W}";
|
||||||
|
case WeekNumbering::SUNDAY:
|
||||||
|
return "{:%U}";
|
||||||
|
default:
|
||||||
|
return iso8601Calendar_ ? "{:%V}"
|
||||||
|
: ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
|
||||||
|
}
|
||||||
|
}();
|
||||||
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("\\{\\}"), defaultFmt)});
|
std::regex("\\{\\}"), weekFmt)});
|
||||||
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) {
|
||||||
const auto defaultFmt =
|
fmtMap_.insert({4, weekFmt});
|
||||||
iso8601Calendar_ ? "{:%V}" : ((first_day_of_week() == Monday) ? "{:%W}" : "{:%U}");
|
|
||||||
fmtMap_.insert({4, defaultFmt});
|
|
||||||
} else {
|
} else {
|
||||||
cldWnLen_ = 0;
|
cldWnLen_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user