summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2011-11-20 18:30:43 +0000
committersr55 <[email protected]>2011-11-20 18:30:43 +0000
commitc0c88720f5f59104770be38f0e84d7c2897ef465 (patch)
treeb1a17f7d388203cf99f5eec0665c1806dd1b8221
parent24cfd6cf3e18288052533ea385a6d0b648fac139 (diff)
WinGui: (WPF) Add global exception handler and new wpf exception view.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4361 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--win/CS/HandBrakeWPF/App.xaml.cs96
-rw-r--r--win/CS/HandBrakeWPF/Factories/ViewModelFactory.cs14
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj12
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ErrorViewModel.cs137
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/Interfaces/IErrorViewModel.cs18
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ViewModelBase.cs46
-rw-r--r--win/CS/HandBrakeWPF/Views/ErrorView.xaml55
-rw-r--r--win/CS/HandBrakeWPF/Views/ErrorView.xaml.cs27
8 files changed, 395 insertions, 10 deletions
diff --git a/win/CS/HandBrakeWPF/App.xaml.cs b/win/CS/HandBrakeWPF/App.xaml.cs
index e934546cf..13efba30b 100644
--- a/win/CS/HandBrakeWPF/App.xaml.cs
+++ b/win/CS/HandBrakeWPF/App.xaml.cs
@@ -1,20 +1,106 @@
-/* App.xaml.cs $
- This file is part of the HandBrake source code.
- Homepage: <http://handbrake.fr>.
- It may be used under the terms of the GNU General Public License. */
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="App.xaml.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Interaction logic for App.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
namespace HandBrakeWPF
{
+ using System;
+ using System.Windows;
+
+ using Caliburn.Micro;
+
+ using HandBrake.ApplicationServices.Exceptions;
+
+ using HandBrakeWPF.ViewModels;
+
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
- public partial class App
+ public partial class App
{
/// <summary>
/// Initializes a new instance of the <see cref="App"/> class.
/// </summary>
public App()
{
+ Application.Current.Dispatcher.UnhandledException += this.Dispatcher_UnhandledException;
+ AppDomain.CurrentDomain.UnhandledException +=
+ new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
+ }
+
+ /// <summary>
+ /// Non-UI Thread expection handler.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The UnhandledExceptionEventArgs.
+ /// </param>
+ private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ this.ShowError(e.ExceptionObject);
+ }
+
+ /// <summary>
+ /// Handle unhandled exceptions. UI thread only.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The DispatcherUnhandledExceptionEventArgs.
+ /// </param>
+ private void Dispatcher_UnhandledException(
+ object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ this.ShowError(e.Exception);
+ e.Handled = true;
+ }
+
+ /// <summary>
+ /// Show an error dialog for the user.
+ /// </summary>
+ /// <param name="exception">
+ /// The exception.
+ /// </param>
+ private void ShowError(object exception)
+ {
+ try
+ {
+ IWindowManager windowManager = IoC.Get<IWindowManager>();
+ if (windowManager != null)
+ {
+ ErrorViewModel errorView = new ErrorViewModel();
+
+ if (exception.GetType() == typeof(GeneralApplicationException))
+ {
+ GeneralApplicationException applicationException = exception as GeneralApplicationException;
+ if (applicationException != null)
+ {
+ errorView.ErrorMessage = applicationException.Error;
+ errorView.Solution = applicationException.Solution;
+ errorView.Details = applicationException.ActualException.ToString();
+ }
+ }
+ else
+ {
+ errorView.Details = exception.ToString();
+ }
+
+ windowManager.ShowDialog(errorView);
+ }
+ }
+ catch (Exception)
+ {
+ MessageBox.Show("An Unknown Error has occured. \n\n Exception:" + exception, "Unhandled Exception",
+ MessageBoxButton.OK, MessageBoxImage.Error);
+ }
}
}
}
diff --git a/win/CS/HandBrakeWPF/Factories/ViewModelFactory.cs b/win/CS/HandBrakeWPF/Factories/ViewModelFactory.cs
index 6b110fcd1..2c840f441 100644
--- a/win/CS/HandBrakeWPF/Factories/ViewModelFactory.cs
+++ b/win/CS/HandBrakeWPF/Factories/ViewModelFactory.cs
@@ -13,6 +13,9 @@ namespace HandBrakeWPF.Factories
using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrakeWPF.ViewModels;
+ using HandBrakeWPF.ViewModels.Interfaces;
+
/// <summary>
/// The View Model Factory
/// </summary>
@@ -42,5 +45,16 @@ namespace HandBrakeWPF.Factories
this.windowManager = windowManager;
this.userSettingsService = userSettingsService;
}
+
+ /// <summary>
+ /// Create an ErrorViewModel
+ /// </summary>
+ /// <returns>
+ /// An Error ViewModel
+ /// </returns>
+ public IErrorViewModel CreateErrorViewModel()
+ {
+ return new ErrorViewModel();
+ }
}
}
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index 6cdf5c969..ce8a1b9d9 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -54,6 +54,8 @@
<Reference Include="Ookii.Dialogs.Wpf">
<HintPath>..\libraries\OokiiDialogs\Ookii.Dialogs.Wpf.dll</HintPath>
</Reference>
+ <Reference Include="PresentationFramework" />
+ <Reference Include="PresentationFramework.Aero" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
@@ -70,7 +72,6 @@
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
- <Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
@@ -84,6 +85,8 @@
<Compile Include="UserSettingConstants.cs" />
<Compile Include="ViewModels\AboutViewModel.cs" />
<Compile Include="ViewModels\AddPresetViewModel.cs" />
+ <Compile Include="ViewModels\ErrorViewModel.cs" />
+ <Compile Include="ViewModels\Interfaces\IErrorViewModel.cs" />
<Compile Include="ViewModels\Interfaces\ILogViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IAboutViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IMainViewModel.cs" />
@@ -114,6 +117,9 @@
<Compile Include="Views\AddPresetView.xaml.cs">
<DependentUpon>AddPresetView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\ErrorView.xaml.cs">
+ <DependentUpon>ErrorView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\LogView.xaml.cs">
<DependentUpon>LogView.xaml</DependentUpon>
</Compile>
@@ -191,6 +197,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Views\ErrorView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\LogView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/win/CS/HandBrakeWPF/ViewModels/ErrorViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ErrorViewModel.cs
new file mode 100644
index 000000000..b93671970
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/ErrorViewModel.cs
@@ -0,0 +1,137 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ErrorViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the ErrorViewModel type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels
+{
+ using System;
+ using System.ComponentModel.Composition;
+ using System.Windows;
+
+ using HandBrakeWPF.ViewModels.Interfaces;
+
+ /// <summary>
+ /// The Error View Model
+ /// </summary>
+ [Export(typeof(IErrorViewModel))]
+ public class ErrorViewModel : ViewModelBase, IErrorViewModel
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// The details.
+ /// </summary>
+ private string details;
+
+ /// <summary>
+ /// The error message.
+ /// </summary>
+ private string errorMessage;
+
+ /// <summary>
+ /// The solution.
+ /// </summary>
+ private string solution;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ErrorViewModel"/> class.
+ /// </summary>
+ public ErrorViewModel()
+ : base(null)
+ {
+ this.Title = "Error";
+ this.ErrorMessage = "An Unknown Error has occured.";
+ this.Details = "There is no further information available about this error.";
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets Details.
+ /// </summary>
+ public string Details
+ {
+ get
+ {
+ return string.IsNullOrEmpty(this.details) ? "There is no further information available about this error." : this.details;
+ }
+
+ set
+ {
+ this.details = value;
+ this.NotifyOfPropertyChange("Details");
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets ErrorMessage.
+ /// </summary>
+ public string ErrorMessage
+ {
+ get
+ {
+ return this.errorMessage;
+ }
+
+ set
+ {
+ this.errorMessage = value;
+ this.NotifyOfPropertyChange("ErrorMessage");
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Solution.
+ /// </summary>
+ public string Solution
+ {
+ get
+ {
+ return string.IsNullOrEmpty(this.solution) ? "If the problem presists, please try restarting HandBrake." : this.solution;
+ }
+
+ set
+ {
+ this.solution = value;
+ this.NotifyOfPropertyChange("Solution");
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Close this window.
+ /// </summary>
+ public void Close()
+ {
+ try
+ {
+ this.TryClose();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+
+ }
+
+ /// <summary>
+ /// Copy the Error to the clipboard.
+ /// </summary>
+ public void Copy()
+ {
+ Clipboard.SetDataObject(this.ErrorMessage + Environment.NewLine + this.Details, true);
+ }
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IErrorViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IErrorViewModel.cs
new file mode 100644
index 000000000..51a2b7a98
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IErrorViewModel.cs
@@ -0,0 +1,18 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IErrorViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the IErrorViewModel type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels.Interfaces
+{
+ /// <summary>
+ /// The Error View Model Interface
+ /// </summary>
+ public interface IErrorViewModel
+ {
+ }
+}
diff --git a/win/CS/HandBrakeWPF/ViewModels/ViewModelBase.cs b/win/CS/HandBrakeWPF/ViewModels/ViewModelBase.cs
index f9781800c..e226fc549 100644
--- a/win/CS/HandBrakeWPF/ViewModels/ViewModelBase.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/ViewModelBase.cs
@@ -18,12 +18,23 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public class ViewModelBase : Screen, IViewModelBase
{
+ #region Constants and Fields
+
/// <summary>
/// Backing Field to prevent the Load method being called more than once.
/// </summary>
private bool hasLoaded;
/// <summary>
+ /// The title.
+ /// </summary>
+ private string title;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
/// Initializes a new instance of the <see cref="ViewModelBase"/> class.
/// </summary>
/// <param name="windowManager">
@@ -34,22 +45,47 @@ namespace HandBrakeWPF.ViewModels
this.WindowManager = windowManager;
}
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets Details.
+ /// </summary>
+ public string Title
+ {
+ get
+ {
+ return this.title;
+ }
+
+ set
+ {
+ this.title = value;
+ this.NotifyOfPropertyChange("Title");
+ }
+ }
+
/// <summary>
/// Gets WindowManager.
/// </summary>
public IWindowManager WindowManager { get; private set; }
+ #endregion
+
+ #region Public Methods
+
/// <summary>
/// Perform any Initialisation for this ViewModelBase.
/// </summary>
public void Load()
{
- if (!hasLoaded)
+ if (!this.hasLoaded)
{
- hasLoaded = true;
+ this.hasLoaded = true;
// Initialise the ViewModels OnLoad method if it exists.
- this.OnLoad();
+ this.OnLoad();
}
}
@@ -60,5 +96,7 @@ namespace HandBrakeWPF.ViewModels
{
// Impliment in the ViewModel to perform viewmodel specific code.
}
+
+ #endregion
}
-}
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Views/ErrorView.xaml b/win/CS/HandBrakeWPF/Views/ErrorView.xaml
new file mode 100644
index 000000000..c0c7f8d45
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/ErrorView.xaml
@@ -0,0 +1,55 @@
+<Window x:Class="HandBrakeWPF.Views.ErrorView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cal="http://www.caliburnproject.org"
+ Title="{Binding Title}" Height="380" Width="680" FontSize="11" Background="#FFF0F0F0">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="70" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <!-- Header -->
+ <StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,0" Background="White">
+ <Image Source="Images/ErrorX.png" Width="64" Height="64" Margin="10,0,0,0" />
+ <Grid Margin="10,0,0,0" Height="64">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <TextBlock Text="{Binding ErrorMessage}" FontWeight="Bold" Grid.Row="0" Margin="0,5,0,0" />
+ <TextBlock Text="{Binding Solution}" Grid.Row="1" Margin="0,5,0,0" />
+
+ <TextBlock Text="Error Details:" FontWeight="Bold" Margin="0,0,0,2" VerticalAlignment="Bottom" Grid.Row="2" />
+ </Grid>
+ </StackPanel>
+
+ <!-- Details -->
+ <TextBox Text="{Binding Details}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsReadOnly="True" TextWrapping="Wrap"
+ VerticalScrollBarVisibility="Auto" Margin="84,10,10,10" Grid.Row="1" />
+
+
+ <!-- Controls -->
+ <Grid Grid.Row ="2" Background="LightGray">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+ <Button Padding="8,2" Margin="5" Grid.Column="1" cal:Message.Attach="[Event Click] = [Action Copy]">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Image Source="Images/copy.png" Grid.Column="0" Width="16" Height="16" />
+ <TextBlock Text="Copy" Grid.Column="1" />
+ </Grid>
+ </Button>
+
+ <Button Content="Close" Padding="8,2" Margin="0,5,10,5" Grid.Column="2" cal:Message.Attach="[Event Click] = [Action Close]"></Button>
+ </Grid>
+ </Grid>
+</Window>
diff --git a/win/CS/HandBrakeWPF/Views/ErrorView.xaml.cs b/win/CS/HandBrakeWPF/Views/ErrorView.xaml.cs
new file mode 100644
index 000000000..b21194e35
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/ErrorView.xaml.cs
@@ -0,0 +1,27 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ErrorView.xaml.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Interaction logic for ErrorView.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Views
+{
+ using System.Windows;
+
+ /// <summary>
+ /// Interaction logic for ErrorView.xaml
+ /// </summary>
+ public partial class ErrorView : Window
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ErrorView"/> class.
+ /// </summary>
+ public ErrorView()
+ {
+ InitializeComponent();
+ }
+ }
+}