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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
 }