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<IApplicationInfo> appInfoMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<ITaskbar> taskbarMock;
|
||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||
|
||||
|
@ -35,14 +34,10 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
controllerMock = new Mock<IApplicationController>();
|
||||
appInfoMock = new Mock<IApplicationInfo>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
taskbarMock = new Mock<ITaskbar>();
|
||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new BrowserOperation(controllerMock.Object, appInfoMock.Object, loggerMock.Object, taskbarMock.Object, uiFactoryMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Behaviour;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
{
|
||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<IClientController> clientControllerMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
|
||||
private ClientControllerOperation sut;
|
||||
|
||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
clientControllerMock = new Mock<IClientController>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
|
||||
sut = new ClientControllerOperation(clientControllerMock.Object, loggerMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new ClientControllerOperation(clientControllerMock.Object, loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -10,7 +10,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|||
using Moq;
|
||||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<INativeMethods> nativeMethodsMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
|
||||
private ClipboardOperation sut;
|
||||
|
||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
nativeMethodsMock = new Mock<INativeMethods>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
|
||||
sut = new ClipboardOperation(loggerMock.Object, nativeMethodsMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new ClipboardOperation(loggerMock.Object, nativeMethodsMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
|
@ -21,7 +20,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
private Mock<IDisplayMonitor> displayMonitorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<ITaskbar> taskbarMock;
|
||||
|
||||
private DisplayMonitorOperation sut;
|
||||
|
@ -31,13 +29,9 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
displayMonitorMock = new Mock<IDisplayMonitor>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
taskbarMock = new Mock<ITaskbar>();
|
||||
|
||||
sut = new DisplayMonitorOperation(displayMonitorMock.Object, loggerMock.Object, taskbarMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new DisplayMonitorOperation(displayMonitorMock.Object, loggerMock.Object, taskbarMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
|
@ -22,7 +21,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
private Mock<IKeyboardInterceptor> keyboardInterceptorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<INativeMethods> nativeMethodsMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
|
||||
private KeyboardInterceptorOperation sut;
|
||||
|
||||
|
@ -32,12 +30,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
keyboardInterceptorMock = new Mock<IKeyboardInterceptor>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
nativeMethodsMock = new Mock<INativeMethods>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
|
||||
sut = new KeyboardInterceptorOperation(keyboardInterceptorMock.Object, loggerMock.Object, nativeMethodsMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new KeyboardInterceptorOperation(keyboardInterceptorMock.Object, loggerMock.Object, nativeMethodsMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
|
@ -22,7 +21,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
private Mock<IMouseInterceptor> mouseInterceptorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<INativeMethods> nativeMethodsMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
|
||||
private MouseInterceptorOperation sut;
|
||||
|
||||
|
@ -32,12 +30,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
mouseInterceptorMock = new Mock<IMouseInterceptor>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
nativeMethodsMock = new Mock<INativeMethods>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
|
||||
sut = new MouseInterceptorOperation(loggerMock.Object, mouseInterceptorMock.Object, nativeMethodsMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new MouseInterceptorOperation(loggerMock.Object, mouseInterceptorMock.Object, nativeMethodsMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
{
|
||||
|
@ -20,7 +19,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<IProcessMonitor> processMonitorMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
|
||||
private ProcessMonitorOperation sut;
|
||||
|
||||
|
@ -29,12 +27,8 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
processMonitorMock = new Mock<IProcessMonitor>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
|
||||
sut = new ProcessMonitorOperation(loggerMock.Object, processMonitorMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new ProcessMonitorOperation(loggerMock.Object, processMonitorMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<ITaskbarSettings> settingsMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
|
||||
private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupplyMock;
|
||||
private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetworkMock;
|
||||
|
@ -40,7 +39,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
settingsMock = new Mock<ITaskbarSettings>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
|
||||
powerSupplyMock = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
||||
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||
|
@ -64,10 +62,7 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
systemInfoMock.Object,
|
||||
taskbarMock.Object,
|
||||
textMock.Object,
|
||||
uiFactoryMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
uiFactoryMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,7 +11,6 @@ using Moq;
|
|||
using SafeExamBrowser.Client.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
||||
{
|
||||
|
@ -19,7 +18,6 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
public class WindowMonitorOperationTests
|
||||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<IWindowMonitor> windowMonitorMock;
|
||||
|
||||
private WindowMonitorOperation sut;
|
||||
|
@ -28,13 +26,9 @@ namespace SafeExamBrowser.Client.UnitTests.Behaviour.Operations
|
|||
public void Initialize()
|
||||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
windowMonitorMock = new Mock<IWindowMonitor>();
|
||||
|
||||
sut = new WindowMonitorOperation(loggerMock.Object, windowMonitorMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new WindowMonitorOperation(loggerMock.Object, windowMonitorMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private IUserInterfaceFactory uiFactory;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public BrowserOperation(
|
||||
IApplicationController browserController,
|
||||
|
@ -44,7 +44,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing browser...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeBrowser, true);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeBrowser, true);
|
||||
|
||||
var browserButton = uiFactory.CreateApplicationButton(browserInfo);
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Terminating browser...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_TerminateBrowser, true);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_TerminateBrowser, true);
|
||||
|
||||
browserController.Terminate();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private IClientController controller;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public ClientControllerOperation(IClientController controller, ILogger logger)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Starting event handling...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartEventHandling);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartEventHandling);
|
||||
|
||||
controller.Start();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Stopping event handling...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopEventHandling);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopEventHandling);
|
||||
|
||||
controller.Stop();
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private INativeMethods nativeMethods;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private void EmptyClipboard()
|
||||
{
|
||||
logger.Info("Emptying clipboard...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_EmptyClipboard);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_EmptyClipboard);
|
||||
|
||||
nativeMethods.EmptyClipboard();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private ITaskbar taskbar;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing working area...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeWorkingArea);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeWorkingArea);
|
||||
|
||||
displayMonitor.PreventSleepMode();
|
||||
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
||||
|
@ -49,7 +49,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Restoring working area...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_RestoreWorkingArea);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_RestoreWorkingArea);
|
||||
|
||||
displayMonitor.StopMonitoringDisplayChanges();
|
||||
displayMonitor.ResetPrimaryDisplay();
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private INativeMethods nativeMethods;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public KeyboardInterceptorOperation(
|
||||
IKeyboardInterceptor keyboardInterceptor,
|
||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Starting keyboard interception...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
||||
|
||||
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Stopping keyboard interception...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopKeyboardInterception);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopKeyboardInterception);
|
||||
|
||||
nativeMethods.DeregisterKeyboardHook(keyboardInterceptor);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private INativeMethods nativeMethods;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public MouseInterceptorOperation(
|
||||
ILogger logger,
|
||||
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Starting mouse interception...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartMouseInterception);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StartMouseInterception);
|
||||
|
||||
nativeMethods.RegisterMouseHook(mouseInterceptor);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Stopping mouse interception...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopMouseInterception);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopMouseInterception);
|
||||
|
||||
nativeMethods.DeregisterMouseHook(mouseInterceptor);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private IProcessMonitor processMonitor;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
|
||||
{
|
||||
|
@ -31,12 +31,12 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing process monitoring...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_WaitExplorerTermination, true);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_WaitExplorerTermination, true);
|
||||
|
||||
processMonitor.CloseExplorerShell();
|
||||
processMonitor.StartMonitoringExplorer();
|
||||
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeProcessMonitoring);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeProcessMonitoring);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
@ -49,11 +49,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Stopping process monitoring...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopProcessMonitoring);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopProcessMonitoring);
|
||||
|
||||
// TODO
|
||||
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_WaitExplorerStartup, true);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_WaitExplorerStartup, true);
|
||||
|
||||
processMonitor.StopMonitoringExplorer();
|
||||
processMonitor.StartExplorerShell();
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private IText text;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public TaskbarOperation(
|
||||
ILogger logger,
|
||||
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing taskbar...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeTaskbar);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeTaskbar);
|
||||
|
||||
if (settings.AllowApplicationLog)
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Terminating taskbar...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_TerminateTaskbar);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_TerminateTaskbar);
|
||||
|
||||
if (settings.AllowApplicationLog)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
private IWindowMonitor windowMonitor;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing window monitoring...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeWindowMonitoring);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeWindowMonitoring);
|
||||
|
||||
windowMonitor.HideAllWindows();
|
||||
windowMonitor.StartMonitoringWindows();
|
||||
|
@ -45,7 +45,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Stopping window monitoring...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_StopWindowMonitoring);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_StopWindowMonitoring);
|
||||
|
||||
windowMonitor.StopMonitoringWindows();
|
||||
windowMonitor.RestoreHiddenWindows();
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
* 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
|
||||
{
|
||||
public interface IRuntimeController
|
||||
|
@ -21,6 +18,6 @@ namespace SafeExamBrowser.Contracts.Behaviour
|
|||
/// <summary>
|
||||
/// Tries to start the runtime. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
||||
/// </summary>
|
||||
bool TryStart(Queue<IOperation> operations);
|
||||
bool TryStart();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
|||
public interface IOperation
|
||||
{
|
||||
/// <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>
|
||||
bool Abort { get; }
|
||||
|
||||
/// <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>
|
||||
ISplashScreen SplashScreen { set; }
|
||||
IProgressIndicator ProgressIndicator { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs the operation.
|
||||
|
|
|
@ -6,24 +6,29 @@
|
|||
* 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
|
||||
{
|
||||
public interface IOperationSequence
|
||||
{
|
||||
/// <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>
|
||||
bool TryPerform(Queue<IOperation> operations);
|
||||
IProgressIndicator ProgressIndicator { set; }
|
||||
|
||||
/// <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>
|
||||
bool TryRepeat();
|
||||
|
||||
/// <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>
|
||||
bool TryRevert();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
SplashScreen_StartEventHandling,
|
||||
SplashScreen_StartKeyboardInterception,
|
||||
SplashScreen_StartMouseInterception,
|
||||
SplashScreen_StartupProcedure,
|
||||
SplashScreen_StopEventHandling,
|
||||
SplashScreen_StopKeyboardInterception,
|
||||
SplashScreen_StopMouseInterception,
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
<Compile Include="UserInterface\IBrowserControl.cs" />
|
||||
<Compile Include="UserInterface\IBrowserWindow.cs" />
|
||||
<Compile Include="UserInterface\IMessageBox.cs" />
|
||||
<Compile Include="UserInterface\IProgressIndicator.cs" />
|
||||
<Compile Include="UserInterface\IRuntimeWindow.cs" />
|
||||
<Compile Include="UserInterface\MessageBoxResult.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/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.UserInterface
|
||||
{
|
||||
public interface IRuntimeWindow : ILogObserver, IWindow
|
||||
public interface IRuntimeWindow : ILogObserver, IProgressIndicator, IWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the status text of the runtime window. If the busy flag is set,
|
||||
/// the window will show an animation to indicate a long-running operation.
|
||||
/// Hides the progress bar.
|
||||
/// </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/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
|
||||
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 SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||
|
||||
namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||
|
@ -19,7 +18,6 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
public class I18nOperationTests
|
||||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<IText> textMock;
|
||||
|
||||
private I18nOperation sut;
|
||||
|
@ -28,13 +26,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
public void Initialize()
|
||||
{
|
||||
loggerMock = new Mock<ILogger>();
|
||||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
textMock = new Mock<IText>();
|
||||
|
||||
sut = new I18nOperation(loggerMock.Object, textMock.Object)
|
||||
{
|
||||
SplashScreen = splashScreenMock.Object
|
||||
};
|
||||
sut = new I18nOperation(loggerMock.Object, textMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -11,8 +11,6 @@ using System.Collections.Generic;
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||
|
@ -23,28 +21,17 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
public class OperationSequenceTests
|
||||
{
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<IRuntimeInfo> runtimeInfoMock;
|
||||
private Mock<IText> textMock;
|
||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||
|
||||
private IOperationSequence sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
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
|
||||
|
||||
[TestMethod]
|
||||
public void MustCorrectlyAbortProcess()
|
||||
public void MustCorrectlyAbortPerform()
|
||||
{
|
||||
var operationA = new Mock<IOperation>();
|
||||
var operationB = new Mock<IOperation>();
|
||||
|
@ -57,7 +44,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.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.Revert(), Times.Once);
|
||||
|
@ -81,7 +69,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.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.Revert(), Times.Never);
|
||||
|
@ -110,7 +99,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.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(a == 1);
|
||||
|
@ -134,7 +124,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationC.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.Revert(), Times.Once);
|
||||
|
@ -169,7 +160,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationC.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.IsTrue(d == 0);
|
||||
|
@ -195,7 +187,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.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.Revert(), Times.Once);
|
||||
|
@ -208,18 +201,23 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
[TestMethod]
|
||||
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]
|
||||
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);
|
||||
}
|
||||
|
@ -229,10 +227,147 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
#region Repeat Tests
|
||||
|
||||
[TestMethod]
|
||||
public void Fail()
|
||||
public void MustCorrectlyAbortRepeat()
|
||||
{
|
||||
// TODO
|
||||
Assert.Fail();
|
||||
var operationA = new Mock<IOperation>();
|
||||
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
|
||||
|
@ -251,7 +386,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.Object);
|
||||
operations.Enqueue(operationC.Object);
|
||||
|
||||
sut.TryPerform(operations);
|
||||
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||
|
||||
sut.TryPerform();
|
||||
|
||||
var success = sut.TryRevert();
|
||||
|
||||
|
@ -279,7 +416,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.Object);
|
||||
operations.Enqueue(operationC.Object);
|
||||
|
||||
sut.TryPerform(operations);
|
||||
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||
|
||||
sut.TryPerform();
|
||||
|
||||
var success = sut.TryRevert();
|
||||
|
||||
|
@ -305,7 +444,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.Object);
|
||||
operations.Enqueue(operationC.Object);
|
||||
|
||||
sut.TryPerform(operations);
|
||||
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||
|
||||
sut.TryPerform();
|
||||
|
||||
var success = sut.TryRevert();
|
||||
|
||||
|
@ -330,7 +471,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
operations.Enqueue(operationB.Object);
|
||||
operations.Enqueue(operationC.Object);
|
||||
|
||||
sut.TryPerform(operations);
|
||||
var sut = new OperationSequence(loggerMock.Object, operations);
|
||||
|
||||
sut.TryPerform();
|
||||
|
||||
var success = sut.TryRevert();
|
||||
|
||||
|
@ -342,15 +485,18 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
}
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustNotFailWithoutPerformWhenReverting()
|
||||
public void MustSucceedRevertingWithoutCallingPerform()
|
||||
{
|
||||
var sut = new OperationSequence(loggerMock.Object, new Queue<IOperation>());
|
||||
var success = sut.TryRevert();
|
||||
|
||||
Assert.IsTrue(success);
|
||||
|
@ -359,8 +505,15 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
[TestMethod]
|
||||
public void MustNotFailInCaseOfUnexpectedErrorWhenReverting()
|
||||
{
|
||||
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
||||
sut.TryRevert();
|
||||
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.TryRevert();
|
||||
|
||||
Assert.IsFalse(success);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
private IText text;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public I18nOperation(ILogger logger, IText text)
|
||||
{
|
||||
|
|
|
@ -10,8 +10,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
|
@ -20,42 +18,34 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
public class OperationSequence : IOperationSequence
|
||||
{
|
||||
private ILogger logger;
|
||||
private IRuntimeInfo runtimeInfo;
|
||||
private ISplashScreen splashScreen;
|
||||
private IText text;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
||||
private Queue<IOperation> operations = new Queue<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.runtimeInfo = runtimeInfo;
|
||||
this.text = text;
|
||||
this.uiFactory = uiFactory;
|
||||
this.operations = new Queue<IOperation>(operations);
|
||||
}
|
||||
|
||||
public bool TryPerform(Queue<IOperation> operations)
|
||||
public bool TryPerform()
|
||||
{
|
||||
var success = false;
|
||||
|
||||
try
|
||||
{
|
||||
Initialize(operations.Count);
|
||||
success = Perform(operations);
|
||||
Initialize();
|
||||
success = Perform();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
RevertOperations();
|
||||
Revert();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error($"Failed to perform operations!", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Finish();
|
||||
logger.Error("Failed to perform operations!", e);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -63,7 +53,19 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
|
||||
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()
|
||||
|
@ -73,46 +75,38 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
try
|
||||
{
|
||||
Initialize();
|
||||
success = RevertOperations(false);
|
||||
success = Revert(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error($"Failed to revert operations!", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Finish();
|
||||
logger.Error("Failed to revert operations!", e);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private void Initialize(int? operationCount = null)
|
||||
private void Initialize(bool indeterminate = false)
|
||||
{
|
||||
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
||||
|
||||
if (operationCount.HasValue)
|
||||
if (indeterminate)
|
||||
{
|
||||
splashScreen.SetMaxProgress(operationCount.Value);
|
||||
ProgressIndicator?.SetIndeterminate();
|
||||
}
|
||||
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)
|
||||
{
|
||||
stack.Push(operation);
|
||||
operation.SplashScreen = splashScreen;
|
||||
|
||||
try
|
||||
{
|
||||
operation.ProgressIndicator = ProgressIndicator;
|
||||
operation.Perform();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -127,13 +121,40 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
return false;
|
||||
}
|
||||
|
||||
splashScreen.Progress();
|
||||
ProgressIndicator?.Progress();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -143,6 +164,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
|
||||
try
|
||||
{
|
||||
operation.ProgressIndicator = ProgressIndicator;
|
||||
operation.Revert();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -153,16 +175,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
|
||||
if (regress)
|
||||
{
|
||||
splashScreen.Regress();
|
||||
ProgressIndicator?.Regress();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private void Finish()
|
||||
{
|
||||
splashScreen?.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,9 +87,6 @@
|
|||
<Entry key="SplashScreen_StartMouseInterception">
|
||||
Starting mouse interception
|
||||
</Entry>
|
||||
<Entry key="SplashScreen_StartupProcedure">
|
||||
Initiating startup procedure
|
||||
</Entry>
|
||||
<Entry key="SplashScreen_StopEventHandling">
|
||||
Stopping event handling
|
||||
</Entry>
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
private Mock<IRuntimeInfo> info;
|
||||
private Mock<ISettingsRepository> repository;
|
||||
private Mock<ISettings> settings;
|
||||
private Mock<ISplashScreen> splashScreen;
|
||||
private Mock<IText> text;
|
||||
private Mock<IUserInterfaceFactory> uiFactory;
|
||||
private ConfigurationOperation sut;
|
||||
|
@ -38,7 +37,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
info = new Mock<IRuntimeInfo>();
|
||||
repository = new Mock<ISettingsRepository>();
|
||||
settings = new Mock<ISettings>();
|
||||
splashScreen = new Mock<ISplashScreen>();
|
||||
text = new Mock<IText>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
|
@ -54,17 +52,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
{
|
||||
repository.Setup(r => r.LoadDefaults());
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new string[] { })
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new string[] { });
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
@ -76,10 +68,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
{
|
||||
var path = @"an/invalid\path.'*%yolo/()";
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path })
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path });
|
||||
|
||||
sut.Perform();
|
||||
}
|
||||
|
@ -93,10 +82,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
info.SetupGet(r => r.ProgramDataFolder).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 })
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", path });
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
@ -111,10 +97,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
info.SetupGet(r => r.ProgramDataFolder).Returns(location);
|
||||
info.SetupGet(r => r.AppDataFolder).Returns($@"{location}\WRONG");
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
@ -128,10 +111,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
|
||||
info.SetupGet(r => r.AppDataFolder).Returns(location);
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
@ -141,10 +121,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
[TestMethod]
|
||||
public void MustFallbackToDefaultsAsLastPrio()
|
||||
{
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
@ -159,10 +136,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
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);
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
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);
|
||||
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
|
||||
|
||||
sut.Perform();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
private Mock<ILogger> logger;
|
||||
private Mock<IServiceProxy> service;
|
||||
private Mock<ISettingsRepository> settings;
|
||||
private Mock<ISplashScreen> splashScreen;
|
||||
private Mock<IProgressIndicator> progressIndicator;
|
||||
private Mock<IText> text;
|
||||
private ServiceOperation sut;
|
||||
|
||||
|
@ -34,13 +34,10 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|||
logger = new Mock<ILogger>();
|
||||
service = new Mock<IServiceProxy>();
|
||||
settings = new Mock<ISettingsRepository>();
|
||||
splashScreen = new Mock<ISplashScreen>();
|
||||
progressIndicator = new Mock<IProgressIndicator>();
|
||||
text = new Mock<IText>();
|
||||
|
||||
sut = new ServiceOperation(logger.Object, service.Object, settings.Object, text.Object)
|
||||
{
|
||||
SplashScreen = splashScreen.Object
|
||||
};
|
||||
sut = new ServiceOperation(logger.Object, service.Object, settings.Object, text.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Runtime
|
|||
instances.BuildObjectGraph();
|
||||
instances.LogStartupInformation();
|
||||
|
||||
var success = instances.RuntimeController.TryStart(instances.StartupOperations);
|
||||
var success = instances.RuntimeController.TryStart();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
private string[] commandLineArgs;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public ConfigurationOperation(
|
||||
ILogger logger,
|
||||
|
@ -48,7 +48,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info("Initializing application configuration...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeConfiguration);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeConfiguration);
|
||||
|
||||
ISettings settings;
|
||||
var isValidUri = TryGetSettingsUri(out Uri uri);
|
||||
|
@ -73,7 +73,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
|
||||
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()
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
private KioskMode kioskMode;
|
||||
|
||||
public bool Abort { get; private set; }
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||
|
||||
public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
kioskMode = settingsRepository.Current.KioskMode;
|
||||
|
||||
logger.Info($"Initializing kiosk mode '{kioskMode}'...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeKioskMode);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeKioskMode);
|
||||
|
||||
if (kioskMode == KioskMode.CreateNewDesktop)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info($"Reverting kiosk mode '{kioskMode}'...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_RevertKioskMode);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_RevertKioskMode);
|
||||
|
||||
if (kioskMode == KioskMode.CreateNewDesktop)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
private IText text;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
public void Perform()
|
||||
{
|
||||
logger.Info($"Initializing service connection...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeServiceConnection);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_InitializeServiceConnection);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
public void Revert()
|
||||
{
|
||||
logger.Info("Closing service connection...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_CloseServiceConnection);
|
||||
ProgressIndicator?.UpdateText(TextKey.SplashScreen_CloseServiceConnection);
|
||||
|
||||
if (serviceAvailable)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SafeExamBrowser.Contracts.Behaviour;
|
||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
|
@ -22,18 +21,21 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
internal class RuntimeController : IRuntimeController
|
||||
{
|
||||
private ILogger logger;
|
||||
private IOperationSequence bootstrapSequence;
|
||||
private IOperationSequence sessionSequence;
|
||||
private IRuntimeInfo runtimeInfo;
|
||||
private IRuntimeWindow runtimeWindow;
|
||||
private IServiceProxy serviceProxy;
|
||||
private ISettingsRepository settingsRepository;
|
||||
private IOperationSequence operationSequence;
|
||||
private ISplashScreen splashScreen;
|
||||
private Action terminationCallback;
|
||||
private IText text;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
||||
public RuntimeController(
|
||||
ILogger logger,
|
||||
IOperationSequence operationSequence,
|
||||
IOperationSequence bootstrapSequence,
|
||||
IOperationSequence sessionSequence,
|
||||
IRuntimeInfo runtimeInfo,
|
||||
IServiceProxy serviceProxy,
|
||||
ISettingsRepository settingsRepository,
|
||||
|
@ -42,7 +44,8 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
IUserInterfaceFactory uiFactory)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.operationSequence = operationSequence;
|
||||
this.bootstrapSequence = bootstrapSequence;
|
||||
this.sessionSequence = sessionSequence;
|
||||
this.runtimeInfo = runtimeInfo;
|
||||
this.serviceProxy = serviceProxy;
|
||||
this.settingsRepository = settingsRepository;
|
||||
|
@ -51,21 +54,30 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
this.uiFactory = uiFactory;
|
||||
}
|
||||
|
||||
public bool TryStart(Queue<IOperation> operations)
|
||||
public bool TryStart()
|
||||
{
|
||||
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)
|
||||
{
|
||||
runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
|
||||
|
||||
logger.Info("--- Application successfully initialized! ---");
|
||||
logger.Log(string.Empty);
|
||||
logger.Subscribe(runtimeWindow);
|
||||
|
||||
StartSession();
|
||||
splashScreen.Hide();
|
||||
|
||||
StartSession(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -76,33 +88,6 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
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()
|
||||
{
|
||||
StopSession();
|
||||
|
@ -113,12 +98,13 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
// - Revert kiosk mode (or do that when stopping session?)
|
||||
|
||||
logger.Unsubscribe(runtimeWindow);
|
||||
runtimeWindow.Close();
|
||||
runtimeWindow?.Close();
|
||||
splashScreen?.Show();
|
||||
|
||||
logger.Log(string.Empty);
|
||||
logger.Info("--- Initiating shutdown procedure ---");
|
||||
|
||||
var success = operationSequence.TryRevert();
|
||||
var success = bootstrapSequence.TryRevert();
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
@ -128,6 +114,48 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
{
|
||||
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()
|
||||
|
@ -135,7 +163,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
logger.Info("Stopping current session...");
|
||||
runtimeWindow.Show();
|
||||
runtimeWindow.BringToForeground();
|
||||
runtimeWindow.UpdateStatus(TextKey.RuntimeWindow_StopSession, true);
|
||||
runtimeWindow.UpdateText(TextKey.RuntimeWindow_StopSession, true);
|
||||
|
||||
// TODO:
|
||||
// - Terminate client (or does it terminate itself?)
|
||||
|
|
|
@ -35,11 +35,12 @@ namespace SafeExamBrowser.Runtime
|
|||
private ISystemInfo systemInfo;
|
||||
|
||||
internal IRuntimeController RuntimeController { get; private set; }
|
||||
internal Queue<IOperation> StartupOperations { get; private set; }
|
||||
|
||||
internal void BuildObjectGraph()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
var bootstrapOperations = new Queue<IOperation>();
|
||||
var sessionOperations = new Queue<IOperation>();
|
||||
var nativeMethods = new NativeMethods();
|
||||
var settingsRepository = new SettingsRepository();
|
||||
var uiFactory = new UserInterfaceFactory();
|
||||
|
@ -52,16 +53,19 @@ namespace SafeExamBrowser.Runtime
|
|||
InitializeLogging();
|
||||
|
||||
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");
|
||||
|
||||
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>();
|
||||
StartupOperations.Enqueue(new I18nOperation(logger, text));
|
||||
StartupOperations.Enqueue(new ConfigurationOperation(logger, runtimeInfo, settingsRepository, text, uiFactory, args));
|
||||
StartupOperations.Enqueue(new ServiceOperation(logger, serviceProxy, settingsRepository, text));
|
||||
StartupOperations.Enqueue(new KioskModeOperation(logger, settingsRepository));
|
||||
sessionOperations.Enqueue(new ConfigurationOperation(logger, runtimeInfo, settingsRepository, text, uiFactory, args));
|
||||
sessionOperations.Enqueue(new ServiceOperation(logger, serviceProxy, settingsRepository, text));
|
||||
sessionOperations.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()
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
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">
|
||||
<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>
|
||||
<BlurEffect Radius="10" />
|
||||
</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" />
|
||||
<TextBlock x:Name="InfoTextBlock" Grid.Column="1" Foreground="Gray" Margin="10,75,175,10" TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<ProgressBar x:Name="ProgressBar" Grid.Row="1" IsIndeterminate="True" Background="WhiteSmoke" BorderThickness="0" Foreground="DodgerBlue" Visibility="Hidden" />
|
||||
<TextBlock x:Name="StatusTextBlock" Grid.Row="1" FontSize="12" FontWeight="Bold" Foreground="Black" HorizontalAlignment="Center" Text="{Binding Status}" VerticalAlignment="Center" />
|
||||
<ProgressBar x:Name="ProgressBar" Grid.Row="1" Background="WhiteSmoke" BorderThickness="0" Foreground="DodgerBlue"
|
||||
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">
|
||||
<ScrollViewer x:Name="LogScrollViewer" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="0,10,0,0">
|
||||
<ScrollViewer.Resources>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
@ -62,6 +61,11 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
Dispatcher.Invoke(base.Hide);
|
||||
}
|
||||
|
||||
public void HideProgressBar()
|
||||
{
|
||||
model.ProgressBarVisibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
public void Notify(ILogContent content)
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
Title = $"{runtimeInfo.ProgramTitle} - Version {runtimeInfo.ProgramVersion}";
|
||||
|
@ -103,6 +131,8 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
InfoTextBlock.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
|
||||
|
||||
model = new RuntimeWindowViewModel();
|
||||
AnimatedBorder.DataContext = model;
|
||||
ProgressBar.DataContext = model;
|
||||
StatusTextBlock.DataContext = model;
|
||||
|
||||
Closing += (o, args) => args.Cancel = !allowClose;
|
||||
|
|
|
@ -118,8 +118,8 @@
|
|||
<Compile Include="Utilities\XamlIconResource.cs" />
|
||||
<Compile Include="ViewModels\DateTimeViewModel.cs" />
|
||||
<Compile Include="ViewModels\LogViewModel.cs" />
|
||||
<Compile Include="ViewModels\ProgressIndicatorViewModel.cs" />
|
||||
<Compile Include="ViewModels\RuntimeWindowViewModel.cs" />
|
||||
<Compile Include="ViewModels\SplashScreenViewModel.cs" />
|
||||
<Page Include="AboutWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
public partial class SplashScreen : Window, ISplashScreen
|
||||
{
|
||||
private bool allowClose;
|
||||
private SplashScreenViewModel model = new SplashScreenViewModel();
|
||||
private ProgressIndicatorViewModel model = new ProgressIndicatorViewModel();
|
||||
private IRuntimeInfo runtimeInfo;
|
||||
private IText text;
|
||||
private WindowClosingEventHandler closing;
|
||||
|
@ -77,11 +77,16 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
model.IsIndeterminate = true;
|
||||
}
|
||||
|
||||
public void SetMaxProgress(int max)
|
||||
public void SetMaxValue(int max)
|
||||
{
|
||||
model.MaxProgress = max;
|
||||
}
|
||||
|
||||
public void SetValue(int value)
|
||||
{
|
||||
model.CurrentProgress = value;
|
||||
}
|
||||
|
||||
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
||||
{
|
||||
model.StopBusyIndication();
|
||||
|
|
|
@ -11,7 +11,7 @@ using System.Timers;
|
|||
|
||||
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||
{
|
||||
class SplashScreenViewModel : INotifyPropertyChanged
|
||||
internal class ProgressIndicatorViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private int currentProgress;
|
||||
private bool isIndeterminate;
|
||||
|
@ -73,7 +73,7 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public void StartBusyIndication()
|
||||
public virtual void StartBusyIndication()
|
||||
{
|
||||
StopBusyIndication();
|
||||
|
||||
|
@ -87,12 +87,17 @@ namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
|||
busyTimer.Start();
|
||||
}
|
||||
|
||||
public void StopBusyIndication()
|
||||
public virtual void StopBusyIndication()
|
||||
{
|
||||
busyTimer?.Stop();
|
||||
busyTimer?.Close();
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
private void BusyTimer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var next = Status ?? string.Empty;
|
|
@ -6,65 +6,52 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Classic.ViewModels
|
||||
{
|
||||
internal class RuntimeWindowViewModel : INotifyPropertyChanged
|
||||
internal class RuntimeWindowViewModel : ProgressIndicatorViewModel
|
||||
{
|
||||
private string status;
|
||||
private Timer timer;
|
||||
private Visibility animatedBorderVisibility, progressBarVisibility;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public string Status
|
||||
public Visibility AnimatedBorderVisibility
|
||||
{
|
||||
get
|
||||
{
|
||||
return status;
|
||||
return animatedBorderVisibility;
|
||||
}
|
||||
set
|
||||
{
|
||||
status = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Status)));
|
||||
animatedBorderVisibility = value;
|
||||
OnPropertyChanged(nameof(AnimatedBorderVisibility));
|
||||
}
|
||||
}
|
||||
|
||||
public void StartBusyIndication()
|
||||
public Visibility ProgressBarVisibility
|
||||
{
|
||||
StopBusyIndication();
|
||||
|
||||
timer = new Timer
|
||||
get
|
||||
{
|
||||
AutoReset = true,
|
||||
Interval = 750
|
||||
};
|
||||
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.Start();
|
||||
return progressBarVisibility;
|
||||
}
|
||||
set
|
||||
{
|
||||
progressBarVisibility = value;
|
||||
OnPropertyChanged(nameof(ProgressBarVisibility));
|
||||
}
|
||||
}
|
||||
|
||||
public void StopBusyIndication()
|
||||
public override void StartBusyIndication()
|
||||
{
|
||||
timer?.Stop();
|
||||
timer?.Close();
|
||||
base.StartBusyIndication();
|
||||
|
||||
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("..."))
|
||||
{
|
||||
next = Status.Substring(0, Status.Length - 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
next += ".";
|
||||
}
|
||||
|
||||
Status = next;
|
||||
AnimatedBorderVisibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,11 +77,16 @@ namespace SafeExamBrowser.UserInterface.Windows10
|
|||
model.IsIndeterminate = true;
|
||||
}
|
||||
|
||||
public void SetMaxProgress(int max)
|
||||
public void SetMaxValue(int max)
|
||||
{
|
||||
model.MaxProgress = max;
|
||||
}
|
||||
|
||||
public void SetValue(int value)
|
||||
{
|
||||
model.CurrentProgress = value;
|
||||
}
|
||||
|
||||
public void UpdateText(TextKey key, bool showBusyIndication = false)
|
||||
{
|
||||
model.StopBusyIndication();
|
||||
|
|
Loading…
Reference in a new issue