feat: recurrence rule editing in EventEditor and ordinal BYDAY support

Add recurrence_frequency, recurrence_interval, recurrence_count, and
recurrence_by_weekday editor fields. Frequency cycles with Space.
BYDAY input accepts comma-separated names and ordinal prefixes (1MO).

Extend RecurrenceRule::by_weekday from std::chrono::weekday to ByWeekday
{ordinal, day} struct. Parser accepts ordinal BYDAY (+1MO, -1FR).
Remove strict BY*/FREQ pairing constraint to match RFC 5545.
This commit is contained in:
2026-07-23 18:45:50 +01:00
parent 40fc4651cb
commit 6c1f58ffb0
10 changed files with 499 additions and 34 deletions

View File

@@ -1,6 +1,7 @@
#pragma once
#include <chrono>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
@@ -14,12 +15,20 @@ enum class TimeBasis { floating, utc, zoned };
enum class RecurrenceFrequency { daily, weekly, monthly, yearly };
// BYDAY selector. For non-ordinal: use {0, weekday}. For ordinal: {n, weekday}.
struct ByWeekday {
int ordinal{0}; // 0 = non-ordinal; 1-5 or -5 to -1 = ordinal position
std::chrono::weekday day;
bool operator==(const ByWeekday&) const = default;
};
struct RecurrenceRule {
RecurrenceFrequency frequency{RecurrenceFrequency::daily};
unsigned interval{1};
std::optional<unsigned> count;
std::optional<TimePoint> until;
std::vector<std::chrono::weekday> by_weekday;
std::vector<ByWeekday> by_weekday;
std::vector<int> by_month_day;
std::vector<unsigned> by_month;

View File

@@ -25,6 +25,11 @@ enum class EditorField : std::size_t {
all_day,
location,
notes,
// Recurrence fields
recurrence_frequency, // none/daily/weekly/monthly/yearly
recurrence_interval, // number
recurrence_count, // number or empty for unlimited
recurrence_by_weekday, // comma-separated: MO,TU,WE,TH,FR
count,
};