Returns one CalendarEvent per occurrence of entry within [rangeStart, rangeEnd]. For non-repeating entries this is at most one event. A hard cap of 500 occurrences prevents infinite loops for misconfigured entries.
| 103 | // For non-repeating entries this is at most one event. |
| 104 | // A hard cap of 500 occurrences prevents infinite loops for misconfigured entries. |
| 105 | static QList<CalendarEvent> |
| 106 | EntryToCalendarEvents(const MacroScheduleEntry &entry, const QDate &rangeStart, |
| 107 | const QDate &rangeEnd) |
| 108 | { |
| 109 | QList<CalendarEvent> result; |
| 110 | |
| 111 | const QDateTime windowStart(rangeStart, QTime(0, 0)); |
| 112 | const QDateTime windowEnd(rangeEnd, QTime(23, 59, 59)); |
| 113 | |
| 114 | // Walk occurrences starting from the entry's first trigger time. |
| 115 | // We use a copy to advance lastTriggered without modifying the real entry. |
| 116 | MacroScheduleEntry cursor = entry; |
| 117 | cursor.lastTriggered = |
| 118 | QDateTime(); // start from the very first occurrence |
| 119 | cursor.timesTriggered = 0; |
| 120 | |
| 121 | static constexpr int MAX_OCCURRENCES = 500; |
| 122 | |
| 123 | for (int i = 0; i < MAX_OCCURRENCES; ++i) { |
| 124 | const QDateTime next = cursor.NextTriggerTime(); |
| 125 | if (!next.isValid() || next > windowEnd) { |
| 126 | break; |
| 127 | } |
| 128 | |
| 129 | if (next >= windowStart) { |
| 130 | CalendarEvent ev; |
| 131 | // Use id + occurrence index to make each event unique |
| 132 | // while still allowing the tab to look up the parent entry. |
| 133 | ev.id = QString::fromStdString(entry.id); |
| 134 | ev.title = entry.GetSummary(); |
| 135 | ev.color = ColorForEntry(entry); |
| 136 | ev.userData = ev.id; |
| 137 | ev.start = next; |
| 138 | if (entry.hasEndDate && entry.endDate.isValid()) { |
| 139 | ev.end = entry.endDate; |
| 140 | } |
| 141 | result.append(ev); |
| 142 | } |
| 143 | |
| 144 | if (!entry.doesRepeat) { |
| 145 | break; // one-shot — no more occurrences |
| 146 | } |
| 147 | |
| 148 | // Advance cursor past this occurrence |
| 149 | cursor.lastTriggered = next; |
| 150 | ++cursor.timesTriggered; |
| 151 | |
| 152 | if (cursor.IsExpired()) { |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | return result; |
| 158 | } |
| 159 | |
| 160 | // --------------------------------------------------------------------------- |
| 161 | // Table columns |
no test coverage detected