diff --git a/TimetableDesigner.Core/Unit.cs b/TimetableDesigner.Core/Unit.cs new file mode 100644 index 0000000..f08a740 --- /dev/null +++ b/TimetableDesigner.Core/Unit.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace TimetableDesigner.Core +{ + [Serializable] + public abstract class Unit + { + #region FIELDS + + private ulong _id; + private Guid _guid; + private string _name; + + #endregion + + + + #region PROPERTIES + + public ulong Id => _id; + public Guid Guid => _guid; + public string Name + { + get => _name; + set => _name = value; + } + + #endregion + + + + #region CONSTRUCTORS + + public Unit(ulong id) + { + _id = id; + _guid = Guid.NewGuid(); + _name = string.Empty; + } + + #endregion + } +} diff --git a/TimetableDesigner.Export/Exporter.cs b/TimetableDesigner.Export/Exporter.cs new file mode 100644 index 0000000..c509648 --- /dev/null +++ b/TimetableDesigner.Export/Exporter.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TimetableDesigner.Core; + +namespace TimetableDesigner.Export +{ + public abstract class Exporter + { + #region FIELDS + + protected Project _project; + protected HashSet _groups; + protected HashSet _subgroups; + protected HashSet _teachers; + protected HashSet _classrooms; + + #endregion + + + + #region PROPERTIES + + public ICollection Groups => _groups; + public ICollection Subgroups => _subgroups; + public ICollection Teachers => _teachers; + public ICollection Classrooms => _classrooms; + + + #endregion + + + + #region CONSTRUCTORS + + protected Exporter(Project project) + { + _project = project; + _groups = new HashSet(); + _subgroups = new HashSet(); + _teachers = new HashSet(); + _classrooms = new HashSet(); + } + + #endregion + + + + #region PUBLIC METHODS + + public abstract void Export(string path); + + #endregion + } +} diff --git a/TimetableDesigner.Export/ExporterHTML.cs b/TimetableDesigner.Export/ExporterHTML.cs new file mode 100644 index 0000000..88930d6 --- /dev/null +++ b/TimetableDesigner.Export/ExporterHTML.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TimetableDesigner.Core; + +namespace TimetableDesigner.Export +{ + public class ExporterHTML : Exporter + { + #region CONSTRUCTORS + + public ExporterHTML(Project project) : base(project) { } + + #endregion + + + + #region PUBLIC METHODS + + public override void Export(string path) => Export(path, null); + public void Export(string path, string? css) + { + string content = BuildDocument(css); + + using (StreamWriter writer = new StreamWriter(path)) + { + writer.WriteLine(content); + } + } + + #endregion + + + + #region PRIVATE METHODS + + private string BuildDocument(string? css) + { + if (css == null) + { + StringBuilder cssBuilder = new StringBuilder(); + cssBuilder.AppendLine("h1 {text-align: center;}"); + cssBuilder.AppendLine("table, td, th { border: 1px solid black; border-collapse: collapse; }"); + cssBuilder.AppendLine("td, th { padding: 10px; }"); + css = cssBuilder.ToString(); + } + + StringBuilder builder = new StringBuilder(); + + builder.AppendLine(""); + builder.AppendLine(""); + builder.AppendLine(""); + builder.AppendLine(""); + builder.AppendLine(""); + + if (Groups.Count > 0) + { + builder.AppendLine("

Groups

"); + + foreach (Group group in Groups) + { + builder.AppendLine("

"); + builder.AppendLine(group.Name); + builder.AppendLine("

"); + builder.AppendLine(BuildTable(group)); + } + } + + if (Subgroups.Count > 0) + { + builder.AppendLine("

Subgroups

"); + + foreach (Subgroup subgroup in Subgroups) + { + builder.AppendLine("

"); + builder.AppendLine(subgroup.Name); + builder.AppendLine("

"); + builder.AppendLine(BuildTable(subgroup)); + } + } + + if (Teachers.Count > 0) + { + builder.AppendLine("

Teachers

"); + + foreach (Teacher teacher in Teachers) + { + builder.AppendLine("

"); + builder.AppendLine(teacher.Name); + builder.AppendLine("

"); + builder.AppendLine(BuildTable(teacher)); + } + } + + if (Classrooms.Count > 0) + { + builder.AppendLine("

Classrooms

"); + + foreach (Classroom classroom in Classrooms) + { + builder.AppendLine("

"); + builder.AppendLine(classroom.Name); + builder.AppendLine("

"); + builder.AppendLine(BuildTable(classroom)); + } + } + + builder.AppendLine(""); + builder.AppendLine(""); + + return builder.ToString(); + } + + private string BuildTable(Unit unit) + { + IEnumerable classes = _project.Classes.Where(c => c.Classroom == unit || c.Teacher == unit || c.Group == unit || (unit is Group g && c.Group is Subgroup s && g.AssignedSubgroups.Contains(s))) + .Where(c => c.Slot is not null && c.Day is not null); + IEnumerable days = _project.TimetableTemplate.Days; + IEnumerable slots = _project.TimetableTemplate.Slots; + + StringBuilder builder = new StringBuilder(); + + builder.AppendLine(""); + builder.AppendLine(""); + builder.AppendLine(""); + foreach (TimetableDay day in days) + { + builder.AppendLine($""); + } + builder.AppendLine(""); + foreach (TimetableSpan slot in slots) + { + builder.AppendLine(""); + builder.AppendLine($""); + foreach (TimetableDay day in days) + { + IEnumerable slotClasses = classes.Where(x => x.Day == day && x.Slot == slot); + + builder.AppendLine(""); + } + builder.AppendLine(""); + } + builder.AppendLine("
{day.Name}
{slot}"); + foreach (Class slotClass in slotClasses) + { + string group = slotClass.Group is null ? "none" : slotClass.Group.Name; + string teacher = slotClass.Teacher is null ? "none" : slotClass.Teacher.Name; + string classroom = slotClass.Classroom is null ? "none" : slotClass.Classroom.Name; + builder.AppendLine($"

"); + builder.AppendLine(slotClass.Name); + builder.AppendLine("

"); + } + builder.AppendLine("
"); + + return builder.ToString(); + + } + + #endregion + } +} diff --git a/TimetableDesigner.Scheduler/TimetableDesigner.Scheduler.csproj b/TimetableDesigner.Export/TimetableDesigner.Export.csproj similarity index 62% rename from TimetableDesigner.Scheduler/TimetableDesigner.Scheduler.csproj rename to TimetableDesigner.Export/TimetableDesigner.Export.csproj index cfadb03..a9f5fbe 100644 --- a/TimetableDesigner.Scheduler/TimetableDesigner.Scheduler.csproj +++ b/TimetableDesigner.Export/TimetableDesigner.Export.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/TimetableDesigner.Scheduler/Scheduler.cs b/TimetableDesigner.Scheduler/Scheduler.cs deleted file mode 100644 index b632a26..0000000 --- a/TimetableDesigner.Scheduler/Scheduler.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace TimetableDesigner.Scheduler -{ - public class Class1 - { - - } -} \ No newline at end of file diff --git a/TimetableDesigner/Resources/Images/HTML.png b/TimetableDesigner/Resources/Images/HTML.png new file mode 100644 index 0000000..be3bf78 Binary files /dev/null and b/TimetableDesigner/Resources/Images/HTML.png differ diff --git a/TimetableDesigner/Resources/Images/Import.png b/TimetableDesigner/Resources/Images/Import.png new file mode 100644 index 0000000..9e08cac Binary files /dev/null and b/TimetableDesigner/Resources/Images/Import.png differ diff --git a/TimetableDesigner/ViewModels/Views/ExportHTMLViewVM.cs b/TimetableDesigner/ViewModels/Views/ExportHTMLViewVM.cs new file mode 100644 index 0000000..9dbd9cd --- /dev/null +++ b/TimetableDesigner/ViewModels/Views/ExportHTMLViewVM.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using System.Xml.Serialization; +using TimetableDesigner.Commands; +using TimetableDesigner.Core; +using TimetableDesigner.Customs; +using TimetableDesigner.Export; +using TimetableDesigner.Services.FileDialog; +using TimetableDesigner.Services.MessageBox; +using TimetableDesigner.Services.Project; +using TimetableDesigner.ViewModels.Models; + +namespace TimetableDesigner.ViewModels.Views +{ + public class ExportHTMLViewVM : ObservableObject, IViewVM + { + #region FIELDS + + private readonly IProjectService _projectService; + private readonly IFileDialogService _fileDialogService; + private readonly IMessageBoxService _messageBoxSercvice; + + #endregion + + + + #region PROPERTIES + + public ObservableDictionary Groups { get; set; } + public ObservableDictionary Subgroups { get; set; } + public ObservableDictionary Teachers { get; set; } + public ObservableDictionary Classrooms { get; set; } + + public ICommand ExportCommand { get; set; } + + #endregion + + + + #region CONSTRUCTORS + + public ExportHTMLViewVM() + { + _projectService = ServiceProvider.Instance.GetService(); + _fileDialogService = ServiceProvider.Instance.GetService(); + _messageBoxSercvice = ServiceProvider.Instance.GetService(); + + ObservableCollection groups = _projectService.ProjectViewModel.Groups; + groups.CollectionChanged += Groups_CollectionChanged; + Groups = new ObservableDictionary(groups.ToDictionary(x => x, x => true)); + + ObservableCollection subgroups = _projectService.ProjectViewModel.Subgroups; + subgroups.CollectionChanged += Subgroups_CollectionChanged; + Subgroups = new ObservableDictionary(subgroups.ToDictionary(x => x, x => true)); + + ObservableCollection teachers = _projectService.ProjectViewModel.Teachers; + teachers.CollectionChanged += Teachers_CollectionChanged; + Teachers = new ObservableDictionary(teachers.ToDictionary(x => x, x => true)); + + ObservableCollection classrooms = _projectService.ProjectViewModel.Classrooms; + classrooms.CollectionChanged += Classrooms_CollectionChanged; + Classrooms = new ObservableDictionary(classrooms.ToDictionary(x => x, x => true)); + + ExportCommand = new RelayCommand(a => Export()); + } + + #endregion + + + + #region PRIVATE METHODS + + private void Export() + { + Dictionary> types = new Dictionary>() + { + { "HTML", new List { "html" } } + }; + string? path = _fileDialogService.SaveFile(types); + if (path is null) + { + return; + } + + Project project = _projectService.Project; + IEnumerable groups = Groups.Cast>().Where(x => x.Value).Select(x => x.Key.Group); + IEnumerable subgroups = Subgroups.Cast>().Where(x => x.Value).Select(x => x.Key.Subgroup); + IEnumerable teachers = Teachers.Cast>().Where(x => x.Value).Select(x => x.Key.Teacher); + IEnumerable classrooms = Classrooms.Cast>().Where(x => x.Value).Select(x => x.Key.Classroom); + + Exporter exporter = new ExporterHTML(project); + foreach (Group group in groups) + { + exporter.Groups.Add(group); + } + foreach (Subgroup subgroup in subgroups) + { + exporter.Subgroups.Add(subgroup); + } + foreach (Teacher teacher in teachers) + { + exporter.Teachers.Add(teacher); + } + foreach (Classroom classroom in classrooms) + { + exporter.Classrooms.Add(classroom); + } + exporter.Export(path); + + _messageBoxSercvice.ShowInformation("Data was exported successfully"); + } + + private void Groups_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + if (e.OldItems is not null) + { + foreach (GroupVM vm in e.OldItems) + { + Groups.Remove(vm); + } + } + + if (e.NewItems is not null) + { + foreach (GroupVM vm in e.NewItems) + { + Groups.Add(vm, true); + } + } + } + + private void Subgroups_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + if (e.OldItems is not null) + { + foreach (SubgroupVM vm in e.OldItems) + { + Subgroups.Remove(vm); + } + } + + if (e.NewItems is not null) + { + foreach (SubgroupVM vm in e.NewItems) + { + Subgroups.Add(vm, true); + } + } + } + + private void Teachers_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + if (e.OldItems is not null) + { + foreach (TeacherVM vm in e.OldItems) + { + Teachers.Remove(vm); + } + } + + if (e.NewItems is not null) + { + foreach (TeacherVM vm in e.NewItems) + { + Teachers.Add(vm, true); + } + } + } + + private void Classrooms_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + if (e.OldItems is not null) + { + foreach (ClassroomVM vm in e.OldItems) + { + Classrooms.Remove(vm); + } + } + + if (e.NewItems is not null) + { + foreach (ClassroomVM vm in e.NewItems) + { + Classrooms.Add(vm, true); + } + } + } + + #endregion + } +} diff --git a/TimetableDesigner/Views/ExportHTMLView.xaml b/TimetableDesigner/Views/ExportHTMLView.xaml new file mode 100644 index 0000000..a18f2db --- /dev/null +++ b/TimetableDesigner/Views/ExportHTMLView.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +