SEBWIN-141: Implemented draft of application controls for action center.
This commit is contained in:
		
							parent
							
								
									1991f9c2d1
								
							
						
					
					
						commit
						519fb9e57b
					
				
					 39 changed files with 474 additions and 115 deletions
				
			
		| 
						 | 
					@ -29,7 +29,7 @@ namespace SafeExamBrowser.Browser
 | 
				
			||||||
		private int instanceIdCounter = default(int);
 | 
							private int instanceIdCounter = default(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private AppConfig appConfig;
 | 
							private AppConfig appConfig;
 | 
				
			||||||
		private IApplicationButton button;
 | 
							private IList<IApplicationControl> controls;
 | 
				
			||||||
		private IList<IApplicationInstance> instances;
 | 
							private IList<IApplicationInstance> instances;
 | 
				
			||||||
		private IMessageBox messageBox;
 | 
							private IMessageBox messageBox;
 | 
				
			||||||
		private IModuleLogger logger;
 | 
							private IModuleLogger logger;
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ namespace SafeExamBrowser.Browser
 | 
				
			||||||
			IUserInterfaceFactory uiFactory)
 | 
								IUserInterfaceFactory uiFactory)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.appConfig = appConfig;
 | 
								this.appConfig = appConfig;
 | 
				
			||||||
 | 
								this.controls = new List<IApplicationControl>();
 | 
				
			||||||
			this.instances = new List<IApplicationInstance>();
 | 
								this.instances = new List<IApplicationInstance>();
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
			this.messageBox = messageBox;
 | 
								this.messageBox = messageBox;
 | 
				
			||||||
| 
						 | 
					@ -69,10 +70,10 @@ namespace SafeExamBrowser.Browser
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void RegisterApplicationButton(IApplicationButton button)
 | 
							public void RegisterApplicationControl(IApplicationControl control)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.button = button;
 | 
								control.Clicked += ApplicationControl_Clicked;
 | 
				
			||||||
			this.button.Clicked += Button_OnClick;
 | 
								controls.Add(control);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Start()
 | 
							public void Start()
 | 
				
			||||||
| 
						 | 
					@ -108,7 +109,11 @@ namespace SafeExamBrowser.Browser
 | 
				
			||||||
			instance.PopupRequested += Instance_PopupRequested;
 | 
								instance.PopupRequested += Instance_PopupRequested;
 | 
				
			||||||
			instance.Terminated += Instance_Terminated;
 | 
								instance.Terminated += Instance_Terminated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			button.RegisterInstance(instance);
 | 
								foreach (var control in controls)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									control.RegisterInstance(instance);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			instances.Add(instance);
 | 
								instances.Add(instance);
 | 
				
			||||||
			instance.Window.Show();
 | 
								instance.Window.Show();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,7 +140,7 @@ namespace SafeExamBrowser.Browser
 | 
				
			||||||
			return cefSettings;
 | 
								return cefSettings;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void Button_OnClick(InstanceIdentifier id = null)
 | 
							private void ApplicationControl_Clicked(InstanceIdentifier id = null)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (id == null)
 | 
								if (id == null)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,14 +11,14 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Client.UnitTests.Notifications
 | 
					namespace SafeExamBrowser.Client.UnitTests.Notifications
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	class NotificationButtonMock : INotificationButton
 | 
						class NotificationButtonMock : INotificationControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private NotificationButtonClickedEventHandler clicked;
 | 
							private NotificationControlClickedEventHandler clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool HasSubscribed;
 | 
							public bool HasSubscribed;
 | 
				
			||||||
		public bool HasUnsubscribed;
 | 
							public bool HasUnsubscribed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public event NotificationButtonClickedEventHandler Clicked
 | 
							public event NotificationControlClickedEventHandler Clicked
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			add
 | 
								add
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,24 +19,26 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
				
			||||||
	[TestClass]
 | 
						[TestClass]
 | 
				
			||||||
	public class BrowserOperationTests
 | 
						public class BrowserOperationTests
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private Mock<IApplicationController> controllerMock;
 | 
							private Mock<IActionCenter> actionCenter;
 | 
				
			||||||
		private Mock<IApplicationInfo> appInfoMock;
 | 
							private Mock<IApplicationController> controller;
 | 
				
			||||||
		private Mock<ILogger> loggerMock;
 | 
							private Mock<IApplicationInfo> appInfo;
 | 
				
			||||||
		private Mock<ITaskbar> taskbarMock;
 | 
							private Mock<ILogger> logger;
 | 
				
			||||||
		private Mock<IUserInterfaceFactory> uiFactoryMock;
 | 
							private Mock<ITaskbar> taskbar;
 | 
				
			||||||
 | 
							private Mock<IUserInterfaceFactory> uiFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private BrowserOperation sut;
 | 
							private BrowserOperation sut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestInitialize]
 | 
							[TestInitialize]
 | 
				
			||||||
		public void Initialize()
 | 
							public void Initialize()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			controllerMock = new Mock<IApplicationController>();
 | 
								actionCenter = new Mock<IActionCenter>();
 | 
				
			||||||
			appInfoMock = new Mock<IApplicationInfo>();
 | 
								controller = new Mock<IApplicationController>();
 | 
				
			||||||
			loggerMock = new Mock<ILogger>();
 | 
								appInfo = new Mock<IApplicationInfo>();
 | 
				
			||||||
			taskbarMock = new Mock<ITaskbar>();
 | 
								logger = new Mock<ILogger>();
 | 
				
			||||||
			uiFactoryMock = new Mock<IUserInterfaceFactory>();
 | 
								taskbar = new Mock<ITaskbar>();
 | 
				
			||||||
 | 
								uiFactory = new Mock<IUserInterfaceFactory>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object);
 | 
								sut = new BrowserOperation(actionCenter.Object, controller.Object, appInfo.Object, logger.Object, taskbar.Object, uiFactory.Object);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -44,15 +46,15 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var order = 0;
 | 
								var order = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			controllerMock.Setup(c => c.Initialize()).Callback(() => Assert.AreEqual(++order, 1));
 | 
								controller.Setup(c => c.Initialize()).Callback(() => Assert.AreEqual(++order, 1));
 | 
				
			||||||
			controllerMock.Setup(c => c.RegisterApplicationButton(It.IsAny<IApplicationButton>())).Callback(() => Assert.AreEqual(++order, 2));
 | 
								controller.Setup(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 2));
 | 
				
			||||||
			taskbarMock.Setup(t => t.AddApplication(It.IsAny<IApplicationButton>())).Callback(() => Assert.AreEqual(++order, 3));
 | 
								taskbar.Setup(t => t.AddApplicationControl(It.IsAny<IApplicationControl>())).Callback(() => Assert.AreEqual(++order, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			controllerMock.Verify(c => c.Initialize(), Times.Once);
 | 
								controller.Verify(c => c.Initialize(), Times.Once);
 | 
				
			||||||
			controllerMock.Verify(c => c.RegisterApplicationButton(It.IsAny<IApplicationButton>()), Times.Once);
 | 
								controller.Verify(c => c.RegisterApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
 | 
				
			||||||
			taskbarMock.Verify(t => t.AddApplication(It.IsAny<IApplicationButton>()), Times.Once);
 | 
								taskbar.Verify(t => t.AddApplicationControl(It.IsAny<IApplicationControl>()), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -60,7 +62,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			controllerMock.Verify(c => c.Terminate(), Times.Once);
 | 
								controller.Verify(c => c.Terminate(), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,6 @@ using Moq;
 | 
				
			||||||
using SafeExamBrowser.Client.Operations;
 | 
					using SafeExamBrowser.Client.Operations;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Client;
 | 
					using SafeExamBrowser.Contracts.Client;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
using SafeExamBrowser.Contracts.I18n;
 | 
					 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
using SafeExamBrowser.Contracts.SystemComponents;
 | 
					using SafeExamBrowser.Contracts.SystemComponents;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
| 
						 | 
					@ -58,7 +57,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
				
			||||||
			settings.AllowWirelessNetwork = true;
 | 
								settings.AllowWirelessNetwork = true;
 | 
				
			||||||
			settings.EnableTaskbar = true;
 | 
								settings.EnableTaskbar = true;
 | 
				
			||||||
			systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
 | 
								systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
 | 
				
			||||||
			uiFactoryMock.Setup(u => u.CreateNotification(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationButton>().Object);
 | 
								uiFactoryMock.Setup(u => u.CreateNotificationControl(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationControl>().Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new TaskbarOperation(
 | 
								sut = new TaskbarOperation(
 | 
				
			||||||
				loggerMock.Object,
 | 
									loggerMock.Object,
 | 
				
			||||||
| 
						 | 
					@ -84,7 +83,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
 | 
				
			||||||
			powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
 | 
								powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
 | 
				
			||||||
			wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
 | 
								wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
 | 
				
			||||||
			taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
 | 
								taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
 | 
				
			||||||
			taskbarMock.Verify(t => t.AddNotification(It.IsAny<INotificationButton>()), Times.Exactly(2));
 | 
								taskbarMock.Verify(t => t.AddNotificationControl(It.IsAny<INotificationControl>()), Times.Exactly(2));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,7 +230,7 @@ namespace SafeExamBrowser.Client
 | 
				
			||||||
			var moduleLogger = new ModuleLogger(logger, "BrowserController");
 | 
								var moduleLogger = new ModuleLogger(logger, "BrowserController");
 | 
				
			||||||
			var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
 | 
								var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, messageBox, moduleLogger, text, uiFactory);
 | 
				
			||||||
			var browserInfo = new BrowserApplicationInfo();
 | 
								var browserInfo = new BrowserApplicationInfo();
 | 
				
			||||||
			var operation = new BrowserOperation(browserController, browserInfo, logger, taskbar, uiFactory);
 | 
								var operation = new BrowserOperation(actionCenter, browserController, browserInfo, logger, taskbar, uiFactory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.browserController = browserController;
 | 
								this.browserController = browserController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	internal class AboutNotificationController : INotificationController
 | 
						internal class AboutNotificationController : INotificationController
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private INotificationButton notification;
 | 
							private INotificationControl notification;
 | 
				
			||||||
		private AppConfig appConfig;
 | 
							private AppConfig appConfig;
 | 
				
			||||||
		private IUserInterfaceFactory uiFactory;
 | 
							private IUserInterfaceFactory uiFactory;
 | 
				
			||||||
		private IWindow window;
 | 
							private IWindow window;
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
				
			||||||
			this.uiFactory = uiFactory;
 | 
								this.uiFactory = uiFactory;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void RegisterNotification(INotificationButton notification)
 | 
							public void RegisterNotification(INotificationControl notification)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.notification = notification;
 | 
								this.notification = notification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	internal class LogNotificationController : INotificationController
 | 
						internal class LogNotificationController : INotificationController
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private INotificationButton notification;
 | 
							private INotificationControl notification;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IUserInterfaceFactory uiFactory;
 | 
							private IUserInterfaceFactory uiFactory;
 | 
				
			||||||
		private IWindow window;
 | 
							private IWindow window;
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ namespace SafeExamBrowser.Client.Notifications
 | 
				
			||||||
			this.uiFactory = uiFactory;
 | 
								this.uiFactory = uiFactory;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void RegisterNotification(INotificationButton notification)
 | 
							public void RegisterNotification(INotificationControl notification)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.notification = notification;
 | 
								this.notification = notification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ using SafeExamBrowser.Contracts.Client;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Core.OperationModel;
 | 
					using SafeExamBrowser.Contracts.Core.OperationModel;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
 | 
					using SafeExamBrowser.Contracts.Core.OperationModel.Events;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
using SafeExamBrowser.Contracts.SystemComponents;
 | 
					using SafeExamBrowser.Contracts.SystemComponents;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface;
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
| 
						 | 
					@ -69,10 +70,21 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public OperationResult Perform()
 | 
							public OperationResult Perform()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			foreach (var activator in activators)
 | 
								StatusChanged?.Invoke(TextKey.OperationStatus_InitializeActionCenter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (settings.EnableActionCenter)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				actionCenter.Register(activator);
 | 
									logger.Info("Initializing action center...");
 | 
				
			||||||
				activator.Start();
 | 
					
 | 
				
			||||||
 | 
									foreach (var activator in activators)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										actionCenter.Register(activator);
 | 
				
			||||||
 | 
										activator.Start();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									logger.Info("Action center is disabled, skipping initialization.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return OperationResult.Success;
 | 
								return OperationResult.Success;
 | 
				
			||||||
| 
						 | 
					@ -80,9 +92,20 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public OperationResult Revert()
 | 
							public OperationResult Revert()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			foreach (var activator in activators)
 | 
								StatusChanged?.Invoke(TextKey.OperationStatus_TerminateActionCenter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (settings.EnableActionCenter)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				activator.Stop();
 | 
									logger.Info("Terminating action center...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									foreach (var activator in activators)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										activator.Stop();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									logger.Info("Action center was disabled, skipping termination.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return OperationResult.Success;
 | 
								return OperationResult.Success;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	internal class BrowserOperation : IOperation
 | 
						internal class BrowserOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							private IActionCenter actionCenter;
 | 
				
			||||||
		private IApplicationController browserController;
 | 
							private IApplicationController browserController;
 | 
				
			||||||
		private IApplicationInfo browserInfo;
 | 
							private IApplicationInfo browserInfo;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
| 
						 | 
					@ -28,12 +29,14 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
		public event StatusChangedEventHandler StatusChanged;
 | 
							public event StatusChangedEventHandler StatusChanged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public BrowserOperation(
 | 
							public BrowserOperation(
 | 
				
			||||||
 | 
								IActionCenter actionCenter,
 | 
				
			||||||
			IApplicationController browserController,
 | 
								IApplicationController browserController,
 | 
				
			||||||
			IApplicationInfo browserInfo,
 | 
								IApplicationInfo browserInfo,
 | 
				
			||||||
			ILogger logger,
 | 
								ILogger logger,
 | 
				
			||||||
			ITaskbar taskbar,
 | 
								ITaskbar taskbar,
 | 
				
			||||||
			IUserInterfaceFactory uiFactory)
 | 
								IUserInterfaceFactory uiFactory)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								this.actionCenter = actionCenter;
 | 
				
			||||||
			this.browserController = browserController;
 | 
								this.browserController = browserController;
 | 
				
			||||||
			this.browserInfo = browserInfo;
 | 
								this.browserInfo = browserInfo;
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
| 
						 | 
					@ -46,12 +49,15 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
			logger.Info("Initializing browser...");
 | 
								logger.Info("Initializing browser...");
 | 
				
			||||||
			StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
 | 
								StatusChanged?.Invoke(TextKey.OperationStatus_InitializeBrowser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var browserButton = uiFactory.CreateApplicationButton(browserInfo);
 | 
								var actionCenterControl = uiFactory.CreateApplicationControl(browserInfo, Location.ActionCenter);
 | 
				
			||||||
 | 
								var taskbarControl = uiFactory.CreateApplicationControl(browserInfo, Location.Taskbar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			browserController.Initialize();
 | 
								browserController.Initialize();
 | 
				
			||||||
			browserController.RegisterApplicationButton(browserButton);
 | 
								browserController.RegisterApplicationControl(actionCenterControl);
 | 
				
			||||||
 | 
								browserController.RegisterApplicationControl(taskbarControl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			taskbar.AddApplication(browserButton);
 | 
								actionCenter.AddApplicationControl(actionCenterControl);
 | 
				
			||||||
 | 
								taskbar.AddApplicationControl(taskbarControl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return OperationResult.Success;
 | 
								return OperationResult.Success;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,10 +142,10 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void AddAboutNotification()
 | 
							private void AddAboutNotification()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var aboutNotification = uiFactory.CreateNotification(aboutInfo);
 | 
								var aboutNotification = uiFactory.CreateNotificationControl(aboutInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			aboutController.RegisterNotification(aboutNotification);
 | 
								aboutController.RegisterNotification(aboutNotification);
 | 
				
			||||||
			taskbar.AddNotification(aboutNotification);
 | 
								taskbar.AddNotificationControl(aboutNotification);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void AddKeyboardLayoutControl()
 | 
							private void AddKeyboardLayoutControl()
 | 
				
			||||||
| 
						 | 
					@ -158,10 +158,10 @@ namespace SafeExamBrowser.Client.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void AddLogNotification()
 | 
							private void AddLogNotification()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var logNotification = uiFactory.CreateNotification(logInfo);
 | 
								var logNotification = uiFactory.CreateNotificationControl(logInfo);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			logController.RegisterNotification(logNotification);
 | 
								logController.RegisterNotification(logNotification);
 | 
				
			||||||
			taskbar.AddNotification(logNotification);
 | 
								taskbar.AddNotificationControl(logNotification);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void AddPowerSupplyControl()
 | 
							private void AddPowerSupplyControl()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,9 +21,9 @@ namespace SafeExamBrowser.Contracts.Applications
 | 
				
			||||||
		void Initialize();
 | 
							void Initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Registers the taskbar button for this application.
 | 
							/// Registers an application control for this application.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void RegisterApplicationButton(IApplicationButton button);
 | 
							void RegisterApplicationControl(IApplicationControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Starts the execution of the application.
 | 
							/// Starts the execution of the application.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ namespace SafeExamBrowser.Contracts.Client
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Registers the taskbar notification.
 | 
							/// Registers the taskbar notification.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void RegisterNotification(INotificationButton notification);
 | 
							void RegisterNotification(INotificationControl notification);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Instructs the controller to shut down and release all used resources.
 | 
							/// Instructs the controller to shut down and release all used resources.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,6 +56,7 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
				
			||||||
		OperationStatus_CloseRuntimeConnection,
 | 
							OperationStatus_CloseRuntimeConnection,
 | 
				
			||||||
		OperationStatus_EmptyClipboard,
 | 
							OperationStatus_EmptyClipboard,
 | 
				
			||||||
		OperationStatus_FinalizeServiceSession,
 | 
							OperationStatus_FinalizeServiceSession,
 | 
				
			||||||
 | 
							OperationStatus_InitializeActionCenter,
 | 
				
			||||||
		OperationStatus_InitializeBrowser,
 | 
							OperationStatus_InitializeBrowser,
 | 
				
			||||||
		OperationStatus_InitializeClient,
 | 
							OperationStatus_InitializeClient,
 | 
				
			||||||
		OperationStatus_InitializeConfiguration,
 | 
							OperationStatus_InitializeConfiguration,
 | 
				
			||||||
| 
						 | 
					@ -80,6 +81,7 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
				
			||||||
		OperationStatus_StopMouseInterception,
 | 
							OperationStatus_StopMouseInterception,
 | 
				
			||||||
		OperationStatus_StopProcessMonitoring,
 | 
							OperationStatus_StopProcessMonitoring,
 | 
				
			||||||
		OperationStatus_StopWindowMonitoring,
 | 
							OperationStatus_StopWindowMonitoring,
 | 
				
			||||||
 | 
							OperationStatus_TerminateActionCenter,
 | 
				
			||||||
		OperationStatus_TerminateBrowser,
 | 
							OperationStatus_TerminateBrowser,
 | 
				
			||||||
		OperationStatus_TerminateTaskbar,
 | 
							OperationStatus_TerminateTaskbar,
 | 
				
			||||||
		OperationStatus_WaitExplorerStartup,
 | 
							OperationStatus_WaitExplorerStartup,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,11 +188,12 @@
 | 
				
			||||||
    <Compile Include="UserInterface\MessageBox\IMessageBox.cs" />
 | 
					    <Compile Include="UserInterface\MessageBox\IMessageBox.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\IProgressIndicator.cs" />
 | 
					    <Compile Include="UserInterface\IProgressIndicator.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\ActivatorEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\ActivatorEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\ApplicationButtonClickedEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\ApplicationControlClickedEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\KeyboardLayoutSelectedEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\KeyboardLayoutSelectedEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\NotificationButtonClickedEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\NotificationControlClickedEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\IActionCenter.cs" />
 | 
					    <Compile Include="UserInterface\Shell\IActionCenter.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\IActionCenterActivator.cs" />
 | 
					    <Compile Include="UserInterface\Shell\IActionCenterActivator.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="UserInterface\Shell\Location.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Windows\Events\WindowClosingEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Windows\Events\WindowClosingEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\WirelessNetworkSelectedEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\WirelessNetworkSelectedEventHandler.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\Events\QuitButtonClickedEventHandler.cs" />
 | 
					    <Compile Include="UserInterface\Shell\Events\QuitButtonClickedEventHandler.cs" />
 | 
				
			||||||
| 
						 | 
					@ -200,7 +201,7 @@
 | 
				
			||||||
    <Compile Include="UserInterface\Windows\IPasswordDialogResult.cs" />
 | 
					    <Compile Include="UserInterface\Windows\IPasswordDialogResult.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Windows\IRuntimeWindow.cs" />
 | 
					    <Compile Include="UserInterface\Windows\IRuntimeWindow.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\MessageBox\MessageBoxResult.cs" />
 | 
					    <Compile Include="UserInterface\MessageBox\MessageBoxResult.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\INotificationButton.cs" />
 | 
					    <Compile Include="UserInterface\Shell\INotificationControl.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Windows\ISplashScreen.cs" />
 | 
					    <Compile Include="UserInterface\Windows\ISplashScreen.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\ISystemKeyboardLayoutControl.cs" />
 | 
					    <Compile Include="UserInterface\Shell\ISystemKeyboardLayoutControl.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\ISystemPowerSupplyControl.cs" />
 | 
					    <Compile Include="UserInterface\Shell\ISystemPowerSupplyControl.cs" />
 | 
				
			||||||
| 
						 | 
					@ -209,7 +210,7 @@
 | 
				
			||||||
    <Compile Include="UserInterface\Shell\ITaskbar.cs" />
 | 
					    <Compile Include="UserInterface\Shell\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\Shell\IApplicationButton.cs" />
 | 
					    <Compile Include="UserInterface\Shell\IApplicationControl.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\IUserInterfaceFactory.cs" />
 | 
					    <Compile Include="UserInterface\IUserInterfaceFactory.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\Windows\IWindow.cs" />
 | 
					    <Compile Include="UserInterface\Windows\IWindow.cs" />
 | 
				
			||||||
    <Compile Include="UserInterface\MessageBox\MessageBoxAction.cs" />
 | 
					    <Compile Include="UserInterface\MessageBox\MessageBoxAction.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,9 +31,9 @@ namespace SafeExamBrowser.Contracts.UserInterface
 | 
				
			||||||
		IWindow CreateAboutWindow(AppConfig appConfig);
 | 
							IWindow CreateAboutWindow(AppConfig appConfig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Creates a taskbar button, initialized with the given application information.
 | 
							/// Creates an application control for the specified location, initialized with the given application information.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		IApplicationButton CreateApplicationButton(IApplicationInfo info);
 | 
							IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Creates a new browser window loaded with the given browser control and settings.
 | 
							/// Creates a new browser window loaded with the given browser control and settings.
 | 
				
			||||||
| 
						 | 
					@ -51,9 +51,9 @@ namespace SafeExamBrowser.Contracts.UserInterface
 | 
				
			||||||
		IWindow CreateLogWindow(ILogger logger);
 | 
							IWindow CreateLogWindow(ILogger logger);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Creates a taskbar notification, initialized with the given notification information.
 | 
							/// Creates a notification control, initialized with the given notification information.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		INotificationButton CreateNotification(INotificationInfo info);
 | 
							INotificationControl CreateNotificationControl(INotificationInfo info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Creates a password dialog with the given message and title.
 | 
							/// Creates a password dialog with the given message and title.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,8 @@ using SafeExamBrowser.Contracts.Applications;
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Indicates that an <see cref="IApplicationButton"/> has been clicked, optionally specifying the ID of the selected instance (if
 | 
						/// Indicates that an <see cref="IApplicationControl"/> has been clicked, optionally specifying the identifier of the selected instance (if
 | 
				
			||||||
	/// multiple instances of the same application are running).
 | 
						/// multiple instances of the same application are running).
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public delegate void ApplicationButtonClickedEventHandler(InstanceIdentifier id = null);
 | 
						public delegate void ApplicationControlClickedEventHandler(InstanceIdentifier id = null);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell.Events
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Indicates that the user clicked on a <see cref="INotificationButton"/> in the <see cref="ITaskbar"/>.
 | 
						/// Indicates that the user clicked on a <see cref="INotificationControl"/> in the shell.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public delegate void NotificationButtonClickedEventHandler();
 | 
						public delegate void NotificationControlClickedEventHandler();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@
 | 
				
			||||||
 * 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.UserInterface.Shell.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
| 
						 | 
					@ -13,6 +15,26 @@ namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public interface IActionCenter
 | 
						public interface IActionCenter
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Event fired when the user clicked the quit button.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Adds the given application control to the action center.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void AddApplicationControl(IApplicationControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Adds the given notification control to the action center.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void AddNotificationControl(INotificationControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Adds the given system control to the action center.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void AddSystemControl(ISystemControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Closes the action center.
 | 
							/// Closes the action center.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,18 +12,18 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The button of a (third-party) application which can be loaded into the <see cref="ITaskbar"/>.
 | 
						/// The control for a (third-party) application which can be loaded into the shell.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public interface IApplicationButton
 | 
						public interface IApplicationControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Event fired when the user clicked on the application button. If multiple instances of an application are active,
 | 
							/// Event fired when the user clicked on the application control. If multiple instances of an application are active,
 | 
				
			||||||
		/// the handler is only executed when the user selects one of the instances.
 | 
							/// the handler should only executed when the user selects one of the instances.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		event ApplicationButtonClickedEventHandler Clicked;
 | 
							event ApplicationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Registers a new instance of an application, to be started / displayed if the user clicked the taskbar button.
 | 
							/// Registers a new instance of an application to be accessed via the application control.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void RegisterInstance(IApplicationInstance instance);
 | 
							void RegisterInstance(IApplicationInstance instance);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -11,13 +11,13 @@ using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// The button of a notification which can be loaded into the <see cref="ITaskbar"/>.
 | 
						/// The control for a notification which can be loaded into the shell.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	public interface INotificationButton
 | 
						public interface INotificationControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Event fired when the user clicked on the notification icon.
 | 
							/// Event fired when the user clicked on the notification control.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		event NotificationButtonClickedEventHandler Clicked;
 | 
							event NotificationControlClickedEventHandler Clicked;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -26,14 +26,14 @@ namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
		event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
							event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Adds the given application button to the taskbar.
 | 
							/// Adds the given application control to the taskbar.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void AddApplication(IApplicationButton button);
 | 
							void AddApplicationControl(IApplicationControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Adds the given notification button to the taskbar.
 | 
							/// Adds the given notification control to the taskbar.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		void AddNotification(INotificationButton button);
 | 
							void AddNotificationControl(INotificationControl control);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Adds the given system control to the taskbar.
 | 
							/// Adds the given system control to the taskbar.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								SafeExamBrowser.Contracts/UserInterface/Shell/Location.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SafeExamBrowser.Contracts/UserInterface/Shell/Location.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2019 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/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Contracts.UserInterface.Shell
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// Defines all possible locations of a user control in the shell.
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public enum Location
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// A user control styled for and placed in the action center.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							ActionCenter,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// A user control styled for and placed in the taskbar.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Taskbar
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -126,6 +126,9 @@
 | 
				
			||||||
  <Entry key="OperationStatus_FinalizeServiceSession">
 | 
					  <Entry key="OperationStatus_FinalizeServiceSession">
 | 
				
			||||||
    Finalizing service session
 | 
					    Finalizing service session
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
 | 
					  <Entry key="OperationStatus_InitializeActionCenter">
 | 
				
			||||||
 | 
					    Initializing action center
 | 
				
			||||||
 | 
					  </Entry>
 | 
				
			||||||
  <Entry key="OperationStatus_InitializeBrowser">
 | 
					  <Entry key="OperationStatus_InitializeBrowser">
 | 
				
			||||||
    Initializing browser
 | 
					    Initializing browser
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
| 
						 | 
					@ -198,6 +201,9 @@
 | 
				
			||||||
  <Entry key="OperationStatus_StopWindowMonitoring">
 | 
					  <Entry key="OperationStatus_StopWindowMonitoring">
 | 
				
			||||||
    Stopping window monitoring
 | 
					    Stopping window monitoring
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
 | 
					  <Entry key="OperationStatus_TerminateActionCenter">
 | 
				
			||||||
 | 
					    Terminating action center
 | 
				
			||||||
 | 
					  </Entry>
 | 
				
			||||||
  <Entry key="OperationStatus_TerminateBrowser">
 | 
					  <Entry key="OperationStatus_TerminateBrowser">
 | 
				
			||||||
    Terminating browser
 | 
					    Terminating browser
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,9 +4,30 @@
 | 
				
			||||||
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
					        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
				
			||||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
        xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop"
 | 
					        xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop"
 | 
				
			||||||
        mc:Ignorable="d" Title="ActionCenter" Height="1000" Width="400" Background="#EEF0F0F0" AllowsTransparency="True" WindowStyle="None"
 | 
					        mc:Ignorable="d" Title="ActionCenter" Height="1000" Width="400" Background="#EEF0F0F0" AllowsTransparency="True" WindowStyle="None" Topmost="True" ResizeMode="NoResize">
 | 
				
			||||||
        Topmost="True" ResizeMode="NoResize">
 | 
					    <Window.Resources>
 | 
				
			||||||
 | 
					        <ResourceDictionary>
 | 
				
			||||||
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="./Templates/ScrollViewers.xaml" />
 | 
				
			||||||
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					        </ResourceDictionary>
 | 
				
			||||||
 | 
					    </Window.Resources>
 | 
				
			||||||
    <Grid>
 | 
					    <Grid>
 | 
				
			||||||
        
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="*" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="Auto" />
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					        <ScrollViewer Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Template="{StaticResource SmallBarScrollViewer}">
 | 
				
			||||||
 | 
					            <StackPanel x:Name="ApplicationPanel" Orientation="Vertical" />
 | 
				
			||||||
 | 
					        </ScrollViewer>
 | 
				
			||||||
 | 
					        <UniformGrid x:Name="ControlPanel" Grid.Row="1" Columns="4" Margin="5">
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					            <Label Height="60">Control</Label>
 | 
				
			||||||
 | 
					        </UniformGrid>
 | 
				
			||||||
    </Grid>
 | 
					    </Grid>
 | 
				
			||||||
</Window>
 | 
					</Window>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,16 +10,37 @@ using System;
 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Media.Animation;
 | 
					using System.Windows.Media.Animation;
 | 
				
			||||||
using SafeExamBrowser.Contracts.UserInterface.Shell;
 | 
					using SafeExamBrowser.Contracts.UserInterface.Shell;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.UserInterface.Desktop
 | 
					namespace SafeExamBrowser.UserInterface.Desktop
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public partial class ActionCenter : Window, IActionCenter
 | 
						public partial class ActionCenter : Window, IActionCenter
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							public event QuitButtonClickedEventHandler QuitButtonClicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ActionCenter()
 | 
							public ActionCenter()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			InitializeComponent();
 | 
								InitializeComponent();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void AddApplicationControl(IApplicationControl control)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (control is UIElement uiElement)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ApplicationPanel.Children.Add(uiElement);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void AddNotificationControl(INotificationControl control)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void AddSystemControl(ISystemControl control)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public new void Close()
 | 
							public new void Close()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Dispatcher.Invoke(base.Close);
 | 
								Dispatcher.Invoke(base.Close);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenterApplicationButton"
 | 
				
			||||||
 | 
					             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.Desktop.Controls"
 | 
				
			||||||
 | 
					             mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800">
 | 
				
			||||||
 | 
					    <UserControl.Resources>
 | 
				
			||||||
 | 
					        <ResourceDictionary>
 | 
				
			||||||
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="../Templates/Buttons.xaml" />
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
				
			||||||
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					        </ResourceDictionary>
 | 
				
			||||||
 | 
					    </UserControl.Resources>
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					        <Button x:Name="Button" Background="Transparent" Click="Button_Click" Height="40" Padding="10" Template="{StaticResource ActionCenterButton}">
 | 
				
			||||||
 | 
					            <StackPanel Orientation="Horizontal">
 | 
				
			||||||
 | 
					                <ContentControl x:Name="Icon" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,10,0" Width="20" />
 | 
				
			||||||
 | 
					                <TextBlock x:Name="Text" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="5" MaxWidth="350" TextTrimming="CharacterEllipsis" />
 | 
				
			||||||
 | 
					            </StackPanel>
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</UserControl>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2019 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.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Applications;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Core;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
 | 
					using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public partial class ActionCenterApplicationButton : UserControl
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private IApplicationInfo info;
 | 
				
			||||||
 | 
							private IApplicationInstance instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal event ApplicationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ActionCenterApplicationButton(IApplicationInfo info, IApplicationInstance instance = null)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this.info = info;
 | 
				
			||||||
 | 
								this.instance = instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								InitializeComponent();
 | 
				
			||||||
 | 
								InitializeApplicationInstanceButton();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void InitializeApplicationInstanceButton()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Icon.Content = IconResourceLoader.Load(info.IconResource);
 | 
				
			||||||
 | 
								Text.Text = instance?.Name ?? info.Name;
 | 
				
			||||||
 | 
								Button.ToolTip = instance?.Name ?? info.Tooltip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (instance != null)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									instance.IconChanged += Instance_IconChanged;
 | 
				
			||||||
 | 
									instance.NameChanged += Instance_NameChanged;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Instance_IconChanged(IIconResource icon)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.InvokeAsync(() => Icon.Content = IconResourceLoader.Load(icon));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Instance_NameChanged(string name)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.Invoke(() =>
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Text.Text = name;
 | 
				
			||||||
 | 
									Button.ToolTip = name;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Button_Click(object sender, RoutedEventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Clicked?.Invoke(instance?.Id);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ActionCenterApplicationControl"
 | 
				
			||||||
 | 
					             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.Desktop.Controls"
 | 
				
			||||||
 | 
					             mc:Ignorable="d" d:DesignHeight="250" d:DesignWidth="500">
 | 
				
			||||||
 | 
					    <UserControl.Resources>
 | 
				
			||||||
 | 
					        <ResourceDictionary>
 | 
				
			||||||
 | 
					            <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="../Templates/Buttons.xaml" />
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
				
			||||||
 | 
					                <ResourceDictionary Source="../Templates/ScrollViewers.xaml" />
 | 
				
			||||||
 | 
					            </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
 | 
					        </ResourceDictionary>
 | 
				
			||||||
 | 
					    </UserControl.Resources>
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="Auto" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="*" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="*" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="Auto" />
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					        <TextBlock Grid.Row="0" x:Name="ApplicationName" Background="#AAD3D3D3" FontWeight="Bold" Padding="5" TextAlignment="Center" />
 | 
				
			||||||
 | 
					        <ContentControl Grid.Row="1" x:Name="ApplicationButton" />
 | 
				
			||||||
 | 
					        <StackPanel Grid.Row="2" x:Name="InstancePanel" Orientation="Vertical" />
 | 
				
			||||||
 | 
					        <Border Grid.Row="3" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="75,4" />
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</UserControl>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2019 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.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Applications;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface.Shell;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface.Shell.Events;
 | 
				
			||||||
 | 
					using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public partial class ActionCenterApplicationControl : UserControl, IApplicationControl
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private IApplicationInfo info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public event ApplicationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ActionCenterApplicationControl(IApplicationInfo info)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this.info = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								InitializeComponent();
 | 
				
			||||||
 | 
								InitializeApplicationControl(info);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void RegisterInstance(IApplicationInstance instance)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.Invoke(() =>
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									var button = new ActionCenterApplicationButton(info, instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									button.Clicked += (id) => Clicked?.Invoke(id);
 | 
				
			||||||
 | 
									instance.Terminated += (id) => Instance_OnTerminated(id, button);
 | 
				
			||||||
 | 
									InstancePanel.Children.Add(button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									ApplicationName.Visibility = Visibility.Visible;
 | 
				
			||||||
 | 
									ApplicationButton.Visibility = Visibility.Collapsed;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void InitializeApplicationControl(IApplicationInfo info)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var button = new ActionCenterApplicationButton(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								button.Button.Click += (o, args) => Clicked?.Invoke();
 | 
				
			||||||
 | 
								ApplicationName.Text = info.Name;
 | 
				
			||||||
 | 
								ApplicationButton.Content = button;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Instance_OnTerminated(InstanceIdentifier id, ActionCenterApplicationButton button)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Dispatcher.InvokeAsync(() =>
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									InstancePanel.Children.Remove(button);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (InstancePanel.Children.Count == 0)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										ApplicationName.Visibility = Visibility.Collapsed;
 | 
				
			||||||
 | 
										ApplicationButton.Visibility = Visibility.Visible;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -15,9 +15,9 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
					namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public partial class NotificationButton : UserControl, INotificationButton
 | 
						public partial class NotificationButton : UserControl, INotificationControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		public event NotificationButtonClickedEventHandler Clicked;
 | 
							public event NotificationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public NotificationButton(INotificationInfo info)
 | 
							public NotificationButton(INotificationInfo info)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ApplicationButton"
 | 
					<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.TaskbarApplicationControl"
 | 
				
			||||||
             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" 
 | 
				
			||||||
| 
						 | 
					@ -20,26 +20,26 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
					namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public partial class ApplicationButton : UserControl, IApplicationButton
 | 
						public partial class TaskbarApplicationControl : UserControl, IApplicationControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private IApplicationInfo info;
 | 
							private IApplicationInfo info;
 | 
				
			||||||
		private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
 | 
							private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public event ApplicationButtonClickedEventHandler Clicked;
 | 
							public event ApplicationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ApplicationButton(IApplicationInfo info)
 | 
							public TaskbarApplicationControl(IApplicationInfo info)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.info = info;
 | 
								this.info = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			InitializeComponent();
 | 
								InitializeComponent();
 | 
				
			||||||
			InitializeApplicationButton();
 | 
								InitializeApplicationControl();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void RegisterInstance(IApplicationInstance instance)
 | 
							public void RegisterInstance(IApplicationInstance instance)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Dispatcher.Invoke(() =>
 | 
								Dispatcher.Invoke(() =>
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				var instanceButton = new ApplicationInstanceButton(instance, info);
 | 
									var instanceButton = new TaskbarApplicationInstanceButton(instance, info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				instanceButton.Clicked += (id) => Clicked?.Invoke(id);
 | 
									instanceButton.Clicked += (id) => Clicked?.Invoke(id);
 | 
				
			||||||
				instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
 | 
									instance.Terminated += (id) => Instance_OnTerminated(id, instanceButton);
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void InitializeApplicationButton()
 | 
							private void InitializeApplicationControl()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var originalBrush = Button.Background;
 | 
								var originalBrush = Button.Background;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,7 @@ namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void Instance_OnTerminated(InstanceIdentifier id, ApplicationInstanceButton instanceButton)
 | 
							private void Instance_OnTerminated(InstanceIdentifier id, TaskbarApplicationInstanceButton instanceButton)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Dispatcher.InvokeAsync(() =>
 | 
								Dispatcher.InvokeAsync(() =>
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.ApplicationInstanceButton"
 | 
					<UserControl x:Class="SafeExamBrowser.UserInterface.Desktop.Controls.TaskbarApplicationInstanceButton"
 | 
				
			||||||
             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" 
 | 
				
			||||||
| 
						 | 
					@ -15,14 +15,14 @@ using SafeExamBrowser.UserInterface.Desktop.Utilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
					namespace SafeExamBrowser.UserInterface.Desktop.Controls
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public partial class ApplicationInstanceButton : UserControl
 | 
						public partial class TaskbarApplicationInstanceButton : UserControl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private IApplicationInfo info;
 | 
							private IApplicationInfo info;
 | 
				
			||||||
		private IApplicationInstance instance;
 | 
							private IApplicationInstance instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal event ApplicationButtonClickedEventHandler Clicked;
 | 
							internal event ApplicationControlClickedEventHandler Clicked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
 | 
							public TaskbarApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.info = info;
 | 
								this.info = info;
 | 
				
			||||||
			this.instance = instance;
 | 
								this.instance = instance;
 | 
				
			||||||
| 
						 | 
					@ -74,11 +74,17 @@
 | 
				
			||||||
    <Compile Include="BrowserWindow.xaml.cs">
 | 
					    <Compile Include="BrowserWindow.xaml.cs">
 | 
				
			||||||
      <DependentUpon>BrowserWindow.xaml</DependentUpon>
 | 
					      <DependentUpon>BrowserWindow.xaml</DependentUpon>
 | 
				
			||||||
    </Compile>
 | 
					    </Compile>
 | 
				
			||||||
    <Compile Include="Controls\ApplicationButton.xaml.cs">
 | 
					    <Compile Include="Controls\ActionCenterApplicationControl.xaml.cs">
 | 
				
			||||||
      <DependentUpon>ApplicationButton.xaml</DependentUpon>
 | 
					      <DependentUpon>ActionCenterApplicationControl.xaml</DependentUpon>
 | 
				
			||||||
    </Compile>
 | 
					    </Compile>
 | 
				
			||||||
    <Compile Include="Controls\ApplicationInstanceButton.xaml.cs">
 | 
					    <Compile Include="Controls\ActionCenterApplicationButton.xaml.cs">
 | 
				
			||||||
      <DependentUpon>ApplicationInstanceButton.xaml</DependentUpon>
 | 
					      <DependentUpon>ActionCenterApplicationButton.xaml</DependentUpon>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Include="Controls\TaskbarApplicationControl.xaml.cs">
 | 
				
			||||||
 | 
					      <DependentUpon>TaskbarApplicationControl.xaml</DependentUpon>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Include="Controls\TaskbarApplicationInstanceButton.xaml.cs">
 | 
				
			||||||
 | 
					      <DependentUpon>TaskbarApplicationInstanceButton.xaml</DependentUpon>
 | 
				
			||||||
    </Compile>
 | 
					    </Compile>
 | 
				
			||||||
    <Compile Include="Controls\DateTimeControl.xaml.cs">
 | 
					    <Compile Include="Controls\DateTimeControl.xaml.cs">
 | 
				
			||||||
      <DependentUpon>DateTimeControl.xaml</DependentUpon>
 | 
					      <DependentUpon>DateTimeControl.xaml</DependentUpon>
 | 
				
			||||||
| 
						 | 
					@ -137,11 +143,19 @@
 | 
				
			||||||
      <SubType>Designer</SubType>
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
      <Generator>MSBuild:Compile</Generator>
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
    </Page>
 | 
					    </Page>
 | 
				
			||||||
    <Page Include="Controls\ApplicationButton.xaml">
 | 
					    <Page Include="Controls\ActionCenterApplicationControl.xaml">
 | 
				
			||||||
      <SubType>Designer</SubType>
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
      <Generator>MSBuild:Compile</Generator>
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
    </Page>
 | 
					    </Page>
 | 
				
			||||||
    <Page Include="Controls\ApplicationInstanceButton.xaml">
 | 
					    <Page Include="Controls\ActionCenterApplicationButton.xaml">
 | 
				
			||||||
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
 | 
					    </Page>
 | 
				
			||||||
 | 
					    <Page Include="Controls\TaskbarApplicationControl.xaml">
 | 
				
			||||||
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
 | 
					    </Page>
 | 
				
			||||||
 | 
					    <Page Include="Controls\TaskbarApplicationInstanceButton.xaml">
 | 
				
			||||||
      <SubType>Designer</SubType>
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
      <Generator>MSBuild:Compile</Generator>
 | 
					      <Generator>MSBuild:Compile</Generator>
 | 
				
			||||||
    </Page>
 | 
					    </Page>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,8 +21,7 @@
 | 
				
			||||||
            <ColumnDefinition Width="Auto" />
 | 
					            <ColumnDefinition Width="Auto" />
 | 
				
			||||||
            <ColumnDefinition Width="40" />
 | 
					            <ColumnDefinition Width="40" />
 | 
				
			||||||
        </Grid.ColumnDefinitions>
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
        <ScrollViewer Grid.Column="0" x:Name="ApplicationScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"
 | 
					        <ScrollViewer Grid.Column="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" Template="{StaticResource SmallBarScrollViewer}">
 | 
				
			||||||
                      Template="{StaticResource SmallBarScrollViewer}">
 | 
					 | 
				
			||||||
            <StackPanel x:Name="ApplicationStackPanel" Orientation="Horizontal" />
 | 
					            <StackPanel x:Name="ApplicationStackPanel" Orientation="Horizontal" />
 | 
				
			||||||
        </ScrollViewer>
 | 
					        </ScrollViewer>
 | 
				
			||||||
        <StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
 | 
					        <StackPanel Grid.Column="1" x:Name="NotificationStackPanel" Orientation="Horizontal" VerticalAlignment="Stretch" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,17 +38,17 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
				
			||||||
			QuitButton.Clicked += QuitButton_Clicked;
 | 
								QuitButton.Clicked += QuitButton_Clicked;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void AddApplication(IApplicationButton button)
 | 
							public void AddApplicationControl(IApplicationControl control)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (button is UIElement uiElement)
 | 
								if (control is UIElement uiElement)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				ApplicationStackPanel.Children.Add(uiElement);
 | 
									ApplicationStackPanel.Children.Add(uiElement);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void AddNotification(INotificationButton button)
 | 
							public void AddNotificationControl(INotificationControl control)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (button is UIElement uiElement)
 | 
								if (control is UIElement uiElement)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				NotificationStackPanel.Children.Add(uiElement);
 | 
									NotificationStackPanel.Children.Add(uiElement);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,27 +3,25 @@
 | 
				
			||||||
    <ResourceDictionary.MergedDictionaries>
 | 
					    <ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
        <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
					        <ResourceDictionary Source="../Templates/Colors.xaml" />
 | 
				
			||||||
    </ResourceDictionary.MergedDictionaries>
 | 
					    </ResourceDictionary.MergedDictionaries>
 | 
				
			||||||
    <ControlTemplate x:Key="TaskbarButton" TargetType="Button">
 | 
					    <ControlTemplate x:Key="ActionCenterButton" TargetType="Button">
 | 
				
			||||||
        <Border x:Name="ButtonContent" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}"
 | 
					        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
				
			||||||
                BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
					 | 
				
			||||||
            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
					            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
				
			||||||
                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
					                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
				
			||||||
        </Border>
 | 
					        </Border>
 | 
				
			||||||
        <ControlTemplate.Triggers>
 | 
					        <ControlTemplate.Triggers>
 | 
				
			||||||
            <Trigger Property="IsMouseOver" Value="True">
 | 
					            <Trigger Property="IsMouseOver" Value="True">
 | 
				
			||||||
                <Setter TargetName="ButtonContent" Property="Background" Value="LightBlue" />
 | 
					                <Setter TargetName="ButtonContent" Property="Background" Value="#AAADD8E6" />
 | 
				
			||||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="DodgerBlue" />
 | 
					                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="DodgerBlue" />
 | 
				
			||||||
            </Trigger>
 | 
					            </Trigger>
 | 
				
			||||||
            <Trigger Property="IsPressed" Value="True">
 | 
					            <Trigger Property="IsPressed" Value="True">
 | 
				
			||||||
                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="SkyBlue" />
 | 
					                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="#AA87CEEB" />
 | 
				
			||||||
                <Setter TargetName="ButtonContent" Property="BorderThickness" Value="2" />
 | 
					                <Setter TargetName="ButtonContent" Property="BorderThickness" Value="2" />
 | 
				
			||||||
                <Setter Property="Cursor" Value="Hand" />
 | 
					                <Setter Property="Cursor" Value="Hand" />
 | 
				
			||||||
            </Trigger>
 | 
					            </Trigger>
 | 
				
			||||||
        </ControlTemplate.Triggers>
 | 
					        </ControlTemplate.Triggers>
 | 
				
			||||||
    </ControlTemplate>
 | 
					    </ControlTemplate>
 | 
				
			||||||
    <ControlTemplate x:Key="BrowserButton" TargetType="Button">
 | 
					    <ControlTemplate x:Key="BrowserButton" TargetType="Button">
 | 
				
			||||||
        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand"
 | 
					        <Border x:Name="ButtonContent" Background="Transparent" BorderBrush="Transparent" BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
				
			||||||
                Padding="{TemplateBinding Padding}">
 | 
					 | 
				
			||||||
            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
					            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
				
			||||||
                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
					                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
				
			||||||
        </Border>
 | 
					        </Border>
 | 
				
			||||||
| 
						 | 
					@ -42,4 +40,22 @@
 | 
				
			||||||
            </Trigger>
 | 
					            </Trigger>
 | 
				
			||||||
        </ControlTemplate.Triggers>
 | 
					        </ControlTemplate.Triggers>
 | 
				
			||||||
    </ControlTemplate>
 | 
					    </ControlTemplate>
 | 
				
			||||||
 | 
					    <ControlTemplate x:Key="TaskbarButton" TargetType="Button">
 | 
				
			||||||
 | 
					        <Border x:Name="ButtonContent" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}"
 | 
				
			||||||
 | 
					                BorderThickness="1" Cursor="Hand" Padding="{TemplateBinding Padding}">
 | 
				
			||||||
 | 
					            <ContentPresenter ContentSource="Content" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
 | 
				
			||||||
 | 
					                              RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
 | 
				
			||||||
 | 
					        </Border>
 | 
				
			||||||
 | 
					        <ControlTemplate.Triggers>
 | 
				
			||||||
 | 
					            <Trigger Property="IsMouseOver" Value="True">
 | 
				
			||||||
 | 
					                <Setter TargetName="ButtonContent" Property="Background" Value="LightBlue" />
 | 
				
			||||||
 | 
					                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="DodgerBlue" />
 | 
				
			||||||
 | 
					            </Trigger>
 | 
				
			||||||
 | 
					            <Trigger Property="IsPressed" Value="True">
 | 
				
			||||||
 | 
					                <Setter TargetName="ButtonContent" Property="BorderBrush" Value="SkyBlue" />
 | 
				
			||||||
 | 
					                <Setter TargetName="ButtonContent" Property="BorderThickness" Value="2" />
 | 
				
			||||||
 | 
					                <Setter Property="Cursor" Value="Hand" />
 | 
				
			||||||
 | 
					            </Trigger>
 | 
				
			||||||
 | 
					        </ControlTemplate.Triggers>
 | 
				
			||||||
 | 
					    </ControlTemplate>
 | 
				
			||||||
</ResourceDictionary>
 | 
					</ResourceDictionary>
 | 
				
			||||||
| 
						 | 
					@ -40,9 +40,16 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
				
			||||||
			return new AboutWindow(appConfig, text);
 | 
								return new AboutWindow(appConfig, text);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public IApplicationButton CreateApplicationButton(IApplicationInfo info)
 | 
							public IApplicationControl CreateApplicationControl(IApplicationInfo info, Location location)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return new ApplicationButton(info);
 | 
								if (location == Location.ActionCenter)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return new ActionCenterApplicationControl(info);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return new TaskbarApplicationControl(info);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow)
 | 
							public IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow)
 | 
				
			||||||
| 
						 | 
					@ -79,7 +86,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
 | 
				
			||||||
			return logWindow;
 | 
								return logWindow;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public INotificationButton CreateNotification(INotificationInfo info)
 | 
							public INotificationControl CreateNotificationControl(INotificationInfo info)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return new NotificationButton(info);
 | 
								return new NotificationButton(info);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue