Example #1
0
        /// <summary>
        /// This will create a timetable file from a studentDataBundle instance
        /// </summary>
        /// <param name="studentDataBundle">The timetable to save</param>
        /// <returns></returns>
        public static async Task <bool> CreateTimetable(StudentDataBundle studentDataBundle)
        {
            var found = false; //whether a timetable with the same name exists

            try
            {
                //try to get timetable file with same name
                await DataFolder.GetFileAsync(studentDataBundle.Name + ".tb");
            }
            catch
            {
                found = true;
            }

            //if it's found , then it cannot be made. Another name must be chosen
            if (!found)
            {
                var dialog = new MessageDialog("A StudentDataBundle with that name already exists.\nPlease chooose another name.", "Oops");
                await dialog.ShowAsync();

                return(false);
            }
            else
            {
                //create the file and asynchronously serialize the data bundle to xml then add the object to the list
                StorageFile file = await DataFolder.CreateFileAsync(studentDataBundle.Name + ".tb");

                Stream filestream = await file.OpenStreamForWriteAsync();

                await Task.Run(() => Serializer.Serialize(filestream, studentDataBundle));

                Timetables.Add(studentDataBundle);
                return(true);//return success
            }
        }
Example #2
0
        public void FillWith(StudentDataBundle studentDataBundle)
        {
            timeLabels.Children.Clear();
            root.Children.Clear();
            if (studentDataBundle.Courses.Count > 0 && studentDataBundle.GetTotalInstances() > 0)
            {
                lowerBound = CoreTime.GetEarliest(studentDataBundle);
                upperBound = CoreTime.GetLatest(studentDataBundle);

                //set size based on whether there is a weekedend or not
                labelContainer.Width = ((studentDataBundle.hasWeekend()) ? 7 : 5) * Constants.EventControlWidth;
                this.Width           = Constants.EventControlWidth * ((studentDataBundle.hasWeekend()) ? 7 : 5) + 43;

                this.Height = (upperBound.TotalMinutes - lowerBound.TotalMinutes) / 60 * Constants.EventControlHeight + 43;


                for (int x = 0; x < studentDataBundle.Courses.Count; x++)
                {
                    Course model = studentDataBundle.Courses[x];
                    foreach (Instance instance in model.Instances)
                    {
                        //foreach instance we
                        EventControl cont = new EventControl(model);                                                                              //create a control
                        cont.setTime(instance.StartTime, instance.EndTime);                                                                       //set the text
                        instances[instance.Day].Add(cont);                                                                                        //add it to the appropiate list
                        root.Children.Add(cont);                                                                                                  //add it to the view
                        Canvas.SetLeft(cont, Constants.EventControlWidth * instance.Day);                                                         //set it at the x coord and y coord
                        Canvas.SetTop(cont, ((instance.StartTime.TotalMinutes - lowerBound.TotalMinutes) / 60.0) * Constants.EventControlHeight); //take lenght in account (i.e 2 hour lesson)
                        double dt     = (instance.EndTime.TotalMinutes - instance.StartTime.TotalMinutes);
                        double height = dt / 60;
                        cont.Height = height * Constants.EventControlHeight; //set the height proportionately to the duration
                    }
                }

                //create the time labels and the outline lines
                for (int x = lowerBound.TotalMinutes; x <= upperBound.TotalMinutes; x += 30)
                {
                    TextBlock block = new TextBlock {
                        FontSize = (x % 60 == 0) ? 12 : 10
                    };
                    //block.Text = string.Format("{0}:{1}", ((int)x / 60).ToString(), ((x % 60)).ToString());
                    // block.Text = (x / 60).ToString() + ":00";
                    double hours = x / 60.0;
                    block.Text = Math.Truncate(hours).ToString() + ":" + ((hours - Math.Truncate(hours)) * 60).ToString();
                    timeLabels.Children.Add(block);
                    Canvas.SetLeft(block, 0);
                    Canvas.SetTop(block, Constants.EventControlHeight * ((x - lowerBound.TotalMinutes) / 60.0) - block.ActualHeight);

                    Line indicator = new Line {
                        Stroke = new SolidColorBrush(Colors.DarkGray), StrokeThickness = 1
                    };
                    root.Children.Add(indicator);
                    indicator.X1 = 0;
                    indicator.Y1 = Constants.EventControlHeight * ((x - lowerBound.TotalMinutes) / 60.0);
                    indicator.X2 = Constants.EventControlWidth * ((studentDataBundle.hasWeekend()) ? 7 : 5) + timeLabels.ActualWidth;
                    indicator.Y2 = indicator.Y1;
                    Canvas.SetZIndex(indicator, -1);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Export a timetable to a .tb file
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static async Task <bool> ExportTimetable(StudentDataBundle table)
        {
            //file picker to let the use choose a file
            FileSavePicker saver = new FileSavePicker();

            saver.DefaultFileExtension   = ".tb";
            saver.SuggestedFileName      = table.Name;
            saver.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            saver.FileTypeChoices.Add("StudentDataBundle file", new List <string> {
                ".tb"
            });                                                 //.tb is the file extension
            StorageFile file = await saver.PickSaveFileAsync(); //le the use pick a file

            //if the use did not press Cancel , it should not be null , so write to it
            if (file != null)
            {
                Stream stream = await file.OpenStreamForWriteAsync();

                await Task.Run(() =>
                {
                    Serializer.Serialize(stream, table);
                });
            }
            return(true);
        }
Example #4
0
 public InstanceControl(Instance instance, StudentDataBundle studentDataBundle)
 {
     this.InitializeComponent();
     this.Loaded += InstanceControl_Loaded;
     self         = instance;
     selfParent   = studentDataBundle;
 }
Example #5
0
        /// <summary>
        /// Fills the list with all the timetables
        /// </summary>
        /// <returns></returns>
        public static async Task <bool> GetTimetables()
        {
            Timetables.Clear();                           //empty it just in case it has data
            var success = true;                           //assume it works

            var names = await DataFolder.GetFilesAsync(); //list of all files in data folder

            foreach (var name in names)
            {
                Stream st = await name.OpenStreamForReadAsync();    //open a read-only data stream

                //asynchrnously deserialize each file
                await Task.Run(() =>
                {
                    try
                    {
                        StudentDataBundle table = Serializer.Deserialize(st) as StudentDataBundle;

                        Timetables.Add(table);
                    }
                    catch
                    {
                        success = false;
                    }
                });

                st.Dispose();
            }
            return(success);
        }
 public TimetableBox(StudentDataBundle table)
 {
     this.InitializeComponent();
     _name.Text        = table.Name;
     _description.Text = table.Description;
     _nameLabel.Text   = table.Name;
     self = table;
     preview.FillWith(self);
 }
Example #7
0
 public void FillWith(ref StudentDataBundle tb)
 {
     root.Children.Clear();
     currentTarget = tb;
     for (int x = 0; x < tb.Courses.Count; x++)
     {
         Course temp = tb.Courses[x];
         addEvent(temp);
     }
 }
Example #8
0
        public void FillWith(StudentDataBundle table)
        {
            nextPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
            description.Text     = table.Description;
            Course earliest = new Course {
                Name = "null"
            };
            Instance earliestInstance = new Instance {
                StartTime = Time.MaximumTime, EndTime = Time.MaximumTime
            };

            foreach (Course model in table.Courses)
            {
                EventControl control = new EventControl(model);
                control.Margin = new Thickness(5, 0, 5, 0);
                eventHolder.Children.Add(control);
                foreach (Instance instance in model.Instances)
                {
                    if (instance.Day == (int)DateTime.Now.DayOfWeek - 1)
                    {
                        Time now = new Time {
                            Hours = DateTime.Now.Hour, Minutes = DateTime.Now.Minute
                        };
                        if (now < instance.StartTime)
                        {
                            if (earliestInstance.StartTime < now)
                            {
                                earliestInstance = instance;
                                earliest         = model;
                            }
                            else
                            {
                                if (instance.StartTime - now < earliestInstance.StartTime - now)
                                {
                                    earliestInstance = instance;
                                    earliest         = model;
                                }
                            }
                        }
                    }
                }
            }
            if (earliest.Name != "null")
            {
                eventControl.FillWith(earliest);
                eventControl.setTime(earliestInstance.StartTime, earliestInstance.EndTime);
            }
            else
            {
                nextPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            }
        }
Example #9
0
 protected override void OnNavigatedTo(NavigationEventArgs e)
 {
     //a StudentDataBundle must be passed in order to reach this page
     if (e.Parameter.GetType() == typeof(StudentDataBundle))
     {
         //self will contain a reference to the current StudentDataBundle
         self = e.Parameter as StudentDataBundle;
         //fill the StudentDataBundle preview with the StudentDataBundle
         table.FillWith(self);
     }
     else
     {
     }
 }
        /// <summary>
        /// Check for the earliest time for space setting the StudentDataBundle view.
        /// </summary>
        /// <param name="tb"></param>
        /// <returns>Earliest Time</returns>
        public static Time GetEarliest(StudentDataBundle tb)
        {
            Time earliest = Time.MaximumTime;

            foreach (Course t in tb.Courses)
            {
                foreach (Instance instance in t.Instances)
                {
                    if (instance.StartTime <= earliest)
                    {
                        earliest = instance.StartTime;
                    }
                }
            }
            return(earliest);
        }
        /// <summary>
        /// Check for the latest time for space setting the StudentDataBundle view.
        /// </summary>
        /// <param name="tb"></param>
        /// <returns>Latest time</returns>
        public static Time GetLatest(StudentDataBundle tb)
        {
            Time latest = Time.MinimumTime;

            foreach (Course t in tb.Courses)
            {
                foreach (Instance instance in t.Instances)
                {
                    if (instance.EndTime >= latest)
                    {
                        latest = instance.EndTime;
                    }
                }
            }
            return(latest);
        }
Example #12
0
        /// <summary>
        /// This will delete a timetable
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static async Task <bool> DeleteTimetable(StudentDataBundle table)
        {
            //bool success = true;
            try
            {
                //finds the file with that name and deletes. Then removes the object from the list.
                StorageFile file = await DataFolder.GetFileAsync(table.Name + ".tb");

                await file.DeleteAsync();

                Timetables.Remove(table);
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Example #13
0
        /// <summary>
        /// Imports a .tb file
        /// </summary>
        /// <returns></returns>
        public static async Task <bool> ImportTimetable()
        {
            try
            {
                //let the user pick file
                FileOpenPicker opener = new FileOpenPicker();
                opener.FileTypeFilter.Add(".tb");
                opener.CommitButtonText       = "Open StudentDataBundle";
                opener.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                StorageFile file = await opener.PickSingleFileAsync();

                Stream str = await file.OpenStreamForReadAsync();

                bool doRename = false;
                //if the user changed the filename it could break the app so it must be renamed
                await Task.Run(() =>
                {
                    StudentDataBundle table = Serializer.Deserialize(str) as StudentDataBundle;
                    if (file.Name != table.Name)
                    {
                        doRename = true;
                    }
                    Timetables.Add(table);
                    str.Dispose();
                });

                //copy it to the data folder
                file = await file.CopyAsync(DataFolder, Timetables.Last().Name + ".tb", NameCollisionOption.FailIfExists);

                //rename appropiately
                if (doRename)
                {
                    await file.RenameAsync(Timetables.Last().Name + ".tb", NameCollisionOption.ReplaceExisting);
                }
                return(true);
            }
            catch (Exception x)
            {
                return(false);
            }
        }
 /// <summary>
 /// This method checks whether a proposed instace is overlapping another
 /// </summary>
 /// <param name="instance">The instance we are checking the overlap with</param>
 /// <param name="table">The StudentDataBundle in which we check for overlaps</param>
 /// <returns></returns>
 public static TimeOverlapData isOverlapping(Instance instance, StudentDataBundle table)
 {
     foreach (Course model in table.Courses)
     {
         foreach (Instance current in model.Instances)
         {
             if (instance.Day == current.Day)
             {
                 if (instance != current && !model.Instances.Contains(instance) && !(current.EndTime == instance.EndTime || current.StartTime == instance.StartTime))
                 {
                     if (instance.StartTime == current.StartTime)
                     {
                         return new TimeOverlapData {
                                    isOverlapping = true, OverlappingEventName = model.Name
                         }
                     }
                     ;
                     if (instance.StartTime < current.StartTime)
                     {
                         if (instance.EndTime > current.StartTime)
                         {
                             return(new TimeOverlapData {
                                 isOverlapping = true, OverlappingEventName = model.Name
                             });
                         }
                     }
                     if (instance.StartTime >= current.StartTime && instance.EndTime <= current.EndTime)
                     {
                         return(new TimeOverlapData {
                             isOverlapping = true, OverlappingEventName = model.Name
                         });
                     }
                 }
             }
         }
     }
     return(new TimeOverlapData {
         isOverlapping = false
     });
 }
Example #15
0
        /// <summary>
        /// Save a timetable over the old version
        /// </summary>
        /// <param name="table">The timetable to save</param>
        /// <returns></returns>
        public static async Task <bool> SaveTimetable(StudentDataBundle table)
        {
            try
            {
                //find timetable file , open for writing and serialize it
                StorageFile file = await DataFolder.CreateFileAsync(table.Name + ".tb", CreationCollisionOption.ReplaceExisting);

                Stream dataStream = await file.OpenStreamForWriteAsync();

                await Task.Run(() =>
                {
                    Serializer.Serialize(dataStream, table);
                });

                dataStream.Dispose();//to avoid two streams exceptions
                return(true);
            }
            catch
            {
                return(false);
            }
        }
Example #16
0
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            self = e.Parameter as StudentDataBundle;//keep a reference to the timetable
            refresh();

            //go back to previous page
            back.Tapped += async(a, b) =>
            {
                await CoreData.SaveTimetable(self);

                Frame.Navigate(typeof(MainPage), self);
            };

            //create new course
            add.Tapped += (a, b) =>
            {
                self.Courses.Add(new Course {
                    Name = "New Class"
                });
                refresh();
            };
        }
        private async void create_clicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            ValidatorResponse TitleErrors = Validator.isStringValid(
                target: _name.Text, scope: "title", allowDigits: true, allowEmpty: false, max: Validator.TimetableTitleMax, fileName: true);

            ValidatorResponse DescriptionErrors = Validator.isStringValid(
                target: _description.Text, scope: "description", allowDigits: true, allowEmpty: true, max: Validator.TimetableDescriptionMax);

            if (!TitleErrors.isValid || !DescriptionErrors.isValid)
            {
                string errorMessage = TitleErrors.Errors.Aggregate("Cannot create timetable because of the following errors:\n", (current, s) => current + (s + "\n"));
                errorMessage = DescriptionErrors.Errors.Aggregate(errorMessage, (current, s) => current + (s + "\n"));

                var dialog = new MessageDialog(content: errorMessage
                                               , title: "An error occured");
                await dialog.ShowAsync();
            }
            else
            {
                var tb = new StudentDataBundle {
                    Name = _name.Text, Description = _description.Text
                };
                if (await CoreData.CreateTimetable(tb))
                {
                    // CoreData.Timetables.Add(tb);
                    OnCreate();
                    toFront.Begin();
                    _name.Text        = "";
                    _description.Text = "";
                }
                else
                {
                    var diag = new MessageDialog("There was an error creating it");
                    await diag.ShowAsync();
                }
            }
        }
        /// <summary>
        /// handle file double clicking to import
        /// </summary>
        /// <param name="args"></param>
        protected async override void OnFileActivated(FileActivatedEventArgs args)
        {
            bool error = false;

            try
            {
                StudentDataBundle fileTable = new StudentDataBundle();
                StorageFile       file      = args.Files[0] as Windows.Storage.StorageFile;
                Stream            stream    = await file.OpenStreamForReadAsync();

                await Task.Run(() =>
                {
                    fileTable = CoreData.Serializer.Deserialize(stream) as StudentDataBundle;
                    CoreData.Timetables.Add(fileTable);
                });

                await CoreData.SaveTimetable(fileTable);

                var rootFrame = new Frame();
                rootFrame.Navigate(typeof(MainPage), fileTable);
                Window.Current.Content = rootFrame;
                MainPage p = rootFrame.Content as MainPage;

                Window.Current.Activate();
            }
            catch
            {
                error = true;
            }
            if (error)
            {
                //cannot await in catch clause , so a variable is needed
                Windows.UI.Popups.MessageDialog dialog = new Windows.UI.Popups.MessageDialog("Something is wrong with this file - or there already is a file with the same name", "We have a problem");
                await dialog.ShowAsync();
            }
        }
Example #19
0
        /// <summary>
        /// Edit name or description of  timetable
        /// </summary>
        /// <param name="table">The edit target</param>
        /// <param name="rename">Whether it should be renamed</param>
        /// <param name="newName">The new name (if rename = true)</param>
        /// <returns></returns>
        public static async Task <bool> EditTimetable(StudentDataBundle table, bool rename = false, string newName = "")
        {
            try
            {
                //get the file and overwrite with new data
                var file = await DataFolder.GetFileAsync(table.Name + ".tb");

                table.Name = newName;
                Stream dataStream = await file.OpenStreamForWriteAsync();

                await Task.Run(() => Serializer.Serialize(dataStream, table));

                //if it should rename , rename it asynchrnously
                if (rename)
                {
                    await file.RenameAsync(newName + ".tb");
                }
                return(true);
            }
            catch
            {
                return(false);//error
            }
        }
Example #20
0
        StudentDataBundle selfTB; //reference to parent StudentDataBundle for deletion

        public ClassBox(
            Course model, UIElementCollection parent, StudentDataBundle tb)
        {
            this.InitializeComponent();
            self   = model;
            selfTB = tb;

            //setting initial values
            name.Text           = model.Name;
            teacher.Text        = model.Teacher;
            room.Text           = model.Class;
            notes.Text          = model.Notes;
            color.SelectedColor = model.TileColor;
            border.BorderBrush  = new SolidColorBrush(model.TileColor);

            //lambdas to handle changes
            color.ColorChanged += (col) =>
            {
                model.TileColor      = col;
                border.BorderBrush   = new SolidColorBrush(model.TileColor);
                deleteBtn.Foreground = new SolidColorBrush(model.TileColor);
            };

            //when text changes , perform a validation check/fix
            name.TextChanged += (a, b) =>
            {
                Validator.isStringValid(
                    target: name.Text, scope: "name", allowDigits: true, allowEmpty: false, max: Validator.EventTitleMax,
                    autoFix: true, fixTarget: name, autoNotify: true);
                model.Name = name.Text;
            };

            notes.TextChanged += (a, b) =>
            {
                Validator.isStringValid(
                    target: notes.Text, scope: "note", allowDigits: true, allowEmpty: true, max: Validator.EventNotesMax,
                    autoFix: true, fixTarget: notes, autoNotify: true);
                model.Notes = notes.Text;
            };
            room.TextChanged += (a, b) =>
            {
                Validator.isStringValid(
                    target: room.Text, scope: "room name", allowDigits: true, allowEmpty: false, max: Validator.EventClassMax,
                    autoFix: true, fixTarget: room, autoNotify: true);
                model.Class = room.Text;
            };
            teacher.TextChanged += (a, b) =>
            {
                Validator.isStringValid(
                    target: teacher.Text, scope: "teacher name", allowDigits: false, allowEmpty: false, max: Validator.EventTeacherMax,
                    autoFix: true, fixTarget: teacher, autoNotify: true);
                model.Teacher = teacher.Text;
            };

            //lambdas to handle tap events (delete/add)
            deleteBtn.Tapped += async(a, b) =>
            {
                MessageDialog diag = new MessageDialog("This action cannot be undone", "Are you sure you want to delete " + model.Name);
                diag.Commands.Add(new UICommand("Delete", (d) =>
                {
                    parent.Remove(this);
                    tb.Courses.Remove(model);
                }));
                diag.Commands.Add(new UICommand("Cancel"));
                await diag.ShowAsync();
            };



            add.Tapped += (a, b) =>
            {
                Instance inst = new Instance {
                    Day = 0, StartTime = new Time {
                        Hours = 9, Minutes = 0
                    }, EndTime = new Time {
                        Hours = 10, Minutes = 0
                    }, EventName = self.Name
                };
                self.Instances.Add(inst);
                refresh();
            };

            refresh();
        }
 public void FillWith(ref StudentDataBundle studentDataBundle)
 {
     list.FillWith(ref studentDataBundle);
     self = studentDataBundle;
 }