| 6 | namespace AetherSDR { |
| 7 | |
| 8 | PendingReminder nextReminderAcross(const QList<NetEntry>& entries, const QDateTime& afterUtc) |
| 9 | { |
| 10 | PendingReminder best; |
| 11 | const QDateTime afterUtcNorm = afterUtc.toUTC(); |
| 12 | |
| 13 | for (int i = 0; i < entries.size(); ++i) { |
| 14 | const NetEntry& entry = entries.at(i); |
| 15 | if (!entry.enabled) |
| 16 | continue; |
| 17 | |
| 18 | const int lead = entry.reminderLeadMinutes > 0 ? entry.reminderLeadMinutes : 0; |
| 19 | const qint64 leadSecs = static_cast<qint64>(lead) * 60; |
| 20 | |
| 21 | // Walk occurrences forward until this entry yields a reminder instant |
| 22 | // strictly after `afterUtc`. The lead-time can push a reminder before |
| 23 | // its occurrence into the past, so the soonest future *occurrence* does |
| 24 | // not always give the soonest future *reminder* — advance until it does. |
| 25 | QDateTime cursorUtc = afterUtcNorm; |
| 26 | for (int guard = 0; guard < 64; ++guard) { |
| 27 | const QDateTime occ = NetRecurrence::nextOccurrence(entry, cursorUtc); |
| 28 | if (!occ.isValid()) |
| 29 | break; |
| 30 | const QDateTime occUtc = occ.toUTC(); |
| 31 | const QDateTime reminderUtc = occUtc.addSecs(-leadSecs); |
| 32 | if (reminderUtc > afterUtcNorm) { |
| 33 | if (!best.isValid() || reminderUtc < best.reminderUtc) { |
| 34 | best.entryIndex = i; |
| 35 | best.occurrenceUtc = occUtc; |
| 36 | best.reminderUtc = reminderUtc; |
| 37 | } |
| 38 | break; |
| 39 | } |
| 40 | // Reminder already in the past; skip this occurrence and look further. |
| 41 | cursorUtc = occUtc; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | return best; |
| 46 | } |
| 47 | |
| 48 | } // namespace AetherSDR |