diff --git a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs index e9acd50e..ac9f8870 100644 --- a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs +++ b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs @@ -217,7 +217,7 @@ namespace SafeExamBrowser.Browser private void DialogHandler_DialogRequested(DialogRequestedEventArgs args) { - var result = fileSystemDialog.Show(args.Element, args.InitialPath, args.Operation, title: args.Title, owner: window); + var result = fileSystemDialog.Show(args.Element, args.Operation, args.InitialPath, title: args.Title, owner: window); if (result.Success) { diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs index 940961ea..518f2f9c 100644 --- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs @@ -29,6 +29,7 @@ using SafeExamBrowser.Monitoring.Contracts.Applications; using SafeExamBrowser.Monitoring.Contracts.Display; using SafeExamBrowser.Settings; using SafeExamBrowser.UserInterface.Contracts; +using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog; using SafeExamBrowser.UserInterface.Contracts.MessageBox; using SafeExamBrowser.UserInterface.Contracts.Shell; using SafeExamBrowser.UserInterface.Contracts.Windows; @@ -48,6 +49,7 @@ namespace SafeExamBrowser.Client.UnitTests private ClientContext context; private Mock displayMonitor; private Mock explorerShell; + private Mock fileSystemDialog; private Mock hashAlgorithm; private Mock logger; private Mock messageBox; @@ -73,6 +75,7 @@ namespace SafeExamBrowser.Client.UnitTests context = new ClientContext(); displayMonitor = new Mock(); explorerShell = new Mock(); + fileSystemDialog = new Mock(); hashAlgorithm = new Mock(); logger = new Mock(); messageBox = new Mock(); @@ -95,6 +98,7 @@ namespace SafeExamBrowser.Client.UnitTests context, displayMonitor.Object, explorerShell.Object, + fileSystemDialog.Object, hashAlgorithm.Object, logger.Object, messageBox.Object, @@ -396,17 +400,21 @@ namespace SafeExamBrowser.Client.UnitTests public void Operations_MustAskForApplicationPath() { var args = new ApplicationNotFoundEventArgs(default(string), default(string)); - var dialog = new Mock(); - var result = new FolderDialogResult { FolderPath = @"C:\Some\random\path\", Success = true }; + var result = new FileSystemDialogResult { FullPath = @"C:\Some\random\path\", Success = true }; - dialog.Setup(d => d.Show(It.IsAny())).Returns(result); + fileSystemDialog.Setup(d => d.Show( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).Returns(result); text.SetReturnsDefault(string.Empty); - uiFactory.Setup(f => f.CreateFolderDialog(It.IsAny())).Returns(dialog.Object); sut.TryStart(); operationSequence.Raise(s => s.ActionRequired += null, args); - Assert.AreEqual(result.FolderPath, args.CustomPath); + Assert.AreEqual(result.FullPath, args.CustomPath); Assert.IsTrue(args.Success); } @@ -414,12 +422,16 @@ namespace SafeExamBrowser.Client.UnitTests public void Operations_MustAbortAskingForApplicationPath() { var args = new ApplicationNotFoundEventArgs(default(string), default(string)); - var dialog = new Mock(); - var result = new FolderDialogResult { Success = false }; + var result = new FileSystemDialogResult { Success = false }; - dialog.Setup(d => d.Show(It.IsAny())).Returns(result); + fileSystemDialog.Setup(d => d.Show( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())).Returns(result); text.SetReturnsDefault(string.Empty); - uiFactory.Setup(f => f.CreateFolderDialog(It.IsAny())).Returns(dialog.Object); sut.TryStart(); operationSequence.Raise(s => s.ActionRequired += null, args); diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs index 7f9227af..147d4ea9 100644 --- a/SafeExamBrowser.Client/ClientController.cs +++ b/SafeExamBrowser.Client/ClientController.cs @@ -28,6 +28,7 @@ using SafeExamBrowser.Monitoring.Contracts.Applications; using SafeExamBrowser.Monitoring.Contracts.Display; using SafeExamBrowser.Settings; using SafeExamBrowser.UserInterface.Contracts; +using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog; using SafeExamBrowser.UserInterface.Contracts.MessageBox; using SafeExamBrowser.UserInterface.Contracts.Shell; using SafeExamBrowser.UserInterface.Contracts.Windows; @@ -43,6 +44,7 @@ namespace SafeExamBrowser.Client private ClientContext context; private IDisplayMonitor displayMonitor; private IExplorerShell explorerShell; + private IFileSystemDialog fileSystemDialog; private IHashAlgorithm hashAlgorithm; private ILogger logger; private IMessageBox messageBox; @@ -64,6 +66,7 @@ namespace SafeExamBrowser.Client ClientContext context, IDisplayMonitor displayMonitor, IExplorerShell explorerShell, + IFileSystemDialog fileSystemDialog, IHashAlgorithm hashAlgorithm, ILogger logger, IMessageBox messageBox, @@ -79,6 +82,7 @@ namespace SafeExamBrowser.Client this.context = context; this.displayMonitor = displayMonitor; this.explorerShell = explorerShell; + this.fileSystemDialog = fileSystemDialog; this.hashAlgorithm = hashAlgorithm; this.logger = logger; this.messageBox = messageBox; @@ -535,12 +539,11 @@ namespace SafeExamBrowser.Client private void AskForApplicationPath(ApplicationNotFoundEventArgs args) { 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); + var result = fileSystemDialog.Show(FileSystemElement.Folder, FileSystemOperation.Open, message: message, owner: splashScreen); if (result.Success) { - args.CustomPath = result.FolderPath; + args.CustomPath = result.FullPath; args.Success = true; } } diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs index fe344f0e..52eb67bb 100644 --- a/SafeExamBrowser.Client/CompositionRoot.cs +++ b/SafeExamBrowser.Client/CompositionRoot.cs @@ -103,6 +103,7 @@ namespace SafeExamBrowser.Client var applicationFactory = new ApplicationFactory(applicationMonitor, ModuleLogger(nameof(ApplicationFactory)), nativeMethods, processFactory); var displayMonitor = new DisplayMonitor(ModuleLogger(nameof(DisplayMonitor)), nativeMethods, systemInfo); var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods); + var fileSystemDialog = BuildFileSystemDialog(); var hashAlgorithm = new HashAlgorithm(); var operations = new Queue(); @@ -129,6 +130,7 @@ namespace SafeExamBrowser.Client context, displayMonitor, explorerShell, + fileSystemDialog, hashAlgorithm, logger, messageBox, diff --git a/SafeExamBrowser.UserInterface.Contracts/FileSystemDialog/IFileSystemDialog.cs b/SafeExamBrowser.UserInterface.Contracts/FileSystemDialog/IFileSystemDialog.cs index 6ca62704..03d5ddde 100644 --- a/SafeExamBrowser.UserInterface.Contracts/FileSystemDialog/IFileSystemDialog.cs +++ b/SafeExamBrowser.UserInterface.Contracts/FileSystemDialog/IFileSystemDialog.cs @@ -15,6 +15,6 @@ namespace SafeExamBrowser.UserInterface.Contracts.FileSystemDialog /// /// Creates a dialog according to the given parameters and shows it to the user. /// - FileSystemDialogResult Show(FileSystemElement element, string initialPath, FileSystemOperation operation, string message = default(string), string title = default(string), IWindow owner = default(IWindow)); + FileSystemDialogResult Show(FileSystemElement element, FileSystemOperation operation, string initialPath = default(string), string message = default(string), string title = default(string), IWindow owner = default(IWindow)); } } diff --git a/SafeExamBrowser.UserInterface.Contracts/IUserInterfaceFactory.cs b/SafeExamBrowser.UserInterface.Contracts/IUserInterfaceFactory.cs index 9f1c92c4..cf5316f0 100644 --- a/SafeExamBrowser.UserInterface.Contracts/IUserInterfaceFactory.cs +++ b/SafeExamBrowser.UserInterface.Contracts/IUserInterfaceFactory.cs @@ -49,11 +49,6 @@ namespace SafeExamBrowser.UserInterface.Contracts /// IBrowserWindow CreateBrowserWindow(IBrowserControl control, BrowserSettings settings, bool isMainWindow); - /// - /// Creates a folder dialog with the given message. - /// - IFolderDialog CreateFolderDialog(string message); - /// /// Creates a system control which allows to change the keyboard layout of the computer. /// diff --git a/SafeExamBrowser.UserInterface.Contracts/SafeExamBrowser.UserInterface.Contracts.csproj b/SafeExamBrowser.UserInterface.Contracts/SafeExamBrowser.UserInterface.Contracts.csproj index 4a19d963..a9be80e2 100644 --- a/SafeExamBrowser.UserInterface.Contracts/SafeExamBrowser.UserInterface.Contracts.csproj +++ b/SafeExamBrowser.UserInterface.Contracts/SafeExamBrowser.UserInterface.Contracts.csproj @@ -85,11 +85,9 @@ - - diff --git a/SafeExamBrowser.UserInterface.Contracts/Windows/Data/FolderDialogResult.cs b/SafeExamBrowser.UserInterface.Contracts/Windows/Data/FolderDialogResult.cs deleted file mode 100644 index fa961598..00000000 --- a/SafeExamBrowser.UserInterface.Contracts/Windows/Data/FolderDialogResult.cs +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2020 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 -{ - /// - /// Defines the user interaction result of an . - /// - public class FolderDialogResult - { - /// - /// The full path of the folder selected by the user, or null if the interaction was unsuccessful. - /// - public string FolderPath { get; set; } - - /// - /// Indicates whether the user confirmed the dialog or not. - /// - public bool Success { get; set; } - } -} diff --git a/SafeExamBrowser.UserInterface.Contracts/Windows/IFolderDialog.cs b/SafeExamBrowser.UserInterface.Contracts/Windows/IFolderDialog.cs deleted file mode 100644 index eab8f8eb..00000000 --- a/SafeExamBrowser.UserInterface.Contracts/Windows/IFolderDialog.cs +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2020 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 - { - /// - /// Shows the dialog to the user. If a parent window is specified, the dialog is rendered modally for the given parent. - /// - FolderDialogResult Show(IWindow parent = null); - } -} diff --git a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml index 06d30d0d..83dfed50 100644 --- a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml +++ b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml @@ -21,10 +21,14 @@ - - - - + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml.cs b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml.cs index bc6572ec..6c149eb8 100644 --- a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml.cs +++ b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialog.xaml.cs @@ -34,9 +34,9 @@ namespace SafeExamBrowser.UserInterface.Desktop public FileSystemDialog( FileSystemElement element, - string initialPath, FileSystemOperation operation, IText text, + string initialPath = default(string), string message = default(string), string title = default(string), IWindow parent = default(IWindow)) @@ -242,7 +242,7 @@ namespace SafeExamBrowser.UserInterface.Desktop var header = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(2) }; var image = new Image { - Height = 20, + Height = 16, Source = IconLoader.LoadIconFor(file) }; var item = new TreeViewItem(); diff --git a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialogFactory.cs b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialogFactory.cs index a9fa8e52..8ba1ebb4 100644 --- a/SafeExamBrowser.UserInterface.Desktop/FileSystemDialogFactory.cs +++ b/SafeExamBrowser.UserInterface.Desktop/FileSystemDialogFactory.cs @@ -22,15 +22,15 @@ namespace SafeExamBrowser.UserInterface.Desktop this.text = text; } - public FileSystemDialogResult Show(FileSystemElement element, string initialPath, FileSystemOperation operation, string message = null, string title = null, IWindow owner = null) + public FileSystemDialogResult Show(FileSystemElement element, FileSystemOperation operation, string initialPath = default(string), string message = null, string title = null, IWindow owner = null) { if (owner is Window window) { - return window.Dispatcher.Invoke(() => new FileSystemDialog(element, initialPath, operation, text, message, title, owner).Show()); + return window.Dispatcher.Invoke(() => new FileSystemDialog(element, operation, text, initialPath, message, title, owner).Show()); } else { - return new FileSystemDialog(element, initialPath, operation, text, message, title).Show(); + return new FileSystemDialog(element, operation, text, initialPath, message, title).Show(); } } } diff --git a/SafeExamBrowser.UserInterface.Desktop/FolderDialog.cs b/SafeExamBrowser.UserInterface.Desktop/FolderDialog.cs deleted file mode 100644 index c9d2463b..00000000 --- a/SafeExamBrowser.UserInterface.Desktop/FolderDialog.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020 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); - } - } -} diff --git a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj index ef112625..6c4ae2c2 100644 --- a/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj +++ b/SafeExamBrowser.UserInterface.Desktop/SafeExamBrowser.UserInterface.Desktop.csproj @@ -152,7 +152,6 @@ FileSystemDialog.xaml - LockScreen.xaml diff --git a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs index 661c8ab3..4a25ac58 100644 --- a/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs +++ b/SafeExamBrowser.UserInterface.Desktop/UserInterfaceFactory.cs @@ -75,11 +75,6 @@ namespace SafeExamBrowser.UserInterface.Desktop return Application.Current.Dispatcher.Invoke(() => new BrowserWindow(control, settings, isMainWindow, text)); } - public IFolderDialog CreateFolderDialog(string message) - { - return new FolderDialog(message); - } - public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location) { if (location == Location.ActionCenter) diff --git a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml index fa5741db..c0dac204 100644 --- a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml +++ b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml @@ -21,10 +21,14 @@ - - - - + + + + + + + + diff --git a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml.cs b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml.cs index 45ae3001..75c0a251 100644 --- a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml.cs +++ b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialog.xaml.cs @@ -34,9 +34,9 @@ namespace SafeExamBrowser.UserInterface.Mobile public FileSystemDialog( FileSystemElement element, - string initialPath, FileSystemOperation operation, IText text, + string initialPath = default(string), string message = default(string), string title = default(string), IWindow parent = default(IWindow)) diff --git a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialogFactory.cs b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialogFactory.cs index 40750f16..76489633 100644 --- a/SafeExamBrowser.UserInterface.Mobile/FileSystemDialogFactory.cs +++ b/SafeExamBrowser.UserInterface.Mobile/FileSystemDialogFactory.cs @@ -22,15 +22,15 @@ namespace SafeExamBrowser.UserInterface.Mobile this.text = text; } - public FileSystemDialogResult Show(FileSystemElement element, string initialPath, FileSystemOperation operation, string message = null, string title = null, IWindow owner = null) + public FileSystemDialogResult Show(FileSystemElement element, FileSystemOperation operation, string initialPath = default(string), string message = null, string title = null, IWindow owner = null) { if (owner is Window window) { - return window.Dispatcher.Invoke(() => new FileSystemDialog(element, initialPath, operation, text, message, title, owner).Show()); + return window.Dispatcher.Invoke(() => new FileSystemDialog(element, operation, text, initialPath, message, title, owner).Show()); } else { - return new FileSystemDialog(element, initialPath, operation, text, message, title).Show(); + return new FileSystemDialog(element, operation, text, initialPath, message, title).Show(); } } } diff --git a/SafeExamBrowser.UserInterface.Mobile/FolderDialog.cs b/SafeExamBrowser.UserInterface.Mobile/FolderDialog.cs deleted file mode 100644 index 62ebf3cc..00000000 --- a/SafeExamBrowser.UserInterface.Mobile/FolderDialog.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020 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); - } - } -} diff --git a/SafeExamBrowser.UserInterface.Mobile/SafeExamBrowser.UserInterface.Mobile.csproj b/SafeExamBrowser.UserInterface.Mobile/SafeExamBrowser.UserInterface.Mobile.csproj index e9137db6..90ae825d 100644 --- a/SafeExamBrowser.UserInterface.Mobile/SafeExamBrowser.UserInterface.Mobile.csproj +++ b/SafeExamBrowser.UserInterface.Mobile/SafeExamBrowser.UserInterface.Mobile.csproj @@ -153,7 +153,6 @@ FileSystemDialog.xaml - LockScreen.xaml diff --git a/SafeExamBrowser.UserInterface.Mobile/UserInterfaceFactory.cs b/SafeExamBrowser.UserInterface.Mobile/UserInterfaceFactory.cs index e56ab5cf..c1a9abb7 100644 --- a/SafeExamBrowser.UserInterface.Mobile/UserInterfaceFactory.cs +++ b/SafeExamBrowser.UserInterface.Mobile/UserInterfaceFactory.cs @@ -75,11 +75,6 @@ namespace SafeExamBrowser.UserInterface.Mobile return Application.Current.Dispatcher.Invoke(() => new BrowserWindow(control, settings, isMainWindow, text)); } - public IFolderDialog CreateFolderDialog(string message) - { - return new FolderDialog(message); - } - public ISystemControl CreateKeyboardLayoutControl(IKeyboard keyboard, Location location) { if (location == Location.ActionCenter)