SEBWIN-219: Finally found appropriate solution for handling bootstrap- and session-operations.
This commit is contained in:
parent
196836b7eb
commit
5b57734406
46 changed files with 559 additions and 393 deletions
|
@ -23,7 +23,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
private Mock<IApplicationController> controllerMock;
|
private Mock<IApplicationController> controllerMock;
|
||||||
private Mock<IApplicationInfo> appInfoMock;
|
private Mock<IApplicationInfo> appInfoMock;
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
private Mock<ITaskbar> taskbarMock;
|
private Mock<ITaskbar> taskbarMock;
|
||||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||||
|
|
||||||
|
@ -35,14 +34,10 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
controllerMock = new Mock<IApplicationController>();
|
controllerMock = new Mock<IApplicationController>();
|
||||||
appInfoMock = new Mock<IApplicationInfo>();
|
appInfoMock = new Mock<IApplicationInfo>();
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
taskbarMock = new Mock<ITaskbar>();
|
taskbarMock = new Mock<ITaskbar>();
|
||||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
||||||
|
|
||||||
sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object)
|
sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<IClientController> clientControllerMock;
|
private Mock<IClientController> clientControllerMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
|
|
||||||
private ClientControllerOperation sut;
|
private ClientControllerOperation sut;
|
||||||
|
|
||||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
clientControllerMock = new Mock<IClientController>();
|
clientControllerMock = new Mock<IClientController>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
|
|
||||||
sut = new ClientControllerOperation(clientControllerMock.Object, loggerMock.Object)
|
sut = new ClientControllerOperation(clientControllerMock.Object, loggerMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -10,7 +10,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.WindowsApi;
|
using SafeExamBrowser.Contracts.WindowsApi;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<INativeMethods> nativeMethodsMock;
|
private Mock<INativeMethods> nativeMethodsMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
|
|
||||||
private ClipboardOperation sut;
|
private ClipboardOperation sut;
|
||||||
|
|
||||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
nativeMethodsMock = new Mock<INativeMethods>();
|
nativeMethodsMock = new Mock<INativeMethods>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
|
|
||||||
sut = new ClipboardOperation(loggerMock.Object, nativeMethodsMock.Object)
|
sut = new ClipboardOperation(loggerMock.Object, nativeMethodsMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
|
@ -21,7 +20,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
private Mock<IDisplayMonitor> displayMonitorMock;
|
private Mock<IDisplayMonitor> displayMonitorMock;
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
private Mock<ITaskbar> taskbarMock;
|
private Mock<ITaskbar> taskbarMock;
|
||||||
|
|
||||||
private DisplayMonitorOperation sut;
|
private DisplayMonitorOperation sut;
|
||||||
|
@ -31,13 +29,9 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
displayMonitorMock = new Mock<IDisplayMonitor>();
|
displayMonitorMock = new Mock<IDisplayMonitor>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
taskbarMock = new Mock<ITaskbar>();
|
taskbarMock = new Mock<ITaskbar>();
|
||||||
|
|
||||||
sut = new DisplayMonitorOperation(displayMonitorMock.Object, loggerMock.Object, taskbarMock.Object)
|
sut = new DisplayMonitorOperation(displayMonitorMock.Object, loggerMock.Object, taskbarMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.WindowsApi;
|
using SafeExamBrowser.Contracts.WindowsApi;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
|
@ -22,7 +21,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
private Mock<IKeyboardInterceptor> keyboardInterceptorMock;
|
private Mock<IKeyboardInterceptor> keyboardInterceptorMock;
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<INativeMethods> nativeMethodsMock;
|
private Mock<INativeMethods> nativeMethodsMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
|
|
||||||
private KeyboardInterceptorOperation sut;
|
private KeyboardInterceptorOperation sut;
|
||||||
|
|
||||||
|
@ -32,12 +30,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
keyboardInterceptorMock = new Mock<IKeyboardInterceptor>();
|
keyboardInterceptorMock = new Mock<IKeyboardInterceptor>();
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
nativeMethodsMock = new Mock<INativeMethods>();
|
nativeMethodsMock = new Mock<INativeMethods>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
|
|
||||||
sut = new KeyboardInterceptorOperation(keyboardInterceptorMock.Object, loggerMock.Object, nativeMethodsMock.Object)
|
sut = new KeyboardInterceptorOperation(keyboardInterceptorMock.Object, loggerMock.Object, nativeMethodsMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Contracts.WindowsApi;
|
using SafeExamBrowser.Contracts.WindowsApi;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
|
@ -22,7 +21,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
private Mock<IMouseInterceptor> mouseInterceptorMock;
|
private Mock<IMouseInterceptor> mouseInterceptorMock;
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<INativeMethods> nativeMethodsMock;
|
private Mock<INativeMethods> nativeMethodsMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
|
|
||||||
private MouseInterceptorOperation sut;
|
private MouseInterceptorOperation sut;
|
||||||
|
|
||||||
|
@ -32,12 +30,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
mouseInterceptorMock = new Mock<IMouseInterceptor>();
|
mouseInterceptorMock = new Mock<IMouseInterceptor>();
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
nativeMethodsMock = new Mock<INativeMethods>();
|
nativeMethodsMock = new Mock<INativeMethods>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
|
|
||||||
sut = new MouseInterceptorOperation(loggerMock.Object, mouseInterceptorMock.Object, nativeMethodsMock.Object)
|
sut = new MouseInterceptorOperation(loggerMock.Object, mouseInterceptorMock.Object, nativeMethodsMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<IProcessMonitor> processMonitorMock;
|
private Mock<IProcessMonitor> processMonitorMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
|
|
||||||
private ProcessMonitorOperation sut;
|
private ProcessMonitorOperation sut;
|
||||||
|
|
||||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
processMonitorMock = new Mock<IProcessMonitor>();
|
processMonitorMock = new Mock<IProcessMonitor>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
|
|
||||||
sut = new ProcessMonitorOperation(loggerMock.Object, processMonitorMock.Object)
|
sut = new ProcessMonitorOperation(loggerMock.Object, processMonitorMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<ITaskbarSettings> settingsMock;
|
private Mock<ITaskbarSettings> settingsMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
|
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
|
||||||
private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupplyMock;
|
private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupplyMock;
|
||||||
private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetworkMock;
|
private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetworkMock;
|
||||||
|
@ -40,7 +39,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
settingsMock = new Mock<ITaskbarSettings>();
|
settingsMock = new Mock<ITaskbarSettings>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
|
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
|
||||||
powerSupplyMock = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
powerSupplyMock = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
||||||
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||||
|
@ -64,10 +62,7 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
systemInfoMock.Object,
|
systemInfoMock.Object,
|
||||||
taskbarMock.Object,
|
taskbarMock.Object,
|
||||||
textMock.Object,
|
textMock.Object,
|
||||||
uiFactoryMock.Object)
|
uiFactoryMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
||||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
|
@ -19,7 +18,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
public class WindowMonitorOperationTests
|
public class WindowMonitorOperationTests
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
private Mock<IWindowMonitor> windowMonitorMock;
|
private Mock<IWindowMonitor> windowMonitorMock;
|
||||||
|
|
||||||
private WindowMonitorOperation sut;
|
private WindowMonitorOperation sut;
|
||||||
|
@ -28,13 +26,9 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
windowMonitorMock = new Mock<IWindowMonitor>();
|
windowMonitorMock = new Mock<IWindowMonitor>();
|
||||||
|
|
||||||
sut = new WindowMonitorOperation(loggerMock.Object, windowMonitorMock.Object)
|
sut = new WindowMonitorOperation(loggerMock.Object, windowMonitorMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public BrowserOperation(
|
public BrowserOperation(
|
||||||
IApplicationController browserController,
|
IApplicationController browserController,
|
||||||
|
@ -44,7 +44,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing browser...");
|
logger.Info("Initializing browser...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeBrowser, true);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeBrowser, true);
|
||||||
|
|
||||||
var browserButton = uiFactory.CreateApplicationButton(browserInfo);
|
var browserButton = uiFactory.CreateApplicationButton(browserInfo);
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Terminating browser...");
|
logger.Info("Terminating browser...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_TerminateBrowser, true);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_TerminateBrowser, true);
|
||||||
|
|
||||||
browserController.Terminate();
|
browserController.Terminate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IClientController controller;
|
private IClientController controller;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ClientControllerOperation(IClientController controller, ILogger logger)
|
public ClientControllerOperation(IClientController controller, ILogger logger)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Starting event handling...");
|
logger.Info("Starting event handling...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartEventHandling);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartEventHandling);
|
||||||
|
|
||||||
controller.Start();
|
controller.Start();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping event handling...");
|
logger.Info("Stopping event handling...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopEventHandling);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopEventHandling);
|
||||||
|
|
||||||
controller.Stop();
|
controller.Stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
|
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private void EmptyClipboard()
|
private void EmptyClipboard()
|
||||||
{
|
{
|
||||||
logger.Info("Emptying clipboard...");
|
logger.Info("Emptying clipboard...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_EmptyClipboard);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_EmptyClipboard);
|
||||||
|
|
||||||
nativeMethods.EmptyClipboard();
|
nativeMethods.EmptyClipboard();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ITaskbar taskbar;
|
private ITaskbar taskbar;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
|
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing working area...");
|
logger.Info("Initializing working area...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeWorkingArea);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeWorkingArea);
|
||||||
|
|
||||||
displayMonitor.PreventSleepMode();
|
displayMonitor.PreventSleepMode();
|
||||||
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
||||||
|
@ -49,7 +49,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Restoring working area...");
|
logger.Info("Restoring working area...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_RestoreWorkingArea);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_RestoreWorkingArea);
|
||||||
|
|
||||||
displayMonitor.StopMonitoringDisplayChanges();
|
displayMonitor.StopMonitoringDisplayChanges();
|
||||||
displayMonitor.ResetPrimaryDisplay();
|
displayMonitor.ResetPrimaryDisplay();
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public KeyboardInterceptorOperation(
|
public KeyboardInterceptorOperation(
|
||||||
IKeyboardInterceptor keyboardInterceptor,
|
IKeyboardInterceptor keyboardInterceptor,
|
||||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Starting keyboard interception...");
|
logger.Info("Starting keyboard interception...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
||||||
|
|
||||||
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
|
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping keyboard interception...");
|
logger.Info("Stopping keyboard interception...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopKeyboardInterception);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopKeyboardInterception);
|
||||||
|
|
||||||
nativeMethods.DeregisterKeyboardHook(keyboardInterceptor);
|
nativeMethods.DeregisterKeyboardHook(keyboardInterceptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public MouseInterceptorOperation(
|
public MouseInterceptorOperation(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Starting mouse interception...");
|
logger.Info("Starting mouse interception...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartMouseInterception);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartMouseInterception);
|
||||||
|
|
||||||
nativeMethods.RegisterMouseHook(mouseInterceptor);
|
nativeMethods.RegisterMouseHook(mouseInterceptor);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping mouse interception...");
|
logger.Info("Stopping mouse interception...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopMouseInterception);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopMouseInterception);
|
||||||
|
|
||||||
nativeMethods.DeregisterMouseHook(mouseInterceptor);
|
nativeMethods.DeregisterMouseHook(mouseInterceptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IProcessMonitor processMonitor;
|
private IProcessMonitor processMonitor;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
|
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
|
||||||
{
|
{
|
||||||
|
@ -31,12 +31,12 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing process monitoring...");
|
logger.Info("Initializing process monitoring...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_WaitExplorerTermination, true);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_WaitExplorerTermination, true);
|
||||||
|
|
||||||
processMonitor.CloseExplorerShell();
|
processMonitor.CloseExplorerShell();
|
||||||
processMonitor.StartMonitoringExplorer();
|
processMonitor.StartMonitoringExplorer();
|
||||||
|
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeProcessMonitoring);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeProcessMonitoring);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping process monitoring...");
|
logger.Info("Stopping process monitoring...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopProcessMonitoring);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopProcessMonitoring);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_WaitExplorerStartup, true);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_WaitExplorerStartup, true);
|
||||||
|
|
||||||
processMonitor.StopMonitoringExplorer();
|
processMonitor.StopMonitoringExplorer();
|
||||||
processMonitor.StartExplorerShell();
|
processMonitor.StartExplorerShell();
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public TaskbarOperation(
|
public TaskbarOperation(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing taskbar...");
|
logger.Info("Initializing taskbar...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeTaskbar);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeTaskbar);
|
||||||
|
|
||||||
if (settings.AllowApplicationLog)
|
if (settings.AllowApplicationLog)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Terminating taskbar...");
|
logger.Info("Terminating taskbar...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_TerminateTaskbar);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_TerminateTaskbar);
|
||||||
|
|
||||||
if (settings.AllowApplicationLog)
|
if (settings.AllowApplicationLog)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IWindowMonitor windowMonitor;
|
private IWindowMonitor windowMonitor;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
|
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing window monitoring...");
|
logger.Info("Initializing window monitoring...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeWindowMonitoring);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeWindowMonitoring);
|
||||||
|
|
||||||
windowMonitor.HideAllWindows();
|
windowMonitor.HideAllWindows();
|
||||||
windowMonitor.StartMonitoringWindows();
|
windowMonitor.StartMonitoringWindows();
|
||||||
|
@ -45,7 +45,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping window monitoring...");
|
logger.Info("Stopping window monitoring...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopWindowMonitoring);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopWindowMonitoring);
|
||||||
|
|
||||||
windowMonitor.StopMonitoringWindows();
|
windowMonitor.StopMonitoringWindows();
|
||||||
windowMonitor.RestoreHiddenWindows();
|
windowMonitor.RestoreHiddenWindows();
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
* 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 System.Collections.Generic;
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour
|
namespace SafeExamBrowser.Contracts.Behaviour
|
||||||
{
|
{
|
||||||
public interface IRuntimeController
|
public interface IRuntimeController
|
||||||
|
@ -21,6 +18,6 @@ namespace SafeExamBrowser.Contracts.Behaviour
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to start the runtime. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
/// Tries to start the runtime. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool TryStart(Queue<IOperation> operations);
|
bool TryStart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
||||||
public interface IOperation
|
public interface IOperation
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the procedure to which this operation belongs should be aborted.
|
/// Determines whether the procedure to which this operation belongs to should be aborted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool Abort { get; }
|
bool Abort { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The splash screen to be used to show status information to the user.
|
/// The progress indicator to be used to show status information to the user. Will be ignored if <c>null</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ISplashScreen SplashScreen { set; }
|
IProgressIndicator ProgressIndicator { set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs the operation.
|
/// Performs the operation.
|
||||||
|
|
|
@ -6,24 +6,29 @@
|
||||||
* 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 System.Collections.Generic;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
||||||
{
|
{
|
||||||
public interface IOperationSequence
|
public interface IOperationSequence
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to perform the given sequence of operations. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
/// The progress indicator to be used when performing any action. Will be ignored if <c>null</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool TryPerform(Queue<IOperation> operations);
|
IProgressIndicator ProgressIndicator { set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to repeat all operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
/// Tries to perform the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
|
/// </summary>
|
||||||
|
bool TryPerform();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to repeat the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool TryRepeat();
|
bool TryRepeat();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to revert all operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
/// Tries to revert the operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool TryRevert();
|
bool TryRevert();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
SplashScreen_StartEventHandling,
|
SplashScreen_StartEventHandling,
|
||||||
SplashScreen_StartKeyboardInterception,
|
SplashScreen_StartKeyboardInterception,
|
||||||
SplashScreen_StartMouseInterception,
|
SplashScreen_StartMouseInterception,
|
||||||
SplashScreen_StartupProcedure,
|
|
||||||
SplashScreen_StopEventHandling,
|
SplashScreen_StopEventHandling,
|
||||||
SplashScreen_StopKeyboardInterception,
|
SplashScreen_StopKeyboardInterception,
|
||||||
SplashScreen_StopMouseInterception,
|
SplashScreen_StopMouseInterception,
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
<Compile Include="UserInterface\IBrowserControl.cs" />
|
<Compile Include="UserInterface\IBrowserControl.cs" />
|
||||||
<Compile Include="UserInterface\IBrowserWindow.cs" />
|
<Compile Include="UserInterface\IBrowserWindow.cs" />
|
||||||
<Compile Include="UserInterface\IMessageBox.cs" />
|
<Compile Include="UserInterface\IMessageBox.cs" />
|
||||||
|
<Compile Include="UserInterface\IProgressIndicator.cs" />
|
||||||
<Compile Include="UserInterface\IRuntimeWindow.cs" />
|
<Compile Include="UserInterface\IRuntimeWindow.cs" />
|
||||||
<Compile Include="UserInterface\MessageBoxResult.cs" />
|
<Compile Include="UserInterface\MessageBoxResult.cs" />
|
||||||
<Compile Include="UserInterface\Taskbar\INotificationButton.cs" />
|
<Compile Include="UserInterface\Taskbar\INotificationButton.cs" />
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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 SafeExamBrowser.Contracts.I18n;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.Contracts.UserInterface
|
||||||
|
{
|
||||||
|
public interface IProgressIndicator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the progress value according to the specified amount.
|
||||||
|
/// </summary>
|
||||||
|
void Progress(int amount = 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Regresses the progress value according to the specified amount.
|
||||||
|
/// </summary>
|
||||||
|
void Regress(int amount = 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the style of the progress indicator to indeterminate (<c>Progress</c> and <c>Regress</c> won't have any effect when called).
|
||||||
|
/// </summary>
|
||||||
|
void SetIndeterminate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the maximum progress value.
|
||||||
|
/// </summary>
|
||||||
|
void SetMaxValue(int max);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the current progress value.
|
||||||
|
/// </summary>
|
||||||
|
void SetValue(int value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the status text. If the busy flag is set, an animation will be shown to indicate a long-running operation.
|
||||||
|
/// </summary>
|
||||||
|
void UpdateText(TextKey key, bool showBusyIndication = false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,17 +6,20 @@
|
||||||
* 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.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.UserInterface
|
namespace SafeExamBrowser.Contracts.UserInterface
|
||||||
{
|
{
|
||||||
public interface IRuntimeWindow : ILogObserver, IWindow
|
public interface IRuntimeWindow : ILogObserver, IProgressIndicator, IWindow
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the status text of the runtime window. If the busy flag is set,
|
/// Hides the progress bar.
|
||||||
/// the window will show an animation to indicate a long-running operation.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void UpdateStatus(TextKey key, bool showBusyIndication = false);
|
void HideProgressBar();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows the progress bar.
|
||||||
|
/// </summary>
|
||||||
|
void ShowProgressBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,37 +6,9 @@
|
||||||
* 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.I18n;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.UserInterface
|
namespace SafeExamBrowser.Contracts.UserInterface
|
||||||
{
|
{
|
||||||
public interface ISplashScreen : IWindow
|
public interface ISplashScreen : IProgressIndicator, IWindow
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Updates the progress bar of the splash screen according to the specified amount.
|
|
||||||
/// </summary>
|
|
||||||
void Progress(int amount = 1);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Regresses the progress bar of the splash screen according to the specified amount.
|
|
||||||
/// </summary>
|
|
||||||
void Regress(int amount = 1);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the style of the progress bar to indeterminate, i.e. <c>Progress</c> and
|
|
||||||
/// <c>Regress</c> won't have any effect when called.
|
|
||||||
/// </summary>
|
|
||||||
void SetIndeterminate();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the maximum of the splash screen's progress bar.
|
|
||||||
/// </summary>
|
|
||||||
void SetMaxProgress(int max);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the status text of the splash screen. If the busy flag is set,
|
|
||||||
/// the splash screen will show an animation to indicate a long-running operation.
|
|
||||||
/// </summary>
|
|
||||||
void UpdateText(TextKey key, bool showBusyIndication = false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Core.Behaviour.Operations;
|
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
|
@ -19,7 +18,6 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
public class I18nOperationTests
|
public class I18nOperationTests
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<ISplashScreen> splashScreenMock;
|
|
||||||
private Mock<IText> textMock;
|
private Mock<IText> textMock;
|
||||||
|
|
||||||
private I18nOperation sut;
|
private I18nOperation sut;
|
||||||
|
@ -28,13 +26,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
splashScreenMock = new Mock<ISplashScreen>();
|
|
||||||
textMock = new Mock<IText>();
|
textMock = new Mock<IText>();
|
||||||
|
|
||||||
sut = new I18nOperation(loggerMock.Object, textMock.Object)
|
sut = new I18nOperation(loggerMock.Object, textMock.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreenMock.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -11,8 +11,6 @@ using System.Collections.Generic;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
using SafeExamBrowser.Core.Behaviour.Operations;
|
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||||
|
@ -23,28 +21,17 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
public class OperationSequenceTests
|
public class OperationSequenceTests
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<IRuntimeInfo> runtimeInfoMock;
|
|
||||||
private Mock<IText> textMock;
|
|
||||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
|
||||||
|
|
||||||
private IOperationSequence sut;
|
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
runtimeInfoMock = new Mock<IRuntimeInfo>();
|
|
||||||
textMock = new Mock<IText>();
|
|
||||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
|
||||||
uiFactoryMock.Setup(f => f.CreateSplashScreen(runtimeInfoMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
|
|
||||||
|
|
||||||
sut = new OperationSequence(loggerMock.Object, runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Perform Tests
|
#region Perform Tests
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustCorrectlyAbortProcess()
|
public void MustCorrectlyAbortPerform()
|
||||||
{
|
{
|
||||||
var operationA = new Mock<IOperation>();
|
var operationA = new Mock<IOperation>();
|
||||||
var operationB = new Mock<IOperation>();
|
var operationB = new Mock<IOperation>();
|
||||||
|
@ -57,7 +44,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var success = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -81,7 +69,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var success = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Never);
|
operationA.Verify(o => o.Revert(), Times.Never);
|
||||||
|
@ -110,7 +99,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var success = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
Assert.IsTrue(success);
|
Assert.IsTrue(success);
|
||||||
Assert.IsTrue(a == 1);
|
Assert.IsTrue(a == 1);
|
||||||
|
@ -134,7 +124,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
operations.Enqueue(operationD.Object);
|
operations.Enqueue(operationD.Object);
|
||||||
|
|
||||||
var success = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -169,7 +160,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
operations.Enqueue(operationD.Object);
|
operations.Enqueue(operationD.Object);
|
||||||
|
|
||||||
var success = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
Assert.IsFalse(success);
|
Assert.IsFalse(success);
|
||||||
Assert.IsTrue(d == 0);
|
Assert.IsTrue(d == 0);
|
||||||
|
@ -195,7 +187,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var result = sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -208,18 +201,23 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustSucceedWithEmptyQueue()
|
public void MustSucceedWithEmptyQueue()
|
||||||
{
|
{
|
||||||
var result = sut.TryPerform(new Queue<IOperation>());
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustNotFailInCaseOfUnexpectedError()
|
public void MustNotFailInCaseOfUnexpectedError()
|
||||||
{
|
{
|
||||||
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
var indicatorMock = new Mock<IProgressIndicator>();
|
||||||
|
|
||||||
var success = sut.TryPerform(new Queue<IOperation>());
|
indicatorMock.Setup(i => i.SetMaxValue(It.IsAny<int>())).Throws<Exception>();
|
||||||
|
sut.ProgressIndicator = indicatorMock.Object;
|
||||||
|
|
||||||
|
var success = sut.TryPerform();
|
||||||
|
|
||||||
Assert.IsFalse(success);
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
@ -229,10 +227,147 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
#region Repeat Tests
|
#region Repeat Tests
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Fail()
|
public void MustCorrectlyAbortRepeat()
|
||||||
{
|
{
|
||||||
// TODO
|
var operationA = new Mock<IOperation>();
|
||||||
Assert.Fail();
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationB.SetupGet(o => o.Abort).Returns(true);
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationB.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationC.Verify(o => o.Repeat(), Times.Never);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustRepeatOperations()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Perform(), Times.Never);
|
||||||
|
operationA.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationB.Verify(o => o.Perform(), Times.Never);
|
||||||
|
operationB.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationC.Verify(o => o.Perform(), Times.Never);
|
||||||
|
operationC.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustRepeatOperationsInSequence()
|
||||||
|
{
|
||||||
|
int current = 0, a = 0, b = 0, c = 0;
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationA.Setup(o => o.Repeat()).Callback(() => a = ++current);
|
||||||
|
operationB.Setup(o => o.Repeat()).Callback(() => b = ++current);
|
||||||
|
operationC.Setup(o => o.Repeat()).Callback(() => c = ++current);
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
Assert.IsTrue(a == 1);
|
||||||
|
Assert.IsTrue(b == 2);
|
||||||
|
Assert.IsTrue(c == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotRevertOperationsInCaseOfError()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operationD = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationC.Setup(o => o.Repeat()).Throws<Exception>();
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
operations.Enqueue(operationD.Object);
|
||||||
|
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationB.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationC.Verify(o => o.Repeat(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
operationD.Verify(o => o.Repeat(), Times.Never);
|
||||||
|
operationD.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustSucceedRepeatingWithEmptyQueue()
|
||||||
|
{
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustSucceedRepeatingWithoutCallingPerform()
|
||||||
|
{
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotFailInCaseOfUnexpectedErrorWhenRepeating()
|
||||||
|
{
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
var indicatorMock = new Mock<IProgressIndicator>();
|
||||||
|
|
||||||
|
indicatorMock.Setup(i => i.SetMaxValue(It.IsAny<int>())).Throws<Exception>();
|
||||||
|
sut.ProgressIndicator = indicatorMock.Object;
|
||||||
|
|
||||||
|
var success = sut.TryRepeat();
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -251,7 +386,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
|
||||||
|
sut.TryPerform();
|
||||||
|
|
||||||
var success = sut.TryRevert();
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
@ -279,7 +416,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
|
||||||
|
sut.TryPerform();
|
||||||
|
|
||||||
var success = sut.TryRevert();
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
@ -305,7 +444,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
|
||||||
|
sut.TryPerform();
|
||||||
|
|
||||||
var success = sut.TryRevert();
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
@ -330,7 +471,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
sut.TryPerform(operations);
|
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||||
|
|
||||||
|
sut.TryPerform();
|
||||||
|
|
||||||
var success = sut.TryRevert();
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
@ -342,15 +485,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustNotFailWithEmptyQueueWhenReverting()
|
public void MustSucceedWithEmptyQueueWhenReverting()
|
||||||
{
|
{
|
||||||
sut.TryPerform(new Queue<IOperation>());
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
|
|
||||||
|
sut.TryPerform();
|
||||||
sut.TryRevert();
|
sut.TryRevert();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustNotFailWithoutPerformWhenReverting()
|
public void MustSucceedRevertingWithoutCallingPerform()
|
||||||
{
|
{
|
||||||
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
var success = sut.TryRevert();
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
Assert.IsTrue(success);
|
Assert.IsTrue(success);
|
||||||
|
@ -359,8 +505,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustNotFailInCaseOfUnexpectedErrorWhenReverting()
|
public void MustNotFailInCaseOfUnexpectedErrorWhenReverting()
|
||||||
{
|
{
|
||||||
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||||
sut.TryRevert();
|
var indicatorMock = new Mock<IProgressIndicator>();
|
||||||
|
|
||||||
|
indicatorMock.Setup(i => i.SetMaxValue(It.IsAny<int>())).Throws<Exception>();
|
||||||
|
sut.ProgressIndicator = indicatorMock.Object;
|
||||||
|
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public I18nOperation(ILogger logger, IText text)
|
public I18nOperation(ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,8 +10,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
|
@ -20,42 +18,34 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
public class OperationSequence : IOperationSequence
|
public class OperationSequence : IOperationSequence
|
||||||
{
|
{
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IRuntimeInfo runtimeInfo;
|
private Queue<IOperation> operations = new Queue<IOperation>();
|
||||||
private ISplashScreen splashScreen;
|
|
||||||
private IText text;
|
|
||||||
private IUserInterfaceFactory uiFactory;
|
|
||||||
|
|
||||||
private Stack<IOperation> stack = new Stack<IOperation>();
|
private Stack<IOperation> stack = new Stack<IOperation>();
|
||||||
|
|
||||||
public OperationSequence(ILogger logger, IRuntimeInfo runtimeInfo, IText text, IUserInterfaceFactory uiFactory)
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
|
public OperationSequence(ILogger logger, Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.runtimeInfo = runtimeInfo;
|
this.operations = new Queue<IOperation>(operations);
|
||||||
this.text = text;
|
|
||||||
this.uiFactory = uiFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryPerform(Queue<IOperation> operations)
|
public bool TryPerform()
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Initialize(operations.Count);
|
Initialize();
|
||||||
success = Perform(operations);
|
success = Perform();
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
RevertOperations();
|
Revert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to perform operations!", e);
|
logger.Error("Failed to perform operations!", e);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -63,7 +53,19 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
|
|
||||||
public bool TryRepeat()
|
public bool TryRepeat()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var success = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
success = Repeat();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to repeat operations!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryRevert()
|
public bool TryRevert()
|
||||||
|
@ -73,46 +75,38 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
success = RevertOperations(false);
|
success = Revert(false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to revert operations!", e);
|
logger.Error("Failed to revert operations!", e);
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize(int? operationCount = null)
|
private void Initialize(bool indeterminate = false)
|
||||||
{
|
{
|
||||||
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
if (indeterminate)
|
||||||
|
|
||||||
if (operationCount.HasValue)
|
|
||||||
{
|
{
|
||||||
splashScreen.SetMaxProgress(operationCount.Value);
|
ProgressIndicator?.SetIndeterminate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
splashScreen.SetIndeterminate();
|
ProgressIndicator?.SetValue(0);
|
||||||
|
ProgressIndicator?.SetMaxValue(operations.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
splashScreen.UpdateText(TextKey.SplashScreen_StartupProcedure);
|
|
||||||
splashScreen.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Perform(Queue<IOperation> operations)
|
private bool Perform()
|
||||||
{
|
{
|
||||||
foreach (var operation in operations)
|
foreach (var operation in operations)
|
||||||
{
|
{
|
||||||
stack.Push(operation);
|
stack.Push(operation);
|
||||||
operation.SplashScreen = splashScreen;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
operation.ProgressIndicator = ProgressIndicator;
|
||||||
operation.Perform();
|
operation.Perform();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -127,13 +121,40 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
splashScreen.Progress();
|
ProgressIndicator?.Progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RevertOperations(bool regress = true)
|
private bool Repeat()
|
||||||
|
{
|
||||||
|
foreach (var operation in operations)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
operation.ProgressIndicator = ProgressIndicator;
|
||||||
|
operation.Repeat();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to repeat operation '{operation.GetType().Name}'!", e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operation.Abort)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressIndicator?.Progress();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Revert(bool regress = true)
|
||||||
{
|
{
|
||||||
var success = true;
|
var success = true;
|
||||||
|
|
||||||
|
@ -143,6 +164,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
operation.ProgressIndicator = ProgressIndicator;
|
||||||
operation.Revert();
|
operation.Revert();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -153,16 +175,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
|
|
||||||
if (regress)
|
if (regress)
|
||||||
{
|
{
|
||||||
splashScreen.Regress();
|
ProgressIndicator?.Regress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Finish()
|
|
||||||
{
|
|
||||||
splashScreen?.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,9 +87,6 @@
|
||||||
<Entry key="SplashScreen_StartMouseInterception">
|
<Entry key="SplashScreen_StartMouseInterception">
|
||||||
Starting mouse interception
|
Starting mouse interception
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="SplashScreen_StartupProcedure">
|
|
||||||
Initiating startup procedure
|
|
||||||
</Entry>
|
|
||||||
<Entry key="SplashScreen_StopEventHandling">
|
<Entry key="SplashScreen_StopEventHandling">
|
||||||
Stopping event handling
|
Stopping event handling
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
private Mock<IRuntimeInfo> info;
|
private Mock<IRuntimeInfo> info;
|
||||||
private Mock<ISettingsRepository> repository;
|
private Mock<ISettingsRepository> repository;
|
||||||
private Mock<ISettings> settings;
|
private Mock<ISettings> settings;
|
||||||
private Mock<ISplashScreen> splashScreen;
|
|
||||||
private Mock<IText> text;
|
private Mock<IText> text;
|
||||||
private Mock<IUserInterfaceFactory> uiFactory;
|
private Mock<IUserInterfaceFactory> uiFactory;
|
||||||
private ConfigurationOperation sut;
|
private ConfigurationOperation sut;
|
||||||
|
@ -38,7 +37,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
info = new Mock<IRuntimeInfo>();
|
info = new Mock<IRuntimeInfo>();
|
||||||
repository = new Mock<ISettingsRepository>();
|
repository = new Mock<ISettingsRepository>();
|
||||||
settings = new Mock<ISettings>();
|
settings = new Mock<ISettings>();
|
||||||
splashScreen = new Mock<ISplashScreen>();
|
|
||||||
text = new Mock<IText>();
|
text = new Mock<IText>();
|
||||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||||
|
|
||||||
|
@ -54,17 +52,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
repository.Setup(r => r.LoadDefaults());
|
repository.Setup(r => r.LoadDefaults());
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new string[] { })
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new string[] { });
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -76,10 +68,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
var path = @"an/invalid\path.'*%yolo/()";
|
var path = @"an/invalid\path.'*%yolo/()";
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path })
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path });
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
}
|
}
|
||||||
|
@ -93,10 +82,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
||||||
info.SetupGet(r => r.AppDataFolder).Returns(location);
|
info.SetupGet(r => r.AppDataFolder).Returns(location);
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", path })
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", path });
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -111,10 +97,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
||||||
info.SetupGet(r => r.AppDataFolder).Returns($@"{location}\WRONG");
|
info.SetupGet(r => r.AppDataFolder).Returns($@"{location}\WRONG");
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -128,10 +111,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
|
|
||||||
info.SetupGet(r => r.AppDataFolder).Returns(location);
|
info.SetupGet(r => r.AppDataFolder).Returns(location);
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -141,10 +121,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustFallbackToDefaultsAsLastPrio()
|
public void MustFallbackToDefaultsAsLastPrio()
|
||||||
{
|
{
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -159,10 +136,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
||||||
uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.Yes);
|
uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.Yes);
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
@ -174,10 +148,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.No);
|
uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.No);
|
||||||
|
|
||||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
private Mock<ILogger> logger;
|
private Mock<ILogger> logger;
|
||||||
private Mock<IServiceProxy> service;
|
private Mock<IServiceProxy> service;
|
||||||
private Mock<ISettingsRepository> settings;
|
private Mock<ISettingsRepository> settings;
|
||||||
private Mock<ISplashScreen> splashScreen;
|
private Mock<IProgressIndicator> progressIndicator;
|
||||||
private Mock<IText> text;
|
private Mock<IText> text;
|
||||||
private ServiceOperation sut;
|
private ServiceOperation sut;
|
||||||
|
|
||||||
|
@ -34,13 +34,10 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
logger = new Mock<ILogger>();
|
logger = new Mock<ILogger>();
|
||||||
service = new Mock<IServiceProxy>();
|
service = new Mock<IServiceProxy>();
|
||||||
settings = new Mock<ISettingsRepository>();
|
settings = new Mock<ISettingsRepository>();
|
||||||
splashScreen = new Mock<ISplashScreen>();
|
progressIndicator = new Mock<IProgressIndicator>();
|
||||||
text = new Mock<IText>();
|
text = new Mock<IText>();
|
||||||
|
|
||||||
sut = new ServiceOperation(logger.Object, service.Object, settings.Object, text.Object)
|
sut = new ServiceOperation(logger.Object, service.Object, settings.Object, text.Object);
|
||||||
{
|
|
||||||
SplashScreen = splashScreen.Object
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Runtime
|
||||||
instances.BuildObjectGraph();
|
instances.BuildObjectGraph();
|
||||||
instances.LogStartupInformation();
|
instances.LogStartupInformation();
|
||||||
|
|
||||||
var success = instances.RuntimeController.TryStart(instances.StartupOperations);
|
var success = instances.RuntimeController.TryStart();
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private string[] commandLineArgs;
|
private string[] commandLineArgs;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ConfigurationOperation(
|
public ConfigurationOperation(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
|
@ -48,7 +48,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Initializing application configuration...");
|
logger.Info("Initializing application configuration...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeConfiguration);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeConfiguration);
|
||||||
|
|
||||||
ISettings settings;
|
ISettings settings;
|
||||||
var isValidUri = TryGetSettingsUri(out Uri uri);
|
var isValidUri = TryGetSettingsUri(out Uri uri);
|
||||||
|
@ -73,7 +73,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
public void Repeat()
|
public void Repeat()
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO: How will the new settings be retrieved? Uri passed to the repository? If yes, how does the Uri get here?!
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private KioskMode kioskMode;
|
private KioskMode kioskMode;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
|
public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
kioskMode = settingsRepository.Current.KioskMode;
|
kioskMode = settingsRepository.Current.KioskMode;
|
||||||
|
|
||||||
logger.Info($"Initializing kiosk mode '{kioskMode}'...");
|
logger.Info($"Initializing kiosk mode '{kioskMode}'...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeKioskMode);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeKioskMode);
|
||||||
|
|
||||||
if (kioskMode == KioskMode.CreateNewDesktop)
|
if (kioskMode == KioskMode.CreateNewDesktop)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info($"Reverting kiosk mode '{kioskMode}'...");
|
logger.Info($"Reverting kiosk mode '{kioskMode}'...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_RevertKioskMode);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_RevertKioskMode);
|
||||||
|
|
||||||
if (kioskMode == KioskMode.CreateNewDesktop)
|
if (kioskMode == KioskMode.CreateNewDesktop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
public bool Abort { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ServiceOperation(ILogger logger, IServiceProxy service, ISettingsRepository settingsRepository, IText text)
|
public ServiceOperation(ILogger logger, IServiceProxy service, ISettingsRepository settingsRepository, IText text)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
public void Perform()
|
public void Perform()
|
||||||
{
|
{
|
||||||
logger.Info($"Initializing service connection...");
|
logger.Info($"Initializing service connection...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeServiceConnection);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeServiceConnection);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Closing service connection...");
|
logger.Info("Closing service connection...");
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_CloseServiceConnection);
|
ProgressIndicator?.UpdateText(TextKey.SplashScreen_CloseServiceConnection);
|
||||||
|
|
||||||
if (serviceAvailable)
|
if (serviceAvailable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Communication;
|
using SafeExamBrowser.Contracts.Communication;
|
||||||
|
@ -22,18 +21,21 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
internal class RuntimeController : IRuntimeController
|
internal class RuntimeController : IRuntimeController
|
||||||
{
|
{
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
|
private IOperationSequence bootstrapSequence;
|
||||||
|
private IOperationSequence sessionSequence;
|
||||||
private IRuntimeInfo runtimeInfo;
|
private IRuntimeInfo runtimeInfo;
|
||||||
private IRuntimeWindow runtimeWindow;
|
private IRuntimeWindow runtimeWindow;
|
||||||
private IServiceProxy serviceProxy;
|
private IServiceProxy serviceProxy;
|
||||||
private ISettingsRepository settingsRepository;
|
private ISettingsRepository settingsRepository;
|
||||||
private IOperationSequence operationSequence;
|
private ISplashScreen splashScreen;
|
||||||
private Action terminationCallback;
|
private Action terminationCallback;
|
||||||
private IText text;
|
private IText text;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public RuntimeController(
|
public RuntimeController(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
IOperationSequence operationSequence,
|
IOperationSequence bootstrapSequence,
|
||||||
|
IOperationSequence sessionSequence,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRuntimeInfo runtimeInfo,
|
||||||
IServiceProxy serviceProxy,
|
IServiceProxy serviceProxy,
|
||||||
ISettingsRepository settingsRepository,
|
ISettingsRepository settingsRepository,
|
||||||
|
@ -42,7 +44,8 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
IUserInterfaceFactory uiFactory)
|
IUserInterfaceFactory uiFactory)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.operationSequence = operationSequence;
|
this.bootstrapSequence = bootstrapSequence;
|
||||||
|
this.sessionSequence = sessionSequence;
|
||||||
this.runtimeInfo = runtimeInfo;
|
this.runtimeInfo = runtimeInfo;
|
||||||
this.serviceProxy = serviceProxy;
|
this.serviceProxy = serviceProxy;
|
||||||
this.settingsRepository = settingsRepository;
|
this.settingsRepository = settingsRepository;
|
||||||
|
@ -51,21 +54,30 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryStart(Queue<IOperation> operations)
|
public bool TryStart()
|
||||||
{
|
{
|
||||||
logger.Info("--- Initiating startup procedure ---");
|
logger.Info("--- Initiating startup procedure ---");
|
||||||
|
|
||||||
var success = operationSequence.TryPerform(operations);
|
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
||||||
|
splashScreen.Show();
|
||||||
|
|
||||||
runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
|
bootstrapSequence.ProgressIndicator = splashScreen;
|
||||||
|
|
||||||
|
var success = bootstrapSequence.TryPerform();
|
||||||
|
|
||||||
|
System.Threading.Thread.Sleep(5000);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
|
||||||
|
|
||||||
logger.Info("--- Application successfully initialized! ---");
|
logger.Info("--- Application successfully initialized! ---");
|
||||||
logger.Log(string.Empty);
|
logger.Log(string.Empty);
|
||||||
logger.Subscribe(runtimeWindow);
|
logger.Subscribe(runtimeWindow);
|
||||||
|
|
||||||
StartSession();
|
splashScreen.Hide();
|
||||||
|
|
||||||
|
StartSession(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -76,33 +88,6 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartSession()
|
|
||||||
{
|
|
||||||
runtimeWindow.Show();
|
|
||||||
|
|
||||||
logger.Info("Starting new session...");
|
|
||||||
runtimeWindow.UpdateStatus(TextKey.RuntimeWindow_StartSession, true);
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - Initialize configuration
|
|
||||||
// - Initialize kiosk mode
|
|
||||||
// - Initialize session data
|
|
||||||
// - Start runtime communication host
|
|
||||||
// - Create and connect to client
|
|
||||||
// - Initialize session with service
|
|
||||||
// - Verify session integrity and start event handling
|
|
||||||
System.Threading.Thread.Sleep(10000);
|
|
||||||
|
|
||||||
runtimeWindow.UpdateStatus(TextKey.RuntimeWindow_ApplicationRunning);
|
|
||||||
|
|
||||||
if (settingsRepository.Current.KioskMode == KioskMode.DisableExplorerShell)
|
|
||||||
{
|
|
||||||
runtimeWindow.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
terminationCallback.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
StopSession();
|
StopSession();
|
||||||
|
@ -113,12 +98,13 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
// - Revert kiosk mode (or do that when stopping session?)
|
// - Revert kiosk mode (or do that when stopping session?)
|
||||||
|
|
||||||
logger.Unsubscribe(runtimeWindow);
|
logger.Unsubscribe(runtimeWindow);
|
||||||
runtimeWindow.Close();
|
runtimeWindow?.Close();
|
||||||
|
splashScreen?.Show();
|
||||||
|
|
||||||
logger.Log(string.Empty);
|
logger.Log(string.Empty);
|
||||||
logger.Info("--- Initiating shutdown procedure ---");
|
logger.Info("--- Initiating shutdown procedure ---");
|
||||||
|
|
||||||
var success = operationSequence.TryRevert();
|
var success = bootstrapSequence.TryRevert();
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +114,48 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
{
|
{
|
||||||
logger.Info("--- Shutdown procedure failed! ---");
|
logger.Info("--- Shutdown procedure failed! ---");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
splashScreen?.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartSession(bool initial = false)
|
||||||
|
{
|
||||||
|
logger.Info("Starting new session...");
|
||||||
|
runtimeWindow.UpdateText(TextKey.RuntimeWindow_StartSession, true);
|
||||||
|
runtimeWindow.Show();
|
||||||
|
|
||||||
|
sessionSequence.ProgressIndicator = runtimeWindow;
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - Initialize configuration
|
||||||
|
// - Initialize kiosk mode
|
||||||
|
// - Initialize session data
|
||||||
|
// - Create and connect to client
|
||||||
|
// - Initialize session with service
|
||||||
|
// - Verify session integrity and start event handling
|
||||||
|
var success = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Threading.Thread.Sleep(5000);
|
||||||
|
|
||||||
|
runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning);
|
||||||
|
|
||||||
|
if (settingsRepository.Current.KioskMode == KioskMode.DisableExplorerShell)
|
||||||
|
{
|
||||||
|
runtimeWindow.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Threading.Thread.Sleep(5000);
|
||||||
|
|
||||||
|
terminationCallback.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopSession()
|
private void StopSession()
|
||||||
|
@ -135,7 +163,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
logger.Info("Stopping current session...");
|
logger.Info("Stopping current session...");
|
||||||
runtimeWindow.Show();
|
runtimeWindow.Show();
|
||||||
runtimeWindow.BringToForeground();
|
runtimeWindow.BringToForeground();
|
||||||
runtimeWindow.UpdateStatus(TextKey.RuntimeWindow_StopSession, true);
|
runtimeWindow.UpdateText(TextKey.RuntimeWindow_StopSession, true);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - Terminate client (or does it terminate itself?)
|
// - Terminate client (or does it terminate itself?)
|
||||||
|
|
|
@ -35,11 +35,12 @@ namespace SafeExamBrowser.Runtime
|
||||||
private ISystemInfo systemInfo;
|
private ISystemInfo systemInfo;
|
||||||
|
|
||||||
internal IRuntimeController RuntimeController { get; private set; }
|
internal IRuntimeController RuntimeController { get; private set; }
|
||||||
internal Queue<IOperation> StartupOperations { get; private set; }
|
|
||||||
|
|
||||||
internal void BuildObjectGraph()
|
internal void BuildObjectGraph()
|
||||||
{
|
{
|
||||||
var args = Environment.GetCommandLineArgs();
|
var args = Environment.GetCommandLineArgs();
|
||||||
|
var bootstrapOperations = new Queue<IOperation>();
|
||||||
|
var sessionOperations = new Queue<IOperation>();
|
||||||
var nativeMethods = new NativeMethods();
|
var nativeMethods = new NativeMethods();
|
||||||
var settingsRepository = new SettingsRepository();
|
var settingsRepository = new SettingsRepository();
|
||||||
var uiFactory = new UserInterfaceFactory();
|
var uiFactory = new UserInterfaceFactory();
|
||||||
|
@ -52,16 +53,19 @@ namespace SafeExamBrowser.Runtime
|
||||||
InitializeLogging();
|
InitializeLogging();
|
||||||
|
|
||||||
var text = new Text(logger);
|
var text = new Text(logger);
|
||||||
var operationSequence = new OperationSequence(logger, runtimeInfo, text, uiFactory);
|
|
||||||
var serviceProxy = new ServiceProxy(new ModuleLogger(logger, typeof(ServiceProxy)), "net.pipe://localhost/safeexambrowser/service");
|
var serviceProxy = new ServiceProxy(new ModuleLogger(logger, typeof(ServiceProxy)), "net.pipe://localhost/safeexambrowser/service");
|
||||||
|
|
||||||
RuntimeController = new RuntimeController(logger, operationSequence, runtimeInfo, serviceProxy, settingsRepository, Application.Current.Shutdown, text, uiFactory);
|
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
|
||||||
|
// TODO: RuntimeHostOperation here (is IBootstrapOperation -> only performed once per runtime!)
|
||||||
|
|
||||||
StartupOperations = new Queue<IOperation>();
|
sessionOperations.Enqueue(new ConfigurationOperation(logger, runtimeInfo, settingsRepository, text, uiFactory, args));
|
||||||
StartupOperations.Enqueue(new I18nOperation(logger, text));
|
sessionOperations.Enqueue(new ServiceOperation(logger, serviceProxy, settingsRepository, text));
|
||||||
StartupOperations.Enqueue(new ConfigurationOperation(logger, runtimeInfo, settingsRepository, text, uiFactory, args));
|
sessionOperations.Enqueue(new KioskModeOperation(logger, settingsRepository));
|
||||||
StartupOperations.Enqueue(new ServiceOperation(logger, serviceProxy, settingsRepository, text));
|
|
||||||
StartupOperations.Enqueue(new KioskModeOperation(logger, settingsRepository));
|
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
|
||||||
|
var sessionSequence = new OperationSequence(logger, sessionOperations);
|
||||||
|
|
||||||
|
RuntimeController = new RuntimeController(logger, bootstrapSequence, sessionSequence, runtimeInfo, serviceProxy, settingsRepository, Application.Current.Shutdown, text, uiFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LogStartupInformation()
|
internal void LogStartupInformation()
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
mc:Ignorable="d" Background="White" Foreground="White" Height="500" Width="750" WindowStyle="None" WindowStartupLocation="CenterScreen"
|
mc:Ignorable="d" Background="White" Foreground="White" Height="500" Width="750" WindowStyle="None" WindowStartupLocation="CenterScreen"
|
||||||
Icon="./Images/SafeExamBrowser.ico" ResizeMode="NoResize" Title="Safe Exam Browser" Topmost="True">
|
Icon="./Images/SafeExamBrowser.ico" ResizeMode="NoResize" Title="Safe Exam Browser" Topmost="True">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Border x:Name="AnimatedBorder" Panel.ZIndex="10" BorderBrush="DodgerBlue" BorderThickness="5">
|
<Border x:Name="AnimatedBorder" Panel.ZIndex="10" BorderBrush="DodgerBlue" BorderThickness="5" Visibility="{Binding AnimatedBorderVisibility}">
|
||||||
<Border.Effect>
|
<Border.Effect>
|
||||||
<BlurEffect Radius="10" />
|
<BlurEffect Radius="10" />
|
||||||
</Border.Effect>
|
</Border.Effect>
|
||||||
|
@ -41,8 +41,11 @@
|
||||||
<Image Grid.Column="0" Grid.ColumnSpan="2" Margin="-25,0,0,0" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Classic;component/Images/SplashScreen.png" />
|
<Image Grid.Column="0" Grid.ColumnSpan="2" Margin="-25,0,0,0" Source="pack://application:,,,/SafeExamBrowser.UserInterface.Classic;component/Images/SplashScreen.png" />
|
||||||
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" Margin="10,75,175,10" TextWrapping="Wrap" />
|
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" Margin="10,75,175,10" TextWrapping="Wrap" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<ProgressBar x:Name="ProgressBar" Grid.Row="1" IsIndeterminate="True" Background="WhiteSmoke" BorderThickness="0" Foreground="DodgerBlue" Visibility="Hidden" />
|
<ProgressBar x:Name="ProgressBar" Grid.Row="1" Background="WhiteSmoke" BorderThickness="0" Foreground="DodgerBlue"
|
||||||
<TextBlock x:Name="StatusTextBlock" Grid.Row="1" FontSize="12" FontWeight="Bold" Foreground="Black" HorizontalAlignment="Center" Text="{Binding Status}" VerticalAlignment="Center" />
|
IsIndeterminate="{Binding IsIndeterminate}" Maximum="{Binding MaxProgress}" Value="{Binding CurrentProgress}"
|
||||||
|
Visibility="{Binding ProgressBarVisibility}" />
|
||||||
|
<TextBlock x:Name="StatusTextBlock" Grid.Row="1" FontSize="12" FontWeight="Bold" Foreground="Black" HorizontalAlignment="Center"
|
||||||
|
Text="{Binding Status}" VerticalAlignment="Center" />
|
||||||
<Border Grid.Row="2" BorderBrush="DodgerBlue" BorderThickness="0,0.5,0,0">
|
<Border Grid.Row="2" BorderBrush="DodgerBlue" BorderThickness="0,0.5,0,0">
|
||||||
<ScrollViewer x:Name="LogScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,10,0,0">
|
<ScrollViewer x:Name="LogScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,10,0,0">
|
||||||
<ScrollViewer.Resources>
|
<ScrollViewer.Resources>
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Documents;
|
using System.Windows.Documents;
|
||||||
using System.Windows.Input;
|
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
@ -62,6 +61,11 @@ namespace SafeExamBrowser.UserInterface.Classic
|
||||||
Dispatcher.Invoke(base.Hide);
|
Dispatcher.Invoke(base.Hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HideProgressBar()
|
||||||
|
{
|
||||||
|
model.ProgressBarVisibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
|
||||||
public void Notify(ILogContent content)
|
public void Notify(ILogContent content)
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(() =>
|
Dispatcher.Invoke(() =>
|
||||||
|
@ -71,28 +75,52 @@ namespace SafeExamBrowser.UserInterface.Classic
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Progress(int amount = 1)
|
||||||
|
{
|
||||||
|
model.CurrentProgress += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Regress(int amount = 1)
|
||||||
|
{
|
||||||
|
model.CurrentProgress -= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetIndeterminate()
|
||||||
|
{
|
||||||
|
model.IsIndeterminate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxValue(int max)
|
||||||
|
{
|
||||||
|
model.MaxProgress = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(int value)
|
||||||
|
{
|
||||||
|
model.CurrentProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowProgressBar()
|
||||||
|
{
|
||||||
|
model.ProgressBarVisibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
||||||
|
{
|
||||||
|
model.StopBusyIndication();
|
||||||
|
model.Status = text.Get(key);
|
||||||
|
|
||||||
|
if (showBusyIndication)
|
||||||
|
{
|
||||||
|
model.StartBusyIndication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public new void Show()
|
public new void Show()
|
||||||
{
|
{
|
||||||
Dispatcher.Invoke(base.Show);
|
Dispatcher.Invoke(base.Show);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateStatus(TextKey key, bool showBusyIndication = false)
|
|
||||||
{
|
|
||||||
Dispatcher.Invoke(() =>
|
|
||||||
{
|
|
||||||
AnimatedBorder.Visibility = showBusyIndication ? Visibility.Hidden : Visibility.Visible;
|
|
||||||
ProgressBar.Visibility = showBusyIndication ? Visibility.Visible : Visibility.Hidden;
|
|
||||||
|
|
||||||
model.StopBusyIndication();
|
|
||||||
model.Status = text.Get(key);
|
|
||||||
|
|
||||||
if (showBusyIndication)
|
|
||||||
{
|
|
||||||
model.StartBusyIndication();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeRuntimeWindow()
|
private void InitializeRuntimeWindow()
|
||||||
{
|
{
|
||||||
Title = $"{runtimeInfo.ProgramTitle} - Version {runtimeInfo.ProgramVersion}";
|
Title = $"{runtimeInfo.ProgramTitle} - Version {runtimeInfo.ProgramVersion}";
|
||||||
|
@ -103,6 +131,8 @@ namespace SafeExamBrowser.UserInterface.Classic
|
||||||
InfoTextBlock.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
|
InfoTextBlock.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
|
||||||
|
|
||||||
model = new RuntimeWindowViewModel();
|
model = new RuntimeWindowViewModel();
|
||||||
|
AnimatedBorder.DataContext = model;
|
||||||
|
ProgressBar.DataContext = model;
|
||||||
StatusTextBlock.DataContext = model;
|
StatusTextBlock.DataContext = model;
|
||||||
|
|
||||||
Closing += (o, args) => args.Cancel = !allowClose;
|
Closing += (o, args) => args.Cancel = !allowClose;
|
||||||
|
|
|
@ -118,8 +118,8 @@
|
||||||
<Compile Include="Utilities\XamlIconResource.cs" />
|
<Compile Include="Utilities\XamlIconResource.cs" />
|
||||||
<Compile Include="ViewModels\DateTimeViewModel.cs" />
|
<Compile Include="ViewModels\DateTimeViewModel.cs" />
|
||||||
<Compile Include="ViewModels\LogViewModel.cs" />
|
<Compile Include="ViewModels\LogViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\ProgressIndicatorViewModel.cs" />
|
||||||
<Compile Include="ViewModels\RuntimeWindowViewModel.cs" />
|
<Compile Include="ViewModels\RuntimeWindowViewModel.cs" />
|
||||||
<Compile Include="ViewModels\SplashScreenViewModel.cs" />
|
|
||||||
<Page Include="AboutWindow.xaml">
|
<Page Include="AboutWindow.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SafeExamBrowser.UserInterface.Classic
|
||||||
public partial class SplashScreen : Window, ISplashScreen
|
public partial class SplashScreen : Window, ISplashScreen
|
||||||
{
|
{
|
||||||
private bool allowClose;
|
private bool allowClose;
|
||||||
private SplashScreenViewModel model = new SplashScreenViewModel();
|
private ProgressIndicatorViewModel model = new ProgressIndicatorViewModel();
|
||||||
private IRuntimeInfo runtimeInfo;
|
private IRuntimeInfo runtimeInfo;
|
||||||
private IText text;
|
private IText text;
|
||||||
private WindowClosingEventHandler closing;
|
private WindowClosingEventHandler closing;
|
||||||
|
@ -77,11 +77,16 @@ namespace SafeExamBrowser.UserInterface.Classic
|
||||||
model.IsIndeterminate = true;
|
model.IsIndeterminate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMaxProgress(int max)
|
public void SetMaxValue(int max)
|
||||||
{
|
{
|
||||||
model.MaxProgress = max;
|
model.MaxProgress = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValue(int value)
|
||||||
|
{
|
||||||
|
model.CurrentProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
||||||
{
|
{
|
||||||
model.StopBusyIndication();
|
model.StopBusyIndication();
|
||||||
|
|
|
@ -11,7 +11,7 @@ using System.Timers;
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||||
{
|
{
|
||||||
class SplashScreenViewModel : INotifyPropertyChanged
|
internal class ProgressIndicatorViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private int currentProgress;
|
private int currentProgress;
|
||||||
private bool isIndeterminate;
|
private bool isIndeterminate;
|
||||||
|
@ -73,7 +73,7 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartBusyIndication()
|
public virtual void StartBusyIndication()
|
||||||
{
|
{
|
||||||
StopBusyIndication();
|
StopBusyIndication();
|
||||||
|
|
||||||
|
@ -87,12 +87,17 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||||
busyTimer.Start();
|
busyTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopBusyIndication()
|
public virtual void StopBusyIndication()
|
||||||
{
|
{
|
||||||
busyTimer?.Stop();
|
busyTimer?.Stop();
|
||||||
busyTimer?.Close();
|
busyTimer?.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void OnPropertyChanged(string propertyName)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
private void BusyTimer_Elapsed(object sender, ElapsedEventArgs e)
|
private void BusyTimer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
var next = Status ?? string.Empty;
|
var next = Status ?? string.Empty;
|
|
@ -6,65 +6,52 @@
|
||||||
* 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 System.ComponentModel;
|
using System.Windows;
|
||||||
using System.Timers;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||||
{
|
{
|
||||||
internal class RuntimeWindowViewModel : INotifyPropertyChanged
|
internal class RuntimeWindowViewModel : ProgressIndicatorViewModel
|
||||||
{
|
{
|
||||||
private string status;
|
private Visibility animatedBorderVisibility, progressBarVisibility;
|
||||||
private Timer timer;
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public Visibility AnimatedBorderVisibility
|
||||||
|
|
||||||
public string Status
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return status;
|
return animatedBorderVisibility;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
status = value;
|
animatedBorderVisibility = value;
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Status)));
|
OnPropertyChanged(nameof(AnimatedBorderVisibility));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartBusyIndication()
|
public Visibility ProgressBarVisibility
|
||||||
{
|
{
|
||||||
StopBusyIndication();
|
get
|
||||||
|
|
||||||
timer = new Timer
|
|
||||||
{
|
{
|
||||||
AutoReset = true,
|
return progressBarVisibility;
|
||||||
Interval = 750
|
}
|
||||||
};
|
set
|
||||||
|
{
|
||||||
timer.Elapsed += Timer_Elapsed;
|
progressBarVisibility = value;
|
||||||
timer.Start();
|
OnPropertyChanged(nameof(ProgressBarVisibility));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopBusyIndication()
|
public override void StartBusyIndication()
|
||||||
{
|
{
|
||||||
timer?.Stop();
|
base.StartBusyIndication();
|
||||||
timer?.Close();
|
|
||||||
|
AnimatedBorderVisibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
public override void StopBusyIndication()
|
||||||
{
|
{
|
||||||
var next = Status ?? string.Empty;
|
base.StopBusyIndication();
|
||||||
|
|
||||||
if (next.EndsWith("..."))
|
AnimatedBorderVisibility = Visibility.Visible;
|
||||||
{
|
|
||||||
next = Status.Substring(0, Status.Length - 3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next += ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,11 +77,16 @@ namespace SafeExamBrowser.UserInterface.Windows10
|
||||||
model.IsIndeterminate = true;
|
model.IsIndeterminate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMaxProgress(int max)
|
public void SetMaxValue(int max)
|
||||||
{
|
{
|
||||||
model.MaxProgress = max;
|
model.MaxProgress = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetValue(int value)
|
||||||
|
{
|
||||||
|
model.CurrentProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
||||||
{
|
{
|
||||||
model.StopBusyIndication();
|
model.StopBusyIndication();
|
||||||
|
|
Loading…
Reference in a new issue