diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-12-13 00:23:55 +0200 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2019-12-13 00:23:55 +0200 |
| commit | fea4547613d57f8fcc8cb94671c54d82a5b11dbb (patch) | |
| tree | 19db6439b6694884da2414df5d6ae92ba2464bcf /Software/Visual_Studio | |
| parent | 85e27ca4c292329a894a49ed950912285465fa2e (diff) | |
| download | Tango-fea4547613d57f8fcc8cb94671c54d82a5b11dbb.tar.gz Tango-fea4547613d57f8fcc8cb94671c54d82a5b11dbb.zip | |
Added browser cef loading error support.
Implemented better module loading error handling in general.
Diffstat (limited to 'Software/Visual_Studio')
11 files changed, 209 insertions, 107 deletions
diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/BrowserModule.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/BrowserModule.cs index cd8372277..dc7b294d5 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/BrowserModule.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/BrowserModule.cs @@ -10,6 +10,8 @@ using Tango.PPC.Browser.Views; using Tango.SharedUI.Helpers; using Tango.Core.DI; using Tango.PPC.Common.Application; +using System.IO; +using Tango.Core.Helpers; namespace Tango.PPC.Browser { @@ -68,7 +70,7 @@ namespace Tango.PPC.Browser { get { - return typeof(BrowserView); + return IsCefAvailable() ? typeof(BrowserView) : typeof(ErrorView); } } @@ -83,6 +85,11 @@ namespace Tango.PPC.Browser } } + private bool IsCefAvailable() + { + return File.Exists(Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "x86", "CefSharp.Core.dll")); + } + /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Tango.PPC.Browser.csproj b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Tango.PPC.Browser.csproj index 58d525c32..b742d4d75 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Tango.PPC.Browser.csproj +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Tango.PPC.Browser.csproj @@ -80,6 +80,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\ErrorView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> </ItemGroup> <ItemGroup> <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> @@ -110,6 +114,9 @@ <Compile Include="Views\BrowserView.xaml.cs"> <DependentUpon>BrowserView.xaml</DependentUpon> </Compile> + <Compile Include="Views\ErrorView.xaml.cs"> + <DependentUpon>ErrorView.xaml</DependentUpon> + </Compile> <EmbeddedResource Include="Properties\Resources.resx"> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/ViewModels/BrowserViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/ViewModels/BrowserViewVM.cs index 9f66bb6a6..9650aa342 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/ViewModels/BrowserViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/ViewModels/BrowserViewVM.cs @@ -1,6 +1,4 @@ -using CefSharp; -using CefSharp.Wpf; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -42,23 +40,6 @@ namespace Tango.PPC.Browser.ViewModels { DisplayAddressBar = true; - if (!DesignMode) - { - try - { - var settings = new CefSettings(); - settings.BrowserSubprocessPath = @"x86\CefSharp.BrowserSubprocess.exe"; - settings.UserAgent = "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"; - - Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null); - } - catch (Exception ex) - { - //Log Here Not Throw! - throw; - } - } - GoCommand = new RelayCommand(Go); } @@ -76,6 +57,7 @@ namespace Tango.PPC.Browser.ViewModels public override void OnNavigatedTo() { base.OnNavigatedTo(); + KeyboardView.Default.OutputMode = KeyboardOutputMode.Windows; if (!_isFromObject) @@ -92,9 +74,9 @@ namespace Tango.PPC.Browser.ViewModels KeyboardView.Default.OutputMode = KeyboardOutputMode.Wpf; } - public override Task<bool> OnNavigateBackRequest() + public override Task<bool> OnNavigateBackRequest() { - if (View.CanGoBack()) + if (View != null && View.CanGoBack()) { View.GoBack(); return Task.FromResult(false); @@ -115,7 +97,10 @@ namespace Tango.PPC.Browser.ViewModels private void Go() { - View.NavigateTo(Address); + if (View != null) + { + View.NavigateTo(Address); + } } public void OnNavigatedToWithObject(BrowserNavigationRequest obj) diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/BrowserView.xaml.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/BrowserView.xaml.cs index e3f4c29e3..cdba301ed 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/BrowserView.xaml.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/BrowserView.xaml.cs @@ -19,6 +19,7 @@ using CefSharp; using CefSharp.Wpf; using Tango.Core.DI; using Tango.Core.Helpers; +using Tango.Logging; using Tango.PPC.Browser.BoundsObjects; using Tango.PPC.Browser.ViewContracts; using Tango.PPC.Common.Helpers; @@ -35,6 +36,19 @@ namespace Tango.PPC.Browser.Views public BrowserView() { + try + { + var settings = new CefSettings(); + settings.BrowserSubprocessPath = @"x86\CefSharp.BrowserSubprocess.exe"; + settings.UserAgent = "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"; + + Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null); + } + catch (Exception ex) + { + LogManager.Default.Log(ex, "Error loading cef."); + } + InitializeComponent(); TangoIOC.Default.Register<IBrowserView>(this); diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml new file mode 100644 index 000000000..25e3381ba --- /dev/null +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml @@ -0,0 +1,23 @@ +<UserControl x:Class="Tango.PPC.Browser.Views.ErrorView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:vm="clr-namespace:Tango.PPC.Browser.ViewModels" + xmlns:global="clr-namespace:Tango.PPC.Browser" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Tango.PPC.Browser.Views" + mc:Ignorable="d" + d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:BrowserViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.BrowserViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> + <Grid> + <Grid Background="White" IsHitTestVisible="False"> + <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> + <touch:TouchIcon Icon="Alert" Foreground="{StaticResource TangoGrayTextBrush}" Width="100" Height="100" /> + <TextBlock HorizontalAlignment="Center" Foreground="{StaticResource TangoGrayTextBrush}" FontSize="40" Margin="0 20 0 0">Browser Not Loaded</TextBlock> + <TextBlock Margin="0 10 0 0" Foreground="{StaticResource TangoGrayTextBrush}" HorizontalAlignment="Center" Width="600" TextAlignment="Center" TextWrapping="Wrap"> + The browser module was not loaded properly or has caused some error. + </TextBlock> + </StackPanel> + </Grid> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml.cs new file mode 100644 index 000000000..0d59b80f0 --- /dev/null +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Browser/Views/ErrorView.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.PPC.Browser.ViewContracts; + +namespace Tango.PPC.Browser.Views +{ + /// <summary> + /// Interaction logic for ErrorView.xaml + /// </summary> + public partial class ErrorView : UserControl + { + public ErrorView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs index feb7e371f..375b648d0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs @@ -103,7 +103,7 @@ namespace Tango.PPC.UI.Modules if (moduleAssembly != null) { - foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) + foreach (var moduleType in moduleAssembly.GetLoadableTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) { if (!AllModules.ToList().Exists(x => x.GetType() == moduleType)) { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs index 2a825cc19..3502648d4 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs @@ -12,6 +12,7 @@ using Tango.Core.Commands; using Tango.PPC.Common; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Notifications; using Tango.PPC.Common.Threading; using Tango.PPC.UI.Views; using Tango.SharedUI.Controls; @@ -36,6 +37,7 @@ namespace Tango.PPC.UI.Navigation private List<AwaitingVMResult> _awaitingVMResults; private IDispatcherProvider _dispatcherProvider; private IPPCModuleLoader _moduleLoader; + private INotificationProvider _notificationProvider; private Object _currentVM; private String _lastFullPath; private bool _preventHistory; @@ -75,12 +77,13 @@ namespace Tango.PPC.UI.Navigation /// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class. /// </summary> /// <param name="moduleLoader">The module loader.</param> - public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider) + public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider) { IsBackEnabled = true; _awaitingVMResults = new List<AwaitingVMResult>(); _navigationHistory = new Stack<String>(); _moduleLoader = moduleLoader; + _notificationProvider = notificationProvider; NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x)); NavigateBackCommand = new RelayCommand(async () => await NavigateBack()); @@ -197,105 +200,127 @@ namespace Tango.PPC.UI.Navigation /// <param name="fullPath">The full path.</param> public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<PPCViewModel, PPCViewModel> onNavigating = null, Action<PPCViewModel, PPCViewModel> onNavigated = null) { - String[] path = fullPath.Split('.'); - var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); + try + { + String[] path = fullPath.Split('.'); + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); + + if (module == null) + { + await _notificationProvider.ShowError("The specified module was not loaded."); + return false; + } - if (path.Length == 1 && path[0] == CurrentModule.Name) return true; + if (path.Length == 1 && path[0] == CurrentModule.Name) return true; - LogManager.Log($"Navigating to: {fullPath}..."); + LogManager.Log($"Navigating to: {fullPath}..."); - var fromVM = _currentVM; + var fromVM = _currentVM; - if (_currentVM != null && _currentVM is INavigationBlocker) - { - if (_navigating_back) + if (_currentVM != null && _currentVM is INavigationBlocker) { - if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) + if (_navigating_back) { - return false; + if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) + { + return false; + } } - } - else - { - if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + else { - return false; + if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + { + return false; + } } } - } - if (pushToHistory && _lastFullPath != null && !_preventHistory) - { - _navigationHistory.Push(_lastFullPath); - RaisePropertyChanged(nameof(CanNavigateBack)); - } - - _lastFullPath = fullPath; + if (pushToHistory && _lastFullPath != null && !_preventHistory) + { + _navigationHistory.Push(_lastFullPath); + RaisePropertyChanged(nameof(CanNavigateBack)); + } - MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); - var navigationControl = LayoutView.Instance.NavigationControl; - CurrentModule = module; - var moduleView = navigationControl.NavigateTo(module.Name); + _lastFullPath = fullPath; - _currentVM = moduleView.DataContext; + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var navigationControl = LayoutView.Instance.NavigationControl; + CurrentModule = module; + var moduleView = navigationControl.NavigateTo(module.Name); - if (path.Length > 1) - { - var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); + _currentVM = moduleView.DataContext; - if (moduleNavigation != null) + if (path.Length > 1) { - moduleNavigation.RegisterForLoadedOrNow(async (x, e) => - { - var lastView = moduleNavigation.GetElement(path.Last()); - - if (lastView != null) - { - onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel); - } + var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); - foreach (var view in path.Skip(1)) + if (moduleNavigation != null) + { + moduleNavigation.RegisterForLoadedOrNow(async (x, e) => { - await Task.Delay(100); + var lastView = moduleNavigation.GetElement(path.Last()); - FrameworkElement v = null; + if (lastView != null) + { + onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel); + } - v = moduleNavigation.NavigateTo(view, () => + foreach (var view in path.Skip(1)) { - if (v != null) + await Task.Delay(100); + + FrameworkElement v = null; + + v = moduleNavigation.NavigateTo(view, () => { - NotifyOnNavigated(fromVM, v.DataContext); - onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel); - NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel); - } - }); + if (v != null) + { + NotifyOnNavigated(fromVM, v.DataContext); + onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + } + }); - NotifyOnBeforeNavigated(fromVM, v.DataContext); + NotifyOnBeforeNavigated(fromVM, v.DataContext); - if (v != null) - { - _currentVM = v.DataContext; + if (v != null) + { + _currentVM = v.DataContext; - if (view != path.Last()) + if (view != path.Last()) + { + moduleNavigation = v.FindChildOffline<NavigationControl>(); + } + } + else { - moduleNavigation = v.FindChildOffline<NavigationControl>(); + throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); } } - else - { - throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); - } - } - }); + }); + } + else + { + onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); + + NotifyOnBeforeNavigated(fromVM, _currentVM); + + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); + + NotifyOnNavigated(fromVM, _currentVM); + + onNavigated?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, _currentVM as PPCViewModel); + } } else { - onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); - NotifyOnBeforeNavigated(fromVM, _currentVM); + onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); NotifyOnNavigated(fromVM, _currentVM); @@ -303,22 +328,14 @@ namespace Tango.PPC.UI.Navigation onNavigated?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); NotifyAwaitingVMResults(fromVM as PPCViewModel, _currentVM as PPCViewModel); } + + return true; } - else + catch (Exception ex) { - NotifyOnBeforeNavigated(fromVM, _currentVM); - - onNavigating?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); - - await Task.Delay(navigationControl.TransitionDuration.TimeSpan); - - NotifyOnNavigated(fromVM, _currentVM); - - onNavigated?.Invoke(fromVM as PPCViewModel, _currentVM as PPCViewModel); - NotifyAwaitingVMResults(fromVM as PPCViewModel, _currentVM as PPCViewModel); + await _notificationProvider.ShowError($"Error navigating to '{fullPath}'."); + return false; } - - return true; } /// <summary> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index 8bb1c0fe3..206aa112b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -342,10 +342,17 @@ namespace Tango.PPC.UI.PPCApplication { if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType)) { - LogManager.Log("Loading module view " + module.Name + "..."); - FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; - SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); - Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + try + { + LogManager.Log("Loading module view " + module.Name + "..."); + FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; + SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); + Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading module view for module {module.Name}."); + } } } }); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index 27fbf49d8..4e4e760f9 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -468,6 +468,7 @@ <ProjectReference Include="..\Modules\Tango.PPC.Browser\Tango.PPC.Browser.csproj"> <Project>{f02eaa84-ad59-465b-99a2-4422c13bfb72}</Project> <Name>Tango.PPC.Browser</Name> + <Private>True</Private> </ProjectReference> <ProjectReference Include="..\Modules\Tango.PPC.BugReporting\Tango.PPC.BugReporting.csproj"> <Project>{8146fa0a-0725-4a1a-82e6-696c58f33a2b}</Project> diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/AssemblyExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/AssemblyExtensions.cs index f75e76d3a..bad90d47f 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/AssemblyExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/AssemblyExtensions.cs @@ -33,5 +33,17 @@ public static class AssemblyExtensions .AddDays(version.Revision); } } + + public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) + { + try + { + return assembly.GetTypes(); + } + catch (ReflectionTypeLoadException e) + { + return e.Types.Where(t => t != null); + } + } } |
