From 8335c47b0f491e0c012a8eada2fe42241219c6ca Mon Sep 17 00:00:00 2001 From: Christian Fiedler Date: Fri, 12 Jul 2013 18:08:17 +0200 Subject: [PATCH] #57 #90 #80 --- .../Assets/icons/DarkTheme/add_159.png | Bin 0 -> 3967 bytes .../Assets/icons/DarkTheme/delete_159.png | Bin 0 -> 6256 bytes .../Assets/icons/DarkTheme/favorite_159.png | Bin 0 -> 7676 bytes .../Assets/icons/DarkTheme/info_159.png | Bin 0 -> 5112 bytes .../Assets/icons/LightTheme/add_159.png | Bin 0 -> 3899 bytes .../Assets/icons/LightTheme/delete_159.png | Bin 0 -> 6785 bytes .../Assets/icons/LightTheme/favorite_159.png | Bin 0 -> 8632 bytes .../Assets/icons/LightTheme/info_159.png | Bin 0 -> 5274 bytes CampusAppWP8/CampusAppWP8/CampusAppWP8.csproj | 50 ++- .../Departments/DepartmentFavoriteFeed.cs | 89 ++++ .../Feed/Departments/DepartmentFeed.cs | 110 ++++- .../CampusAppWP8/Feed/Events/EventFeed.cs | 22 +- .../CampusAppWP8/Feed/News/NewsFeed.cs | 21 +- .../Model/Departments/ChairModel.cs | 106 +++-- .../Model/Departments/DepartmentModel.cs | 113 ++--- .../Model/Departments/DepartmentViewModel.cs | 39 -- .../Model/Departments/FacultyModel.cs | 220 ++++++++- .../Model/Events/RSSChannelModel.cs | 45 -- .../CampusAppWP8/Model/Events/RSSModel.cs | 204 --------- .../CampusAppWP8/Model/Events/RSSViewModel.cs | 47 -- .../Pages/Departments/DepartmentPage.xaml | 67 +-- .../Pages/Departments/DepartmentPage.xaml.cs | 179 ++++---- .../Pages/Events/EventIndexPage.xaml.cs | 37 +- .../CampusAppWP8/Pages/Events/EventPage.xaml | 2 +- .../Pages/Events/EventPage.xaml.cs | 7 +- .../Pages/News/NewsIndexPage.xaml.cs | 37 +- .../CampusAppWP8/Pages/News/NewsPage.xaml | 2 +- .../CampusAppWP8/Pages/News/NewsPage.xaml.cs | 5 +- .../Openinghours/OpeninghoursPage.xaml.cs | 2 +- .../Resources/AppResources.Designer.cs | 54 +++ .../CampusAppWP8/Resources/AppResources.resx | 18 + .../Resources/Constants.Designer.cs | 72 +++ .../CampusAppWP8/Resources/Constants.resx | 24 + .../CampusAppWP8/Resources/Icons.Designer.cs | 163 ++++--- .../CampusAppWP8/Resources/Icons.resx | 12 + .../CampusAppWP8/Utility/HttpRequest.cs | 2 +- .../CampusAppWP8/Utility/XmlManager.cs | 35 ++ CampusAppWP8/CampusAppWP8/model/MainModel.cs | 424 ++++++++++++++++++ .../CampusAppWP8/model/RSS/RSSModel.cs | 235 ++++++++++ .../CampusAppWP8/model/RSS/RSSViewModel.cs | 53 +++ CampusAppWP8/CampusAppWP8/model/XmlModel.cs | 71 +++ .../CampusAppWP8/pages/StartPage.xaml | 2 +- .../CampusAppWP8/pages/StartPage.xaml.cs | 6 + .../departments/DepartmentFavoritePage.xaml | 74 +++ .../DepartmentFavoritePage.xaml.cs | 112 +++++ .../departments/DepartmentIndexPage.xaml | 77 ++++ .../departments/DepartmentIndexPage.xaml.cs | 160 +++++++ .../pages/departments/DepartmentInfoPage.xaml | 36 ++ .../departments/DepartmentInfoPage.xaml.cs | 56 +++ .../CampusAppWP8/utility/FeedEventHandler.cs | 5 +- CampusAppWP8/CampusAppWP8/utility/File.cs | 231 ++++++++++ CampusAppWP8/CampusAppWP8/utility/FileList.cs | 10 + .../CampusAppWP8/utility/FileManager.cs | 3 +- CampusAppWP8/CampusAppWP8/utility/XmlFile.cs | 38 ++ 54 files changed, 2667 insertions(+), 710 deletions(-) create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/add_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/delete_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/favorite_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/info_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/add_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/delete_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/favorite_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/info_159.png create mode 100644 CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFavoriteFeed.cs delete mode 100644 CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentViewModel.cs delete mode 100644 CampusAppWP8/CampusAppWP8/Model/Events/RSSChannelModel.cs delete mode 100644 CampusAppWP8/CampusAppWP8/Model/Events/RSSModel.cs delete mode 100644 CampusAppWP8/CampusAppWP8/Model/Events/RSSViewModel.cs create mode 100644 CampusAppWP8/CampusAppWP8/model/MainModel.cs create mode 100644 CampusAppWP8/CampusAppWP8/model/RSS/RSSModel.cs create mode 100644 CampusAppWP8/CampusAppWP8/model/RSS/RSSViewModel.cs create mode 100644 CampusAppWP8/CampusAppWP8/model/XmlModel.cs create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentFavoritePage.xaml create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentFavoritePage.xaml.cs create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml.cs create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml create mode 100644 CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml.cs create mode 100644 CampusAppWP8/CampusAppWP8/utility/File.cs create mode 100644 CampusAppWP8/CampusAppWP8/utility/XmlFile.cs diff --git a/CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/add_159.png b/CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/add_159.png new file mode 100644 index 0000000000000000000000000000000000000000..056c566723eb3af9d839c5b6b7e208511ae70e29 GIT binary patch literal 3967 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 KpUXO@geCy-yvWD^ literal 0 HcmV?d00001 diff --git a/CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/info_159.png b/CampusAppWP8/CampusAppWP8/Assets/icons/DarkTheme/info_159.png new file mode 100644 index 0000000000000000000000000000000000000000..9423186231db860f0b89fae030feb450ffab2401 GIT binary patch literal 5112 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 PYs}#3>gTe~DWM4fDLXwq literal 0 HcmV?d00001 diff --git a/CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/delete_159.png b/CampusAppWP8/CampusAppWP8/Assets/icons/LightTheme/delete_159.png new file mode 100644 index 0000000000000000000000000000000000000000..dbd6125333fea614c890da3d4bca3f6021a800c8 GIT binary patch literal 6785 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 literal 0 HcmV?d00001 diff --git a/CampusAppWP8/CampusAppWP8/CampusAppWP8.csproj b/CampusAppWP8/CampusAppWP8/CampusAppWP8.csproj index 3fdb572d..ff671827 100644 --- a/CampusAppWP8/CampusAppWP8/CampusAppWP8.csproj +++ b/CampusAppWP8/CampusAppWP8/CampusAppWP8.csproj @@ -96,16 +96,16 @@ App.xaml + - - - + + @@ -113,16 +113,27 @@ + + CampusMapPage.xaml + + DepartmentFavoritePage.xaml + + + DepartmentIndexPage.xaml + + + DepartmentInfoPage.xaml + DepartmentPage.xaml @@ -159,7 +170,7 @@ NewsPage.xaml - + OpeninghoursPage.xaml @@ -180,17 +191,13 @@ True Constants.resx - - True - True - Icons.resx - PreserveNewest - + + @@ -199,6 +206,7 @@ + @@ -210,6 +218,18 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -277,14 +297,22 @@ PreserveNewest + + + + + + + + @@ -336,8 +364,6 @@ Constants.Designer.cs - PublicResXFileCodeGenerator - Icons.Designer.cs PreserveNewest diff --git a/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFavoriteFeed.cs b/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFavoriteFeed.cs new file mode 100644 index 00000000..5c8b4eab --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFavoriteFeed.cs @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 01.07.2013 +//----------------------------------------------------------------------using System; +namespace CampusAppWP8.Feed.Departments +{ + using System; + using System.IO; + using CampusAppWP8.Model; + using CampusAppWP8.Model.Departments; + using CampusAppWP8.Resources; + using CampusAppWP8.Utility; + + /// + /// Feed object to handle favorite department feeds. + /// + public class DepartmentFavoriteFeed : XmlModel + { + #region Constructor + + /// + /// Initializes a new instance of the class. + /// + public DepartmentFavoriteFeed(bool autoLoad = true) + : base(ModelType.File, Constants.FileDepartment_Favorite_Name, string.Empty) + { + this.isFileUpToDate += new IsFileUpToDate(this.CheckIsFileUpToDate); + + if (autoLoad == true) + { + this.LoadData(); + } + } + + // Constructor + #endregion + + #region Method + + #region Protected + + /// + /// Method implement CheckIsModelUpToDate()-Method . + /// + /// true, if model is up-to-date, otherwise false + private bool CheckIsModelUpToDate(DepartmentModel model) + { + bool retValue = true; + + if((model == null) + || (model.Faculties == null) + || (model.Faculties.Count != 1)) + { + retValue = false; + } + + return retValue; + } + + /// + /// Method implement CheckIsFileUpToDate()-Method . + /// + /// true, if file is up-to-date, otherwise false + private bool CheckIsFileUpToDate(DepartmentModel model, FileInfo info) + { + bool retValue = false; + + if (this.Model == null) + { + retValue = true; + } + else + { + retValue = (model.HasChanged() == false) ? true : false; + } + + return retValue; + } + + // Protected + #endregion + + // Method + #endregion + } +} diff --git a/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFeed.cs b/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFeed.cs index bc1b6175..d8b46d93 100644 --- a/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFeed.cs +++ b/CampusAppWP8/CampusAppWP8/Feed/Departments/DepartmentFeed.cs @@ -1,37 +1,109 @@ -using CampusAppWP8.Model.Departments; -using CampusAppWP8.Utility; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CampusAppWP8.Api.Departments +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- +namespace CampusAppWP8.Feed.Departments { - class DepartmentFeed : XmlFeed + using System; + using System.IO; + using CampusAppWP8.Model; + using CampusAppWP8.Model.Departments; + using CampusAppWP8.Resources; + using CampusAppWP8.Utility; + + /// + /// Feed class for the department information. + /// + public class DepartmentFeed : XmlModel { - public DepartmentFeed() : base(URLList.DepartmentFeedURL, "DepartmentFeed.xml") + #region Constructor + + /// + /// Initializes a new instance of the class. + /// + public DepartmentFeed(bool autoLoad = true) + : base(ModelType.FileAndFeed, Constants.FileDepartment_Name, Constants.UrlDepartment_Addr) { - + this.isFileUpToDate += new IsFileUpToDate(this.CheckIsFileUpToDate); + this.isModelUpToDate += new IsModelUpToDate(this.CheckIsModelUpToDate); + + if (autoLoad == true) + { + this.LoadData(); + } } - public System.Collections.ObjectModel.ObservableCollection _faculties { get; set; } + + // Constructor + #endregion + + #region Method + + #region Protected /// - /// Method implement CheckIsModelUpToDate()-Method + /// Method implement CheckIsModelUpToDate()-Method . /// /// true, if model is up-to-date, otherwise false - protected override bool CheckIsModelUpToDate() + private bool CheckIsModelUpToDate(DepartmentModel model) { - return false; + bool retValue = true; + + if (model == null) + { + retValue = false; + } + else + { + TimeSpan diff = DateTime.Now.Subtract(model.CreateTime); + + if (diff.TotalDays >= 7.0) + { + retValue = false; + } + } + + return retValue; } /// - /// Method implement CheckIsFileUpToDate()-Method + /// Method implement CheckIsFileUpToDate()-Method . /// /// true, if file is up-to-date, otherwise false - protected override bool CheckIsFileUpToDate() + private bool CheckIsFileUpToDate(DepartmentModel model, FileInfo info) { - return false; + bool retValue = true; + + if (model == null) // at loading + { + if (info.Exists == true) + { + TimeSpan diff = DateTime.Now.Subtract(info.LastWriteTime); + + if (diff.TotalDays >= 7.0) + { + retValue = false; + } + } + } + else // at saving + { + if ((info.Exists == false) + || (info.Length == 0)) + { + retValue = false; + } + } + + return retValue; } + + // Protedted + #endregion + + // Method + #endregion } } diff --git a/CampusAppWP8/CampusAppWP8/Feed/Events/EventFeed.cs b/CampusAppWP8/CampusAppWP8/Feed/Events/EventFeed.cs index 0fc6ae6a..696d0ad8 100644 --- a/CampusAppWP8/CampusAppWP8/Feed/Events/EventFeed.cs +++ b/CampusAppWP8/CampusAppWP8/Feed/Events/EventFeed.cs @@ -1,25 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using CampusAppWP8.Model.events_news; -using CampusAppWP8.Utility; - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Api.Events { + using CampusAppWP8.Model.RSS; + using CampusAppWP8.Utility; + /// /// Event Feed. /// public class EventFeed : XmlFeed { /// - /// Default constructor. + /// Initializes a new instance of the class. /// public EventFeed() : base(URLList.EventsFeedURL, "EventFeed.xml") { } + /// /// Method implement CheckIsModelUpToDate()-Method /// diff --git a/CampusAppWP8/CampusAppWP8/Feed/News/NewsFeed.cs b/CampusAppWP8/CampusAppWP8/Feed/News/NewsFeed.cs index 6cd2e40d..b67c93d9 100644 --- a/CampusAppWP8/CampusAppWP8/Feed/News/NewsFeed.cs +++ b/CampusAppWP8/CampusAppWP8/Feed/News/NewsFeed.cs @@ -1,21 +1,22 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using CampusAppWP8.Model.events_news; -using CampusAppWP8.Utility; - +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//----------------------------------------------------------------------------- namespace CampusAppWP8.Api.News { + using CampusAppWP8.Model.RSS; + using CampusAppWP8.Utility; + /// /// News Feed. /// public class NewsFeed : XmlFeed { /// - /// Default constructor. + /// Initializes a new instance of the class. /// public NewsFeed() : base(URLList.NewsFeedURL, "NewsFeed.xml") { diff --git a/CampusAppWP8/CampusAppWP8/Model/Departments/ChairModel.cs b/CampusAppWP8/CampusAppWP8/Model/Departments/ChairModel.cs index c98aadc2..2cbaecea 100644 --- a/CampusAppWP8/CampusAppWP8/Model/Departments/ChairModel.cs +++ b/CampusAppWP8/CampusAppWP8/Model/Departments/ChairModel.cs @@ -1,88 +1,126 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml.Serialization; - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Model.Departments { + using System.Globalization; + using System.Xml.Serialization; + /// /// Class to hold information about a professorship chair. /// - public class ChairModel : BaseModel + public class ChairModel { - private string name_de; // german name of the chair - private string url; // link-url to the chair homepage - private string name_en; // english name of the chair + /// + /// German name of the chair. + /// + private string nameDE = string.Empty; /// - /// Default Constructor. Set every class variable to default value. + /// Link to the chair page. + /// + private string url = string.Empty; + + /// + /// English name of the chair. + /// + private string nameEN = string.Empty; + + /// + /// Initializes a new instance of the class. /// public ChairModel() { - this.name_de = String.Empty; - this.name_en = String.Empty; - this.url = String.Empty; } /// - /// Constructor. Set the german and english name. + /// Initializes a new instance of the class. /// - /// Name of the professorship chair. + /// name of the chair public ChairModel(string name) { - this.name_de = name; - this.name_en = name; - this.url = String.Empty; + this.nameDE = name; + this.nameEN = name; } /// - /// Set or return the german name of the chair. + /// Gets or sets the german name of the chair. /// [XmlAttribute("name_de")] - public string Name_DE + public string NameDE { - get { return this.name_de; } + get + { + return this.nameDE; + } + set { - if (value != this.name_de) + if (value != this.nameDE) { - this.name_de = value; - NotifyPropertyChanged("chair"); + this.nameDE = value; } } } /// - /// Set or return the english name of the chair. + /// Gets or sets the english name of the chair. /// [XmlAttribute("name_en")] - public string Name_EN + public string NameEN { - get { return this.name_en; } + get + { + return this.nameEN; + } + set { - if (value != this.name_en) + if (value != this.nameEN) { - this.name_en = value; - NotifyPropertyChanged("chair"); + this.nameEN = value; } } } /// - /// Set or return the url of the chair homepage. + /// Gets or sets the url of the chair homepage. /// [XmlAttribute("url")] public string Url { - get { return this.url; } + get + { + return this.url; + } + set { if (value != this.url) { this.url = value; - NotifyPropertyChanged("chair"); + } + } + } + + /// + /// Gets the localized name of the chair. + /// + public string Name + { + get + { + if (CultureInfo.CurrentUICulture.Name.StartsWith("de")) + { + return this.NameDE; + } + else + { + return this.NameEN; } } } diff --git a/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentModel.cs b/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentModel.cs index ab547308..5b7db58d 100644 --- a/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentModel.cs +++ b/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentModel.cs @@ -1,86 +1,91 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Windows; -using System.Xml.Serialization; - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Model.Departments { - public class DepartmentModel : BaseModel - { - [XmlElement("chair")] - public ObservableCollection _chairs { get; set; } - - private string _name = "d_mod"; - private Visibility visible; + using System; + using System.Collections.ObjectModel; + using System.Xml.Serialization; + /// + /// View model for department page. + /// + [XmlRoot("root")] + public class DepartmentModel + { + /// + /// Object to store the time when the instance was created. + /// + private DateTime createTime; + + /// + /// List of faculties. + /// + private ObservableCollection faculties; + + /// + /// Initializes a new instance of the class. + /// public DepartmentModel() { - this.visible = Visibility.Collapsed; - this.Chairs = new ObservableCollection(); - //this.LoadData(); + this.Faculties = new ObservableCollection(); + this.createTime = DateTime.Now; } - public DepartmentModel(string name) - { - this.visible = Visibility.Collapsed; - _name = name; - this.Chairs = new ObservableCollection(); - //this.LoadData(); - } - - public void LoadData() - { - this.Chairs.Add(new ChairModel("LS 1")); - this.Chairs.Add(new ChairModel("LS 2")); - this.Chairs.Add(new ChairModel("LS 3")); - this.Chairs.Add(new ChairModel("LS 4")); - } - - public ObservableCollection Chairs + /// + /// Gets or sets the faculty list. + /// + [XmlArray("professorships")] + [XmlArrayItem("faculty")] + public ObservableCollection Faculties { get { - return _chairs; + return this.faculties; } + set { - if (value != _chairs) + if (value != this.faculties) { - _chairs = value; - NotifyPropertyChanged("department"); + this.faculties = value; } } } - public string Name + /// + /// Gets the creation time. + /// + public DateTime CreateTime { get { - return _name; - } - set - { - if (value != _name) - { - _name = value; - NotifyPropertyChanged("chair"); - } + return this.createTime; } } - public Visibility Visible + /// + /// Check if the content of the faculty lists hast changed since the + /// last call of this function. + /// + /// true, if changes happend since last request, otherwise false + public bool HasChanged() { - get { return this.visible; } - set + bool retValue = false; + + foreach (FacultyModel temp in this.Faculties) { - if (value != this.visible) + if ((temp.HasChanged() == true) && (retValue == false)) { - this.visible = value; + retValue = true; } } + + return retValue; } } } diff --git a/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentViewModel.cs b/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentViewModel.cs deleted file mode 100644 index 5b57d3c6..00000000 --- a/CampusAppWP8/CampusAppWP8/Model/Departments/DepartmentViewModel.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Serialization; - -namespace CampusAppWP8.Model.Departments -{ - [XmlRoot("root")] - public class DepartmentViewModel : BaseViewModel - { - [XmlArray("professorships")] - [XmlArrayItem("faculty")] - public ObservableCollection _faculties { get; set; } - - public DepartmentViewModel() - { - this.Faculties = new ObservableCollection(); - } - - public ObservableCollection Faculties - { - get - { - return _faculties; - } - set - { - if (value != _faculties) - { - _faculties = value; - NotifyPropertyChanged("foodDays"); - } - } - } - } -} diff --git a/CampusAppWP8/CampusAppWP8/Model/Departments/FacultyModel.cs b/CampusAppWP8/CampusAppWP8/Model/Departments/FacultyModel.cs index 3ceea2a8..1c3419ef 100644 --- a/CampusAppWP8/CampusAppWP8/Model/Departments/FacultyModel.cs +++ b/CampusAppWP8/CampusAppWP8/Model/Departments/FacultyModel.cs @@ -1,62 +1,238 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Xml.Serialization; -using CampusAppWP8.Resources; - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Model.Departments { - public class FacultyModel : BaseModel + using System.Collections.ObjectModel; + using System.Xml.Serialization; + using CampusAppWP8.Resources; + + /// + /// Model for holding the faculty information. + /// + public class FacultyModel { - [XmlElement("chair")] - public ObservableCollection chairs { get; set; } - //public ObservableCollection _faculties { get; set; } - - private string name = "t_fak"; + /// + /// Object to hold the information of the chair containing to this + /// faculty. + /// + private ObservableCollection chairs; + /// + /// Name of the faculty. + /// + private string name = string.Empty; + + /// + /// For checking of change. + /// + private bool hasChanged = false; + + /// + /// Initializes a new instance of the class. + /// public FacultyModel() { - //this.Faculties = new ObservableCollection(); this.chairs = new ObservableCollection(); } + /// + /// Initializes a new instance of the class. + /// + /// name of the faculty public FacultyModel(string name) { this.name = name; - //this.Faculties = new ObservableCollection(); this.chairs = new ObservableCollection(); } + /// + /// Gets or sets the list of the chairs containing to this faculty. + /// + [XmlElement("chair")] public ObservableCollection Chairs { - get { return this.chairs; } + get + { + return this.chairs; + } + set { if (value != this.chairs) { this.chairs = value; - NotifyPropertyChanged("faculty"); } } } - [XmlAttribute("id")] + /// + /// Gets the name of the faculty. + /// public string Name { get { return AppResources.Faculty + " " + this.name; } + } + + /// + /// Gets or sets the id of the faculty. + /// + [XmlAttribute("id")] + public string Id + { + get + { + return this.name; + } + set { - if (value != this.name) + this.name = value; + } + } + + /// + /// Remove a chair model from the lost. + /// + /// name of the chair + /// true, if succeeded + public bool RemoveChair(string chairName) + { + bool retValue = false; + + ChairModel tempChair = null; + + foreach (ChairModel temp in this.Chairs) + { + if (temp.Name.Equals(chairName) == true) { - this.name = value; - NotifyPropertyChanged("faculty"); + tempChair = temp; } } + + if (tempChair != null) + { + retValue = this.Chairs.Remove(tempChair); + this.hasChanged = true; + } + + return retValue; + } + + /// + /// Add a chair to the list, if it does not already exist. + /// + /// chair model to add + /// true, is succeeded + public bool AddChair(ChairModel chairModel) + { + bool retValue = false; + + if ((chairModel != null) + && (this.Chairs.Contains(chairModel) == false)) + { + bool isIn = false; + + foreach (ChairModel temp in this.Chairs) + { + if ((temp.NameDE.Equals(chairModel.NameDE) == true) + || (temp.NameEN.Equals(chairModel.NameEN) == true)) + { + isIn = true; + } + } + + if (isIn == false) + { + this.Chairs.Add(chairModel); + this.hasChanged = true; + retValue = true; + } + } + + return retValue; + } + + /// + /// Create a chair model and add it to the list, if it does not already + /// exist. + /// + /// german name of the chair + /// english name of the chair + /// url of the chair home page + /// true, if succeeded + public bool AddChair(string nameDE, string nameEN, string url) + { + bool retValue = false; + + bool isIn = false; + + foreach (ChairModel temp in this.Chairs) + { + if ((temp.NameDE.Equals(nameDE) == true) + || (temp.NameEN.Equals(nameEN) == true)) + { + isIn = true; + } + } + + if (isIn == false) + { + ChairModel newModel = new ChairModel(); + newModel.NameDE = nameDE; + newModel.NameEN = nameEN; + newModel.Url = url; + + this.Chairs.Add(newModel); + this.hasChanged = true; + retValue = true; + } + + return retValue; + } + + /// + /// Return the chair model of the chair with the specified name. + /// + /// name of the chair + /// chair model, if succeeded, otherwise null + public ChairModel GetChairModel(string name) + { + ChairModel retValue = null; + + foreach (ChairModel temp in this.Chairs) + { + if (temp.Name.Equals(name) == true) + { + retValue = temp; + } + } + + return retValue; + } + + /// + /// Return true if there were changes in the chair list, otherwise false. + /// + /// when true, the hasChanged flag will be reseted + /// true, when changed, otherwise false + public bool HasChanged(bool reset = true) + { + bool retValue = this.hasChanged; + + if (reset == true) + { + this.hasChanged = false; + } + + return retValue; } } } diff --git a/CampusAppWP8/CampusAppWP8/Model/Events/RSSChannelModel.cs b/CampusAppWP8/CampusAppWP8/Model/Events/RSSChannelModel.cs deleted file mode 100644 index 2e8bc8aa..00000000 --- a/CampusAppWP8/CampusAppWP8/Model/Events/RSSChannelModel.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CampusAppWP8.Model; -using System.Collections.ObjectModel; -using System.Xml.Serialization; - -namespace CampusAppWP8.Model.events_news -{ - /// - /// Channel Model, which contains the rss feed item list. - /// - public class RSSChannelModel : BaseModel - { - /// - /// RssFeed information item list. - /// - [XmlElement("item")] - public ObservableCollection item { get; set; } - - /// - /// Default constructor. - /// - public RSSChannelModel() - { - this.item = new ObservableCollection(); - } - - /// - /// Set/Get the rss feed item list. - /// - public ObservableCollection Item - { - get - { - return this.item; - } - set - { - if (value != this.item) - { - this.item = value; - NotifyPropertyChanged("item"); - } - } - } - } -} diff --git a/CampusAppWP8/CampusAppWP8/Model/Events/RSSModel.cs b/CampusAppWP8/CampusAppWP8/Model/Events/RSSModel.cs deleted file mode 100644 index 19d53cb9..00000000 --- a/CampusAppWP8/CampusAppWP8/Model/Events/RSSModel.cs +++ /dev/null @@ -1,204 +0,0 @@ -using CampusAppWP8.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Serialization; - -namespace CampusAppWP8.Model.events_news -{ - /// - /// Contains the rss feed informations. - /// - public class RSSModel : BaseModel - { - /// - /// Title of the fees - /// - private string title; - /// - /// Description text of the feed. - /// - private string text; - /// - /// Timestamp (publication date) of the event or news. - /// - private DateTime timestamp; - /// - /// Url of the feed. - /// - private string link; - - /// - /// Set/Get the title of the feed. - /// - [XmlElement("title")] - public string Title - { - get { return this.title; } - set - { - if (this.title != value) - { - this.title = value; - NotifyPropertyChanged("rss"); - } - } - } - - /// - /// Set/Get the text of the feed. - /// - [XmlElement("description")] - public string Text - { - get { return this.text; } - set - { - if (this.text != HTMLUnicodeToString(value)) - { - this.text = HTMLUnicodeToString(value); - NotifyPropertyChanged("rss"); - } - } - } - - /// - /// Set/Get the timestamp of the feed as string. - /// - [XmlElement("pubDate")] - public string Timestamp - { - get { return this.timestamp.ToString("R"); } - set - { - if (this.timestamp != DateTime.Parse(value)) - { - this.timestamp = DateTime.Parse(value); - NotifyPropertyChanged("rss"); - } - } - } - - /// - /// Set/Get the timestamp of the feed as DateTime object. - /// - public DateTime DTTimestamp - { - get { return this.timestamp; } - set { this.timestamp = value; } - } - - /// - /// Return the date of the timestamp as string. - /// example: Mon, 25.06.2013. - /// - public string Date - { - get { return String.Format("{0:ddd, dd.MM.yyyy}", this.timestamp); } - } - - /// - /// Return the time of the timestamp as string. - /// example: 12:56 Uhr. - /// - public string Time - { - get { return String.Format("{0:h:mm} Uhr", this.timestamp); } - } - - /// - /// Set/Get the link/url of the feed. - /// - [XmlElement("link")] - public string Link - { - get { return this.link; } - set - { - if (this.link != value) - { - this.link = value; - NotifyPropertyChanged("rss"); - } - } - } - - /// - /// Remove or transform html-unicode specific tags into ascii. - /// - /// html string - /// ascii string - private string HTMLUnicodeToString(string htmluni) - { - StringBuilder retValue = new StringBuilder(); - - for(int i = 0; i < htmluni.Length; i++) - { - switch (htmluni[i]) - { - // beginning tag of the unicode - case '&': - { - int startOff = i + 2; - // sear closing tag of the unicode - int endOff = htmluni.IndexOf(';', startOff); - // get and parse value inbetween - string sub = htmluni.Substring(startOff, endOff - startOff); - int cVal = int.Parse(sub); - - switch (cVal) - { - // if the unicode value is 128 (€) - case 128: - retValue.Append('€'); - break; - - default: - retValue.Append((char)cVal); - break; - } - - // set the current index to the end of the unicode tag - i = endOff; - } - break; - case '<': - { - // ignoring <..> html tags - i = htmluni.IndexOf('>', i); - } - break; - case '\t': - // removing tabs - break; - - default: - { - // adding other characters to the return string - retValue.Append(htmluni[i]); - } - break; - } - } - - return retValue.ToString(); - } - - /// - /// Comparing function for Datetime-Timestamps. - /// (currently unused) - /// - /// first item - /// secound item - /// - public static int CompareTimeStamp(RSSModel item1, RSSModel item2) - { - if (item1.DTTimestamp > item2.DTTimestamp) - return -1; - else - return 0; - } - } -} diff --git a/CampusAppWP8/CampusAppWP8/Model/Events/RSSViewModel.cs b/CampusAppWP8/CampusAppWP8/Model/Events/RSSViewModel.cs deleted file mode 100644 index a9625df9..00000000 --- a/CampusAppWP8/CampusAppWP8/Model/Events/RSSViewModel.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CampusAppWP8.Model; -using System.Collections.ObjectModel; -using System.Xml.Serialization; - -namespace CampusAppWP8.Model.events_news -{ - /// - /// ViewModel of the rss feed, containing the feed/channel object. - /// - [XmlRoot("root")] - public class RSSViewModel : BaseViewModel - { - /// - /// channel list for the rss feeds. - /// - [XmlArray("rss")] - [XmlArrayItem("channel")] - public ObservableCollection channel { get; set; } - - /// - /// Default constructor. - /// - public RSSViewModel() - { - this.channel = new ObservableCollection(); - } - - /// - /// Set/Get the channel list. - /// - public ObservableCollection Channel - { - get - { - return this.channel; - } - set - { - if (value != this.channel) - { - this.channel = value; - NotifyPropertyChanged("channel"); - } - } - } - } -} diff --git a/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml b/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml index 3049f3c9..775f1c5d 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml +++ b/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml @@ -15,13 +15,10 @@ OrientationChanged="PhoneApplicationPage_OrientationChanged" shell:SystemTray.IsVisible="True"> - - - - + @@ -33,30 +30,50 @@ - - - - - - - - - + + + + + + - - - - --> + + + + - \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml.cs index a3441909..17af2974 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/Departments/DepartmentPage.xaml.cs @@ -1,130 +1,149 @@ -using CampusAppWP8.Api.Departments; -using CampusAppWP8.Utility; -using Microsoft.Phone.Controls; -using Microsoft.Phone.Tasks; -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Navigation; - - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Pages.Departments { + using System; + using System.Linq; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Navigation; + using CampusAppWP8.Resources; + using Microsoft.Phone.Controls; + /// - /// Pivot page with list of the chairs of the facultis. + /// Pivot page with list of the chairs of the faculties. /// public partial class DepartmentPage : PhoneApplicationPage { /// - /// Stores the last visible department panel. + /// For checking, if the source of the list is already set. /// - private UIElement lastVisibleUIElem = null; + private bool isSourceSet = false; + /// - /// department/chair feed object, storing the model and data. + /// Last clicked button object. /// - private DepartmentFeed feed { get; set; } - + private FrameworkElement lastClickedBtn = null; + /// - /// Default constructor. + /// Initializes a new instance of the class. /// public DepartmentPage() { - InitializeComponent(); - // init feed object - this.feed = new DepartmentFeed(); + this.InitializeComponent(); } /// - /// On naviagtion to this page. - /// Init the feed loading. + /// On navigation to this page. + /// Initialize the feed loading. /// /// event args protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); - this.feed.EventHandler.FeedIsReadyEvent += new FeedEventHandler.FeedReadyHandler(SetupDepartmentPivot); - this.feed.LoadFeed(); - } + if (this.isSourceSet == false) + { + this.DepartmentPivot.ItemsSource = DepartmentIndexPage.GetFeed().GetModel().Faculties; + this.isSourceSet = true; + } - /// - /// Called after the feeds are loaded. - /// Set the pivotitem source of this page. - /// - private void SetupDepartmentPivot() - { - DepartmentPivot.ItemsSource = feed.Model._faculties; + string pivotIndex = string.Empty; + + // Navigate to the selected pivotitem + if (NavigationContext.QueryString.TryGetValue("pivotindex", out pivotIndex)) + { + int pivotIndexInt = int.Parse(pivotIndex) - 1; + + // if the index is in the range of the array + if ((pivotIndexInt >= 0) && (pivotIndexInt < DepartmentIndexPage.GetFeed().GetModel().Faculties.Count())) + { + DepartmentPivot.SelectedIndex = pivotIndexInt; + } + else + { + MessageBox.Show("ERROR: pivotIndex out of range!!!"); + } + } } /// /// On orientation changed. /// - /// unused - /// unused + /// sender object + /// event args private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) { } /// - /// Called at clicking on the department headline buttons. - /// Collapses all visible department panels and open (set to visible) - /// the clicked department list. + /// On clicking a chair TextBlock. + /// Open the browser with the url of the chair. /// - /// clicked department button - /// unused - private void DepartmentBtn_Click(object sender, RoutedEventArgs e) + /// clicked chair TextBlock + /// event args + private void ChairTB_Click(object sender, RoutedEventArgs e) { - // if the sender was a button - if(sender is Button) + FrameworkElement tempBtn = sender as FrameworkElement; + StackPanel tempParent = null; + + if (this.lastClickedBtn != tempBtn) { - Button btn = sender as Button; - - // if the parent is a stackpanel - if(btn.Parent is StackPanel) + if (this.lastClickedBtn != null) { - StackPanel pan = (StackPanel)btn.Parent; - - // if there is a child after the clicked button in the parent panel - if ((pan.Children.Count() > 1) && (pan.Children[1] != null)) - { - // if the clicked department wasn't the one clicked before - if (pan.Children[1] != this.lastVisibleUIElem) - { - // collapse the last visible chair list - if (this.lastVisibleUIElem != null) - this.lastVisibleUIElem.Visibility = Visibility.Collapsed; - - // open the choosen chair list - pan.Children[1].Visibility = Visibility.Visible; - this.lastVisibleUIElem = pan.Children[1]; - } - } + tempParent = this.lastClickedBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Collapsed; } + + tempParent = tempBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Visible; + + this.lastClickedBtn = tempBtn; + } + else + { + tempParent = this.lastClickedBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Collapsed; + this.lastClickedBtn = null; } } /// - /// On clicking a chair textbolock. - /// Open the browser with the url of the chair. + /// On clicking on a add button. + /// Add the chair to the favorite list. /// - /// clicked chair textblock - /// - private void ChairTB_Click(object sender, RoutedEventArgs e) + /// clicked button + /// event args + private void AddBtn_Click(object sender, RoutedEventArgs e) { - if (sender is FrameworkElement) - { - FrameworkElement btn = sender as FrameworkElement; + Button btn = this.lastClickedBtn as Button; + TextBlock btnText = btn.Content as TextBlock; - // if the chair has a url in the tag element - if ((btn.Tag != null) && ((btn.Tag as string).Length > 0)) - { - // open browser with the url - WebBrowserTask task = new WebBrowserTask(); - task.Uri = new Uri(btn.Tag.ToString(), UriKind.Absolute); - task.Show(); - } + Model.Departments.ChairModel tempModel = DepartmentIndexPage.GetFeed().GetModel().Faculties[this.DepartmentPivot.SelectedIndex].GetChairModel(btnText.Text); + + if (tempModel != null) + { + DepartmentIndexPage.GetFavoriteFeed().GetModel().Faculties[0].AddChair(tempModel); } } + + /// + /// On clicking on a info button. + /// Open the info page to this chair. + /// + /// clicked button + /// event args + private void InfoBtn_Click(object sender, RoutedEventArgs e) + { + FrameworkElement infoBtn = sender as FrameworkElement; + string chairName = ((this.lastClickedBtn as Button).Content as TextBlock).Text.ToString(); + + NavigationService.Navigate(new Uri(Constants.PathDepartment_DepartmentInfoPage + "?url=" + infoBtn.Tag.ToString() + "&name=" + chairName, UriKind.Relative)); + } } } \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Pages/Events/EventIndexPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/Events/EventIndexPage.xaml.cs index 78774169..47577b1d 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Events/EventIndexPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/Events/EventIndexPage.xaml.cs @@ -15,7 +15,7 @@ namespace CampusAppWP8.Pages.Events using System.Windows.Controls; using System.Windows.Navigation; using CampusAppWP8.Api.Events; - using CampusAppWP8.Model.events_news; + using CampusAppWP8.Model.RSS; using CampusAppWP8.Utility; using Microsoft.Phone.Controls; @@ -25,9 +25,9 @@ namespace CampusAppWP8.Pages.Events public partial class EventIndexPage : PhoneApplicationPage { /// - /// Gets or sets Event Feed object, which contains the RSS models and data. + /// Event Feed object, which contains the RSS models and data. /// - public static EventFeed eventFeed { get; set; } + private static EventFeed eventFeed; /// /// Initializes a new instance of the class. @@ -38,6 +38,17 @@ namespace CampusAppWP8.Pages.Events EventIndexPage.eventFeed = new EventFeed(); } + /// + /// Gets the eventFeed object. + /// + public static EventFeed GetEventFeed + { + get + { + return EventIndexPage.eventFeed; + } + } + /// /// On navigation to this page, creates a FeedEventHandler and load the RSS feed data. /// @@ -49,8 +60,8 @@ namespace CampusAppWP8.Pages.Events if ((EventIndexPage.eventFeed.Model == null) || (EventIndexPage.eventFeed.Model.Channel == null) || (EventIndexPage.eventFeed.Model.Channel.Count() == 0) - || (EventIndexPage.eventFeed.Model.Channel[0].item == null) - || (EventIndexPage.eventFeed.Model.Channel[0].item.Count() == 0)) + || (EventIndexPage.eventFeed.Model.Channel[0].Item == null) + || (EventIndexPage.eventFeed.Model.Channel[0].Item.Count() == 0)) { // Set handler and load the fees informations. EventIndexPage.eventFeed.EventHandler.FeedIsReadyEvent += new FeedEventHandler.FeedReadyHandler(this.SetupEventPageList); @@ -71,15 +82,15 @@ namespace CampusAppWP8.Pages.Events && (this.ButtonPanel.Items.Count() == 0)) { // Sort the list of rssfeeds. - IEnumerable tempList = EventIndexPage.eventFeed.Model.Channel[0].item.OrderByDescending(e => e.DTTimestamp); - EventIndexPage.eventFeed.Model.Channel[0].item = new ObservableCollection(tempList); + IEnumerable tempList = EventIndexPage.eventFeed.Model.Channel[0].Item.OrderByDescending(e => e.DTTimestamp); + EventIndexPage.eventFeed.Model.Channel[0].Item = new ObservableCollection(tempList); // Create the buttons for the fees selection and add it to the buttonpanel. - for (int i = 0; i < EventIndexPage.eventFeed.Model.Channel[0].item.Count(); i++) + for (int i = 0; i < EventIndexPage.eventFeed.Model.Channel[0].Item.Count(); i++) { Button tempBtn = new Button(); tempBtn.Name = "EventRowAppButton"; - tempBtn.Content = EventIndexPage.eventFeed.Model.Channel[0].item[i].Title; + tempBtn.Content = EventIndexPage.eventFeed.Model.Channel[0].Item[i].Title; tempBtn.VerticalContentAlignment = VerticalAlignment.Stretch; tempBtn.HorizontalContentAlignment = HorizontalAlignment.Stretch; tempBtn.BorderThickness = new Thickness(0.0); @@ -92,14 +103,6 @@ namespace CampusAppWP8.Pages.Events } } - /// - /// Gets the eventFeed object. - /// - public static EventFeed GetEventFeed - { - get { return EventIndexPage.eventFeed; } - } - /// /// Is called on clicking on a feed button. /// Navigates to the event pivot page with the information of the diff --git a/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml b/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml index 7ff46edf..b4ab9f42 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml +++ b/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml @@ -6,7 +6,7 @@ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:viewModel="clr-namespace:CampusAppWP8.Model.events_news" + xmlns:viewModel="clr-namespace:CampusAppWP8.Model.RSS" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" diff --git a/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml.cs index 2520c3b7..751f69b6 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/Events/EventPage.xaml.cs @@ -14,8 +14,7 @@ namespace CampusAppWP8.Pages.Events using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; - using Microsoft.Phone.Tasks; - + /// /// EventPage, where every event fees has his own PivotItem. /// @@ -51,7 +50,7 @@ namespace CampusAppWP8.Pages.Events && (EventIndexPage.GetEventFeed.Model.Channel != null) && (EventIndexPage.GetEventFeed.Model.Channel.Count() >= 1)) { - this.EventPivot.ItemsSource = EventIndexPage.GetEventFeed.Model.Channel[0].item; + this.EventPivot.ItemsSource = EventIndexPage.GetEventFeed.Model.Channel[0].Item; this.isSourceSet = true; } } @@ -64,7 +63,7 @@ namespace CampusAppWP8.Pages.Events int pivotIndexInt = int.Parse(pivotIndex); // if the index is in the range of the array - if ((pivotIndexInt >= 0) && (pivotIndexInt < EventIndexPage.GetEventFeed.Model.Channel[0].item.Count())) + if ((pivotIndexInt >= 0) && (pivotIndexInt < EventIndexPage.GetEventFeed.Model.Channel[0].Item.Count())) { EventPivot.SelectedIndex = pivotIndexInt; } diff --git a/CampusAppWP8/CampusAppWP8/Pages/News/NewsIndexPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/News/NewsIndexPage.xaml.cs index 7702f189..5cfd0bdb 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/News/NewsIndexPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/News/NewsIndexPage.xaml.cs @@ -15,7 +15,7 @@ namespace CampusAppWP8.Pages.News using System.Windows.Controls; using System.Windows.Navigation; using CampusAppWP8.Api.News; - using CampusAppWP8.Model.events_news; + using CampusAppWP8.Model.RSS; using CampusAppWP8.Utility; using Microsoft.Phone.Controls; @@ -25,9 +25,9 @@ namespace CampusAppWP8.Pages.News public partial class NewsIndexPage : PhoneApplicationPage { /// - /// Gets or sets News Feed object, which contains the RSS models and data. + /// News Feed object, which contains the RSS models and data. /// - public static NewsFeed newsFeed { get; set; } + private static NewsFeed newsFeed; /// /// Initializes a new instance of the class. @@ -38,6 +38,17 @@ namespace CampusAppWP8.Pages.News NewsIndexPage.newsFeed = new NewsFeed(); } + /// + /// Gets the newsFeed object. + /// + public static NewsFeed GetNewsFeed + { + get + { + return NewsIndexPage.newsFeed; + } + } + /// /// On navigation to this page, creates a FeedEventHandler and load the RSS feed data. /// @@ -49,8 +60,8 @@ namespace CampusAppWP8.Pages.News if ((NewsIndexPage.newsFeed.Model == null) || (NewsIndexPage.newsFeed.Model.Channel == null) || (NewsIndexPage.newsFeed.Model.Channel.Count() == 0) - || (NewsIndexPage.newsFeed.Model.Channel[0].item == null) - || (NewsIndexPage.newsFeed.Model.Channel[0].item.Count() == 0)) + || (NewsIndexPage.newsFeed.Model.Channel[0].Item == null) + || (NewsIndexPage.newsFeed.Model.Channel[0].Item.Count() == 0)) { // Set handler and load the fees informations. NewsIndexPage.newsFeed.EventHandler.FeedIsReadyEvent += new FeedEventHandler.FeedReadyHandler(this.SetupNewsPageList); @@ -71,15 +82,15 @@ namespace CampusAppWP8.Pages.News && (this.ButtonPanel.Items.Count() == 0)) { // Sort the list of rssfeeds. - IEnumerable tempList = NewsIndexPage.newsFeed.Model.Channel[0].item.OrderByDescending(e => e.DTTimestamp); - NewsIndexPage.newsFeed.Model.Channel[0].item = new ObservableCollection(tempList); + IEnumerable tempList = NewsIndexPage.newsFeed.Model.Channel[0].Item.OrderByDescending(e => e.DTTimestamp); + NewsIndexPage.newsFeed.Model.Channel[0].Item = new ObservableCollection(tempList); // Create the buttons for the fees selection and add it to the buttonpanel. - for (int i = 0; i < NewsIndexPage.newsFeed.Model.Channel[0].item.Count(); i++) + for (int i = 0; i < NewsIndexPage.newsFeed.Model.Channel[0].Item.Count(); i++) { Button tempBtn = new Button(); tempBtn.Name = "NewsRowAppButton"; - tempBtn.Content = NewsIndexPage.newsFeed.Model.Channel[0].item[i].Title; + tempBtn.Content = NewsIndexPage.newsFeed.Model.Channel[0].Item[i].Title; tempBtn.VerticalContentAlignment = VerticalAlignment.Stretch; tempBtn.HorizontalContentAlignment = HorizontalAlignment.Stretch; tempBtn.BorderThickness = new Thickness(0.0); @@ -92,14 +103,6 @@ namespace CampusAppWP8.Pages.News } } - /// - /// Gets the newsFeed object. - /// - public static NewsFeed GetNewsFeed - { - get { return NewsIndexPage.newsFeed; } - } - /// /// Is called on clicking on a feed button. /// Navigates to the news pivot page with the information of the diff --git a/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml b/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml index 5fe92308..0b898115 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml +++ b/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml @@ -6,7 +6,7 @@ xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:viewModel="clr-namespace:CampusAppWP8.Model.events_news" + xmlns:viewModel="clr-namespace:CampusAppWP8.Model.RSS" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" diff --git a/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml.cs index 6b13789f..10071b16 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/News/NewsPage.xaml.cs @@ -14,7 +14,6 @@ namespace CampusAppWP8.Pages.News using System.Windows.Controls; using System.Windows.Navigation; using Microsoft.Phone.Controls; - using Microsoft.Phone.Tasks; /// /// EventPage, where every news fees has his own PivotItem. @@ -52,7 +51,7 @@ namespace CampusAppWP8.Pages.News && (NewsIndexPage.GetNewsFeed.Model.Channel.Count() >= 1) && (this.NewsPivot.Items.Count() == 0)) { - this.NewsPivot.ItemsSource = NewsIndexPage.GetNewsFeed.Model.Channel[0].item; + this.NewsPivot.ItemsSource = NewsIndexPage.GetNewsFeed.Model.Channel[0].Item; this.isSourceSet = true; } } @@ -65,7 +64,7 @@ namespace CampusAppWP8.Pages.News int pivotIndexInt = int.Parse(pivotIndex); // if the index is in the range of the array - if ((pivotIndexInt >= 0) && (pivotIndexInt < NewsIndexPage.GetNewsFeed.Model.Channel[0].item.Count())) + if ((pivotIndexInt >= 0) && (pivotIndexInt < NewsIndexPage.GetNewsFeed.Model.Channel[0].Item.Count())) { NewsPivot.SelectedIndex = pivotIndexInt; } diff --git a/CampusAppWP8/CampusAppWP8/Pages/Openinghours/OpeninghoursPage.xaml.cs b/CampusAppWP8/CampusAppWP8/Pages/Openinghours/OpeninghoursPage.xaml.cs index 6c577d86..c55b66a8 100644 --- a/CampusAppWP8/CampusAppWP8/Pages/Openinghours/OpeninghoursPage.xaml.cs +++ b/CampusAppWP8/CampusAppWP8/Pages/Openinghours/OpeninghoursPage.xaml.cs @@ -120,7 +120,7 @@ namespace CampusAppWP8.Pages.Openinghours if (parent.Children.Count() >= 2) { - if (this.lastOpenUIElem != parent.Children[1]) + if (parent.Children[1].Equals(this.lastOpenUIElem) == false) { this.lastOpenUIElem = parent.Children[1]; this.lastOpenUIElem.Visibility = Visibility.Visible; diff --git a/CampusAppWP8/CampusAppWP8/Resources/AppResources.Designer.cs b/CampusAppWP8/CampusAppWP8/Resources/AppResources.Designer.cs index c7b511b2..5ddd60c2 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/AppResources.Designer.cs +++ b/CampusAppWP8/CampusAppWP8/Resources/AppResources.Designer.cs @@ -60,6 +60,15 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die Hinzufügen ähnelt. + /// + public static string Add { + get { + return ResourceManager.GetString("Add", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die Hinzufügen ähnelt. /// @@ -132,6 +141,33 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die Löschen ähnelt. + /// + public static string Delete { + get { + return ResourceManager.GetString("Delete", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Löschung ist fehlgeschlagen ähnelt. + /// + public static string DeleteFailed { + get { + return ResourceManager.GetString("DeleteFailed", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Löschung war erfolgreich ähnelt. + /// + public static string DeleteSucceeded { + get { + return ResourceManager.GetString("DeleteSucceeded", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die Lehrstühle ähnelt. /// @@ -159,6 +195,15 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die Favoriten ähnelt. + /// + public static string Favorites { + get { + return ResourceManager.GetString("Favorites", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die Hinweis ähnelt. /// @@ -177,6 +222,15 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die Details ähnelt. + /// + public static string Info { + get { + return ResourceManager.GetString("Info", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die Studiengang ähnelt. /// diff --git a/CampusAppWP8/CampusAppWP8/Resources/AppResources.resx b/CampusAppWP8/CampusAppWP8/Resources/AppResources.resx index 4aa62828..a7e1812e 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/AppResources.resx +++ b/CampusAppWP8/CampusAppWP8/Resources/AppResources.resx @@ -287,4 +287,22 @@ Sonntag + + Hinzufügen + + + Favoriten + + + Details + + + Löschen + + + Löschung ist fehlgeschlagen + + + Löschung war erfolgreich + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Resources/Constants.Designer.cs b/CampusAppWP8/CampusAppWP8/Resources/Constants.Designer.cs index c4881720..171a45e1 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/Constants.Designer.cs +++ b/CampusAppWP8/CampusAppWP8/Resources/Constants.Designer.cs @@ -60,6 +60,33 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die DepartmentFavoriteFeed.xml ähnelt. + /// + internal static string FileDepartment_Favorite_Name { + get { + return ResourceManager.GetString("FileDepartment_Favorite_Name", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die DepartmentFeed.xml ähnelt. + /// + internal static string FileDepartment_Name { + get { + return ResourceManager.GetString("FileDepartment_Name", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die ähnelt. + /// + internal static string IsolatedStorage_DepartmentFavoriteModel { + get { + return ResourceManager.GetString("IsolatedStorage_DepartmentFavoriteModel", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die LectureModel ähnelt. /// @@ -159,6 +186,42 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die /Pages/Departments/DepartmentFavoritePage.xaml ähnelt. + /// + internal static string PathDepartment_DepartmentFavoritePage { + get { + return ResourceManager.GetString("PathDepartment_DepartmentFavoritePage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die /Pages/Departments/DepartmentIndexPage.xaml ähnelt. + /// + internal static string PathDepartment_DepartmentIndexPage { + get { + return ResourceManager.GetString("PathDepartment_DepartmentIndexPage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die /Pages/Departments/DepartmentInfoPage.xaml ähnelt. + /// + internal static string PathDepartment_DepartmentInfoPage { + get { + return ResourceManager.GetString("PathDepartment_DepartmentInfoPage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die /Pages/Departments/DepartmentPage.xaml ähnelt. + /// + internal static string PathDepartment_DepartmentPage { + get { + return ResourceManager.GetString("PathDepartment_DepartmentPage", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die /Pages/Events/EventIndexPage.xaml ähnelt. /// @@ -240,6 +303,15 @@ namespace CampusAppWP8.Resources { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die http://www.tu-cottbus.de/campusapp-data/professorships.xml ähnelt. + /// + internal static string UrlDepartment_Addr { + get { + return ResourceManager.GetString("UrlDepartment_Addr", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die http://www.zv.tu-cottbus.de/LSFveranst/LSF4 ähnelt. /// diff --git a/CampusAppWP8/CampusAppWP8/Resources/Constants.resx b/CampusAppWP8/CampusAppWP8/Resources/Constants.resx index 9011849e..2f9fe8c0 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/Constants.resx +++ b/CampusAppWP8/CampusAppWP8/Resources/Constants.resx @@ -189,4 +189,28 @@ /Pages/Openinghours/OpeninghoursPage.xaml + + + + + DepartmentFavoriteFeed.xml + + + DepartmentFeed.xml + + + /Pages/Departments/DepartmentIndexPage.xaml + + + http://www.tu-cottbus.de/campusapp-data/professorships.xml + + + /Pages/Departments/DepartmentFavoritePage.xaml + + + /Pages/Departments/DepartmentInfoPage.xaml + + + /Pages/Departments/DepartmentPage.xaml + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/Resources/Icons.Designer.cs b/CampusAppWP8/CampusAppWP8/Resources/Icons.Designer.cs index a50f46eb..57e08d75 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/Icons.Designer.cs +++ b/CampusAppWP8/CampusAppWP8/Resources/Icons.Designer.cs @@ -1,42 +1,40 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.18046 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 28.06.2013 +//---------------------------------------------------------------------- namespace CampusAppWP8.Resources { using System; using System.Windows; /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// Icons uri string. /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Icons { - + /// + /// Resource manager object. + /// private static global::System.Resources.ResourceManager resourceMan; + /// + /// Culture information object. + /// private static global::System.Globalization.CultureInfo resourceCulture; - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + /// + /// Initializes a new instance of the class. + /// internal Icons() { } /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// Gets the resource manager. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager @@ -45,18 +43,16 @@ namespace CampusAppWP8.Resources { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CampusAppWP8.Resources.Icons", - -typeof(Icons).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CampusAppWP8.Resources.Icons", typeof(Icons).Assembly); resourceMan = temp; } + return resourceMan; } } /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// Gets or sets the culture information. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture @@ -65,6 +61,7 @@ typeof(Icons).Assembly); { return resourceCulture; } + set { resourceCulture = value; @@ -72,30 +69,7 @@ typeof(Icons).Assembly); } /// - /// Returns the full filename of the icon, depending on the current theme. - /// - /// Tagname - /// Filename - private static string Themerize(string _key) - { - string retValue = string.Empty; - - if ((Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"] == Visibility.Visible) - { - retValue = "/Assets/Icons/DarkTheme/"; - } - else - { - retValue = "/Assets/Icons/LightTheme/"; - } - - retValue += ResourceManager.GetString(_key, resourceCulture); - - return retValue; - } - - /// - /// Sucht eine lokalisierte Zeichenfolge, die campus_159.png ähnelt. + /// Gets the uri string of the campus icon. /// public static string Campus { @@ -106,7 +80,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die departments_159.png ähnelt. + /// Gets the uri string of the departments icon. /// public static string Departments { @@ -117,7 +91,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die homework_159.png ähnelt. + /// Gets the uri string of the homework icon. /// public static string Homework { @@ -128,7 +102,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die lectures_159.png ähnelt. + /// Gets the uri string of the lectures icon. /// public static string Lectures { @@ -139,7 +113,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die link_159.png ähnelt. + /// Gets the uri string of the link icon. /// public static string Link { @@ -150,7 +124,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die mensa_159.png ähnelt. + /// Gets the uri string of the mensa icon. /// public static string Mensa { @@ -161,7 +135,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die news_159.png ähnelt. + /// Gets the uri string of the news icon. /// public static string News { @@ -172,7 +146,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die openhours_159.png ähnelt. + /// Gets the uri string of the opening hours icon. /// public static string Openhours { @@ -183,7 +157,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die schedule_159.png ähnelt. + /// Gets the uri string of the schedule icon. /// public static string Schedule { @@ -194,7 +168,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die search_159.png ähnelt. + /// Gets the uri string of the search icon. /// public static string Search { @@ -205,7 +179,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die student_council_159.png ähnelt. + /// Gets the uri string of the student council icon. /// public static string StudentCouncil { @@ -216,7 +190,7 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die webmail_159.png ähnelt. + /// Gets the uri string of the web mail icon. /// public static string WebMail { @@ -227,7 +201,51 @@ typeof(Icons).Assembly); } /// - /// Sucht eine lokalisierte Zeichenfolge, die phone_159.png ähnelt. + /// Gets the uri string of the favorite icon. + /// + public static string Favorite + { + get + { + return Themerize("Favorite"); + } + } + + /// + /// Gets the uri string of the delete icon. + /// + public static string Delete + { + get + { + return Themerize("Delete"); + } + } + + /// + /// Gets the uri string of the info icon. + /// + public static string Info + { + get + { + return Themerize("Info"); + } + } + + /// + /// Gets the uri string of the add icon. + /// + public static string Add + { + get + { + return Themerize("Add"); + } + } + + /// + /// Gets the uri string of the phone icon. /// public static string Phone { @@ -236,5 +254,28 @@ typeof(Icons).Assembly); return Themerize("Phone"); } } + + /// + /// Return the theme depending string of a icon. + /// + /// icon name + /// uri string of the icon + private static string Themerize(string key) + { + string retValue = string.Empty; + + if ((Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"] == Visibility.Visible) + { + retValue = "/Assets/Icons/DarkTheme/"; + } + else + { + retValue = "/Assets/Icons/LiehgtTheme/"; + } + + retValue += ResourceManager.GetString(key, resourceCulture); + + return retValue; + } } } diff --git a/CampusAppWP8/CampusAppWP8/Resources/Icons.resx b/CampusAppWP8/CampusAppWP8/Resources/Icons.resx index 919f1551..0b64716b 100644 --- a/CampusAppWP8/CampusAppWP8/Resources/Icons.resx +++ b/CampusAppWP8/CampusAppWP8/Resources/Icons.resx @@ -117,15 +117,27 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + add_159.png + campus_159.png + + delete_159.png + departments_159.png + + favorite_159.png + homework_159.png + + info_159.png + lectures_159.png diff --git a/CampusAppWP8/CampusAppWP8/Utility/HttpRequest.cs b/CampusAppWP8/CampusAppWP8/Utility/HttpRequest.cs index 1ba0ed8d..ebb30a38 100644 --- a/CampusAppWP8/CampusAppWP8/Utility/HttpRequest.cs +++ b/CampusAppWP8/CampusAppWP8/Utility/HttpRequest.cs @@ -15,7 +15,7 @@ namespace CampusAppWP8.Utility /// /// Class realize the access of restful HttpRequest /// - public abstract class HttpRequest + public class HttpRequest { #region Members diff --git a/CampusAppWP8/CampusAppWP8/Utility/XmlManager.cs b/CampusAppWP8/CampusAppWP8/Utility/XmlManager.cs index abdb4647..2a559743 100644 --- a/CampusAppWP8/CampusAppWP8/Utility/XmlManager.cs +++ b/CampusAppWP8/CampusAppWP8/Utility/XmlManager.cs @@ -7,6 +7,7 @@ //---------------------------------------------------------------------- namespace CampusAppWP8.Utility { + using System.IO; using System.Xml.Linq; using System.Xml.Serialization; @@ -36,5 +37,39 @@ namespace CampusAppWP8.Utility T model = (T)serializer.Deserialize(document.CreateReader()); return model; } + + /// + /// Method serializes a model to a string. + /// + /// type of the model + /// model object + /// serialized string + public static string SerializationToString(T model) + { + string retValue = string.Empty; + + XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); + ns.Add("", ""); + + XmlSerializer serializer = new XmlSerializer(typeof(T)); + TextWriter writer = new StringWriter(); + + serializer.Serialize(writer, model, ns); + + retValue = writer.ToString(); + + if (retValue.StartsWith(""); + retValue = retValue.Substring(endTag + 2); + + if (retValue.StartsWith("\r\n") == true) + { + retValue = retValue.Substring(2); + } + } + + return retValue; + } } } diff --git a/CampusAppWP8/CampusAppWP8/model/MainModel.cs b/CampusAppWP8/CampusAppWP8/model/MainModel.cs new file mode 100644 index 00000000..b1a415a9 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/model/MainModel.cs @@ -0,0 +1,424 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 05.07.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8 +{ + using System; + using System.IO; + using System.Net; + using System.Text; + using CampusAppWP8.Utility; + + /// + /// Base model io handling class. + /// + /// model type + public abstract class MainModel : IDisposable + { + /// + /// Model io type. + /// + private ModelType modelType; + + /// + /// Model object. + /// + private T model = default(T); + + /// + /// File object. + /// + private CampusAppWP8.Utility.File file = null; + + /// + /// Web object. + /// + private HttpRequest api = null; + + /// + /// Filename of saved data. + /// + private string fileName = string.Empty; + + /// + /// Url of the feed data. + /// + private Uri httpApiUri = null; + + /// + /// Initializes a new instance of the class. + /// + /// Model IO type + /// name of the file + /// url of the feed + public MainModel(ModelType modelType, string fileName, string url) + { + this.modelType = modelType; + + if ((url != null) && (url.Equals(string.Empty) == false)) + { + this.httpApiUri = new Uri(url, UriKind.Absolute); + } + + this.fileName = fileName; + + if ((this.IsFile() == true) + && (fileName.Equals(string.Empty) == false)) + { + this.InitFile(CampusAppWP8.Utility.File.IOTypeRead.ReadSync, CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync); + } + + if ((this.IsHttpApi() == true) + && (url.Equals(string.Empty) == false)) + { + this.InitHttpApi(); + } + } + + /// + /// Finalizes an instance of the class. + /// + ~MainModel() + { + this.SaveData(); + } + + /// + /// Delegate of the OnLoading callback function. + /// + public delegate void OnLoading(); + + /// + /// Delegate of the OnLoaded callback function. + /// + public delegate void OnLoaded(); + + /// + /// Delegate of the OnSaving callback function. + /// + public delegate void OnSaving(); + + /// + /// Delegate of the OnSaved callback function. + /// + public delegate void OnSaved(); + + /// + /// Delegate of the IsModelUpToDate callback function. + /// + /// data model + /// true, model is up to date + public delegate bool IsModelUpToDate(T model); + + /// + /// Delegate of the IsFileUpToDate callback function. + /// + /// data model + /// info of the file + /// true, is file is up to date + public delegate bool IsFileUpToDate(T model, FileInfo fileInfo); + + /// + /// Callback pointer, called before loading. + /// + public event OnLoading onLoading = null; + + /// + /// Callback pointer, called after loading. + /// + public event OnLoaded onLoaded = null; + + /// + /// Callback pointer, called before saving. + /// + public event OnSaving onSaving = null; + + /// + /// Callback pointer, called after saving. + /// + public event OnSaved onSaved = null; + + /// + /// Callback pointer, for checking if file is up to date. + /// + public event IsFileUpToDate isFileUpToDate = null; + + /// + /// Callback pointer, for checking if model is up to date. + /// + public event IsModelUpToDate isModelUpToDate = null; + + /// + /// Specifies the I/O type of the model. + /// + public enum ModelType + { + /// + /// Invalid/unset state. + /// + INVALID = 0, + + /// + /// File only (01). + /// + File = 1, + + /// + /// Feed only (10). + /// + Feed = 2, + + /// + /// File and feed (11). + /// + FileAndFeed = 3 + } + + /// + /// Gets or sets the Model. + /// + public T Model + { + get + { + return this.model; + } + + set + { + this.model = value; + } + } + + /// + /// Called before finalizing. Can maybe be removed. + /// + public void Dispose() + { + this.SaveData(); + } + + /// + /// Forces a update from web. + /// + public void ForceWebUpdate() + { + if (this.api != null) + { + if (this.onLoading != null) + { + this.onLoading(); + } + + this.api.HttpGet(this.httpApiUri, this.OnLoadDataComplete); + } + + } + + /// + /// Load the data if necessary, from web or from file, regarding if + /// the file data is up to date. + /// + public void LoadData() + { + bool loadFromFile = true; + + if (this.onLoading != null) + { + this.onLoading(); + } + + if (((this.isModelUpToDate == null) + || (this.isModelUpToDate(this.model) == false)) + && ((this.file != null) || this.api != null)) + { + if (this.file != null) + { + if ((this.file.Exist() == false) + || (this.file.GetFileInfo().Length == 0)) + { + loadFromFile = false; + } + + if (((this.isFileUpToDate != null) && (this.isFileUpToDate(this.model, this.file.GetFileInfo()) == false)) + || (this.isFileUpToDate == null)) + { + loadFromFile = false; + } + } + else + { + loadFromFile = false; + } + + if (this.api == null) + { + loadFromFile = true; + } + + if (loadFromFile == false) + { + this.api.HttpGet(this.httpApiUri, this.OnLoadDataComplete); + } + else + { + string data = this.file.ReadFile(); + + if (data != null && !data.Equals(string.Empty)) + { + this.DeserializeModel(Encoding.UTF8.GetBytes(data)); + } + } + } + + if (loadFromFile == true) + { + if (this.onLoaded != null) + { + this.onLoaded(); + } + } + } + + /// + /// Save the model data if necessary. + /// + public void SaveData() + { + if ((this.file != null) + && ((this.isFileUpToDate == null) || (this.isFileUpToDate(this.model, this.file.GetFileInfo()) == false))) + { + if (this.onSaving != null) + { + this.onSaving(); + } + + byte[] data = this.SerializeModel(); + this.file.WriteFile(data); + + if (this.onSaved != null) + { + this.onSaved(); + } + } + } + + /// + /// Return the model io type. + /// + /// model io type + public ModelType GetModelType() + { + return this.modelType; + } + + /// + /// Return the model. + /// + /// model object + public T GetModel() + { + return this.model; + } + + /// + /// Abstract declaration of the model deserialize function. + /// + /// model data as byte array + /// true, is succeeded + protected abstract bool DeserializeModel(byte[] modelData); + + /// + /// Abstract declaration of the model serialize function. + /// + /// model data as byte array + protected abstract byte[] SerializeModel(); + + /// + /// Check if the model io type is file. + /// + /// true, if the model io type has file. + protected bool IsFile() + { + bool retValue = false; + + if ((this.modelType & ModelType.File) != 0) + { + retValue = true; + } + + return retValue; + } + + /// + /// Check if the model io type is feed. + /// + /// true if the model io type has feed. + protected bool IsHttpApi() + { + bool retValue = false; + + if ((this.modelType & ModelType.Feed) != 0) + { + retValue = true; + } + + return retValue; + } + + /// + /// Initializes the file object. + /// + /// read io type (Default: sync) + /// write io type (Default: async) + private void InitFile(CampusAppWP8.Utility.File.IOTypeRead readType = CampusAppWP8.Utility.File.IOTypeRead.ReadSync, CampusAppWP8.Utility.File.IOTypeWrite writeType = CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync) + { + if ((this.IsFile() == true) + && (this.file == null)) + { + this.file = new CampusAppWP8.Utility.File(this.fileName, readType, writeType); + } + } + + /// + /// Initializes the web object. + /// + private void InitHttpApi() + { + if ((this.IsHttpApi() == true) + && (this.api == null)) + { + this.api = new HttpRequest(); + } + } + + /// + /// Is called after the loading from web is complete. + /// + /// sending object + /// event args + private void OnLoadDataComplete(object sender, DownloadStringCompletedEventArgs e) + { + Exception downloadError = e.Error; + if (downloadError != null) + { + return; + } + + string downloadResult = e.Result; + if (downloadResult != null && !downloadResult.Equals(string.Empty)) + { + this.DeserializeModel(Encoding.UTF8.GetBytes(downloadResult)); + } + + if (this.onLoaded != null) + { + this.onLoaded(); + } + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/model/RSS/RSSModel.cs b/CampusAppWP8/CampusAppWP8/model/RSS/RSSModel.cs new file mode 100644 index 00000000..8f49ef0e --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/model/RSS/RSSModel.cs @@ -0,0 +1,235 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8.Model.RSS +{ + using System; + using System.Text; + using System.Xml.Serialization; + + /// + /// Contains the RSS feed information. + /// + public class RSSModel + { + /// + /// Title of the fees + /// + private string title; + + /// + /// Description text of the feed. + /// + private string text; + + /// + /// Timestamp (publication date) of the event or news. + /// + private DateTime timestamp; + + /// + /// Url of the feed. + /// + private string link; + + /// + /// Gets or sets the title of the feed. + /// + [XmlElement("title")] + public string Title + { + get + { + return this.title; + } + + set + { + if (this.title != value) + { + this.title = value; + } + } + } + + /// + /// Gets or sets the text of the feed. + /// + [XmlElement("description")] + public string Text + { + get + { + return this.text; + } + + set + { + if (this.text != this.HTMLUnicodeToString(value)) + { + this.text = this.HTMLUnicodeToString(value); + } + } + } + + /// + /// Gets or sets the timestamp of the feed as string. + /// + [XmlElement("pubDate")] + public string Timestamp + { + get + { + return this.timestamp.ToString("R"); + } + + set + { + if (this.timestamp != DateTime.Parse(value)) + { + this.timestamp = DateTime.Parse(value); + } + } + } + + /// + /// Gets or sets the timestamp of the feed as DateTime object. + /// + public DateTime DTTimestamp + { + get + { + return this.timestamp; + } + + set + { + this.timestamp = value; + } + } + + /// + /// Gets the date of the timestamp as string. + /// example: Mon, 25.06.2013. + /// + public string Date + { + get + { + return string.Format("{0:ddd, dd.MM.yyyy}", this.timestamp); + } + } + + /// + /// Gets the time of the timestamp as string. + /// example: 12:56 Uhr. + /// + public string Time + { + get + { + return string.Format("{0:h:mm} Uhr", this.timestamp); + } + } + + /// + /// Gets or sets the link/url of the feed. + /// + [XmlElement("link")] + public string Link + { + get + { + return this.link; + } + + set + { + if (this.link != value) + { + this.link = value; + } + } + } + + /// + /// Comparing function for DateTime timestamps. + /// (currently unused) + /// + /// first item + /// second item + /// -1 if item2 is older then item1, otherwise 0 + public static int CompareTimeStamp(RSSModel item1, RSSModel item2) + { + if (item1.DTTimestamp > item2.DTTimestamp) + { + return -1; + } + else + { + return 0; + } + } + + /// + /// Remove or transform html-unicode specific tags into ASCII. + /// + /// html string + /// ASCII string + private string HTMLUnicodeToString(string htmluni) + { + StringBuilder retValue = new StringBuilder(); + + for (int i = 0; i < htmluni.Length; i++) + { + switch (htmluni[i]) + { + // beginning tag of the unicode + case '&': + int startOff = i + 2; + //// sear closing tag of the unicode + int endOff = htmluni.IndexOf(';', startOff); + //// get and parse value inbetween + string sub = htmluni.Substring(startOff, endOff - startOff); + int charVal = int.Parse(sub); + + switch (charVal) + { + // if the unicode value is 128 (€) + case 128: + retValue.Append('€'); + break; + + default: + retValue.Append((char)charVal); + break; + } + + // set the current index to the end of the unicode tag + i = endOff; + break; + + case '<': + // ignoring <..> html tags + i = htmluni.IndexOf('>', i); + break; + + case '\t': + // removing tabs + break; + + default: + // adding other characters to the return string + retValue.Append(htmluni[i]); + break; + } + } + + return retValue.ToString(); + } + } +} diff --git a/CampusAppWP8/CampusAppWP8/model/RSS/RSSViewModel.cs b/CampusAppWP8/CampusAppWP8/model/RSS/RSSViewModel.cs new file mode 100644 index 00000000..f182f1a8 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/model/RSS/RSSViewModel.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8.Model.RSS +{ + using System.Collections.ObjectModel; + using System.Xml.Serialization; + + /// + /// ViewModel of the RSS feed, containing the feed/channel object. + /// + [XmlRoot("root")] + public class RSSViewModel + { + /// + /// Channel list for the RSS feeds. + /// + [XmlArray("rss")] + [XmlArrayItem("channel")] + private ObservableCollection channel; + + /// + /// Initializes a new instance of the class. + /// + public RSSViewModel() + { + this.channel = new ObservableCollection(); + } + + /// + /// Gets or sets the channel list. + /// + public ObservableCollection Channel + { + get + { + return this.channel; + } + + set + { + if (value != this.channel) + { + this.channel = value; + } + } + } + } +} diff --git a/CampusAppWP8/CampusAppWP8/model/XmlModel.cs b/CampusAppWP8/CampusAppWP8/model/XmlModel.cs new file mode 100644 index 00000000..4baedf31 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/model/XmlModel.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 05.07.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8.Model +{ + using System.Text; + using CampusAppWP8.Resources; + using CampusAppWP8.Utility; + + /// + /// Xml model io handler class. + /// + /// model type + public class XmlModel : MainModel + { + /// + /// Initializes a new instance of the class. + /// + /// model io type + /// filename of the data file + /// url of the feed data + public XmlModel(ModelType modelType, string fileName, string url) + : base(modelType, fileName, url) + { + } + + /// + /// Create the model from a xml byte array. + /// + /// model data + /// true, if succeeded + protected override bool DeserializeModel(byte[] modelData) + { + bool retValue = true; + + string data = Encoding.UTF8.GetString(modelData, 0, modelData.Length); + + T tempModel = XmlManager.DeserializationToModel(data, Constants.XMLRootElementName); + if (tempModel != null) + { + this.Model = tempModel; + } + else + { + retValue = false; + } + + return retValue; + } + + /// + /// Serializes the model to a byte array. + /// + /// model data + protected override byte[] SerializeModel() + { + byte[] retValue = null; + + if (this.Model != null) + { + retValue = Encoding.UTF8.GetBytes(XmlManager.SerializationToString(this.Model)); + } + + return retValue; + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/StartPage.xaml b/CampusAppWP8/CampusAppWP8/pages/StartPage.xaml index 91009353..d8b2f5dc 100644 --- a/CampusAppWP8/CampusAppWP8/pages/StartPage.xaml +++ b/CampusAppWP8/CampusAppWP8/pages/StartPage.xaml @@ -86,7 +86,7 @@ - + + + + + + + + + + + + + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentFavoritePage.xaml.cs b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentFavoritePage.xaml.cs new file mode 100644 index 00000000..2647fdf7 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentFavoritePage.xaml.cs @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 01.07.2013 +//---------------------------------------------------------------------- +namespace CampusAppWP8.Pages.Departments +{ + using System; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Navigation; + using CampusAppWP8.Resources; + using Microsoft.Phone.Controls; + + /// + /// Page to visualize the favorite department list. + /// + public partial class DepartmentFavoritePage : PhoneApplicationPage + { + /// + /// Object to store the last clicked chair button. + /// + private FrameworkElement lastClickedBtn = null; + + /// + /// Initializes a new instance of the class. + /// + public DepartmentFavoritePage() + { + this.InitializeComponent(); + } + + /// + /// On navigation to this page. + /// Initialize the list source. + /// + /// event args + protected override void OnNavigatedTo(NavigationEventArgs e) + { + this.ContentPanel.ItemsSource = DepartmentIndexPage.GetFavoriteFeed().GetModel().Faculties[0].Chairs; + } + + /// + /// On clicking on a chair button. + /// Open or close the chair details. + /// + /// clicked button + /// event args + private void ChairTB_Click(object sender, RoutedEventArgs e) + { + FrameworkElement tempBtn = sender as FrameworkElement; + StackPanel tempParent = null; + + if (tempBtn == this.lastClickedBtn) + { + tempParent = this.lastClickedBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Collapsed; + this.lastClickedBtn = null; + } + else + { + if (this.lastClickedBtn != null) + { + tempParent = this.lastClickedBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Collapsed; + } + + tempParent = tempBtn.Parent as StackPanel; + tempParent.Children[1].Visibility = Visibility.Visible; + + this.lastClickedBtn = tempBtn; + } + } + + /// + /// On clicking on a delete button. + /// Removes the chair from the favorite list. + /// + /// clicked button + /// event args + private void DeleteBtn_Click(object sender, RoutedEventArgs e) + { + Button btn = this.lastClickedBtn as Button; + TextBlock btnText = btn.Content as TextBlock; + + if (DepartmentIndexPage.GetFavoriteFeed().GetModel().Faculties[0].RemoveChair(btnText.Text) == true) + { + MessageBox.Show(AppResources.DeleteSucceeded); + } + else + { + MessageBox.Show(AppResources.DeleteFailed); + } + } + + /// + /// On clicking on a info button. + /// Open a department info page. + /// + /// clicked button + /// event args + private void InfoBtn_Click(object sender, RoutedEventArgs e) + { + FrameworkElement infoBtn = sender as FrameworkElement; + string chairName = ((this.lastClickedBtn as Button).Content as TextBlock).Text.ToString(); + + NavigationService.Navigate(new Uri(Constants.PathDepartment_DepartmentInfoPage + "?url=" + infoBtn.Tag.ToString() + "&name=" + chairName, UriKind.Relative)); + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml new file mode 100644 index 00000000..7cf96e78 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml.cs b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml.cs new file mode 100644 index 00000000..9c048b81 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentIndexPage.xaml.cs @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 24.06.2013 +//---------------------------------------------------------------------- +namespace CampusAppWP8.Pages.Departments +{ + using System; + using System.Linq; + using System.Windows; + using System.Windows.Navigation; + using CampusAppWP8.Feed.Departments; + using CampusAppWP8.Resources; + using Microsoft.Phone.Controls; + + /// + /// Page with a list of the faculties. + /// + public partial class DepartmentIndexPage : PhoneApplicationPage + { + /// + /// Department/chair feed object, storing the model and data. + /// + private static DepartmentFeed feed = null; + + /// + /// Department feed object for storing the favorite list. + /// + private static DepartmentFavoriteFeed favorite = null; + + /// + /// Initializes a new instance of the class. + /// + public DepartmentIndexPage() + { + this.InitializeComponent(); + + //// init feed objects + if (DepartmentIndexPage.feed == null) + { + DepartmentIndexPage.feed = new DepartmentFeed(false); + } + + DepartmentIndexPage.feed.onLoaded += new DepartmentFeed.OnLoaded(this.SetupFacultyList); + DepartmentIndexPage.feed.LoadData(); + + if (DepartmentIndexPage.favorite == null) + { + DepartmentIndexPage.favorite = new DepartmentFavoriteFeed(false); + } + + DepartmentIndexPage.favorite.onLoaded += new DepartmentFavoriteFeed.OnLoaded(this.CheckFavoriteFeed); + DepartmentIndexPage.favorite.LoadData(); + } + + /// + /// Return the feed object of the departments. + /// + /// feed object + public static DepartmentFeed GetFeed() + { + return DepartmentIndexPage.feed; // DepartmentIndexPage.feed; + } + + /// + /// Return the feed object of the favorite departments. + /// + /// feed object + public static DepartmentFavoriteFeed GetFavoriteFeed() + { + return DepartmentIndexPage.favorite; // DepartmentIndexPage.favorite; + } + + /// + /// On navigation to this page. + /// Initialize the feed loading. + /// + /// event args + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (NavigationMode.Back != e.NavigationMode) + { + } + } + + /// + /// On navigation from this page. + /// Store the favorite list. + /// + /// event args + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + if (NavigationMode.Back == e.NavigationMode) + { + DepartmentIndexPage.favorite.SaveData(); + } + + base.OnNavigatedFrom(e); + } + + /// + /// On orientation changed. + /// + /// sender object + /// event args + private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) + { + } + + /// + /// Setup the faculty list. + /// + private void SetupFacultyList() + { + this.FacultyList.ItemsSource = DepartmentIndexPage.feed.GetModel().Faculties; + } + + /// + /// Checks if the favorite feed is valid. + /// + private void CheckFavoriteFeed() + { + if (DepartmentIndexPage.favorite.GetModel() == null) + { + DepartmentIndexPage.favorite.Model = new Model.Departments.DepartmentModel(); + } + + if (DepartmentIndexPage.favorite.GetModel().Faculties.Count() == 0) + { + DepartmentIndexPage.favorite.Model.Faculties.Add(new Model.Departments.FacultyModel("favorites")); + } + } + + /// + /// On clicking on the favorite button. + /// + /// clicked button + /// event args + private void FavoriteBtn_Click(object sender, RoutedEventArgs e) + { + NavigationService.Navigate(new Uri(Constants.PathDepartment_DepartmentFavoritePage, UriKind.Relative)); + } + + /// + /// On clicking on a faculty button. + /// + /// clicked button + /// event args + private void FacultyBtn_Click(object sender, RoutedEventArgs e) + { + FrameworkElement tempElem = sender as FrameworkElement; + + NavigationService.Navigate(new Uri(Constants.PathDepartment_DepartmentPage + "?pivotindex=" + tempElem.Tag, UriKind.Relative)); + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml new file mode 100644 index 00000000..19d9b033 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml.cs b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml.cs new file mode 100644 index 00000000..4f9f7c22 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/pages/departments/DepartmentInfoPage.xaml.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 01.07.2013 +//---------------------------------------------------------------------- +namespace CampusAppWP8.Pages.Departments +{ + using System; + using System.Windows.Navigation; + using Microsoft.Phone.Controls; + + /// + /// Info page of a chair. + /// + public partial class DepartmentInfoPage : PhoneApplicationPage + { + /// + /// Initializes a new instance of the class. + /// + public DepartmentInfoPage() + { + this.InitializeComponent(); + } + + /// + /// On navigation to this page. + /// Initialize the page headline text. + /// + /// event args + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + string url = string.Empty; + string chairName = string.Empty; + + if (NavigationContext.QueryString.TryGetValue("url", out url) + && NavigationContext.QueryString.TryGetValue("name", out chairName)) + { + this.PageHeadline.Text = chairName; + this.WebBrowser.Navigate(new Uri(url, UriKind.Absolute)); + } + } + + /// + /// On orientation changed. + /// + /// sender object + /// event args + private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) + { + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/utility/FeedEventHandler.cs b/CampusAppWP8/CampusAppWP8/utility/FeedEventHandler.cs index 4ea85a84..cc5a4e94 100644 --- a/CampusAppWP8/CampusAppWP8/utility/FeedEventHandler.cs +++ b/CampusAppWP8/CampusAppWP8/utility/FeedEventHandler.cs @@ -43,7 +43,10 @@ namespace CampusAppWP8.Utility /// public void FireFeedReadyevent() { - this.FeedIsReadyEvent(); + if (this.FeedIsReadyEvent != null) + { + this.FeedIsReadyEvent(); + } } #endregion diff --git a/CampusAppWP8/CampusAppWP8/utility/File.cs b/CampusAppWP8/CampusAppWP8/utility/File.cs new file mode 100644 index 00000000..8e6fcae3 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/utility/File.cs @@ -0,0 +1,231 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 03.05.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8.Utility +{ + using System; + using System.IO; + using Windows.Storage; + + /// + /// File class. + /// + public class File + { + /// + /// Folder object. + /// + private static readonly IStorageFolder LocalFolder = ApplicationData.Current.LocalFolder; + + /// + /// File name. + /// + private string filename = string.Empty; + + /// + /// Read type. + /// + private IOTypeRead readType; + + /// + /// Write type. + /// + private IOTypeWrite writeType; + + /// + /// Initializes a new instance of the class. + /// + /// file name + /// read type + /// write type + public File(string filename, IOTypeRead read, IOTypeWrite write) + { + this.filename = filename; + this.readType = (read == IOTypeRead.INVALID) ? IOTypeRead.ReadAsync : read; + this.writeType = write; + } + + /// + /// IO read type ENUM. + /// + public enum IOTypeRead + { + /// + /// Invalid/unset state. + /// + INVALID = 0, + + /// + /// Sync read. + /// + ReadSync = 1, + + /// + /// Async read. + /// + ReadAsync = 2 + } + + /// + /// IO write type ENUM. + /// + public enum IOTypeWrite + { + /// + /// Invalid/unset state. + /// + INVALID = 0, + + /// + /// Sync write. + /// + WriteSync = 1, + + /// + /// Async write. + /// + WriteAsync = 2, + + /// + /// Read only, no writing. + /// + ReadOnly = 3 + } + + /// + /// Read data from file to a string. + /// + /// read type + /// data string + public string ReadFile(IOTypeRead ioType = IOTypeRead.INVALID) + { + string retValue = null; + + if (this.Exist() == true) + { + IOTypeRead tempType = ioType; + + if (tempType == IOTypeRead.INVALID) + { + tempType = this.readType; + } + + if (tempType == IOTypeRead.ReadAsync) + { + // retValue = this.ReadAsync(); + retValue = this.ReadSync(); + } + else if (tempType == IOTypeRead.ReadSync) + { + retValue = this.ReadSync(); + } + } + + return retValue; + } + + /// + /// Write bytes to the file. + /// + /// data byte array + /// write type + public void WriteFile(byte[] data, IOTypeWrite ioType = IOTypeWrite.INVALID) + { + IOTypeWrite tempType = ioType; + + if (tempType == IOTypeWrite.INVALID) + { + tempType = this.writeType; + } + + if (tempType == IOTypeWrite.WriteAsync) + { + this.WriteAsync(data); + } + else if (tempType == IOTypeWrite.WriteSync) + { + // this.WriteSync(data); + this.WriteAsync(data); + } + } + + /// + /// Return a info object of the file. + /// + /// info of the file + public FileInfo GetFileInfo() + { + FileInfo info = new FileInfo(File.LocalFolder.Path + "\\" + this.filename); + return info; + } + + /// + /// Check if a file is existing. + /// + /// true, if file exists, otherwise false + public bool Exist() + { + return this.GetFileInfo().Exists; + } + + /// + /// Read data synchronous from file. + /// + /// data string + private string ReadSync() + { + string retValue = null; + + using (Stream fileStream = File.LocalFolder.OpenStreamForReadAsync(this.filename).Result) + { + using (StreamReader streamReader = new StreamReader(fileStream)) + { + retValue = streamReader.ReadToEnd(); + } + } + + return retValue; + } + + /// + /// Read data asynchronous from file. + /// + /// data string + private string ReadAsync() + { + string retValue = string.Empty; + + return retValue; + } + + /// + /// Write data synchronous to file. + /// + /// data array + /// true, if succeeded + private bool WriteSync(byte[] data) + { + bool retValue = true; + + return retValue; + } + + /// + /// Write data asynchronous to file. + /// + /// data array + private async void WriteAsync(byte[] data) + { + var file = await File.LocalFolder.CreateFileAsync(this.filename, CreationCollisionOption.ReplaceExisting); + + using (var s = await file.OpenStreamForWriteAsync()) + { + await s.WriteAsync(data, 0, data.Length); + } + } + } +} \ No newline at end of file diff --git a/CampusAppWP8/CampusAppWP8/utility/FileList.cs b/CampusAppWP8/CampusAppWP8/utility/FileList.cs index 189278eb..18f5b3f1 100644 --- a/CampusAppWP8/CampusAppWP8/utility/FileList.cs +++ b/CampusAppWP8/CampusAppWP8/utility/FileList.cs @@ -24,5 +24,15 @@ namespace CampusAppWP8.Utility /// Opening hours feed file name. /// public static readonly string OpeninghoursXmlFile = "OpeninghoursFeed.xml"; + + /// + /// Department feed file name. + /// + public static readonly string DepartmentXmlFile = "DepartmentFeed.xml"; + + /// + /// Department favorite feed file name. + /// + public static readonly string DepartmentFavoriteXmlFile = "DepartmentFavoriteFeed.xml"; } } diff --git a/CampusAppWP8/CampusAppWP8/utility/FileManager.cs b/CampusAppWP8/CampusAppWP8/utility/FileManager.cs index d3d8b50b..884a4edb 100644 --- a/CampusAppWP8/CampusAppWP8/utility/FileManager.cs +++ b/CampusAppWP8/CampusAppWP8/utility/FileManager.cs @@ -105,7 +105,8 @@ namespace CampusAppWP8.Utility using (Stream stream = await storageFile.OpenStreamForWriteAsync()) { byte[] contentByte = Encoding.UTF8.GetBytes(content); - await stream.WriteAsync(contentByte, 0, contentByte.Length); + //await stream.WriteAsync(contentByte, 0, contentByte.Length); + stream.Write(contentByte, 0, contentByte.Length); } } diff --git a/CampusAppWP8/CampusAppWP8/utility/XmlFile.cs b/CampusAppWP8/CampusAppWP8/utility/XmlFile.cs new file mode 100644 index 00000000..29196969 --- /dev/null +++ b/CampusAppWP8/CampusAppWP8/utility/XmlFile.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// +// Company copyright tag. +// +// fiedlchr +// 05.07.2013 +//----------------------------------------------------------------------------- +namespace CampusAppWP8.Utility +{ + using CampusAppWP8.Resources; + + public class XmlFile : File + { + public XmlFile(string filename) : base(filename, IOTypeRead.ReadAsync, IOTypeWrite.WriteSync) + { + } + + public bool LoadModel(T model) + { + bool retValue = true; + + string data = this.ReadFile(); + + if ((data == null) + || (data.Equals(string.Empty) == true)) + { + retValue = false; + } + else + { + model = XmlManager.DeserializationToModel(data, Constants.XMLRootElementName); + } + + return retValue; + } + + } +} \ No newline at end of file