Still working on the taskbar. Implemented basic version of taskbar buttons with instance popup and made splash screen localizable.
This commit is contained in:
		
							parent
							
								
									fefe1feb01
								
							
						
					
					
						commit
						e623101f8c
					
				
					 27 changed files with 421 additions and 163 deletions
				
			
		
							
								
								
									
										30
									
								
								SafeExamBrowser.Browser/BrowserApplicationController.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SafeExamBrowser.Browser/BrowserApplicationController.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using SafeExamBrowser.Contracts.Behaviour; | ||||||
|  | using SafeExamBrowser.Contracts.UserInterface; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Browser | ||||||
|  | { | ||||||
|  | 	public class BrowserApplicationController : IApplicationController | ||||||
|  | 	{ | ||||||
|  | 		private IApplicationButton button; | ||||||
|  | 
 | ||||||
|  | 		public void RegisterApplicationButton(IApplicationButton button) | ||||||
|  | 		{ | ||||||
|  | 			this.button = button; | ||||||
|  | 			this.button.OnClick += ButtonClick; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void ButtonClick(Guid? instanceId = null) | ||||||
|  | 		{ | ||||||
|  | 			button.RegisterInstance(new BrowserApplicationInstance("A new instance. Yaji...")); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								SafeExamBrowser.Browser/BrowserApplicationInstance.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								SafeExamBrowser.Browser/BrowserApplicationInstance.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Browser | ||||||
|  | { | ||||||
|  | 	public class BrowserApplicationInstance : IApplicationInstance | ||||||
|  | 	{ | ||||||
|  | 		public Guid Id { get; private set; } | ||||||
|  | 		public string Name { get; private set; } | ||||||
|  | 
 | ||||||
|  | 		public BrowserApplicationInstance(string name) | ||||||
|  | 		{ | ||||||
|  | 			Id = Guid.NewGuid(); | ||||||
|  | 			Name = name; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -40,7 +40,9 @@ | ||||||
|     <Reference Include="System.Xml" /> |     <Reference Include="System.Xml" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Compile Include="BrowserApplicationController.cs" /> | ||||||
|     <Compile Include="BrowserApplicationInfo.cs" /> |     <Compile Include="BrowserApplicationInfo.cs" /> | ||||||
|  |     <Compile Include="BrowserApplicationInstance.cs" /> | ||||||
|     <Compile Include="BrowserIconResource.cs" /> |     <Compile Include="BrowserIconResource.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|  | @ -13,8 +13,8 @@ namespace SafeExamBrowser.Contracts.Behaviour | ||||||
| 	public interface IApplicationController | 	public interface IApplicationController | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// The handler to be executed when an application's taskbar button gets clicked. | 		/// Registers the taskbar button for this application. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		TaskbarButtonClickHandler OnClick { get; } | 		void RegisterApplicationButton(IApplicationButton button); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,25 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.Contracts.Configuration | ||||||
|  | { | ||||||
|  | 	public interface IApplicationInstance | ||||||
|  | 	{ | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// The unique identifier for the application instance. | ||||||
|  | 		/// </summary> | ||||||
|  | 		Guid Id { get; } | ||||||
|  | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// The name or (document) title of the application instance. | ||||||
|  | 		/// </summary> | ||||||
|  | 		string Name { get; } | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -10,23 +10,23 @@ namespace SafeExamBrowser.Contracts.Configuration | ||||||
| { | { | ||||||
| 	public interface ISettings | 	public interface ISettings | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> |  | ||||||
| 		/// The copyright information for the application, to be displayed in e.g. the log or the splash screen. |  | ||||||
| 		/// </summary> |  | ||||||
| 		string CopyrightInfo { get; } |  | ||||||
| 
 |  | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// The path where the log files are to be stored. | 		/// The path where the log files are to be stored. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		string LogFolderPath { get; } | 		string LogFolderPath { get; } | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// The information to be printed at the beginning of the application log. | 		/// The copyright information for the application (i.e. the executing assembly). | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		string LogHeader { get; } | 		string ProgramCopyright { get; } | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// The program version of the application. | 		/// The program title of the application (i.e. the executing assembly). | ||||||
|  | 		/// </summary> | ||||||
|  | 		string ProgramTitle { get; } | ||||||
|  | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// The program version of the application (i.e. the executing assembly). | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		string ProgramVersion { get; } | 		string ProgramVersion { get; } | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -18,6 +18,9 @@ namespace SafeExamBrowser.Contracts.I18n | ||||||
| 		MessageBox_SingleInstance, | 		MessageBox_SingleInstance, | ||||||
| 		MessageBox_SingleInstanceTitle, | 		MessageBox_SingleInstanceTitle, | ||||||
| 		MessageBox_StartupError, | 		MessageBox_StartupError, | ||||||
| 		MessageBox_StartupErrorTitle | 		MessageBox_StartupErrorTitle, | ||||||
|  | 		SplashScreen_InitializeBrowser, | ||||||
|  | 		SplashScreen_StartupProcedure, | ||||||
|  | 		Version | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -43,6 +43,7 @@ | ||||||
|     <Compile Include="Behaviour\IApplicationController.cs" /> |     <Compile Include="Behaviour\IApplicationController.cs" /> | ||||||
|     <Compile Include="Configuration\IApplicationIconResource.cs" /> |     <Compile Include="Configuration\IApplicationIconResource.cs" /> | ||||||
|     <Compile Include="Configuration\IApplicationInfo.cs" /> |     <Compile Include="Configuration\IApplicationInfo.cs" /> | ||||||
|  |     <Compile Include="Configuration\IApplicationInstance.cs" /> | ||||||
|     <Compile Include="Configuration\ISettings.cs" /> |     <Compile Include="Configuration\ISettings.cs" /> | ||||||
|     <Compile Include="Behaviour\IShutdownController.cs" /> |     <Compile Include="Behaviour\IShutdownController.cs" /> | ||||||
|     <Compile Include="Behaviour\IStartupController.cs" /> |     <Compile Include="Behaviour\IStartupController.cs" /> | ||||||
|  | @ -60,7 +61,7 @@ | ||||||
|     <Compile Include="UserInterface\ITaskbar.cs" /> |     <Compile Include="UserInterface\ITaskbar.cs" /> | ||||||
|     <Compile Include="I18n\ITextResource.cs" /> |     <Compile Include="I18n\ITextResource.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|     <Compile Include="UserInterface\ITaskbarButton.cs" /> |     <Compile Include="UserInterface\IApplicationButton.cs" /> | ||||||
|     <Compile Include="UserInterface\IUiElementFactory.cs" /> |     <Compile Include="UserInterface\IUiElementFactory.cs" /> | ||||||
|     <Compile Include="UserInterface\MessageBoxAction.cs" /> |     <Compile Include="UserInterface\MessageBoxAction.cs" /> | ||||||
|     <Compile Include="UserInterface\MessageBoxIcon.cs" /> |     <Compile Include="UserInterface\MessageBoxIcon.cs" /> | ||||||
|  |  | ||||||
|  | @ -7,12 +7,13 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| using System; | using System; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Contracts.UserInterface | namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| { | { | ||||||
| 	public delegate void TaskbarButtonClickHandler(Guid? instanceId = null); | 	public delegate void TaskbarButtonClickHandler(Guid? instanceId = null); | ||||||
| 
 | 
 | ||||||
| 	public interface ITaskbarButton | 	public interface IApplicationButton | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// OnClick handler, executed when the user clicks on the application button. If multiple instances of | 		/// OnClick handler, executed when the user clicks on the application button. If multiple instances of | ||||||
|  | @ -21,11 +22,10 @@ namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| 		event TaskbarButtonClickHandler OnClick; | 		event TaskbarButtonClickHandler OnClick; | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Registers a new instance of an application, to be displayed when the user clicks the taskbar button. | 		/// Registers a new instance of an application, to be displayed if the user clicks the taskbar button | ||||||
|  | 		/// when there are already one or more instances of the same application running. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		/// <param name="id">The identifier for the application instance.</param> | 		void RegisterInstance(IApplicationInstance instance); | ||||||
| 		/// <param name="title">An optional title to be displayed (if multiple instances are active).</param> |  | ||||||
| 		void RegisterInstance(Guid id, string title = null); |  | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Unregisters an application instance, e.g. if it gets closed. | 		/// Unregisters an application instance, e.g. if it gets closed. | ||||||
|  | @ -6,11 +6,11 @@ | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| using SafeExamBrowser.Contracts.Logging; | using SafeExamBrowser.Contracts.I18n; | ||||||
| 
 | 
 | ||||||
| namespace SafeExamBrowser.Contracts.UserInterface | namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| { | { | ||||||
| 	public interface ISplashScreen : ILogObserver | 	public interface ISplashScreen | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Closes the splash screen. | 		/// Closes the splash screen. | ||||||
|  | @ -31,5 +31,10 @@ namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| 		/// Updates the progress bar of the splash screen according to the specified amount. | 		/// Updates the progress bar of the splash screen according to the specified amount. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		void UpdateProgress(int amount = 1); | 		void UpdateProgress(int amount = 1); | ||||||
|  | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Updates the status text of the splash screen. | ||||||
|  | 		/// </summary> | ||||||
|  | 		void UpdateText(Key key); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Adds the given application button to the taskbar. | 		/// Adds the given application button to the taskbar. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		void AddButton(ITaskbarButton button); | 		void AddButton(IApplicationButton button); | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Moves the taskbar to the given location on the screen. | 		/// Moves the taskbar to the given location on the screen. | ||||||
|  |  | ||||||
|  | @ -15,6 +15,6 @@ namespace SafeExamBrowser.Contracts.UserInterface | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Creates a taskbar button, initialized with the given application information. | 		/// Creates a taskbar button, initialized with the given application information. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		ITaskbarButton CreateButton(IApplicationInfo info); | 		IApplicationButton CreateApplicationButton(IApplicationInfo info); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| { | { | ||||||
| 	public class StartupController : IStartupController | 	public class StartupController : IStartupController | ||||||
| 	{ | 	{ | ||||||
|  | 		private IApplicationController browserController; | ||||||
| 		private IApplicationInfo browserInfo; | 		private IApplicationInfo browserInfo; | ||||||
| 		private ILogger logger; | 		private ILogger logger; | ||||||
| 		private IMessageBox messageBox; | 		private IMessageBox messageBox; | ||||||
|  | @ -33,7 +34,6 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| 		{ | 		{ | ||||||
| 			get | 			get | ||||||
| 			{ | 			{ | ||||||
| 				yield return InitializeApplicationLog; |  | ||||||
| 				yield return HandleCommandLineArguments; | 				yield return HandleCommandLineArguments; | ||||||
| 				yield return DetectOperatingSystem; | 				yield return DetectOperatingSystem; | ||||||
| 				yield return EstablishWcfServiceConnection; | 				yield return EstablishWcfServiceConnection; | ||||||
|  | @ -46,26 +46,38 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public StartupController(IApplicationInfo browserInfo, ILogger logger, IMessageBox messageBox, ISettings settings, ISplashScreen splashScreen, ITaskbar taskbar, IText text, IUiElementFactory uiFactory) | 		public StartupController( | ||||||
|  | 			IApplicationController browserController, | ||||||
|  | 			IApplicationInfo browserInfo, | ||||||
|  | 			ILogger logger, | ||||||
|  | 			IMessageBox messageBox, | ||||||
|  | 			ISettings settings, | ||||||
|  | 			ISplashScreen splashScreen, | ||||||
|  | 			ITaskbar taskbar, | ||||||
|  | 			IText text, | ||||||
|  | 			IUiElementFactory uiFactory) | ||||||
| 		{ | 		{ | ||||||
| 			this.browserInfo = browserInfo; | 			this.browserController = browserController ?? throw new ArgumentNullException(nameof(browserController)); | ||||||
| 			this.logger = logger; | 			this.browserInfo = browserInfo ?? throw new ArgumentNullException(nameof(browserInfo)); | ||||||
| 			this.messageBox = messageBox; | 			this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); ; | ||||||
| 			this.settings = settings; | 			this.messageBox = messageBox ?? throw new ArgumentNullException(nameof(messageBox)); ; | ||||||
| 			this.splashScreen = splashScreen; | 			this.settings = settings ?? throw new ArgumentNullException(nameof(settings)); ; | ||||||
| 			this.taskbar = taskbar; | 			this.splashScreen = splashScreen ?? throw new ArgumentNullException(nameof(splashScreen)); ; | ||||||
| 			this.text = text; | 			this.taskbar = taskbar ?? throw new ArgumentNullException(nameof(taskbar)); ; | ||||||
| 			this.uiFactory = uiFactory; | 			this.text = text ?? throw new ArgumentNullException(nameof(text)); ; | ||||||
|  | 			this.uiFactory = uiFactory ?? throw new ArgumentNullException(nameof(uiFactory)); ; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public bool TryInitializeApplication() | 		public bool TryInitializeApplication() | ||||||
| 		{ | 		{ | ||||||
| 			try | 			try | ||||||
| 			{ | 			{ | ||||||
|  | 				InitializeApplicationLog(); | ||||||
|  | 				InitializeSplashScreen(); | ||||||
|  | 
 | ||||||
| 				foreach (var operation in StartupOperations) | 				foreach (var operation in StartupOperations) | ||||||
| 				{ | 				{ | ||||||
| 					operation(); | 					operation(); | ||||||
| 
 |  | ||||||
| 					splashScreen.UpdateProgress(); | 					splashScreen.UpdateProgress(); | ||||||
| 
 | 
 | ||||||
| 					// TODO: Remove! | 					// TODO: Remove! | ||||||
|  | @ -85,12 +97,20 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| 
 | 
 | ||||||
| 		private void InitializeApplicationLog() | 		private void InitializeApplicationLog() | ||||||
| 		{ | 		{ | ||||||
| 			logger.Log(settings.LogHeader); | 			var titleLine = $"/* {settings.ProgramTitle}, Version {settings.ProgramVersion}{Environment.NewLine}"; | ||||||
|  | 			var copyrightLine = $"/* {settings.ProgramCopyright}{Environment.NewLine}"; | ||||||
|  | 			var emptyLine = $"/* {Environment.NewLine}"; | ||||||
|  | 			var githubLine = $"/* Please visit https://github.com/SafeExamBrowser for more information."; | ||||||
|  | 
 | ||||||
|  | 			logger.Log($"{titleLine}{copyrightLine}{emptyLine}{githubLine}"); | ||||||
| 			logger.Log($"{Environment.NewLine}# Application started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}{Environment.NewLine}"); | 			logger.Log($"{Environment.NewLine}# Application started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}{Environment.NewLine}"); | ||||||
| 			logger.Info("Initiating startup procedure."); | 			logger.Info("Initiating startup procedure."); | ||||||
| 			logger.Subscribe(splashScreen); | 		} | ||||||
| 
 | 
 | ||||||
|  | 		private void InitializeSplashScreen() | ||||||
|  | 		{ | ||||||
| 			splashScreen.SetMaxProgress(StartupOperations.Count()); | 			splashScreen.SetMaxProgress(StartupOperations.Count()); | ||||||
|  | 			splashScreen.UpdateText(Key.SplashScreen_StartupProcedure); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private void HandleCommandLineArguments() | 		private void HandleCommandLineArguments() | ||||||
|  | @ -151,9 +171,12 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| 
 | 
 | ||||||
| 		private void InitializeBrowser() | 		private void InitializeBrowser() | ||||||
| 		{ | 		{ | ||||||
| 			logger.Info("Initializing browser."); | 			var browserButton = uiFactory.CreateApplicationButton(browserInfo); | ||||||
| 
 | 
 | ||||||
| 			var browserButton = uiFactory.CreateButton(browserInfo); | 			logger.Info("Initializing browser."); | ||||||
|  | 			splashScreen.UpdateText(Key.SplashScreen_InitializeBrowser); | ||||||
|  | 
 | ||||||
|  | 			browserController.RegisterApplicationButton(browserButton); | ||||||
| 
 | 
 | ||||||
| 			// TODO | 			// TODO | ||||||
| 
 | 
 | ||||||
|  | @ -163,7 +186,6 @@ namespace SafeExamBrowser.Core.Behaviour | ||||||
| 		private void FinishInitialization() | 		private void FinishInitialization() | ||||||
| 		{ | 		{ | ||||||
| 			logger.Info("Application successfully initialized!"); | 			logger.Info("Application successfully initialized!"); | ||||||
| 			logger.Unsubscribe(splashScreen); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,7 +15,15 @@ namespace SafeExamBrowser.Core.Configuration | ||||||
| { | { | ||||||
| 	public class Settings : ISettings | 	public class Settings : ISettings | ||||||
| 	{ | 	{ | ||||||
| 		public string CopyrightInfo | 		public string LogFolderPath | ||||||
|  | 		{ | ||||||
|  | 			get | ||||||
|  | 			{ | ||||||
|  | 				return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SafeExamBrowser", "Logs"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public string ProgramCopyright | ||||||
| 		{ | 		{ | ||||||
| 			get | 			get | ||||||
| 			{ | 			{ | ||||||
|  | @ -26,28 +34,14 @@ namespace SafeExamBrowser.Core.Configuration | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public string LogFolderPath | 		public string ProgramTitle | ||||||
| 		{ | 		{ | ||||||
| 			get | 			get | ||||||
| 			{ | 			{ | ||||||
| 				return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SafeExamBrowser", "Logs"); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public string LogHeader |  | ||||||
| 		{ |  | ||||||
| 			get |  | ||||||
| 			{ |  | ||||||
| 				var newline = Environment.NewLine; |  | ||||||
| 				var executable = Assembly.GetEntryAssembly(); | 				var executable = Assembly.GetEntryAssembly(); | ||||||
| 				var title = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title; | 				var title = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title; | ||||||
| 
 | 
 | ||||||
| 				var titleLine = $"/* {title}, Version {ProgramVersion}{newline}"; | 				return title; | ||||||
| 				var copyrightLine = $"/* {CopyrightInfo}{newline}"; |  | ||||||
| 				var emptyLine = $"/* {newline}"; |  | ||||||
| 				var githubLine = $"/* Please visit https://github.com/SafeExamBrowser for more information."; |  | ||||||
| 
 |  | ||||||
| 				return $"{titleLine}{copyrightLine}{emptyLine}{githubLine}"; |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,4 +4,7 @@ | ||||||
|   <MessageBox_ShutdownErrorTitle>Shutdown Error</MessageBox_ShutdownErrorTitle> |   <MessageBox_ShutdownErrorTitle>Shutdown Error</MessageBox_ShutdownErrorTitle> | ||||||
|   <MessageBox_StartupError>An unexpected error occurred during the startup procedure! Please consult the application log for more information...</MessageBox_StartupError> |   <MessageBox_StartupError>An unexpected error occurred during the startup procedure! Please consult the application log for more information...</MessageBox_StartupError> | ||||||
|   <MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle> |   <MessageBox_StartupErrorTitle>Startup Error</MessageBox_StartupErrorTitle> | ||||||
|  |   <SplashScreen_InitializeBrowser>Initializing browser.</SplashScreen_InitializeBrowser> | ||||||
|  |   <SplashScreen_StartupProcedure>Initiating startup procedure.</SplashScreen_StartupProcedure> | ||||||
|  |   <Version>Version</Version> | ||||||
| </Text> | </Text> | ||||||
|  | @ -0,0 +1,35 @@ | ||||||
|  | <UserControl x:Class="SafeExamBrowser.UserInterface.Controls.ApplicationButton" | ||||||
|  |              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||||
|  |              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||||
|  |              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  | ||||||
|  |              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  | ||||||
|  |              xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Controls" | ||||||
|  |              mc:Ignorable="d"  | ||||||
|  |              d:DesignHeight="40" d:DesignWidth="50"> | ||||||
|  |     <Grid> | ||||||
|  |         <Popup x:Name="InstancePopup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}" AllowsTransparency="True"> | ||||||
|  |             <StackPanel x:Name="InstanceStackPanel"> | ||||||
|  |                 <StackPanel.Background> | ||||||
|  |                     <SolidColorBrush Color="Black" Opacity="0.8"/> | ||||||
|  |                 </StackPanel.Background> | ||||||
|  |             </StackPanel> | ||||||
|  |         </Popup> | ||||||
|  |         <Button x:Name="Button" BorderThickness="0" Click="Button_Click" Width="50"> | ||||||
|  |             <Button.Template> | ||||||
|  |                 <ControlTemplate TargetType="Button"> | ||||||
|  |                     <Border x:Name="ButtonContent" Background="#00000000" Padding="5"> | ||||||
|  |                         <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content" /> | ||||||
|  |                     </Border> | ||||||
|  |                     <ControlTemplate.Triggers> | ||||||
|  |                         <Trigger Property="IsMouseOver" Value="True"> | ||||||
|  |                             <Setter TargetName="ButtonContent" Property="Background" Value="#10FFFFFF" /> | ||||||
|  |                         </Trigger> | ||||||
|  |                         <Trigger Property="IsPressed" Value="True"> | ||||||
|  |                             <Setter TargetName="ButtonContent" Property="Background" Value="#2AFFFFFF" /> | ||||||
|  |                         </Trigger> | ||||||
|  |                     </ControlTemplate.Triggers> | ||||||
|  |                 </ControlTemplate> | ||||||
|  |             </Button.Template> | ||||||
|  |         </Button> | ||||||
|  |     </Grid> | ||||||
|  | </UserControl> | ||||||
|  | @ -0,0 +1,74 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Windows; | ||||||
|  | using System.Windows.Controls; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration; | ||||||
|  | using SafeExamBrowser.Contracts.UserInterface; | ||||||
|  | using SafeExamBrowser.UserInterface.Utilities; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.UserInterface.Controls | ||||||
|  | { | ||||||
|  | 	public partial class ApplicationButton : UserControl, IApplicationButton | ||||||
|  | 	{ | ||||||
|  | 		private IApplicationInfo info; | ||||||
|  | 		private IList<IApplicationInstance> instances = new List<IApplicationInstance>(); | ||||||
|  | 
 | ||||||
|  | 		public event TaskbarButtonClickHandler OnClick; | ||||||
|  | 
 | ||||||
|  | 		public ApplicationButton(IApplicationInfo info) | ||||||
|  | 		{ | ||||||
|  | 			this.info = info; | ||||||
|  | 
 | ||||||
|  | 			InitializeComponent(); | ||||||
|  | 			InitializeApplicationButton(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void RegisterInstance(IApplicationInstance instance) | ||||||
|  | 		{ | ||||||
|  | 			var instanceButton = new ApplicationInstanceButton(instance, info); | ||||||
|  | 
 | ||||||
|  | 			instances.Add(instance); | ||||||
|  | 			instanceButton.Click += (id) => OnClick?.Invoke(id); | ||||||
|  | 			InstanceStackPanel.Children.Add(instanceButton); | ||||||
|  | 
 | ||||||
|  | 			if (instances.Count > 1) | ||||||
|  | 			{ | ||||||
|  | 				InstancePopup.IsOpen = true; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public void UnregisterInstance(Guid id) | ||||||
|  | 		{ | ||||||
|  | 			throw new NotImplementedException(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void InitializeApplicationButton() | ||||||
|  | 		{ | ||||||
|  | 			Button.ToolTip = info.Tooltip; | ||||||
|  | 			Button.MouseLeave += (o, args) => InstancePopup.IsOpen = InstancePopup.IsMouseOver; | ||||||
|  | 			Button.Content = ApplicationIconResourceLoader.Load(info.IconResource); | ||||||
|  | 
 | ||||||
|  | 			InstancePopup.MouseLeave += (o, args) => InstancePopup.IsOpen = false; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void Button_Click(object sender, RoutedEventArgs e) | ||||||
|  | 		{ | ||||||
|  | 			if (instances.Count <= 1) | ||||||
|  | 			{ | ||||||
|  | 				OnClick?.Invoke(); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				InstancePopup.IsOpen = true; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,13 +1,12 @@ | ||||||
| <UserControl x:Class="SafeExamBrowser.UserInterface.Controls.TaskbarButton" | <UserControl x:Class="SafeExamBrowser.UserInterface.Controls.ApplicationInstanceButton" | ||||||
|              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||||
|              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||||
|              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  |              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  | ||||||
|              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  |              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  | ||||||
|              xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Controls" |              xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Controls" | ||||||
|              mc:Ignorable="d"  |              mc:Ignorable="d" d:DesignWidth="250"> | ||||||
|              d:DesignHeight="40" d:DesignWidth="50"> |  | ||||||
|     <Grid> |     <Grid> | ||||||
|         <Button x:Name="Button" BorderThickness="0" Click="Button_Click" Width="50"> |         <Button x:Name="Button" BorderThickness="0" Click="Button_Click" Height="25"> | ||||||
|             <Button.Template> |             <Button.Template> | ||||||
|                 <ControlTemplate TargetType="Button"> |                 <ControlTemplate TargetType="Button"> | ||||||
|                     <Border x:Name="ButtonContent" Background="#00000000" Padding="5"> |                     <Border x:Name="ButtonContent" Background="#00000000" Padding="5"> | ||||||
|  | @ -0,0 +1,51 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using System.Windows; | ||||||
|  | using System.Windows.Controls; | ||||||
|  | using System.Windows.Media; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration; | ||||||
|  | using SafeExamBrowser.UserInterface.Utilities; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.UserInterface.Controls | ||||||
|  | { | ||||||
|  | 	public partial class ApplicationInstanceButton : UserControl | ||||||
|  | 	{ | ||||||
|  | 		private IApplicationInfo info; | ||||||
|  | 		private IApplicationInstance instance; | ||||||
|  | 
 | ||||||
|  | 		public delegate void OnClickHandler(Guid instanceId); | ||||||
|  | 		public event OnClickHandler Click; | ||||||
|  | 
 | ||||||
|  | 		public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info) | ||||||
|  | 		{ | ||||||
|  | 			this.info = info; | ||||||
|  | 			this.instance = instance; | ||||||
|  | 
 | ||||||
|  | 			InitializeComponent(); | ||||||
|  | 			InitializeApplicationInstanceButton(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void InitializeApplicationInstanceButton() | ||||||
|  | 		{ | ||||||
|  | 			var panel = new StackPanel { Orientation = Orientation.Horizontal }; | ||||||
|  | 
 | ||||||
|  | 			panel.Children.Add(ApplicationIconResourceLoader.Load(info.IconResource)); | ||||||
|  | 			panel.Children.Add(new TextBlock { Text = instance.Name, Foreground = Brushes.White, Padding = new Thickness(5, 0, 5, 0) }); | ||||||
|  | 
 | ||||||
|  | 			Button.ToolTip = info.Tooltip; | ||||||
|  | 			Button.Content = panel; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void Button_Click(object sender, RoutedEventArgs e) | ||||||
|  | 		{ | ||||||
|  | 			Click?.Invoke(instance.Id); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,72 +0,0 @@ | ||||||
| /* |  | ||||||
|  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) |  | ||||||
|  *  |  | ||||||
|  * This Source Code Form is subject to the terms of the Mozilla Public |  | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| using System; |  | ||||||
| using System.Windows; |  | ||||||
| using System.Windows.Controls; |  | ||||||
| using System.Windows.Markup; |  | ||||||
| using System.Windows.Media.Imaging; |  | ||||||
| using SafeExamBrowser.Contracts.Configuration; |  | ||||||
| using SafeExamBrowser.Contracts.UserInterface; |  | ||||||
| 
 |  | ||||||
| namespace SafeExamBrowser.UserInterface.Controls |  | ||||||
| { |  | ||||||
| 	public partial class TaskbarButton : UserControl, ITaskbarButton |  | ||||||
| 	{ |  | ||||||
| 		public event TaskbarButtonClickHandler OnClick; |  | ||||||
| 
 |  | ||||||
| 		public TaskbarButton(IApplicationInfo info) |  | ||||||
| 		{ |  | ||||||
| 			InitializeComponent(); |  | ||||||
| 			InitializeButton(info); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void RegisterInstance(Guid id, string title = null) |  | ||||||
| 		{ |  | ||||||
| 			throw new NotImplementedException(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void UnregisterInstance(Guid id) |  | ||||||
| 		{ |  | ||||||
| 			throw new NotImplementedException(); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private void InitializeButton(IApplicationInfo info) |  | ||||||
| 		{ |  | ||||||
| 			Button.ToolTip = info.Tooltip; |  | ||||||
| 			 |  | ||||||
| 			if (info.IconResource.IsBitmapResource) |  | ||||||
| 			{ |  | ||||||
| 				var icon = new BitmapImage(); |  | ||||||
| 				var iconImage = new Image(); |  | ||||||
| 
 |  | ||||||
| 				icon.BeginInit(); |  | ||||||
| 				icon.UriSource = info.IconResource.Uri; |  | ||||||
| 				icon.EndInit(); |  | ||||||
| 
 |  | ||||||
| 				iconImage.Source = icon; |  | ||||||
| 				Button.Content = iconImage; |  | ||||||
| 			} |  | ||||||
| 			else if (info.IconResource.IsXamlResource) |  | ||||||
| 			{ |  | ||||||
| 				using (var stream = Application.GetResourceStream(info.IconResource.Uri)?.Stream) |  | ||||||
| 				{ |  | ||||||
| 					Button.Content = XamlReader.Load(stream); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private void Button_Click(object sender, RoutedEventArgs e) |  | ||||||
| 		{ |  | ||||||
| 			// TODO |  | ||||||
| 			OnClick?.Invoke(); |  | ||||||
| 
 |  | ||||||
| 			throw new NotImplementedException(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -47,11 +47,14 @@ | ||||||
|     <Reference Include="PresentationFramework" /> |     <Reference Include="PresentationFramework" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Compile Include="Controls\ApplicationInstanceButton.xaml.cs"> | ||||||
|  |       <DependentUpon>ApplicationInstanceButton.xaml</DependentUpon> | ||||||
|  |     </Compile> | ||||||
|     <Compile Include="Controls\DateTimeControl.xaml.cs"> |     <Compile Include="Controls\DateTimeControl.xaml.cs"> | ||||||
|       <DependentUpon>DateTimeControl.xaml</DependentUpon> |       <DependentUpon>DateTimeControl.xaml</DependentUpon> | ||||||
|     </Compile> |     </Compile> | ||||||
|     <Compile Include="Controls\TaskbarButton.xaml.cs"> |     <Compile Include="Controls\ApplicationButton.xaml.cs"> | ||||||
|       <DependentUpon>TaskbarButton.xaml</DependentUpon> |       <DependentUpon>ApplicationButton.xaml</DependentUpon> | ||||||
|     </Compile> |     </Compile> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs"> |     <Compile Include="Properties\AssemblyInfo.cs"> | ||||||
|       <SubType>Code</SubType> |       <SubType>Code</SubType> | ||||||
|  | @ -73,6 +76,7 @@ | ||||||
|       <DependentUpon>Taskbar.xaml</DependentUpon> |       <DependentUpon>Taskbar.xaml</DependentUpon> | ||||||
|     </Compile> |     </Compile> | ||||||
|     <Compile Include="UiElementFactory.cs" /> |     <Compile Include="UiElementFactory.cs" /> | ||||||
|  |     <Compile Include="Utilities\ApplicationIconResourceLoader.cs" /> | ||||||
|     <Compile Include="ViewModels\DateTimeViewModel.cs" /> |     <Compile Include="ViewModels\DateTimeViewModel.cs" /> | ||||||
|     <Compile Include="ViewModels\SplashScreenViewModel.cs" /> |     <Compile Include="ViewModels\SplashScreenViewModel.cs" /> | ||||||
|     <Compile Include="WpfMessageBox.cs" /> |     <Compile Include="WpfMessageBox.cs" /> | ||||||
|  | @ -86,11 +90,15 @@ | ||||||
|     </None> |     </None> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <Page Include="Controls\ApplicationInstanceButton.xaml"> | ||||||
|  |       <SubType>Designer</SubType> | ||||||
|  |       <Generator>MSBuild:Compile</Generator> | ||||||
|  |     </Page> | ||||||
|     <Page Include="Controls\DateTimeControl.xaml"> |     <Page Include="Controls\DateTimeControl.xaml"> | ||||||
|       <SubType>Designer</SubType> |       <SubType>Designer</SubType> | ||||||
|       <Generator>MSBuild:Compile</Generator> |       <Generator>MSBuild:Compile</Generator> | ||||||
|     </Page> |     </Page> | ||||||
|     <Page Include="Controls\TaskbarButton.xaml"> |     <Page Include="Controls\ApplicationButton.xaml"> | ||||||
|       <SubType>Designer</SubType> |       <SubType>Designer</SubType> | ||||||
|       <Generator>MSBuild:Compile</Generator> |       <Generator>MSBuild:Compile</Generator> | ||||||
|     </Page> |     </Page> | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ | ||||||
| using System.Windows; | using System.Windows; | ||||||
| using System.Windows.Documents; | using System.Windows.Documents; | ||||||
| using SafeExamBrowser.Contracts.Configuration; | using SafeExamBrowser.Contracts.Configuration; | ||||||
| using SafeExamBrowser.Contracts.Logging; | using SafeExamBrowser.Contracts.I18n; | ||||||
| using SafeExamBrowser.Contracts.UserInterface; | using SafeExamBrowser.Contracts.UserInterface; | ||||||
| using SafeExamBrowser.UserInterface.ViewModels; | using SafeExamBrowser.UserInterface.ViewModels; | ||||||
| 
 | 
 | ||||||
|  | @ -18,19 +18,16 @@ namespace SafeExamBrowser.UserInterface | ||||||
| 	public partial class SplashScreen : Window, ISplashScreen | 	public partial class SplashScreen : Window, ISplashScreen | ||||||
| 	{ | 	{ | ||||||
| 		private SplashScreenViewModel model = new SplashScreenViewModel(); | 		private SplashScreenViewModel model = new SplashScreenViewModel(); | ||||||
|  | 		private ISettings settings; | ||||||
|  | 		private IText text; | ||||||
| 
 | 
 | ||||||
| 		public SplashScreen(ISettings settings) | 		public SplashScreen(ISettings settings, IText text) | ||||||
| 		{ | 		{ | ||||||
|  | 			this.settings = settings; | ||||||
|  | 			this.text = text; | ||||||
|  | 
 | ||||||
| 			InitializeComponent(); | 			InitializeComponent(); | ||||||
| 			InitializeSplashScreen(settings); | 			InitializeSplashScreen(); | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public void Notify(ILogContent content) |  | ||||||
| 		{ |  | ||||||
| 			if (content is ILogMessage) |  | ||||||
| 			{ |  | ||||||
| 				model.Status = (content as ILogMessage).Message; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public void SetMaxProgress(int max) | 		public void SetMaxProgress(int max) | ||||||
|  | @ -43,12 +40,17 @@ namespace SafeExamBrowser.UserInterface | ||||||
| 			model.CurrentProgress += amount; | 			model.CurrentProgress += amount; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private void InitializeSplashScreen(ISettings settings) | 		public void UpdateText(Key key) | ||||||
| 		{ | 		{ | ||||||
| 			InfoTextBlock.Inlines.Add(new Run($"Version {settings.ProgramVersion}") { FontStyle = FontStyles.Italic }); | 			model.Status = text.Get(key); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private void InitializeSplashScreen() | ||||||
|  | 		{ | ||||||
|  | 			InfoTextBlock.Inlines.Add(new Run($"{text.Get(Key.Version)} {settings.ProgramVersion}") { FontStyle = FontStyles.Italic }); | ||||||
| 			InfoTextBlock.Inlines.Add(new LineBreak()); | 			InfoTextBlock.Inlines.Add(new LineBreak()); | ||||||
| 			InfoTextBlock.Inlines.Add(new LineBreak()); | 			InfoTextBlock.Inlines.Add(new LineBreak()); | ||||||
| 			InfoTextBlock.Inlines.Add(new Run(settings.CopyrightInfo) { FontSize = 10 }); | 			InfoTextBlock.Inlines.Add(new Run(settings.ProgramCopyright) { FontSize = 10 }); | ||||||
| 			 | 			 | ||||||
| 			StatusTextBlock.DataContext = model; | 			StatusTextBlock.DataContext = model; | ||||||
| 			ProgressBar.DataContext = model; | 			ProgressBar.DataContext = model; | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ namespace SafeExamBrowser.UserInterface | ||||||
| 			InitializeComponent(); | 			InitializeComponent(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public void AddButton(ITaskbarButton button) | 		public void AddButton(IApplicationButton button) | ||||||
| 		{ | 		{ | ||||||
| 			if (button is UIElement) | 			if (button is UIElement) | ||||||
| 			{ | 			{ | ||||||
|  |  | ||||||
|  | @ -14,9 +14,9 @@ namespace SafeExamBrowser.UserInterface | ||||||
| { | { | ||||||
| 	public class UiElementFactory : IUiElementFactory | 	public class UiElementFactory : IUiElementFactory | ||||||
| 	{ | 	{ | ||||||
| 		public ITaskbarButton CreateButton(IApplicationInfo info) | 		public IApplicationButton CreateApplicationButton(IApplicationInfo info) | ||||||
| 		{ | 		{ | ||||||
| 			return new TaskbarButton(info); | 			return new ApplicationButton(info); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  *  | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | using System; | ||||||
|  | using System.Windows; | ||||||
|  | using System.Windows.Controls; | ||||||
|  | using System.Windows.Markup; | ||||||
|  | using System.Windows.Media.Imaging; | ||||||
|  | using SafeExamBrowser.Contracts.Configuration; | ||||||
|  | 
 | ||||||
|  | namespace SafeExamBrowser.UserInterface.Utilities | ||||||
|  | { | ||||||
|  | 	internal static class ApplicationIconResourceLoader | ||||||
|  | 	{ | ||||||
|  | 		internal static UIElement Load(IApplicationIconResource resource) | ||||||
|  | 		{ | ||||||
|  | 			if (resource.IsBitmapResource) | ||||||
|  | 			{ | ||||||
|  | 				var icon = new BitmapImage(); | ||||||
|  | 				var iconImage = new Image(); | ||||||
|  | 
 | ||||||
|  | 				icon.BeginInit(); | ||||||
|  | 				icon.UriSource = resource.Uri; | ||||||
|  | 				icon.EndInit(); | ||||||
|  | 
 | ||||||
|  | 				iconImage.Source = icon; | ||||||
|  | 
 | ||||||
|  | 				return iconImage; | ||||||
|  | 			} | ||||||
|  | 			else if (resource.IsXamlResource) | ||||||
|  | 			{ | ||||||
|  | 				using (var stream = Application.GetResourceStream(resource.Uri)?.Stream) | ||||||
|  | 				{ | ||||||
|  | 					return XamlReader.Load(stream) as UIElement; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			throw new NotSupportedException($"Application icon resource of type '{resource.GetType()}' is not supported!"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -52,7 +52,7 @@ namespace SafeExamBrowser | ||||||
| 			base.OnStartup(e); | 			base.OnStartup(e); | ||||||
| 
 | 
 | ||||||
| 			ShowSplashScreen(); | 			ShowSplashScreen(); | ||||||
| 			Initialize(); | 			InitializeApplication(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		protected override void OnExit(ExitEventArgs e) | 		protected override void OnExit(ExitEventArgs e) | ||||||
|  | @ -62,7 +62,7 @@ namespace SafeExamBrowser | ||||||
| 			base.OnExit(e); | 			base.OnExit(e); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		private void Initialize() | 		private void InitializeApplication() | ||||||
| 		{ | 		{ | ||||||
| 			instances.BuildObjectGraph(); | 			instances.BuildObjectGraph(); | ||||||
| 
 | 
 | ||||||
|  | @ -83,10 +83,12 @@ namespace SafeExamBrowser | ||||||
| 
 | 
 | ||||||
| 		private void ShowSplashScreen() | 		private void ShowSplashScreen() | ||||||
| 		{ | 		{ | ||||||
|  | 			instances.BuildModulesRequiredBySplashScreen(); | ||||||
|  | 
 | ||||||
| 			var splashReadyEvent = new AutoResetEvent(false); | 			var splashReadyEvent = new AutoResetEvent(false); | ||||||
| 			var splashScreenThread = new Thread(() => | 			var splashScreenThread = new Thread(() => | ||||||
| 			{ | 			{ | ||||||
| 				instances.SplashScreen = new UserInterface.SplashScreen(instances.Settings); | 				instances.SplashScreen = new UserInterface.SplashScreen(instances.Settings, instances.Text); | ||||||
| 				instances.SplashScreen.Closed += (o, args) => instances.SplashScreen.Dispatcher.InvokeShutdown(); | 				instances.SplashScreen.Closed += (o, args) => instances.SplashScreen.Dispatcher.InvokeShutdown(); | ||||||
| 				instances.SplashScreen.Show(); | 				instances.SplashScreen.Show(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,35 +22,38 @@ namespace SafeExamBrowser | ||||||
| { | { | ||||||
| 	internal class CompositionRoot | 	internal class CompositionRoot | ||||||
| 	{ | 	{ | ||||||
|  | 		private IApplicationController browserController; | ||||||
| 		private IApplicationInfo browserInfo; | 		private IApplicationInfo browserInfo; | ||||||
| 		private IMessageBox messageBox; | 		private IMessageBox messageBox; | ||||||
| 		private ILogger logger; | 		private ILogger logger; | ||||||
| 		private IUiElementFactory uiFactory; | 		private IUiElementFactory uiFactory; | ||||||
| 		private IText text; |  | ||||||
| 
 | 
 | ||||||
| 		public ISettings Settings { get; private set; } | 		public ISettings Settings { get; private set; } | ||||||
| 		public IShutdownController ShutdownController { get; private set; } | 		public IShutdownController ShutdownController { get; private set; } | ||||||
| 		public IStartupController StartupController { get; private set; } | 		public IStartupController StartupController { get; private set; } | ||||||
| 		public SplashScreen SplashScreen { get; set; } | 		public SplashScreen SplashScreen { get; set; } | ||||||
| 		public Taskbar Taskbar { get; private set; } | 		public Taskbar Taskbar { get; private set; } | ||||||
|  | 		public IText Text { get; private set; } | ||||||
| 
 | 
 | ||||||
| 		public CompositionRoot() | 		public void BuildModulesRequiredBySplashScreen() | ||||||
| 		{ | 		{ | ||||||
| 			browserInfo = new BrowserApplicationInfo(); |  | ||||||
| 			messageBox = new WpfMessageBox(); |  | ||||||
| 			logger = new Logger(); |  | ||||||
| 			Settings = new Settings(); | 			Settings = new Settings(); | ||||||
| 			Taskbar = new Taskbar(); | 			Text = new Text(new XmlTextResource()); | ||||||
| 			uiFactory = new UiElementFactory(); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		public void BuildObjectGraph() | 		public void BuildObjectGraph() | ||||||
| 		{ | 		{ | ||||||
|  | 			browserController = new BrowserApplicationController(); | ||||||
|  | 			browserInfo = new BrowserApplicationInfo(); | ||||||
|  | 			messageBox = new WpfMessageBox(); | ||||||
|  | 			logger = new Logger(); | ||||||
|  | 			uiFactory = new UiElementFactory(); | ||||||
|  | 			Taskbar = new Taskbar(); | ||||||
|  | 
 | ||||||
| 			logger.Subscribe(new LogFileWriter(Settings)); | 			logger.Subscribe(new LogFileWriter(Settings)); | ||||||
| 
 | 
 | ||||||
| 			text = new Text(new XmlTextResource()); | 			ShutdownController = new ShutdownController(logger, messageBox, Text); | ||||||
| 			ShutdownController = new ShutdownController(logger, messageBox, text); | 			StartupController = new StartupController(browserController, browserInfo, logger, messageBox, Settings, SplashScreen, Taskbar, Text, uiFactory); | ||||||
| 			StartupController = new StartupController(browserInfo, logger, messageBox, Settings, SplashScreen, Taskbar, text, uiFactory); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Damian Büchel
						Damian Büchel