static void SendOne(CachedBox box, bool isPrep) { string message = isPrep ? $"{box.PrepDuration}: {box.Title}" : $"Now: {box.Title}"; bool extraTime = box.Importance == Constants.IMPORTANCE_HIGH; Globals.UIAction.ShowToasterNotification(message, extraTime); }
/// <summary> /// Given a box with repeats, find the next time it should be scheduled for. Use this for processing DONE command. /// </summary> /// <returns>YYYYMMDDHHMM, or null if there are no repeats defined, or there are no more instances available</returns> public string AdvanceTime(string boxTime, ParsedRepeatInfo repeats) { //simulate cached box, knowing that Project function only looks at BoxTime and Repeats members var simulatedBox = new CachedBox { BoxTime = boxTime, Repeats = repeats }; var seq = Project(simulatedBox, false, false).OrderBy(r => r.Time); try { var next = seq.First(); return(next.Time); } catch { return(null); //sequence empty } }
CachedBox FullBoxToCachedBox(Box r) { var cb = new CachedBox { BoxTime = r.BoxTime, DoneDate = r.DoneDate, Duration = r.Duration, Importance = r.Importance, IsUnclass = r.IsUnclass, ParentId = r.ParentId, PrepDuration = r.PrepDuration, RepeatInfo = r.RepeatInfo, RowId = r.RowId, TimeType = r.TimeType, Title = r.Title, Visibility = r.Visibility, SmallNotes = r.Notes, Repeats = ParsedRepeatInfo.Build(r.RepeatInfo) }; cb.TruncateSmallNotes(); return(cb); }
/// <summary> /// With delayed execution, find all cases where a task should be repeated /// </summary> /// <param name="box">Only inspects box.BoxTime and Repeats</param> /// <param name="includeCurrent">if true, includes the time the box is currently scheduled for</param> /// <param name="allowAbortOnLowClutter">if true, will skip projections after the currently scheduled time, if low clutter</param> public IEnumerable <AgendaEntry> Project(CachedBox box, bool includeCurrent, bool allowAbortOnLowClutter) { //include the specific time it is now scheduled for whether repeating or not if (includeCurrent) { (DateTime? remindAt1, DateTime? remindAt2) = CalcPendingReminder(box); yield return(new AgendaEntry { Box = box, Time = box.BoxTime, PendingPrepReminder = remindAt1, PendingReminder = remindAt2 }); } bool doProjections = box.Repeats != null; if (allowAbortOnLowClutter && box.Visibility == Constants.VISIBILITY_LOWCLUTTER) { doProjections = false; } if (doProjections) { DateTime?max = DateUtil.ToDateTime(box.Repeats.EndTime); if (max == null) { max = DateTime.Today; } //convert add and delete exceptions to datetime strings and start with all the added ones var deleteExceptions = box.Repeats.Entries.Where(e => e.Kind == ParsedRepeatInfo.RepeatKind.DeleteSpecific) .Select(d => d.Date + d.Time); var addExceptions = box.Repeats.Entries.Where(e => e.Kind == ParsedRepeatInfo.RepeatKind.AddSpecific) .Select(d => d.Date + d.Time); var allTimes = new HashSet <string>(); foreach (string t in addExceptions) { allTimes.Add(t); } //go through all patterns and add times for those unless deleted foreach (var pat in box.Repeats.Entries) { //handle add and delete if (pat.Kind == ParsedRepeatInfo.RepeatKind.DeleteSpecific) { continue; } if (pat.Kind == ParsedRepeatInfo.RepeatKind.AddSpecific) { allTimes.Add(pat.Date + pat.Time); continue; } //handle all other pattern kinds (int hr, int mi) = DateUtil.ToHourMinute(pat.Time, 9, 0); DateTime?running = DateUtil.ToDateTime(box.BoxTime); if (running == null) { continue; } for (int iter = 0; iter < 500; ++iter) //infinite loop control { running = NextTime(running.Value, max.Value, pat, hr, mi); if (running == null) { break; } string t2 = DateUtil.ToYMDHM(running.Value); if (deleteExceptions.Contains(t2)) { continue; } allTimes.Add(t2); } } //provide return values foreach (string t in allTimes) { yield return(new AgendaEntry { Box = box, Time = t }); } } }