Class used for export to SVG and ICal.
        /// <summary> 
        /// Divides list of ExportLecture(s) to groups of overlapping lectures.
        /// </summary> 
        /// <returns> List of groups (group = another list) of ExportLecture(s) </returns>
        /// <param name="lectures">List of ExportLecture(s) to divide.</param>
        public List<List<ExportLecture>> divideToGroups(List<ExportLecture> lectures)
        {
            List<List<ExportLecture>> groups = new List<List<ExportLecture>>();
            groups.Add(new List<ExportLecture>());
            foreach (ExportLecture l in lectures)
            {
                var lastgroup = groups[groups.Count - 1];
                if (lastgroup.Count < 1)
                {
                    groups[groups.Count - 1].Add(l);
                }
                //Is lecture l starting sooner than end time of the last lecture in last group (with 10 minutes toleration)?
                else if (DateTime.Compare(l.StartTime, lastgroup.Max(lec => lec.StartTime + lec.Length - new TimeSpan(0, 10, 0))) < 0
                    && l.Day == lastgroup[lastgroup.Count - 1].Day)
                {
                    //All lectures intersecting with l
                    IEnumerable<ExportLecture> intersecting = lastgroup.Where(lec => (DateTime.Compare(l.StartTime, lec.StartTime + lec.Length - new TimeSpan(0, 10, 0)) < 0));
                    //Only have to worry about 3 and more lectures in one group
                    //If lecture l is intersecting with all of lectures in lastgroup then it belongs to the group
                    if (lastgroup.Count <= 1 || intersecting.Count() == lastgroup.Count)
                    {
                        lastgroup.Add(l);
                    }
                    //Otherwise create a new group with fake lectures
                    else
                    {
                        List<ExportLecture> newGroup = new List<ExportLecture>();
                        //Fake lectures from all last group lectures
                        foreach (ExportLecture lastGroupLec in lastgroup)
                        {

                            ExportLecture fakeLecture = null;
                            //Treat intersecting lectures as not null
                            if (intersecting.Contains(lastGroupLec))
                            {
                                fakeLecture = new ExportLecture(null, lastGroupLec.Day, lastGroupLec.StartTime, lastGroupLec.Length, null, null, null, true);
                            }
                            //Non-intersecting lecture are null = empty slots
                            newGroup.Add(fakeLecture);
                        }

                        //Find first empty slot in newGroup (null lecture) and swap with lecture l
                        int index = newGroup.FindIndex(lecture => lecture == null);
                        newGroup[index] = l;
                        //Finally remove all empty slots and add the newGroup to the groups
                        newGroup.RemoveAll(lecture => lecture == null);
                        groups.Add(newGroup);
                        lastgroup = newGroup;
                    }

                }
                else
                {
                    groups.Add(new List<ExportLecture>());
                    lastgroup = groups[groups.Count - 1];
                    lastgroup.Add(l);
                }
            }
            return groups;
        }
Example #2
0
        /// <summary> 
        /// Generates string in iCal format.
        /// </summary> 
        /// <returns> String following ICal format. </returns>
        /// <param name="lectures">List of lectures with IExportHodina interface to export.</param>
        /// <param name="semesterStart">Beginning of the semester. Only Year, Month and Day are used. </param>
        /// <param name="semesterEnd">End of the semester. Only Year, Month and Day are used. </param>
        public string generateICal(List<TimetableField> lectures, DateTime semesterStart, DateTime semesterEnd)
        {
            string header = "BEGIN:VCALENDAR" + System.Environment.NewLine + "VERSION:2.0" +
                System.Environment.NewLine + "PRODID:-//hacksw/handcal//NONSGML v1.0//EN" +
                System.Environment.NewLine;
            string body = "";

            foreach (TimetableField lecture in lectures)
            {
                var exportLecture = new ExportLecture(lecture);
                body += generateEventFromExportHodina(exportLecture, semesterStart, semesterEnd);
            }

            string tail = "END:VCALENDAR";

            return header + body + tail;
        }
        public void TestGenerate()
        {
            ExportLecture a = new ExportLecture("PredmetA", DayOfWeek.Monday, new DateTime(1, 1, 1, 7, 30, 0), new TimeSpan(2, 0, 0),
                "OsobaA", "MistnostA", "#99999", true);
            ExportLecture b = new ExportLecture("PredmetB", DayOfWeek.Tuesday, new DateTime(1, 1, 1, 17, 0, 0), new TimeSpan(1, 0, 0),
                "OsobaB", "MistnostB", "#99999", true);

            var hodiny = new List<ExportLecture>();
            hodiny.Add(a);
            hodiny.Add(b);

            DateTime semesterStart = new DateTime(2013, 9, 19);
            DateTime semesterEnd = new DateTime(2014, 2, 19);

            ICalGenerator gen = new ICalGenerator();

            string actualOutput = gen.generateICal(hodiny, semesterStart, semesterEnd);
            string stamp = gen.dateTimeDateToICalString(DateTime.Today) +
                gen.hourToICalString(DateTime.Now.Hour, DateTime.Now.Minute);
            string semStartA = gen.dateTimeDateToICalString(gen.closestDayFromDateTime(semesterStart, a.Day));
            string semStartB = gen.dateTimeDateToICalString(gen.closestDayFromDateTime(semesterStart, b.Day));
            string semEnd = gen.dateTimeDateToICalString(semesterEnd);

            string goodOutput = "BEGIN:VCALENDAR" + System.Environment.NewLine +
                    "VERSION:2.0" + System.Environment.NewLine +
                    "PRODID:-//hacksw/handcal//NONSGML v1.0//EN" + System.Environment.NewLine +
                    "BEGIN:VEVENT" + System.Environment.NewLine +
                    "DTSTAMP:" + stamp + System.Environment.NewLine +
                    "DTSTART:" + semStartA + "T073000" + System.Environment.NewLine +
                    "DTEND:" + semStartA + "T093000" + System.Environment.NewLine +
                    "RRULE:FREQ=WEEKLY;UNTIL=" + semEnd + "T000000Z" + System.Environment.NewLine +
                    "SUMMARY:PredmetA" + System.Environment.NewLine +
                    "LOCATION:MistnostA" + System.Environment.NewLine +
                    "END:VEVENT" + System.Environment.NewLine +
                    "BEGIN:VEVENT" + System.Environment.NewLine +
                    "DTSTAMP:" + stamp + System.Environment.NewLine +
                    "DTSTART:" + semStartB + "T170000" + System.Environment.NewLine +
                    "DTEND:" + semStartB + "T180000" + System.Environment.NewLine +
                    "RRULE:FREQ=WEEKLY;UNTIL=" + semEnd + "T000000Z" + System.Environment.NewLine +
                    "SUMMARY:PredmetB" + System.Environment.NewLine +
                    "LOCATION:MistnostB" + System.Environment.NewLine +
                    "END:VEVENT" + System.Environment.NewLine +
                    "END:VCALENDAR";
            Assert.AreEqual<string>(goodOutput, actualOutput);
        }
Example #4
0
        private string generateEventFromExportHodina(ExportLecture lecture, DateTime semesterStart, DateTime semesterEnd)
        {
            string semStart = dateTimeDateToICalString(
                closestDayFromDateTime(semesterStart, lecture.Day));
            string semEnd = dateTimeDateToICalString(semesterEnd);

            string head = "BEGIN:VEVENT" + System.Environment.NewLine;
            string stamp = "DTSTAMP:" + dateTimeDateToICalString(DateTime.Today) +
                hourToICalString(DateTime.Now.Hour, DateTime.Now.Minute) + System.Environment.NewLine;
            string start = "DTSTART:" + semStart +
                hourToICalString(lecture.StartTime.Hour, lecture.StartTime.Minute) +
                System.Environment.NewLine;
            string end = "DTEND:" + semStart +
                hourToICalString((lecture.StartTime + lecture.Length).Hour,
                (lecture.StartTime + lecture.Length).Minute) +
                System.Environment.NewLine;
            string repeat = "RRULE:FREQ=WEEKLY;UNTIL=" + semEnd + "T000000Z" +
                System.Environment.NewLine;
            string summarry = "SUMMARY:" + lecture.Name + System.Environment.NewLine;
            string loc = "LOCATION:" + lecture.Room + System.Environment.NewLine;
            string tail = "END:VEVENT" + System.Environment.NewLine;

            return head + stamp + start + end + repeat + summarry + loc + tail;
        }
Example #5
0
        private string RenderLecture(ExportLecture lecture, int split, int pos)
        {
            string res = "";

            double height = 50.0 / split;
            double width = xSpan(lecture.Length);
            double x = xStartHour(lecture.StartTime);
            double y = yStartDay(lecture.Day);
            double dy = height * pos;

            //Borders
            res += String.Format(new NumberFormatInfo(), "<rect height=\"{0}\" width=\"{1}\" y=\"{2}\" x=\"{3}\" class=\"cardBack\" fill=\"#fff\"/>",
               height, width, y + dy, x) + System.Environment.NewLine;
            //x="{$x + 1}" y="{$y + $dy + 1}" width="{$width - 2}" height="{$height - 2}"
            res += String.Format(new NumberFormatInfo(), "<rect stroke-opacity=\"0.5\" fill-opacity=\"0\" height=\"{0}\" width=\"{1}\" stroke=\"{4}\" y=\"{2}\" x=\"{3}\" stroke-width=\"2\" class=\"cardFrame\"/>",
                height - 2, width - 2, y + dy + 1, x + 1, lecture.DepartementColor) + System.Environment.NewLine;

            if (split >= 3)
            {
                //Fills
                res += String.Format(new NumberFormatInfo(), "<rect height=\"{0}\" width=\"{1}\" y=\"{2}\" x=\"{3}\" class=\"cardTop\" fill=\"{4}\"/>",
                    height / (4 - split), width, y + dy, x, lecture.DepartementColor) + System.Environment.NewLine;
                //Texts
                //x="{$x + $width div 2}" y="{$y + $dy + $height div 5 * 2 + 6}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"stroke-width: 2px; stroke: #fff; stroke-linejoin: miter; font-size: 12px; font-weight: bold; text-anchor: middle; font-family: sans-serif;\">{2}</text>",
                    y + dy + height / 5 * 2 + 6, x + width / 2, lecture.Name) + System.Environment.NewLine;
                //x="{$x + $width div 2}" y="{$y + $dy + $height div 5 * 2 + 6 }"
                //if red in krbalek then it have class=\"label&#10; periodic\"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"font-size: 12px; font-weight: bold; text-anchor: middle; font-family: sans-serif;\" class=\"label&#10; {3}\">{2}</text>",
                    y + dy + height / 5 * 2 + 6, x + width / 2, lecture.Name, lecture.RegularLecture ? "" : "periodic") + System.Environment.NewLine;
                //Room
                //x="{$x + $width - 5}" y="{$y + $dy + $height - 3}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"fill: #000; font-size: 9px; text-anchor: end; font-family: sans-serif;\" class=\"classroomText\">{2}</text>",
                    y + dy + height - 5, x + width - 5, lecture.Room) + System.Environment.NewLine;
                //Lecturer
                //x="{$x + 5}" y="{$y + $dy + $height - 3}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"fill: #000; font-size:9px; text-anchor: start; font-family: sans-serif;\" class=\"lecturerText\">{2}</text>",
                    y + dy + height - 5, x + 5, lecture.Lecturer) + System.Environment.NewLine;
            }
            else
            {
                //Fills
                //x="{$x}" y="{$y + $dy}" width="{$width}" height="{$height - $height div (4 - $split)}"
                res += String.Format(new NumberFormatInfo(), "<rect height=\"{0}\" width=\"{1}\" y=\"{2}\" x=\"{3}\" class=\"cardTop\" fill=\"{4}\"/>",
                    height - (height / (4 - split)), width, y + dy, x, lecture.DepartementColor) + System.Environment.NewLine;
                //x="{$x}" y="{$y + $dy + $height - $height * 1 div (4 - $split)}" width="{$width}" height="{$height div (4 - $split)}"
                res += String.Format(new NumberFormatInfo(), "<rect height=\"{0}\" width=\"{1}\" y=\"{2}\" x=\"{3}\" class=\"cardBottom\" fill=\"#fff\"/>",
                    height / (4 - split), width, y + dy + (height - (height / (4 - split))), x) + System.Environment.NewLine;
                //Texts
                //x="{$x + $width div 2}" y="{$y + $dy + $height div 5 * 2 + 4 - $split * 2}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"stroke-width: 2px; stroke: #fff; stroke-linejoin: miter;  font-size: 12px; font-weight: bold; text-anchor: middle; font-family: sans-serif;\">{2}</text>",
                    y + dy + height / 5 * 2 + 4 - split * 2, x + width / 2, lecture.Name) + System.Environment.NewLine;
                //x="{$x + $width div 2}" y="{$y + $dy + $height div 5 * 2 + 4 - $split * 2}"
                //if red in krbalek then it have class=\"label&#10; periodic\"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"font-size: 12px; font-weight: bold; text-anchor: middle; font-family: sans-serif;\" class=\"label&#10; {3}\">{2}</text>",
                    y + dy + height / 5 * 2 + 4 - split * 2, x + width / 2, lecture.Name, lecture.RegularLecture ? "" : "periodic") + System.Environment.NewLine;
                //Room
                //x="{$x + $width - 5}" y="{$y + $dy + $height - 6 + $split}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"fill: #000; font-size: 9px; text-anchor: end; font-family: sans-serif;\" class=\"classroomText\">{2}</text>",
                    y + dy + height - 6 + split, x + width - 5, lecture.Room) + System.Environment.NewLine;

                //Lecturer
                //x="{$x + 5}" y="{$y + $dy + $height - 6 + $split}"
                res += String.Format(new NumberFormatInfo(), "<text y=\"{0}\" x=\"{1}\" style=\"fill: #000; font-size:9px; text-anchor: start; font-family: sans-serif;\" class=\"lecturerText\">{2}</text>",
                    y + dy + height - 6 + split, x + 5, lecture.Lecturer) + System.Environment.NewLine;
            }

            return res;
        }