public static Predicate <object> GenerateDefaultNameFilter(string nameFilter, string shorthand) { return(new Predicate <object>(o => { BaseDataClass obj = (BaseDataClass)o; string name = obj.Name.RemoveWhitespace().ToUpperInvariant(); string sh = obj.Shorthand.RemoveWhitespace().ToUpperInvariant(); bool contains = name.Contains(nameFilter); if (nameFilter.Length < name.Length) { name = name.Substring(0, nameFilter.Length); } if (shorthand.Length < sh.Length) { sh = sh.Substring(0, shorthand.Length); } if (nameFilter.Length == 0 && shorthand.Length == 0) { return true; } if (contains && name.Length != 0) { return true; } bool nameCheck = name.Length != 0 && GenericHelpers.DamerauLevenshteinDistance(name, nameFilter, (nameFilter.Length + 1) / 2) != int.MaxValue; if (nameCheck) { return true; } bool shCheck = sh.Length != 0 && GenericHelpers.DamerauLevenshteinDistance(sh, shorthand, (sh.Length - 1) / 2) != int.MaxValue; if (shCheck) { return true; } return false; ; })); }
public Teacher() { Assignments.CollectionChanged += AssignmentsChanged; ErrorContainer no_periods = new ErrorContainer((e) => MaxPeriodsPerCycle == 0, (e) => "Teacher has no free periods.", ErrorType.Warning); no_periods.BindProperty(this, nameof(MaxPeriodsPerCycle)); ErrorList.Add(no_periods); ErrorContainer insuf_periods = new ErrorContainer((e) => { int assigned = Assignments.Sum(a => a.TotalPeriods); e.Data = assigned; return(MaxPeriodsPerCycle < assigned); }, (e) => $"Teacher has fewer free periods ({MaxPeriodsPerCycle}) than assigned periods ({e.Data}).", ErrorType.Error); insuf_periods.BindCollection(UnavailablePeriods); insuf_periods.BindCollection(Assignments); ErrorList.Add(insuf_periods); ErrorContainer lesson_missing = new ErrorContainer((e) => { IEnumerable <Assignment> assignmentMismatches = Assignments.Where(a => !Subjects.Contains(a.Lesson.Subject)); e.Data = assignmentMismatches; return(assignmentMismatches.Any()); }, (e) => { IEnumerable <Assignment> data = (IEnumerable <Assignment>)e.Data; return($"The following Assignments have a subject that the teacher does not have: {string.Join(", ", data.Select(a => a.TeacherString))}."); }, ErrorType.Warning); lesson_missing.BindCollection(Assignments); lesson_missing.BindCollection(Subjects); ErrorList.Add(lesson_missing); ErrorContainer insuf_lesson_slots = new ErrorContainer((e) => { IEnumerable <Lesson> errors = Assignments.Where(a => a.Lesson.LessonsPerCycle < a.Lesson.Assignments.Where(a2 => (a2.Teacher ?? this) != this).Sum(a2 => a2.LessonCount) + a.LessonCount ).Select(a => a.Lesson); e.Data = errors; return(errors.Any()); }, (e) => { IEnumerable <Lesson> errors = (IEnumerable <Lesson>)e.Data; return($"The following lessons happen more frequently per cycle than has been assigned: {GenericHelpers.FormatEnumerable(errors)}."); }, ErrorType.Warning); insuf_lesson_slots.BindCollection(Assignments); ErrorList.Add(lesson_missing); BindToErrors(); }
public void ImportFile(object sender, ExecutedRoutedEventArgs e) { string fpath = OpenFileDialogHelper(); if (fpath != null && fpath != App.FilePath) { ImportDialog window = new ImportDialog(ParentWindow); window.ShowDialog(); if (!window.DialogResult ?? false) { return; } LoadData(fpath, (complete) => { DataContainer dataContainer = (DataContainer)complete.Result; DataContainer currentContainer = App.Data; Dictionary <Type, ImportOption> typeImportMapping = new Dictionary <Type, ImportOption>() { { typeof(Teacher), window.ImportTeacher }, { typeof(Group), window.ImportGroup }, { typeof(Subject), window.ImportSubject }, { typeof(Form), window.ImportForm }, { typeof(Lesson), window.ImportLesson }, }; if (window.ImportAssignment == ImportOption.NoImport || window.ImportTeacher == ImportOption.NoImport || window.ImportLesson == ImportOption.NoImport) { foreach (Teacher teacher in currentContainer.Teachers) { teacher.Assignments.Clear(); } } if (window.ImportTimetable == ImportOption.Import) { TimetableStructure.SetData(dataContainer.TimetableStructure); } foreach (KeyValuePair <Type, ImportOption> mapping in typeImportMapping) { if (mapping.Value == ImportOption.Import) { ((IAddRange)currentContainer.FromType(mapping.Key)).AddRange(dataContainer.FromType(mapping.Key)); continue; } if (mapping.Value == ImportOption.Replace || mapping.Value == ImportOption.Merge) { foreach (BaseDataClass currentdata in currentContainer.FromType(mapping.Key).Cast <BaseDataClass>()) { Dictionary <string, BaseDataClass> nameMapping = dataContainer.FromType(mapping.Key).Cast <BaseDataClass>().ToDictionary(bdc => bdc.Name); if (!nameMapping.TryGetValue(currentdata.Name, out BaseDataClass similar)) { foreach (BaseDataClass target in nameMapping.Values) { int max = currentdata.Name.Length > target.Name.Length ? currentdata.Name.Length: target.Name.Length; if (GenericHelpers.DamerauLevenshteinDistance(currentdata.Name, target.Name, max * 3 / 8) != int.MaxValue) { if (System.Windows.MessageBox.Show($"'{currentdata.Name}' is similar to '{target.Name}'. Import '{currentdata.Name}'?", "Import?", MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes) { similar = currentdata; break; } } } } if (similar != null) { if (mapping.Value == ImportOption.Replace) { IList list = currentContainer.FromType(mapping.Key); list[list.IndexOf(similar)] = currentdata; continue; } similar.MergeFrom(currentdata); continue; } currentdata.Delete(currentContainer); continue; } //TODO: Unnecessary? foreach (BaseDataClass dataClass in currentContainer.FromType(mapping.Key)) { dataClass.Delete(currentContainer); } } } }, owner: ParentWindow, save: false); } }
public static void LinkList(this INotifyCollectionChanged collection, IList target) { collection.CollectionChanged += GenericHelpers.GenerateLinkHandler(target); }
public Lesson() { Subject = App.Data.NoneSubject; Assignments.CollectionChanged += AssignmentsChanged; ErrorContainer too_many_lessons = new ErrorContainer(e => LessonLength * LessonsPerCycle > TimetableStructure.TotalSchedulable, e => $"This lesson has a minimum of {LessonsPerCycle * LessonLength} periods per cycle, but there is a maximum of {TimetableStructure.TotalSchedulable} periods per cycle.", ErrorType.Critical);; too_many_lessons.BindProperty(this, nameof(LessonLength)); too_many_lessons.BindProperty(this, nameof(LessonsPerCycle)); ErrorList.Add(too_many_lessons); ErrorContainer too_many_assigned = new ErrorContainer(e => { int total = Assignments.Sum(a => a.LessonCount); e.Data = total; return(total > LessonsPerCycle); }, e => { int total = (int)e.Data; return($"This lesson has {total} lessons assigned, but there is supposed to be {LessonsPerCycle} in total"); }, ErrorType.Error); too_many_assigned.BindProperty(this, nameof(LessonsPerCycle)); too_many_assigned.BindCollection(Assignments); ErrorList.Add(too_many_assigned); ErrorContainer insuf_teacher_slots = new ErrorContainer((e) => { IEnumerable <Teacher> errors = Assignments.Where(a => a.Teacher.MaxPeriodsPerCycle < a.Teacher.Assignments.Where(a2 => (a2.Lesson ?? this) != this).Sum(a2 => a2.TotalPeriods) + a.TotalPeriods).Select(a => a.Teacher); e.Data = errors; return(errors.Any()); }, (e) => { IEnumerable <Lesson> errors = (IEnumerable <Lesson>)e.Data; return($"The following teachers have more periods assigned to them than they have available: {GenericHelpers.FormatEnumerable(errors)}."); }, ErrorType.Error); insuf_teacher_slots.BindCollection(Assignments); insuf_teacher_slots.BindProperty(this, nameof(LessonLength)); ErrorList.Add(insuf_teacher_slots); BindToErrors(); _prevent_gc_holder = Forms.ItemsProcessing <Form>( (f, ip, o, e) => DoConstraintCheck(f.YearGroup)); }