SEBWIN-312: Implemented folder dialog for custom application path selection.

This commit is contained in:
dbuechel 2019-12-06 17:42:46 +01:00
parent b1781ba1ed
commit 6e7ddf1f8a
24 changed files with 248 additions and 33 deletions

View file

@ -26,7 +26,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
private Mock<ILogger> logger; private Mock<ILogger> logger;
private AppSettings settings; private AppSettings settings;
private Mock<ITaskbar> taskbar; private Mock<ITaskbar> taskbar;
private Mock<ITaskView> taskView; private Mock<ITaskview> taskview;
private Mock<IUserInterfaceFactory> uiFactory; private Mock<IUserInterfaceFactory> uiFactory;
private BrowserOperation sut; private BrowserOperation sut;
@ -40,13 +40,13 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
logger = new Mock<ILogger>(); logger = new Mock<ILogger>();
settings = new AppSettings(); settings = new AppSettings();
taskbar = new Mock<ITaskbar>(); taskbar = new Mock<ITaskbar>();
taskView = new Mock<ITaskView>(); taskview = new Mock<ITaskview>();
uiFactory = new Mock<IUserInterfaceFactory>(); uiFactory = new Mock<IUserInterfaceFactory>();
context.Browser = browser.Object; context.Browser = browser.Object;
context.Settings = settings; context.Settings = settings;
sut = new BrowserOperation(actionCenter.Object, context, logger.Object, taskbar.Object, taskView.Object, uiFactory.Object); sut = new BrowserOperation(actionCenter.Object, context, logger.Object, taskbar.Object, taskview.Object, uiFactory.Object);
} }
[TestMethod] [TestMethod]

View file

@ -38,7 +38,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
private Mock<IPowerSupply> powerSupply; private Mock<IPowerSupply> powerSupply;
private Mock<ISystemInfo> systemInfo; private Mock<ISystemInfo> systemInfo;
private Mock<ITaskbar> taskbar; private Mock<ITaskbar> taskbar;
private Mock<ITaskView> taskView; private Mock<ITaskview> taskview;
private Mock<IText> text; private Mock<IText> text;
private Mock<IUserInterfaceFactory> uiFactory; private Mock<IUserInterfaceFactory> uiFactory;
private Mock<IWirelessAdapter> wirelessAdapter; private Mock<IWirelessAdapter> wirelessAdapter;
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
powerSupply = new Mock<IPowerSupply>(); powerSupply = new Mock<IPowerSupply>();
systemInfo = new Mock<ISystemInfo>(); systemInfo = new Mock<ISystemInfo>();
taskbar = new Mock<ITaskbar>(); taskbar = new Mock<ITaskbar>();
taskView = new Mock<ITaskView>(); taskview = new Mock<ITaskview>();
text = new Mock<IText>(); text = new Mock<IText>();
uiFactory = new Mock<IUserInterfaceFactory>(); uiFactory = new Mock<IUserInterfaceFactory>();
wirelessAdapter = new Mock<IWirelessAdapter>(); wirelessAdapter = new Mock<IWirelessAdapter>();
@ -84,7 +84,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
powerSupply.Object, powerSupply.Object,
systemInfo.Object, systemInfo.Object,
taskbar.Object, taskbar.Object,
taskView.Object, taskview.Object,
text.Object, text.Object,
uiFactory.Object, uiFactory.Object,
wirelessAdapter.Object); wirelessAdapter.Object);
@ -94,7 +94,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
public void Perform_MustInitializeActivators() public void Perform_MustInitializeActivators()
{ {
var actionCenterActivator = new Mock<IActionCenterActivator>(); var actionCenterActivator = new Mock<IActionCenterActivator>();
var taskViewActivator = new Mock<ITaskViewActivator>(); var taskViewActivator = new Mock<ITaskviewActivator>();
var terminationActivator = new Mock<ITerminationActivator>(); var terminationActivator = new Mock<ITerminationActivator>();
context.Activators.Add(actionCenterActivator.Object); context.Activators.Add(actionCenterActivator.Object);
@ -261,18 +261,18 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
public void Revert_MustTerminateActivators() public void Revert_MustTerminateActivators()
{ {
var actionCenterActivator = new Mock<IActionCenterActivator>(); var actionCenterActivator = new Mock<IActionCenterActivator>();
var taskViewActivator = new Mock<ITaskViewActivator>(); var taskviewActivator = new Mock<ITaskviewActivator>();
var terminationActivator = new Mock<ITerminationActivator>(); var terminationActivator = new Mock<ITerminationActivator>();
context.Activators.Add(actionCenterActivator.Object); context.Activators.Add(actionCenterActivator.Object);
context.Activators.Add(taskViewActivator.Object); context.Activators.Add(taskviewActivator.Object);
context.Activators.Add(terminationActivator.Object); context.Activators.Add(terminationActivator.Object);
context.Settings.ActionCenter.EnableActionCenter = true; context.Settings.ActionCenter.EnableActionCenter = true;
sut.Revert(); sut.Revert();
actionCenterActivator.Verify(a => a.Stop(), Times.Once); actionCenterActivator.Verify(a => a.Stop(), Times.Once);
taskViewActivator.Verify(a => a.Stop(), Times.Once); taskviewActivator.Verify(a => a.Stop(), Times.Once);
terminationActivator.Verify(a => a.Stop(), Times.Once); terminationActivator.Verify(a => a.Stop(), Times.Once);
} }

View file

@ -528,7 +528,15 @@ namespace SafeExamBrowser.Client
private void AskForApplicationPath(ApplicationNotFoundEventArgs args) private void AskForApplicationPath(ApplicationNotFoundEventArgs args)
{ {
// TODO var message = text.Get(TextKey.FolderDialog_ApplicationLocation).Replace("%%NAME%%", args.DisplayName).Replace("%%EXECUTABLE%%", args.ExecutableName);
var dialog = uiFactory.CreateFolderDialog(message);
var result = dialog.Show(splashScreen);
if (result.Success)
{
args.CustomPath = result.FolderPath;
args.Success = true;
}
} }
private void InformAboutFailedApplicationInitialization(ApplicationInitializationFailedEventArgs args) private void InformAboutFailedApplicationInitialization(ApplicationInitializationFailedEventArgs args)

View file

@ -71,7 +71,7 @@ namespace SafeExamBrowser.Client
private IRuntimeProxy runtimeProxy; private IRuntimeProxy runtimeProxy;
private ISystemInfo systemInfo; private ISystemInfo systemInfo;
private ITaskbar taskbar; private ITaskbar taskbar;
private ITaskView taskview; private ITaskview taskview;
private IText text; private IText text;
private ITextResource textResource; private ITextResource textResource;
private IUserInterfaceFactory uiFactory; private IUserInterfaceFactory uiFactory;
@ -95,7 +95,7 @@ namespace SafeExamBrowser.Client
uiFactory = BuildUserInterfaceFactory(); uiFactory = BuildUserInterfaceFactory();
runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), ModuleLogger(nameof(RuntimeProxy)), Interlocutor.Client); runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), ModuleLogger(nameof(RuntimeProxy)), Interlocutor.Client);
taskbar = BuildTaskbar(); taskbar = BuildTaskbar();
taskview = BuildTaskView(); taskview = BuildTaskview();
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory))); var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, processFactory); var applicationMonitor = new ApplicationMonitor(TWO_SECONDS, ModuleLogger(nameof(ApplicationMonitor)), nativeMethods, processFactory);
@ -265,7 +265,7 @@ namespace SafeExamBrowser.Client
context.Activators.Add(new ActionCenterKeyboardActivator(ModuleLogger(nameof(ActionCenterKeyboardActivator)), nativeMethods)); context.Activators.Add(new ActionCenterKeyboardActivator(ModuleLogger(nameof(ActionCenterKeyboardActivator)), nativeMethods));
context.Activators.Add(new ActionCenterTouchActivator(ModuleLogger(nameof(ActionCenterTouchActivator)), nativeMethods)); context.Activators.Add(new ActionCenterTouchActivator(ModuleLogger(nameof(ActionCenterTouchActivator)), nativeMethods));
context.Activators.Add(new TaskViewKeyboardActivator(ModuleLogger(nameof(TaskViewKeyboardActivator)), nativeMethods)); context.Activators.Add(new TaskviewKeyboardActivator(ModuleLogger(nameof(TaskviewKeyboardActivator)), nativeMethods));
context.Activators.Add(new TerminationActivator(ModuleLogger(nameof(TerminationActivator)), nativeMethods)); context.Activators.Add(new TerminationActivator(ModuleLogger(nameof(TerminationActivator)), nativeMethods));
return operation; return operation;
@ -304,7 +304,7 @@ namespace SafeExamBrowser.Client
} }
} }
private ITaskView BuildTaskView() private ITaskview BuildTaskview()
{ {
switch (uiMode) switch (uiMode)
{ {

View file

@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Operations
private IActionCenter actionCenter; private IActionCenter actionCenter;
private ILogger logger; private ILogger logger;
private ITaskbar taskbar; private ITaskbar taskbar;
private ITaskView taskview; private ITaskview taskview;
private IUserInterfaceFactory uiFactory; private IUserInterfaceFactory uiFactory;
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } } public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Client.Operations
ClientContext context, ClientContext context,
ILogger logger, ILogger logger,
ITaskbar taskbar, ITaskbar taskbar,
ITaskView taskview, ITaskview taskview,
IUserInterfaceFactory uiFactory) : base(context) IUserInterfaceFactory uiFactory) : base(context)
{ {
this.actionCenter = actionCenter; this.actionCenter = actionCenter;

View file

@ -35,7 +35,7 @@ namespace SafeExamBrowser.Client.Operations
private IPowerSupply powerSupply; private IPowerSupply powerSupply;
private ISystemInfo systemInfo; private ISystemInfo systemInfo;
private ITaskbar taskbar; private ITaskbar taskbar;
private ITaskView taskview; private ITaskview taskview;
private IText text; private IText text;
private IUserInterfaceFactory uiFactory; private IUserInterfaceFactory uiFactory;
private IWirelessAdapter wirelessAdapter; private IWirelessAdapter wirelessAdapter;
@ -56,7 +56,7 @@ namespace SafeExamBrowser.Client.Operations
IPowerSupply powerSupply, IPowerSupply powerSupply,
ISystemInfo systemInfo, ISystemInfo systemInfo,
ITaskbar taskbar, ITaskbar taskbar,
ITaskView taskview, ITaskview taskview,
IText text, IText text,
IUserInterfaceFactory uiFactory, IUserInterfaceFactory uiFactory,
IWirelessAdapter wirelessAdapter) : base(context) IWirelessAdapter wirelessAdapter) : base(context)
@ -114,7 +114,7 @@ namespace SafeExamBrowser.Client.Operations
actionCenterActivator.Start(); actionCenterActivator.Start();
} }
if (Context.Settings.Keyboard.AllowAltTab && activator is ITaskViewActivator taskViewActivator) if (Context.Settings.Keyboard.AllowAltTab && activator is ITaskviewActivator taskViewActivator)
{ {
taskview.Register(taskViewActivator); taskview.Register(taskViewActivator);
taskViewActivator.Start(); taskViewActivator.Start();

View file

@ -23,6 +23,7 @@ namespace SafeExamBrowser.I18n.Contracts
BrowserWindow_DeveloperConsoleMenuItem, BrowserWindow_DeveloperConsoleMenuItem,
BrowserWindow_ZoomMenuItem, BrowserWindow_ZoomMenuItem,
Build, Build,
FolderDialog_ApplicationLocation,
LockScreen_AllowOption, LockScreen_AllowOption,
LockScreen_Message, LockScreen_Message,
LockScreen_TerminateOption, LockScreen_TerminateOption,

View file

@ -27,6 +27,9 @@
<Entry key="Build"> <Entry key="Build">
Build Build
</Entry> </Entry>
<Entry key="FolderDialog_ApplicationLocation">
Application "%%NAME%%" could not be found on the system! Please locate the folder containing the main executable "%%EXECUTABLE%%".
</Entry>
<Entry key="LockScreen_AllowOption"> <Entry key="LockScreen_AllowOption">
Temporarily allow the blacklisted applications. This applies only to the currently running instances and session! Temporarily allow the blacklisted applications. This applies only to the currently running instances and session!
</Entry> </Entry>

View file

@ -49,6 +49,11 @@ namespace SafeExamBrowser.UserInterface.Contracts
/// </summary> /// </summary>
IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow); IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow);
/// <summary>
/// Creates a folder dialog with the given message.
/// </summary>
IFolderDialog CreateFolderDialog(string message);
/// <summary> /// <summary>
/// Creates a system control which allows to change the keyboard layout of the computer. /// Creates a system control which allows to change the keyboard layout of the computer.
/// </summary> /// </summary>

View file

@ -76,13 +76,15 @@
<Compile Include="Shell\INotificationControl.cs" /> <Compile Include="Shell\INotificationControl.cs" />
<Compile Include="Shell\ISystemControl.cs" /> <Compile Include="Shell\ISystemControl.cs" />
<Compile Include="Shell\ITaskbar.cs" /> <Compile Include="Shell\ITaskbar.cs" />
<Compile Include="Shell\ITaskView.cs" /> <Compile Include="Shell\ITaskview.cs" />
<Compile Include="Shell\ITaskViewActivator.cs" /> <Compile Include="Shell\ITaskviewActivator.cs" />
<Compile Include="Shell\ITerminationActivator.cs" /> <Compile Include="Shell\ITerminationActivator.cs" />
<Compile Include="Shell\Location.cs" /> <Compile Include="Shell\Location.cs" />
<Compile Include="Windows\Data\FolderDialogResult.cs" />
<Compile Include="Windows\Data\LockScreenOption.cs" /> <Compile Include="Windows\Data\LockScreenOption.cs" />
<Compile Include="Windows\Data\LockScreenResult.cs" /> <Compile Include="Windows\Data\LockScreenResult.cs" />
<Compile Include="Windows\Events\WindowClosingEventHandler.cs" /> <Compile Include="Windows\Events\WindowClosingEventHandler.cs" />
<Compile Include="Windows\IFolderDialog.cs" />
<Compile Include="Windows\ILockScreen.cs" /> <Compile Include="Windows\ILockScreen.cs" />
<Compile Include="Windows\IPasswordDialog.cs" /> <Compile Include="Windows\IPasswordDialog.cs" />
<Compile Include="Windows\Data\PasswordDialogResult.cs" /> <Compile Include="Windows\Data\PasswordDialogResult.cs" />

View file

@ -13,7 +13,7 @@ namespace SafeExamBrowser.UserInterface.Contracts.Shell
/// <summary> /// <summary>
/// The task view provides an overview of all currently running application instances. /// The task view provides an overview of all currently running application instances.
/// </summary> /// </summary>
public interface ITaskView public interface ITaskview
{ {
/// <summary> /// <summary>
/// Adds the given application to the task view. /// Adds the given application to the task view.
@ -23,6 +23,6 @@ namespace SafeExamBrowser.UserInterface.Contracts.Shell
/// <summary> /// <summary>
/// Registers the specified activator for the task view. /// Registers the specified activator for the task view.
/// </summary> /// </summary>
void Register(ITaskViewActivator activator); void Register(ITaskviewActivator activator);
} }
} }

View file

@ -11,9 +11,9 @@ using SafeExamBrowser.UserInterface.Contracts.Shell.Events;
namespace SafeExamBrowser.UserInterface.Contracts.Shell namespace SafeExamBrowser.UserInterface.Contracts.Shell
{ {
/// <summary> /// <summary>
/// A module which can be used to control the <see cref="ITaskView"/>. /// A module which can be used to control the <see cref="ITaskview"/>.
/// </summary> /// </summary>
public interface ITaskViewActivator : IActivator public interface ITaskviewActivator : IActivator
{ {
/// <summary> /// <summary>
/// Fired when the task view should be hidden. /// Fired when the task view should be hidden.

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.UserInterface.Contracts.Windows.Data
{
/// <summary>
/// Defines the user interaction result of an <see cref="IFolderDialog"/>.
/// </summary>
public class FolderDialogResult
{
/// <summary>
/// The full path of the folder selected by the user, or <c>null</c> if the interaction was unsuccessful.
/// </summary>
public string FolderPath { get; set; }
/// <summary>
/// Indicates whether the user confirmed the dialog or not.
/// </summary>
public bool Success { get; set; }
}
}

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
namespace SafeExamBrowser.UserInterface.Contracts.Windows
{
public interface IFolderDialog
{
/// <summary>
/// Shows the dialog to the user. If a parent window is specified, the dialog is rendered modally for the given parent.
/// </summary>
FolderDialogResult Show(IWindow parent = null);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
namespace SafeExamBrowser.UserInterface.Desktop
{
internal class FolderDialog : IFolderDialog
{
private string message;
internal FolderDialog(string message)
{
this.message = message;
}
public FolderDialogResult Show(IWindow parent = null)
{
var result = new FolderDialogResult();
using (var dialog = new FolderBrowserDialog())
{
var dialogResult = DialogResult.None;
dialog.Description = message;
dialog.ShowNewFolderButton = false;
if (parent is Window w)
{
dialogResult = dialog.ShowDialog(new Win32Window(w));
}
else
{
dialogResult = dialog.ShowDialog();
}
if (dialogResult == DialogResult.OK)
{
result.FolderPath = dialog.SelectedPath;
result.Success = true;
}
}
return result;
}
private class Win32Window : System.Windows.Forms.IWin32Window
{
private Window w;
public Win32Window(Window w)
{
this.w = w;
}
public IntPtr Handle => w.Dispatcher.Invoke(() => new WindowInteropHelper(w).Handle);
}
}
}

View file

@ -145,6 +145,7 @@
<Compile Include="Controls\TaskviewWindowControl.xaml.cs"> <Compile Include="Controls\TaskviewWindowControl.xaml.cs">
<DependentUpon>TaskviewWindowControl.xaml</DependentUpon> <DependentUpon>TaskviewWindowControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="FolderDialog.cs" />
<Compile Include="LockScreen.xaml.cs"> <Compile Include="LockScreen.xaml.cs">
<DependentUpon>LockScreen.xaml</DependentUpon> <DependentUpon>LockScreen.xaml</DependentUpon>
</Compile> </Compile>

View file

@ -18,7 +18,7 @@ using SafeExamBrowser.UserInterface.Desktop.Controls;
namespace SafeExamBrowser.UserInterface.Desktop namespace SafeExamBrowser.UserInterface.Desktop
{ {
public partial class Taskview : Window, ITaskView public partial class Taskview : Window, ITaskview
{ {
private IList<IApplication> applications; private IList<IApplication> applications;
private LinkedListNode<TaskviewWindowControl> current; private LinkedListNode<TaskviewWindowControl> current;
@ -41,7 +41,7 @@ namespace SafeExamBrowser.UserInterface.Desktop
applications.Add(application); applications.Add(application);
} }
public void Register(ITaskViewActivator activator) public void Register(ITaskviewActivator activator)
{ {
activator.Deactivated += Activator_Deactivated; activator.Deactivated += Activator_Deactivated;
activator.NextActivated += Activator_Next; activator.NextActivated += Activator_Next;

View file

@ -75,6 +75,11 @@ namespace SafeExamBrowser.UserInterface.Desktop
return new BrowserWindow(control, settings, isMainWindow, text); return new BrowserWindow(control, settings, isMainWindow, text);
} }
public IFolderDialog CreateFolderDialog(string message)
{
return new FolderDialog(message);
}
public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location) public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location)
{ {
if (location == Location.ActionCenter) if (location == Location.ActionCenter)

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using SafeExamBrowser.UserInterface.Contracts.Windows;
using SafeExamBrowser.UserInterface.Contracts.Windows.Data;
namespace SafeExamBrowser.UserInterface.Mobile
{
internal class FolderDialog : IFolderDialog
{
private string message;
internal FolderDialog(string message)
{
this.message = message;
}
public FolderDialogResult Show(IWindow parent = null)
{
var result = new FolderDialogResult();
using (var dialog = new FolderBrowserDialog())
{
var dialogResult = DialogResult.None;
dialog.Description = message;
dialog.ShowNewFolderButton = false;
if (parent is Window w)
{
dialogResult = dialog.ShowDialog(new Win32Window(w));
}
else
{
dialogResult = dialog.ShowDialog();
}
if (dialogResult == DialogResult.OK)
{
result.FolderPath = dialog.SelectedPath;
result.Success = true;
}
}
return result;
}
private class Win32Window : System.Windows.Forms.IWin32Window
{
private Window w;
public Win32Window(Window w)
{
this.w = w;
}
public IntPtr Handle => w.Dispatcher.Invoke(() => new WindowInteropHelper(w).Handle);
}
}
}

View file

@ -146,6 +146,7 @@
<Compile Include="Controls\TaskviewWindowControl.xaml.cs"> <Compile Include="Controls\TaskviewWindowControl.xaml.cs">
<DependentUpon>TaskviewWindowControl.xaml</DependentUpon> <DependentUpon>TaskviewWindowControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="FolderDialog.cs" />
<Compile Include="LockScreen.xaml.cs"> <Compile Include="LockScreen.xaml.cs">
<DependentUpon>LockScreen.xaml</DependentUpon> <DependentUpon>LockScreen.xaml</DependentUpon>
</Compile> </Compile>

View file

@ -18,7 +18,7 @@ using SafeExamBrowser.UserInterface.Mobile.Controls;
namespace SafeExamBrowser.UserInterface.Mobile namespace SafeExamBrowser.UserInterface.Mobile
{ {
public partial class Taskview : Window, ITaskView public partial class Taskview : Window, ITaskview
{ {
private IList<IApplication> applications; private IList<IApplication> applications;
private LinkedListNode<TaskviewWindowControl> current; private LinkedListNode<TaskviewWindowControl> current;
@ -41,7 +41,7 @@ namespace SafeExamBrowser.UserInterface.Mobile
applications.Add(application); applications.Add(application);
} }
public void Register(ITaskViewActivator activator) public void Register(ITaskviewActivator activator)
{ {
activator.Deactivated += Activator_Deactivated; activator.Deactivated += Activator_Deactivated;
activator.NextActivated += Activator_Next; activator.NextActivated += Activator_Next;

View file

@ -75,6 +75,11 @@ namespace SafeExamBrowser.UserInterface.Mobile
return new BrowserWindow(control, settings, isMainWindow, text); return new BrowserWindow(control, settings, isMainWindow, text);
} }
public IFolderDialog CreateFolderDialog(string message)
{
return new FolderDialog(message);
}
public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location) public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location)
{ {
if (location == Location.ActionCenter) if (location == Location.ActionCenter)

View file

@ -15,7 +15,7 @@ using SafeExamBrowser.WindowsApi.Contracts.Events;
namespace SafeExamBrowser.UserInterface.Shared.Activators namespace SafeExamBrowser.UserInterface.Shared.Activators
{ {
public class TaskViewKeyboardActivator : KeyboardActivator, ITaskViewActivator public class TaskviewKeyboardActivator : KeyboardActivator, ITaskviewActivator
{ {
private bool Activated, LeftShift, Tab; private bool Activated, LeftShift, Tab;
private ILogger logger; private ILogger logger;
@ -24,7 +24,7 @@ namespace SafeExamBrowser.UserInterface.Shared.Activators
public event ActivatorEventHandler NextActivated; public event ActivatorEventHandler NextActivated;
public event ActivatorEventHandler PreviousActivated; public event ActivatorEventHandler PreviousActivated;
public TaskViewKeyboardActivator(ILogger logger, INativeMethods nativeMethods) : base(nativeMethods) public TaskviewKeyboardActivator(ILogger logger, INativeMethods nativeMethods) : base(nativeMethods)
{ {
this.logger = logger; this.logger = logger;
} }

View file

@ -66,7 +66,7 @@
<Compile Include="Activators\ActionCenterKeyboardActivator.cs" /> <Compile Include="Activators\ActionCenterKeyboardActivator.cs" />
<Compile Include="Activators\ActionCenterTouchActivator.cs" /> <Compile Include="Activators\ActionCenterTouchActivator.cs" />
<Compile Include="Activators\KeyboardActivator.cs" /> <Compile Include="Activators\KeyboardActivator.cs" />
<Compile Include="Activators\TaskViewKeyboardActivator.cs" /> <Compile Include="Activators\TaskviewKeyboardActivator.cs" />
<Compile Include="Activators\TerminationActivator.cs" /> <Compile Include="Activators\TerminationActivator.cs" />
<Compile Include="Activators\TouchActivator.cs" /> <Compile Include="Activators\TouchActivator.cs" />
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">