Merge branch 'release/#135#183' into develmaster

This commit is contained in:
stubbfel
2013-09-03 14:07:13 +02:00
26 changed files with 884 additions and 183 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -100,14 +100,19 @@
</Compile>
<Compile Include="Feed\Departments\DepartmentFavoriteFeed.cs" />
<Compile Include="Const.cs" />
<Compile Include="Feed\Exams\ExamFeed.cs" />
<Compile Include="Feed\Mensa\MensaFeedSBFMain.cs" />
<Compile Include="Feed\Mensa\MensaFeedCBSouth.cs" />
<Compile Include="Feed\Mensa\MensaFeedCBNorth.cs" />
<Compile Include="Feed\Mensa\MensaFeedCBMain.cs" />
<Compile Include="File\Exams\ExamFile.cs" />
<Compile Include="Model\BinaryModel.cs" />
<Compile Include="Model\Campusmap\CBMainMapModel.cs" />
<Compile Include="Model\Campusmap\CurrentPositionPinModel.cs" />
<Compile Include="Model\Campusmap\HiddenPinPlaceModel.cs" />
<Compile Include="Model\Campusmap\SearchPlacePinModel.cs" />
<Compile Include="Model\Exams\ExamListModel.cs" />
<Compile Include="Model\Exams\ExamModel.cs" />
<Compile Include="Model\GeoDb\PlaceInformation.cs" />
<Compile Include="Model\GeoDb\PlaceModel.cs" />
<Compile Include="Model\GeoDb\PlaceService.cs" />
@@ -119,6 +124,9 @@
<Compile Include="Model\Utility\DegreeListPickerItemListModel.cs" />
<Compile Include="Model\Utility\CleanUrlParamModel.cs" />
<Compile Include="Model\Utility\CampusListPickerItemListModel.cs" />
<Compile Include="Pages\Exams\Exams.xaml.cs">
<DependentUpon>Exams.xaml</DependentUpon>
</Compile>
<Compile Include="Utility\NDEF\NDEFMessage.cs" />
<Compile Include="Utility\NDEF\NDEFRecord.cs" />
<Compile Include="Utility\NDEF\NDEFShortRecord.cs" />
@@ -295,6 +303,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\Exams\Exams.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\Lecture\LecturePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -396,6 +408,7 @@
<Content Include="Assets\Icons\DarkTheme\campus_159.png" />
<Content Include="Assets\Icons\DarkTheme\current_position_159.png" />
<Content Include="Assets\Icons\DarkTheme\delete_159.png" />
<Content Include="Assets\Icons\DarkTheme\exams_159.png" />
<Content Include="Assets\Icons\DarkTheme\favorite_159.png" />
<Content Include="Assets\Icons\DarkTheme\info_159.png" />
<Content Include="Assets\Icons\DarkTheme\phone_159.png" />
@@ -409,6 +422,7 @@
<Content Include="Assets\Icons\LightTheme\delete_159.png" />
<Content Include="Assets\Icons\LightTheme\departments_159.png" />
<Content Include="Assets\Icons\DarkTheme\homework_159.png" />
<Content Include="Assets\Icons\LightTheme\exams_159.png" />
<Content Include="Assets\Icons\LightTheme\favorite_159.png" />
<Content Include="Assets\Icons\LightTheme\homework_159.png" />
<Content Include="Assets\Icons\DarkTheme\link_159.png" />

View File

@@ -0,0 +1,59 @@
//-----------------------------------------------------------------------
// <copyright file="ExamFeed.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>02.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.Feed.Exams
{
using System.IO;
using CampusAppWP8.Model;
using CampusAppWP8.Model.Exams;
using CampusAppWP8.Resources;
/// <summary>Exam feed.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
public class ExamFeed : XmlModel<ExamListModel>
{
/// <summary>Initializes a new instance of the ExamFeed class.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
public ExamFeed()
: base(ModelType.FileAndFeed, Constants.FileExamApp_ExamFeed, Constants.UrlExamApp_ExamFeed)
{
this.IsFileUpToDateOnLoad += new IsFileUpToDate(this.CheckIsFileUpToDate);
this.IsModelUpToDateOnLoad += new IsModelUpToDate(this.CheckIsModelUpToDate);
this.IsFileUpToDateOnSave += new IsFileUpToDate(this.CheckIsFileUpToDate);
this.ValidRootName = Constants.ExamXmlValidRootName;
}
/// <summary>Check is model up to date.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
/// <param name="model">The model.</param>
/// <returns>true if it succeeds, false if it fails.</returns>
private bool CheckIsModelUpToDate(ExamListModel model)
{
if (model == null)
{
return false;
}
return true;
}
/// <summary>Check is file up to date.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
/// <param name="model"> The model.</param>
/// <param name="fileInfo">Information describing the file.</param>
/// <returns>true if it succeeds, false if it fails.</returns>
private bool CheckIsFileUpToDate(ExamListModel model, FileInfo fileInfo)
{
if (fileInfo == null || !fileInfo.Exists || fileInfo.Length < 1)
{
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,94 @@
//-----------------------------------------------------------------------
// <copyright file="ExamFile.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>03.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.File.Exams
{
using System.IO;
using CampusAppWP8.Model;
using Windows.Storage;
/// <summary>Exam file.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
public class ExamFile : BinaryModel
{
/// <summary>The storage file.</summary>
private StorageFile storageFile;
/// <summary>Initializes a new instance of the ExamFile class.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="fileName">Filename of the file.</param>
/// <param name="url"> URL of the document.</param>
public ExamFile(string fileName, string url)
: base(ModelType.FileAndFeed, fileName, url)
{
this.IsFileUpToDateOnLoad += new IsFileUpToDate(this.CheckIsFileUpToDate);
this.IsModelUpToDateOnLoad += new IsModelUpToDate(this.CheckIsModelUpToDate);
this.IsFileUpToDateOnSave += new IsFileUpToDate(this.CheckIsFileUpToDate);
}
/// <summary>Executes the file operation.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
public async void LaunchFile()
{
if (this.storageFile == null)
{
this.storageFile = await this.file.AsStorageFile();
}
if (this.storageFile != null)
{
var options = new Windows.System.LauncherOptions();
Windows.System.Launcher.LaunchFileAsync(this.storageFile);
}
}
/// <summary>Saves the and launch file.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
public void SaveAndLaunchFile()
{
if (this.file.Exist())
{
this.LaunchFile();
}
else
{
this.OnSaved += new ExamFile.OnIO(this.LaunchFile);
this.SaveData();
}
}
/// <summary>Check is model up to date.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="model">The model.</param>
/// <returns>true if it succeeds, false if it fails.</returns>
private bool CheckIsModelUpToDate(byte[] model)
{
if (model == null)
{
return false;
}
return true;
}
/// <summary>Check is file up to date.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="model"> The model.</param>
/// <param name="fileInfo">Information describing the file.</param>
/// <returns>true if it succeeds, false if it fails.</returns>
private bool CheckIsFileUpToDate(byte[] model, FileInfo fileInfo)
{
if (fileInfo == null || !fileInfo.Exists || fileInfo.Length < 1)
{
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,62 @@
//-----------------------------------------------------------------------
// <copyright file="BinaryModel.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>03.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.Model
{
/// <summary>Binary model.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
public abstract class BinaryModel : MainModel<byte[]>
{
/// <summary>Initializes a new instance of the BinaryModel class.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="modelType">Type of the model.</param>
/// <param name="fileName"> Filename of the file.</param>
/// <param name="url"> URL of the document.</param>
public BinaryModel(ModelType modelType, string fileName, string url)
: base(modelType, fileName, url)
{
}
/// <summary>Initializes a new instance of the BinaryModel class.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="modelType"> Type of the model.</param>
/// <param name="sourceName">Name of the source.</param>
public BinaryModel(ModelType modelType, string sourceName)
: base(modelType, sourceName)
{
}
/// <summary>Deserialize model.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="modelData">Information describing the model.</param>
/// <returns>true if it succeeds, false if it fails.</returns>
protected override bool DeserializeModel(byte[] modelData)
{
bool retValue = true;
if (modelData != null)
{
this.Model = modelData;
}
else
{
retValue = false;
}
return retValue;
}
/// <summary>Gets the serialize model.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <returns>an byte Array.</returns>
protected override byte[] SerializeModel()
{
return this.Model;
}
}
}

View File

@@ -0,0 +1,23 @@
//-----------------------------------------------------------------------
// <copyright file="ExamlistModel.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>02.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.Model.Exams
{
using System.Collections.ObjectModel;
using System.Xml.Serialization;
/// <summary>Exam list model.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
[XmlRoot("links")]
public class ExamListModel
{
/// <summary>Gets or sets the exams.</summary>
/// <value>The exams.</value>
[XmlElement("link")]
public ObservableCollection<ExamModel> Exams { get; set; }
}
}

View File

@@ -0,0 +1,67 @@
//-----------------------------------------------------------------------
// <copyright file="ExamModel.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>02.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.Model.Exams
{
using System.Xml.Serialization;
using CampusAppWP8.Utility;
/// <summary>Exam model.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
public class ExamModel
{
/// <summary>Gets or sets the course number.</summary>
/// <value>The course number.</value>
[XmlAttribute("stg")]
public string CourseNumber { get; set; }
/// <summary>Gets or sets the course text.</summary>
/// <value>The course text.</value>
[XmlAttribute("stgtext")]
public string CourseText { get; set; }
/// <summary>Gets or sets the degree number.</summary>
/// <value>The degree number.</value>
[XmlAttribute("abschl")]
public string DegreeNumber { get; set; }
/// <summary>Gets or sets the version.</summary>
/// <value>The version.</value>
[XmlAttribute("pversion")]
public string Version { get; set; }
/// <summary>Gets or sets the type.</summary>
/// <value>The type.</value>
[XmlAttribute("typ")]
public string Type { get; set; }
/// <summary>Gets or sets the title.</summary>
/// <value>The title.</value>
[XmlAttribute("dtxt")]
public string Title { get; set; }
/// <summary>Gets or sets the date.</summary>
/// <value>The date.</value>
[XmlAttribute("datum")]
public string Date { get; set; }
/// <summary>Gets or sets the link.</summary>
/// <value>The link.</value>
[XmlAttribute("link")]
public string Link { get; set; }
/// <summary>Gets the caption.</summary>
/// <value>The caption.</value>
public string Caption
{
get
{
return StringManager.StripHTML(this.CourseText + " (" + this.Type + "/" + this.Version + ")");
}
}
}
}

View File

@@ -11,7 +11,6 @@ namespace CampusAppWP8
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using CampusAppWP8.Model.Utility;
using CampusAppWP8.Utility;
@@ -19,8 +18,13 @@ namespace CampusAppWP8
/// Base model io handling class.
/// </summary>
/// <typeparam name="T">model type</typeparam>
public abstract class MainModel<T> : IDisposable
public abstract class MainModel<T>
{
/// <summary>
/// File object.
/// </summary>
protected CampusAppWP8.Utility.File file = null;
/// <summary>
/// Model io type.
/// </summary>
@@ -31,11 +35,6 @@ namespace CampusAppWP8
/// </summary>
private T model = default(T);
/// <summary>
/// File object.
/// </summary>
private CampusAppWP8.Utility.File file = null;
/// <summary>
/// Web object.
/// </summary>
@@ -88,14 +87,6 @@ namespace CampusAppWP8
}
}
/// <summary>
/// Finalizes an instance of the <see cref="MainModel{T}" /> class.
/// </summary>
~MainModel()
{
this.SaveData();
}
/// <summary>
/// Delegate of the OnIO callback function.
/// </summary>
@@ -238,14 +229,6 @@ namespace CampusAppWP8
}
}
/// <summary>
/// Called before finalizing. Can maybe be removed.
/// </summary>
public void Dispose()
{
this.SaveData();
}
/// <summary>
/// Forces a update from web.
/// </summary>
@@ -335,7 +318,7 @@ namespace CampusAppWP8
{
if (this.file != null)
{
string data = this.file.ReadFile();
byte[] data = this.file.ReadFile();
if (data == null)
{
@@ -343,9 +326,9 @@ namespace CampusAppWP8
}
else
{
if (!data.Equals(string.Empty))
if (data.Length > 0)
{
this.DeserializeModel(Encoding.UTF8.GetBytes(data));
this.DeserializeModel(data);
}
this.RunOnIOCallback(this.OnLoaded);
@@ -494,7 +477,7 @@ namespace CampusAppWP8
if ((this.IsFile() == true)
&& (fileName.Equals(string.Empty) == false))
{
this.InitFile(CampusAppWP8.Utility.File.IOTypeRead.ReadSync, CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync);
this.InitFile();
}
if ((this.IsHttpApi() == true)
@@ -507,16 +490,12 @@ namespace CampusAppWP8
/// <summary>
/// Initializes the file object.
/// </summary>
/// <param name="readType">read io type (Default: sync)</param>
/// <param name="writeType">write io type (Default: async)</param>
private void InitFile(
CampusAppWP8.Utility.File.IOTypeRead readType = CampusAppWP8.Utility.File.IOTypeRead.ReadSync,
CampusAppWP8.Utility.File.IOTypeWrite writeType = CampusAppWP8.Utility.File.IOTypeWrite.WriteAsync)
private void InitFile()
{
if ((this.IsFile() == true)
&& (this.file == null))
{
this.file = new CampusAppWP8.Utility.File(this.fileName, readType, writeType);
this.file = new CampusAppWP8.Utility.File(this.fileName);
}
}
@@ -537,7 +516,7 @@ namespace CampusAppWP8
/// </summary>
/// <param name="sender">sending object</param>
/// <param name="e">event args</param>
private void OnLoadDataComplete(object sender, DownloadStringCompletedEventArgs e)
private void OnLoadDataComplete(object sender, OpenReadCompletedEventArgs e)
{
Exception downloadError = e.Error;
if (downloadError != null)
@@ -546,11 +525,16 @@ namespace CampusAppWP8
}
else
{
string downloadResult = e.Result;
if (downloadResult != null && !downloadResult.Equals(string.Empty))
byte[] data;
using (MemoryStream ms = new MemoryStream())
{
this.DeserializeModel(Encoding.UTF8.GetBytes(downloadResult));
e.Result.CopyTo(ms);
data = ms.ToArray();
}
if (data != null && data.Length > 0)
{
this.DeserializeModel(data);
}
this.RunOnIOCallback(this.OnLoaded);

View File

@@ -15,7 +15,7 @@ namespace CampusAppWP8.Model
/// Xml model io handler class.
/// </summary>
/// <typeparam name="T">model type</typeparam>
public class XmlModel<T> : MainModel<T>
public abstract class XmlModel<T> : MainModel<T>
{
/// <summary>
/// Initializes a new instance of the <see cref="XmlModel{T}" /> class.

View File

@@ -0,0 +1,81 @@
<phone:PhoneApplicationPage
x:Class="CampusAppWP8.Pages.Exams.Exams"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
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:lui="clr-namespace:CampusAppWP8.Utility.Lui.Button"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot ist das Stammraster, in dem alle anderen Seiteninhalte platziert werden-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<ProgressBar Name="ProgressBar" Visibility="Collapsed" IsIndeterminate="True"/>
<phone:Pivot Name="ExamPivot" Title="{Binding Path=LocalizedResources.ExaminationApp_Header, Source={StaticResource LocalizedStrings}}">
<phone:PivotItem Header="{Binding Path=LocalizedResources.Degree_Bachelor, Source={StaticResource LocalizedStrings}}">
<ListBox x:Name="BachelorPanel" ItemsSource="{Binding Value}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Tag="{Binding Link}" Style="{StaticResource ListButtonStyle}" Click="Button_Click">
<TextBlock Text="{Binding Caption}" TextWrapping="Wrap"/>
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
<phone:PivotItem Header="{Binding Path=LocalizedResources.Degree_Master, Source={StaticResource LocalizedStrings}}">
<ListBox x:Name="MasterPanel" ItemsSource="{Binding Value}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Tag="{Binding Link}" Style="{StaticResource ListButtonStyle}" Click="Button_Click">
<TextBlock Text="{Binding Caption}" TextWrapping="Wrap"/>
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
<phone:PivotItem Header="{Binding Path=LocalizedResources.Degree_Diploma, Source={StaticResource LocalizedStrings}}">
<ListBox x:Name="DiplomaPanel" ItemsSource="{Binding Value}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Tag="{Binding Link}" Style="{StaticResource ListButtonStyle}" Click="Button_Click">
<TextBlock Text="{Binding Caption}" TextWrapping="Wrap"/>
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PivotItem>
</phone:Pivot>
</Grid>
</phone:PhoneApplicationPage>

View File

@@ -0,0 +1,203 @@
// <copyright file="Exams.xaml.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>stubbfel</author>
// <sience>02.09.2013</sience>
//----------------------------------------------------------------------
namespace CampusAppWP8.Pages.Exams
{
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using CampusAppWP8.Feed.Exams;
using CampusAppWP8.File.Exams;
using CampusAppWP8.Resources;
using CampusAppWP8.Utility;
using CampusAppWP8.Utility.Lui.MessageBoxes;
using Microsoft.Phone.Controls;
/// <summary>class of ExamsPage.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
public partial class Exams : PhoneApplicationPage
{
/// <summary>The feed.</summary>
private ExamFeed feed;
/// <summary>The exam file.</summary>
private ExamFile file;
/// <summary>Initializes a new instance of the Exams class.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
public Exams()
{
this.InitializeComponent();
this.InitializeFeed();
}
/// <summary>Wird aufgerufen, wenn eine Seite die aktive Seite in einem Frame wird.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
/// <param name="e">Ein Objekt, das die Ereignisdaten enthält.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (this.feed == null)
{
this.InitializeFeed();
}
this.ProgressBar.Visibility = System.Windows.Visibility.Visible;
this.feed.LoadData(Utilities.getLoadModus<Model.Exams.ExamListModel>());
}
/// <summary>
/// Wird aufgerufen, wenn eine Seite nicht mehr die aktive Seite in einem Frame ist.
/// </summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
/// <param name="e">Ein Objekt, das die Ereignisdaten enthält.</param>
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (NavigationMode.Back == e.NavigationMode)
{
App.SaveToIsolatedStorage<int>(Constants.ExamPageModelKey, -1);
this.feed.SaveData();
}
else
{
App.SaveToIsolatedStorage<int>(Constants.ExamPageModelKey, this.ExamPivot.SelectedIndex);
}
}
/// <summary>Method initialize the Feed.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
private void InitializeFeed()
{
this.feed = new ExamFeed();
this.feed.OnLoaded += new ExamFeed.OnIO(this.FeedIsReady);
this.feed.OnFailedWeb += new ExamFeed.OnFailed(this.FeedIsFailWeb);
this.feed.OnFailedFile += new ExamFeed.OnFailed(this.FeedIsFailFile);
}
/// <summary>Method will be execute if the feed is ready.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
private void FeedIsReady()
{
this.SetupExamList();
this.ProgressBar.Visibility = System.Windows.Visibility.Collapsed;
}
/// <summary>Executes the PDF reader operation.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
private void LaunchPDFReader()
{
this.ProgressBar.Visibility = System.Windows.Visibility.Collapsed;
this.file.SaveAndLaunchFile();
}
/// <summary>Sets up the exam list.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
private void SetupExamList()
{
var bachelorList = from exam in this.feed.Model.Exams
where exam.DegreeNumber.Equals(((int)CampusAppWP8.Model.Setting.UserProfilModel.DegreeType.BACHELOR).ToString())
orderby exam.CourseText, exam.Version
select exam;
var masterList = from exam in this.feed.Model.Exams
where exam.DegreeNumber.Equals(((int)CampusAppWP8.Model.Setting.UserProfilModel.DegreeType.MASTER).ToString())
orderby exam.CourseText, exam.Version
select exam;
var diplomaList = from exam in this.feed.Model.Exams
where exam.DegreeNumber.Equals(((int)CampusAppWP8.Model.Setting.UserProfilModel.DegreeType.DIPLOM).ToString())
orderby exam.CourseText, exam.Version
select exam;
this.BachelorPanel.ItemsSource = bachelorList;
this.MasterPanel.ItemsSource = masterList;
this.DiplomaPanel.ItemsSource = diplomaList;
this.ExamPivot.SelectedIndex = this.CalcSelectedIndex();
}
/// <summary>Calculates the selected index.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
/// <returns>The calculated selected index.</returns>
private int CalcSelectedIndex()
{
int result = App.LoadFromIsolatedStorage<int>(Constants.ExamPageModelKey);
if (result < 0 || result > 2)
{
Model.Setting.UserProfilModel.DegreeType degree = Settings.UserProfil.Degree;
switch (degree)
{
case Model.Setting.UserProfilModel.DegreeType.BACHELOR:
result = 0;
break;
case Model.Setting.UserProfilModel.DegreeType.MASTER:
result = 1;
break;
case Model.Setting.UserProfilModel.DegreeType.DIPLOM:
result = 2;
break;
default:
result = 0;
break;
}
}
return result;
}
/// <summary>Method will be execute if the feed is failed.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
private void FeedIsFailWeb()
{
MessageBoxResult result = MessageBoxes.ShowMainModelErrorMessageBox(AppResources.MsgBox_ErrorMainModelLoadWeb);
this.feed.ForceReadFile();
}
/// <summary>Method will be execute if the feed is failed.</summary>
/// <remarks>Stubbfel, 02.09.2013.</remarks>
private void FeedIsFailFile()
{
MessageBoxResult result = MessageBoxes.ShowMainModelErrorMessageBox(AppResources.MsgBox_ErrorMainModelLoadFile);
this.ProgressBar.Visibility = System.Windows.Visibility.Collapsed;
}
/// <summary>Event handler. Called by Button for click events.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="sender">Source of the event.</param>
/// <param name="e"> Routed event information.</param>
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button == null)
{
return;
}
string url = button.Tag as string;
if (url == null)
{
return;
}
// create filename
string[] filenames = url.Split('/');
string filename = url;
if (filenames.Length > 0)
{
filename = filenames[filenames.Length - 1];
}
this.file = new ExamFile(filename, url);
this.file.OnLoaded += new ExamFile.OnIO(this.LaunchPDFReader);
this.file.OnFailedWeb += new ExamFile.OnFailed(this.FeedIsFailWeb);
this.file.OnFailedFile += new ExamFile.OnFailed(this.FeedIsFailFile);
this.file.LoadData();
this.ProgressBar.Visibility = System.Windows.Visibility.Visible;
}
}
}

View File

@@ -158,6 +158,24 @@
</lui:NavigateButton>
</Grid>
<!-- Row 4 -->
<Grid Name="Row4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<lui:NavigateButton Name="examinationAppButton" Url="{Binding Path=Constants.PathExams_ExamsPage, Source={StaticResource Const}}" Grid.Column="0" Style="{StaticResource StartPageButton}">
<StackPanel Style="{StaticResource StartPageStackPanelStyle}">
<Image Source="{Binding Path=ThemelizedIcon.Exams, Source={StaticResource ThemelizedIcons}}" Style="{StaticResource StartPageButtonImg}"/>
<TextBlock Name="examinationAppButtonText" Text="{Binding Path=LocalizedResources.ExaminationApp_Title, Source={StaticResource LocalizedStrings}}" Style="{StaticResource StartPageButtonText}"/>
</StackPanel>
</lui:NavigateButton>
</Grid>
</StackPanel>
</ScrollViewer>

View File

@@ -222,6 +222,24 @@ namespace CampusAppWP8.Resources {
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Prüfungsordnungen ähnelt.
/// </summary>
public static string ExaminationApp_Header {
get {
return ResourceManager.GetString("ExaminationApp_Header", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Prüfungs- ordnungen ähnelt.
/// </summary>
public static string ExaminationApp_Title {
get {
return ResourceManager.GetString("ExaminationApp_Title", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Fakultät ähnelt.
/// </summary>

View File

@@ -419,4 +419,10 @@
<data name="Setting_AppOnlyWifi" xml:space="preserve">
<value>Nur mit Wlan laden</value>
</data>
<data name="ExaminationApp_Title" xml:space="preserve">
<value>Prüfungs- ordnungen</value>
</data>
<data name="ExaminationApp_Header" xml:space="preserve">
<value>Prüfungsordnungen</value>
</data>
</root>

View File

@@ -132,6 +132,24 @@ namespace CampusAppWP8.Resources {
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ExamsPage.LastPivotIndex ähnelt.
/// </summary>
public static string ExamPageModelKey {
get {
return ResourceManager.GetString("ExamPageModelKey", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die links ähnelt.
/// </summary>
public static string ExamXmlValidRootName {
get {
return ResourceManager.GetString("ExamXmlValidRootName", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die DepartmentFavoriteFeed.xml ähnelt.
/// </summary>
@@ -159,6 +177,15 @@ namespace CampusAppWP8.Resources {
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die examlist.xml ähnelt.
/// </summary>
public static string FileExamApp_ExamFeed {
get {
return ResourceManager.GetString("FileExamApp_ExamFeed", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die ClubLinks.xml ähnelt.
/// </summary>
@@ -609,6 +636,15 @@ namespace CampusAppWP8.Resources {
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die /Pages/Exams/Exams.xaml ähnelt.
/// </summary>
public static string PathExams_ExamsPage {
get {
return ResourceManager.GetString("PathExams_ExamsPage", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die /Pages/Lecture/LecturePage.xaml ähnelt.
/// </summary>
@@ -816,6 +852,15 @@ namespace CampusAppWP8.Resources {
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die https://www.zv.tu-cottbus.de/CMS-Webservice/Pruefungsordnung/Uebersicht ähnelt.
/// </summary>
public static string UrlExamApp_ExamFeed {
get {
return ResourceManager.GetString("UrlExamApp_ExamFeed", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die http://www.zv.tu-cottbus.de/LSFveranst/LSF4 ähnelt.
/// </summary>

View File

@@ -435,4 +435,19 @@
<data name="ParamModelMap_SearchTermAlias" xml:space="preserve">
<value>SearchAlias</value>
</data>
<data name="PathExams_ExamsPage" xml:space="preserve">
<value>/Pages/Exams/Exams.xaml</value>
</data>
<data name="ExamXmlValidRootName" xml:space="preserve">
<value>links</value>
</data>
<data name="FileExamApp_ExamFeed" xml:space="preserve">
<value>examlist.xml</value>
</data>
<data name="UrlExamApp_ExamFeed" xml:space="preserve">
<value>https://www.zv.tu-cottbus.de/CMS-Webservice/Pruefungsordnung/Uebersicht</value>
</data>
<data name="ExamPageModelKey" xml:space="preserve">
<value>ExamsPage.LastPivotIndex</value>
</data>
</root>

View File

@@ -99,6 +99,17 @@ namespace CampusAppWP8.Resources
}
}
/// <summary>
/// Gets the uri string of the Exams icon.
/// </summary>
public static string Exams
{
get
{
return Themerize("exams_159.png");
}
}
/// <summary>
/// Gets the uri string of the Favorite icon.
/// </summary>

View File

@@ -138,6 +138,9 @@
<data name="Departments" xml:space="preserve">
<value>departments_159.png</value>
</data>
<data name="Exams" xml:space="preserve">
<value>exams_159.png</value>
</data>
<data name="Favorite" xml:space="preserve">
<value>favorite_159.png</value>
</data>

View File

@@ -10,6 +10,7 @@ namespace CampusAppWP8.Utility
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage;
/// <summary>
@@ -27,27 +28,12 @@ namespace CampusAppWP8.Utility
/// </summary>
private string filename = string.Empty;
/// <summary>
/// Read type.
/// </summary>
private IOTypeRead readType;
/// <summary>
/// Write type.
/// </summary>
private IOTypeWrite writeType;
/// <summary>
/// Initializes a new instance of the <see cref="File" /> class.
/// </summary>
/// <param name="filename">file name</param>
/// <param name="read">read type</param>
/// <param name="write">write type</param>
public File(string filename, IOTypeRead read, IOTypeWrite write)
/// <summary>Initializes a new instance of the <see cref="File" /> class.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="filename"> file name.</param>
public File(string filename)
{
this.filename = filename;
this.readType = (read == IOTypeRead.INVALID) ? IOTypeRead.ReadAsync : read;
this.writeType = write;
}
/// <summary>
@@ -55,113 +41,28 @@ namespace CampusAppWP8.Utility
/// </summary>
public delegate void WriteCallbackFunc();
/// <summary>
/// IO read type ENUM.
/// </summary>
public enum IOTypeRead
/// <summary>Read data from file to a string.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <returns>data string.</returns>
public byte[] ReadFile()
{
/// <summary>
/// Invalid/unset state.
/// </summary>
INVALID = 0,
/// <summary>
/// Sync read.
/// </summary>
ReadSync = 1,
/// <summary>
/// Async read.
/// </summary>
ReadAsync = 2
}
/// <summary>
/// IO write type ENUM.
/// </summary>
public enum IOTypeWrite
{
/// <summary>
/// Invalid/unset state.
/// </summary>
INVALID = 0,
/// <summary>
/// Sync write.
/// </summary>
WriteSync = 1,
/// <summary>
/// Async write.
/// </summary>
WriteAsync = 2,
/// <summary>
/// Read only, no writing.
/// </summary>
ReadOnly = 3
}
/// <summary>
/// Read data from file to a string.
/// </summary>
/// <param name="ioType">read type</param>
/// <returns>data string</returns>
public string ReadFile(IOTypeRead ioType = IOTypeRead.INVALID)
{
string retValue = null;
byte[] 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();
}
retValue = this.ReadSync();
}
return retValue;
}
/// <summary>
/// Write bytes to the file.
/// </summary>
/// <param name="data">data byte array.</param>
/// <param name="onSavedCallback">callback function, called after writing is done.</param>
/// <summary>Write bytes to the file.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="data"> data byte array.</param>
/// <param name="onSavedCallback"> callback function, called after writing is done.</param>
/// <param name="onFailedCallback">callback function, called when writing failed.</param>
/// <param name="ioType">write type.</param>
public void WriteFile(byte[] data, WriteCallbackFunc onSavedCallback, WriteCallbackFunc onFailedCallback, IOTypeWrite ioType = IOTypeWrite.INVALID)
public void WriteFile(byte[] data, WriteCallbackFunc onSavedCallback, WriteCallbackFunc onFailedCallback)
{
IOTypeWrite tempType = ioType;
if (tempType == IOTypeWrite.INVALID)
{
tempType = this.writeType;
}
/*
if (tempType == IOTypeWrite.WriteAsync)
{
this.WriteAsync(data, onSavedCallback, onFailedCallback);
}
else if (tempType == IOTypeWrite.WriteSync)
{
// this.WriteSync(data);
this.WriteAsync(data, onSavedCallback, onFailedCallback);
}
*/
Thread th = new Thread(delegate() { this.WriteAsync(data, onSavedCallback, onFailedCallback); });
th.Start();
}
@@ -185,48 +86,39 @@ namespace CampusAppWP8.Utility
return this.GetFileInfo().Exists;
}
/// <summary>Converts this object to a storage file.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <returns>Storage File</returns>
public async Task<StorageFile> AsStorageFile()
{
if (this.Exist())
{
return await File.LocalFolder.GetFileAsync(this.filename);
}
return null;
}
/// <summary>
/// Read data synchronous from file.
/// </summary>
/// <returns>data string</returns>
private string ReadSync()
private byte[] ReadSync()
{
string retValue = null;
byte[] retValue = null;
using (Stream fileStream = File.LocalFolder.OpenStreamForReadAsync(this.filename).Result)
{
using (StreamReader streamReader = new StreamReader(fileStream))
using (MemoryStream ms = new MemoryStream())
{
retValue = streamReader.ReadToEnd();
fileStream.CopyTo(ms);
retValue = ms.ToArray();
}
}
return retValue;
}
/// <summary>
/// Read data asynchronous from file.
/// </summary>
/// <returns>data string</returns>
private string ReadAsync()
{
string retValue = string.Empty;
return retValue;
}
/// <summary>
/// Write data synchronous to file.
/// </summary>
/// <param name="data">data array</param>
/// <returns>true, if succeeded</returns>
private bool WriteSync(byte[] data)
{
bool retValue = true;
return retValue;
}
/// <summary>
/// Write data asynchronous to file.
/// </summary>

View File

@@ -60,6 +60,17 @@ namespace CampusAppWP8.Utility
client.DownloadStringAsync(url);
}
/// <summary>Method realize the http-get-method resource.</summary>
/// <remarks>Stubbfel, 03.09.2013.</remarks>
/// <param name="url"> Url of the resource.</param>
/// <param name="action">The action.</param>
public void HttpGet(Uri url, Action<object, OpenReadCompletedEventArgs> action)
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(action);
client.OpenReadAsync(url);
}
/// <summary>
/// Method create the Url for the http-get-method
/// </summary>

View File

@@ -31,8 +31,9 @@ namespace CampusAppWP8.Utility
/// <param name="inputString">String with Html-Tags</param>
/// <returns>String without Html-Tags</returns>
public static string StripHTML(string inputString)
{
return Regex.Replace(inputString, HtmlTagPattern, string.Empty);
{
string result = Regex.Replace(inputString, HtmlTagPattern, string.Empty);
return System.Net.HttpUtility.HtmlDecode(result);
}
/// <summary>

View File

@@ -0,0 +1,50 @@
import cairo
import rsvg
import xml.etree.ElementTree as ET
def convertSVGToPNG(src, dst, dstWidth, dstHeight, srcWidth, srcHeight, style,layerID):
ET.register_namespace("","http://www.w3.org/2000/svg")
tree = ET.parse(src)
root = tree.getroot()
for layer in root.findall('./{http://www.w3.org/2000/svg}g'):
name = layer.get('{http://www.inkscape.org/namespaces/inkscape}label')
if name in layerID :
for path in layer.findall('./{http://www.w3.org/2000/svg}path'):
path.set("style",style)
else :
root.remove(layer)
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, dstWidth, dstHeight)
ctx = cairo.Context(img)
width_ratio = float(dstWidth) / float(srcWidth)
height_ratio = float(dstHeight) / float(srcHeight)
ctx.scale(width_ratio, height_ratio)
handler= rsvg.Handle(None,str(ET.tostring(root, encoding='utf8', method='xml')))
handler.render_cairo(ctx)
img.write_to_png(dst)
def convertSVGToPNG2(src, dst, dstWidth, dstHeight, srcWidth, srcHeight, style,layerID):
ET.register_namespace("","http://www.w3.org/2000/svg")
tree = ET.parse(src)
root = tree.getroot()
for path in root.findall('./{http://www.w3.org/2000/svg}path'):
path.set("style",style)
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, dstWidth, dstHeight)
ctx = cairo.Context(img)
width_ratio = float(dstWidth) / float(srcWidth)
height_ratio = float(dstHeight) / float(srcHeight)
ctx.scale(width_ratio, height_ratio)
handler= rsvg.Handle(None,str(ET.tostring(root, encoding='utf8', method='xml')))
handler.render_cairo(ctx)
img.write_to_png(dst)

Binary file not shown.

View File

@@ -0,0 +1,44 @@
import IconCreator
import os
os.chdir("srcImages/functions")
for files in os.listdir("."):
if files.endswith(".svg"):
fileName, fileExtension = os.path.splitext(files)
IconCreator.convertSVGToPNG(files, "../../dstImages/wp8/159x159/LightTheme/functions/"+fileName+".png",159,159,256,256,"fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" , "Icon")
IconCreator.convertSVGToPNG(files, "../../dstImages/wp8/159x159/DarkTheme/functions/"+fileName+".png",159,159,256,256,"fill:#FFFFFF;fill-opacity:1;fill-rule:evenodd;stroke:none", "Icon")
os.chdir("../../")
os.chdir("srcImages/emotions")
for files in os.listdir("."):
if files.endswith(".svg"):
fileName, fileExtension = os.path.splitext(files)
IconCreator.convertSVGToPNG(files, "../../dstImages/wp8/159x159/LightTheme/emotions/"+fileName+".png",159,159,256,256,"fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" , "Emotion Speechbubble")
IconCreator.convertSVGToPNG(files, "../../dstImages/wp8/159x159/DarkTheme/emotions/"+fileName+".png",159,159,256,256,"fill:#FFFFFF;fill-opacity:1;fill-rule:evenodd;stroke:none", "Emotion Speechbubble")
os.chdir("../../")
os.chdir("srcImages/listicons")
for files in os.listdir("."):
if files.endswith(".svg"):
fileName, fileExtension = os.path.splitext(files)
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/LightTheme/listicons/"+fileName+".png",159,159,256,256,"fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" , "Icon")
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/DarkTheme/listicons/"+fileName+".png",159,159,256,256,"fill:#FFFFFF;fill-opacity:1;fill-rule:evenodd;stroke:none", "Icon")
os.chdir("../../")
os.chdir("srcImages/optionbuttons")
for files in os.listdir("."):
if files.endswith(".svg"):
fileName, fileExtension = os.path.splitext(files)
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/LightTheme/optionbuttons/"+fileName+".png",159,159,256,256,"fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" , "Icon")
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/DarkTheme/optionbuttons/"+fileName+".png",159,159,256,256,"fill:#FFFFFF;fill-opacity:1;fill-rule:evenodd;stroke:none", "Icon")
os.chdir("../../")
os.chdir("srcImages/others")
for files in os.listdir("."):
if files.endswith(".svg"):
fileName, fileExtension = os.path.splitext(files)
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/LightTheme/others/"+fileName+".png",159,159,256,256,"fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" , "Icon")
IconCreator.convertSVGToPNG2(files, "../../dstImages/wp8/159x159/DarkTheme/others/"+fileName+".png",159,159,256,256,"fill:#FFFFFF;fill-opacity:1;fill-rule:evenodd;stroke:none", "Icon")
os.chdir("../../")