public static SchedulesOnDay Get(IEnumerable <ViewItemClass> classes, DateTime date, Schedule.Week week, bool trackChanges = false) { SchedulesOnDay answer; for (int i = 0; i < _cached.Count; i++) { if (_cached[i].TryGetTarget(out answer)) { if (answer.Date == date.Date && answer.Classes == classes) { if (trackChanges) { return(answer); } else { return(new SchedulesOnDay(answer)); } } } else { _cached.RemoveAt(i); i--; } } answer = new SchedulesOnDay(classes, date, week, trackChanges); if (trackChanges) { _cached.Add(new WeakReference <SchedulesOnDay>(answer)); } return(answer); }
private DayScheduleItemsArranger(AccountDataItem account, SemesterItemsViewGroup semesterItems, ScheduleViewItemsGroup scheduleGroup, DateTime date, double heightOfHour, double spacingWhenNoAdditionalItems, double spacingWithAdditionalItems, double widthOfCollapsed, bool includeTasksAndEventsAndHolidays) { if (semesterItems.Semester == null) { throw new NullReferenceException("Semester was null"); } _semesterItems = semesterItems; semesterItems.OnItemsChanged += new WeakEventHandler <EventArgs>(SemesterGroup_OnItemsChanged).Handler; scheduleGroup.OnChangesOccurred += new WeakEventHandler <DataChangedEvent>(ScheduleViewItemsGroup_OnChangesOccurred).Handler; Date = date; _spacingWhenNoAdditionalItems = spacingWhenNoAdditionalItems; _spacingWithAdditionalItems = spacingWithAdditionalItems; _widthOfCollapsed = widthOfCollapsed; Account = account; _schoolTimeZone = account.SchoolTimeZone; HeightOfHour = heightOfHour; MinDuration = TimeSpan.FromHours(widthOfCollapsed / HeightOfHour); IsDifferentSemester = !semesterItems.Semester.IsDateDuringThisSemester(date); SchedulesOnDay schedules = null; if (!IsDifferentSemester) { schedules = SchedulesOnDay.Get(account, semesterItems.Classes, date, account.GetWeekOnDifferentDate(date), trackChanges: true); schedules.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(Schedules_CollectionChanged).Handler; } _schedules = schedules; if (includeTasksAndEventsAndHolidays) { // For schedules, if tasks have a specific due time, we don't adjust the dates regardless of time zones causing them to switch to a different day, since they're displayed on the visual schedule. Therefore we set useEffectiveDatesEvenWhenItemsHaveTimes to false. _events = TasksOrEventsOnDay.Get(account, semesterItems.Items, date, today: null, activeOnly: false, useEffectiveDateEvenWhenItemsHaveTimes: false); _events.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(Events_CollectionChanged).Handler; } else { _events = new MyObservableList <BaseViewItemMegaItem>(); } if (includeTasksAndEventsAndHolidays) { _holidays = HolidaysOnDay.Create(semesterItems.Items, date); _holidays.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(_holidays_CollectionChanged).Handler; } else { _holidays = new MyObservableList <ViewItemHoliday>(); } Initialize(schedules, _events, _holidays); }
private DayScheduleItemsArranger(AccountDataItem account, SemesterItemsViewGroup semesterItems, ScheduleViewItemsGroup scheduleGroup, DateTime date, double heightOfHour, double spacingWhenNoAdditionalItems, double spacingWithAdditionalItems, double widthOfCollapsed, bool includeHomeworkAndHolidays) { if (semesterItems.Semester == null) { throw new NullReferenceException("Semester was null"); } _semesterItems = semesterItems; semesterItems.OnItemsChanged += new WeakEventHandler <EventArgs>(SemesterGroup_OnItemsChanged).Handler; scheduleGroup.OnChangesOccurred += new WeakEventHandler <DataChangedEvent>(ScheduleViewItemsGroup_OnChangesOccurred).Handler; Date = date; _spacingWhenNoAdditionalItems = spacingWhenNoAdditionalItems; _spacingWithAdditionalItems = spacingWithAdditionalItems; _widthOfCollapsed = widthOfCollapsed; Account = account; _schoolTimeZone = account.SchoolTimeZone; HeightOfHour = heightOfHour; MinDuration = TimeSpan.FromHours(widthOfCollapsed / HeightOfHour); IsDifferentSemester = !semesterItems.Semester.IsDateDuringThisSemester(date); SchedulesOnDay schedules = null; if (!IsDifferentSemester) { schedules = SchedulesOnDay.Get(semesterItems.Classes, date, account.GetWeekOnDifferentDate(date), trackChanges: true); schedules.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(Schedules_CollectionChanged).Handler; } _schedules = schedules; if (includeHomeworkAndHolidays) { _events = HomeworksOnDay.Get(semesterItems.Items, date); _events.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(Events_CollectionChanged).Handler; } else { _events = new MyObservableList <BaseViewItemHomeworkExamGrade>(); } if (includeHomeworkAndHolidays) { _holidays = HolidaysOnDay.Create(semesterItems.Items, date); _holidays.CollectionChanged += new WeakEventHandler <NotifyCollectionChangedEventArgs>(_holidays_CollectionChanged).Handler; } else { _holidays = new MyObservableList <ViewItemHoliday>(); } Initialize(schedules, _events, _holidays); }
private void Initialize(SchedulesOnDay schedules, MyObservableList <BaseViewItemHomeworkExamGrade> events, MyObservableList <ViewItemHoliday> holidays) { List <ScheduleItem> schedulesCopied; if (schedules == null) { // Different semester case, so no schedules schedulesCopied = new List <ScheduleItem>(); } else { schedulesCopied = schedules.Where(i => i.EndTime.TimeOfDay > i.StartTime.TimeOfDay).Select(i => new ScheduleItem(this, i)).ToList(); } List <EventItem> eventsCopied = new List <EventItem>(); List <BaseViewItemHomeworkExam> allDayEvents = new List <ViewItems.BaseViewItems.BaseViewItemHomeworkExam>(); foreach (var e in events.OfType <BaseViewItemHomeworkExam>()) { if (e.IsDuringDay()) { eventsCopied.Add(new EventItem(this, e)); } else { allDayEvents.Add(e); } } AllDayItems = allDayEvents; Holidays = holidays.ToList(); HasHolidays = Holidays.Any(); _cachedHolidayAndAllDayItems = null; var schedulesFinal = schedulesCopied.ToArray(); var eventsFinal = eventsCopied.ToList(); ScheduleItems = schedulesFinal; // Handle schedule collisions while (schedulesCopied.Count > 0) { var collidingSchedules = new List <ScheduleItem>() { schedulesCopied[0] }; schedulesCopied.RemoveAt(0); AddColliding(schedulesCopied, collidingSchedules); if (collidingSchedules.Count > 1) { for (int i = 0; i < collidingSchedules.Count; i++) { collidingSchedules[i].Column = i; collidingSchedules[i].NumOfColumns = collidingSchedules.Count; } } } // Handle event collisions while (eventsCopied.Count > 0) { var collidingEvents = new List <EventItem>() { eventsCopied[0] }; eventsCopied.RemoveAt(0); AddColliding(eventsCopied, collidingEvents); List <ScheduleItem> scheduleCollisionsWithEvent = new List <ScheduleItem>(); // If there's a colliding schedule, we collapse bool doesCollideWithSchedule = false; foreach (var e in collidingEvents) { foreach (var s in schedulesFinal) { if (s.CollidesWith(e)) { doesCollideWithSchedule = true; scheduleCollisionsWithEvent.Add(s); } } } if (doesCollideWithSchedule) { var firstEvent = collidingEvents[0]; firstEvent.IsCollapsedMode = true; foreach (var e in collidingEvents.Skip(1)) { firstEvent.AddAdditionalItem(e); eventsFinal.Remove(e); } foreach (var s in scheduleCollisionsWithEvent) { if (firstEvent.AdditionalItems != null) { s.LeftOffset = _spacingWithAdditionalItems; } else { // LeftOffset might have been previously assigned, so make sure we're assigning higher value if (_spacingWhenNoAdditionalItems > s.LeftOffset) { s.LeftOffset = _spacingWhenNoAdditionalItems; } } } } else if (collidingEvents.Count == 1) { // Nothing } else if (collidingEvents.Count == 2) { // Exactly two items collidingEvents[0].NumOfColumns = 2; collidingEvents[1].NumOfColumns = 2; collidingEvents[1].Column = 1; } else { // More than two items EventItem prev = null; bool isLeftSide = true; while (collidingEvents.Count > 0) { var curr = collidingEvents[0]; curr.NumOfColumns = 2; collidingEvents.RemoveAt(0); if (prev != null) { if (!isLeftSide) { curr.Column = 1; } // Find out if any items collide with the prev item, and therefore need to become mini-items with the curr item while (collidingEvents.Count > 0) { var next = collidingEvents[0]; if (prev.CollidesWith(next)) { collidingEvents.RemoveAt(0); curr.AddAdditionalItem(next); eventsFinal.Remove(next); } else { break; } } } // Prev becomes curr prev = curr; // And we switch the side isLeftSide = !isLeftSide; } } } EventItems = eventsFinal.ToArray(); if (ScheduleItems.Any() || EventItems.Any()) { var min = ScheduleItems.OfType <BaseScheduleItem>().Concat(EventItems.OfType <BaseScheduleItem>()).Min(i => i.StartTime); if (min.Minutes == 59 && min.Hours != 23) { // So that a task that's due before class (1 min before) doesn't cause an entire hour to be rendered, we adjust 0:59 to the next hour // Note that we exclude incrementing 23:59 since that would make it the next day min = min.Add(TimeSpan.FromMinutes(1)); } StartTime = new TimeSpan(min.Hours, 0, 0); EndTime = new TimeSpan(ScheduleItems.OfType <BaseScheduleItem>().Concat(EventItems.OfType <BaseScheduleItem>()).Max(i => i.EndTime).Hours, 0, 0); if (EndTime < StartTime) { EndTime = StartTime.Add(TimeSpan.FromHours(1)); } } CalculateOffsets(); }
private SchedulesOnDay(SchedulesOnDay other) { base.AddRange(other); }