Working on the wireless network component (IMPORTANT: The commited code is not yet working, I have to find a way to check whether the Wi-Fi is turned off via hard- or software!).
This commit is contained in:
parent
a118f52ee3
commit
396aa56bd5
21 changed files with 593 additions and 3 deletions
|
@ -90,6 +90,8 @@
|
|||
<Compile Include="SystemComponents\BatteryChargeStatus.cs" />
|
||||
<Compile Include="SystemComponents\IKeyboardLayout.cs" />
|
||||
<Compile Include="SystemComponents\ISystemComponent.cs" />
|
||||
<Compile Include="SystemComponents\IWirelessNetwork.cs" />
|
||||
<Compile Include="SystemComponents\WirelessNetworkStatus.cs" />
|
||||
<Compile Include="UserInterface\IBrowserControl.cs" />
|
||||
<Compile Include="UserInterface\IBrowserWindow.cs" />
|
||||
<Compile Include="UserInterface\IMessageBox.cs" />
|
||||
|
@ -98,6 +100,7 @@
|
|||
<Compile Include="UserInterface\Taskbar\ISystemKeyboardLayoutControl.cs" />
|
||||
<Compile Include="UserInterface\Taskbar\ISystemPowerSupplyControl.cs" />
|
||||
<Compile Include="UserInterface\Taskbar\ISystemControl.cs" />
|
||||
<Compile Include="UserInterface\Taskbar\ISystemWirelessNetworkControl.cs" />
|
||||
<Compile Include="UserInterface\Taskbar\ITaskbar.cs" />
|
||||
<Compile Include="I18n\ITextResource.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.SystemComponents
|
||||
{
|
||||
public interface IWirelessNetwork
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier of the network.
|
||||
/// </summary>
|
||||
Guid Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The network name.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The signal strength of this network, as percentage.
|
||||
/// </summary>
|
||||
int SignalStrength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The connection status of this network.
|
||||
/// </summary>
|
||||
WirelessNetworkStatus Status { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
namespace SafeExamBrowser.Contracts.SystemComponents
|
||||
{
|
||||
public enum WirelessNetworkStatus
|
||||
{
|
||||
Undefined = 0,
|
||||
Connected,
|
||||
Disconnected
|
||||
}
|
||||
}
|
|
@ -55,5 +55,10 @@ namespace SafeExamBrowser.Contracts.UserInterface
|
|||
/// Creates a new splash screen which runs on its own thread.
|
||||
/// </summary>
|
||||
ISplashScreen CreateSplashScreen(ISettings settings, IText text);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a system control which allows to change the wireless network connection of the computer.
|
||||
/// </summary>
|
||||
ISystemWirelessNetworkControl CreateWirelessNetworkControl();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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.Collections.Generic;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.UserInterface.Taskbar
|
||||
{
|
||||
public delegate void WirelessNetworkSelectedEventHandler(IWirelessNetwork network);
|
||||
|
||||
public interface ISystemWirelessNetworkControl : ISystemControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines whether the computer has a wireless network adapter.
|
||||
/// </summary>
|
||||
bool HasWirelessNetworkAdapter { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current wireless network status.
|
||||
/// </summary>
|
||||
WirelessNetworkStatus NetworkStatus { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the user selected a wireless network.
|
||||
/// </summary>
|
||||
event WirelessNetworkSelectedEventHandler NetworkSelected;
|
||||
|
||||
/// <summary>
|
||||
/// Updates the list of available networks.
|
||||
/// </summary>
|
||||
void Update(IEnumerable<IWirelessNetwork> networks);
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
private Mock<ISplashScreen> splashScreenMock;
|
||||
private Mock<ISystemComponent<ISystemKeyboardLayoutControl>> keyboardLayoutMock;
|
||||
private Mock<ISystemComponent<ISystemPowerSupplyControl>> powerSupplyMock;
|
||||
private Mock<ISystemComponent<ISystemWirelessNetworkControl>> wirelessNetworkMock;
|
||||
private Mock<ISystemInfo> systemInfoMock;
|
||||
private Mock<ITaskbar> taskbarMock;
|
||||
private Mock<IText> textMock;
|
||||
|
@ -42,6 +43,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
splashScreenMock = new Mock<ISplashScreen>();
|
||||
keyboardLayoutMock = new Mock<ISystemComponent<ISystemKeyboardLayoutControl>>();
|
||||
powerSupplyMock = new Mock<ISystemComponent<ISystemPowerSupplyControl>>();
|
||||
wirelessNetworkMock = new Mock<ISystemComponent<ISystemWirelessNetworkControl>>();
|
||||
systemInfoMock = new Mock<ISystemInfo>();
|
||||
taskbarMock = new Mock<ITaskbar>();
|
||||
textMock = new Mock<IText>();
|
||||
|
@ -49,6 +51,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
|
||||
settingsMock.SetupGet(s => s.AllowApplicationLog).Returns(true);
|
||||
settingsMock.SetupGet(s => s.AllowKeyboardLayout).Returns(true);
|
||||
settingsMock.SetupGet(s => s.AllowWirelessNetwork).Returns(true);
|
||||
systemInfoMock.SetupGet(s => s.HasBattery).Returns(true);
|
||||
uiFactoryMock.Setup(u => u.CreateNotification(It.IsAny<INotificationInfo>())).Returns(new Mock<INotificationButton>().Object);
|
||||
|
||||
|
@ -57,6 +60,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
settingsMock.Object,
|
||||
keyboardLayoutMock.Object,
|
||||
powerSupplyMock.Object,
|
||||
wirelessNetworkMock.Object,
|
||||
systemInfoMock.Object,
|
||||
taskbarMock.Object,
|
||||
textMock.Object,
|
||||
|
@ -73,7 +77,8 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
|
||||
keyboardLayoutMock.Verify(k => k.Initialize(It.IsAny<ISystemKeyboardLayoutControl>()), Times.Once);
|
||||
powerSupplyMock.Verify(p => p.Initialize(It.IsAny<ISystemPowerSupplyControl>()), Times.Once);
|
||||
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(2));
|
||||
wirelessNetworkMock.Verify(w => w.Initialize(It.IsAny<ISystemWirelessNetworkControl>()), Times.Once);
|
||||
taskbarMock.Verify(t => t.AddSystemControl(It.IsAny<ISystemControl>()), Times.Exactly(3));
|
||||
taskbarMock.Verify(t => t.AddNotification(It.IsAny<INotificationButton>()), Times.Once);
|
||||
}
|
||||
|
||||
|
@ -84,6 +89,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
|||
|
||||
keyboardLayoutMock.Verify(k => k.Terminate(), Times.Once);
|
||||
powerSupplyMock.Verify(p => p.Terminate(), Times.Once);
|
||||
wirelessNetworkMock.Verify(w => w.Terminate(), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
private ITaskbarSettings settings;
|
||||
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
|
||||
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
||||
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
||||
private ISystemInfo systemInfo;
|
||||
private ITaskbar taskbar;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
@ -37,6 +38,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
ITaskbarSettings settings,
|
||||
ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout,
|
||||
ISystemComponent<ISystemPowerSupplyControl> powerSupply,
|
||||
ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork,
|
||||
ISystemInfo systemInfo,
|
||||
ITaskbar taskbar,
|
||||
IText text,
|
||||
|
@ -50,6 +52,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
this.taskbar = taskbar;
|
||||
this.text = text;
|
||||
this.uiFactory = uiFactory;
|
||||
this.wirelessNetwork = wirelessNetwork;
|
||||
}
|
||||
|
||||
public void Perform()
|
||||
|
@ -71,6 +74,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
{
|
||||
AddPowerSupplyControl();
|
||||
}
|
||||
|
||||
if (settings.AllowWirelessNetwork)
|
||||
{
|
||||
AddWirelessNetworkControl();
|
||||
}
|
||||
}
|
||||
|
||||
public void Revert()
|
||||
|
@ -92,6 +100,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
{
|
||||
powerSupply.Terminate();
|
||||
}
|
||||
|
||||
if (settings.AllowWirelessNetwork)
|
||||
{
|
||||
wirelessNetwork.Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddKeyboardLayoutControl()
|
||||
|
@ -110,6 +123,14 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
taskbar.AddSystemControl(control);
|
||||
}
|
||||
|
||||
private void AddWirelessNetworkControl()
|
||||
{
|
||||
var control = uiFactory.CreateWirelessNetworkControl();
|
||||
|
||||
wirelessNetwork.Initialize(control);
|
||||
taskbar.AddSystemControl(control);
|
||||
}
|
||||
|
||||
private void CreateLogNotification()
|
||||
{
|
||||
var logInfo = new LogNotificationInfo(text);
|
||||
|
|
|
@ -48,8 +48,12 @@
|
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="SimpleWifi, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SimpleWifi.1.0.0.0\lib\net40\SimpleWifi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -57,6 +61,8 @@
|
|||
<Compile Include="KeyboardLayout.cs" />
|
||||
<Compile Include="PowerSupply.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WirelessNetwork.cs" />
|
||||
<Compile Include="WirelessNetworkDefinition.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
|
||||
|
@ -64,5 +70,8 @@
|
|||
<Name>SafeExamBrowser.Contracts</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
186
SafeExamBrowser.SystemComponents/WirelessNetwork.cs
Normal file
186
SafeExamBrowser.SystemComponents/WirelessNetwork.cs
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Timers;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
using SimpleWifi;
|
||||
using SimpleWifi.Win32;
|
||||
|
||||
namespace SafeExamBrowser.SystemComponents
|
||||
{
|
||||
public class WirelessNetwork : ISystemComponent<ISystemWirelessNetworkControl>
|
||||
{
|
||||
private const int TWO_SECONDS = 2000;
|
||||
|
||||
private ILogger logger;
|
||||
private ISystemWirelessNetworkControl control;
|
||||
private Timer timer;
|
||||
private Wifi wifi;
|
||||
|
||||
public WirelessNetwork(ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public void Initialize(ISystemWirelessNetworkControl control)
|
||||
{
|
||||
this.control = control;
|
||||
this.wifi = new Wifi();
|
||||
|
||||
if (wifi.NoWifiAvailable || IsTurnedOff())
|
||||
{
|
||||
control.HasWirelessNetworkAdapter = false;
|
||||
logger.Info("Wireless networks cannot be monitored, as there is no hardware adapter available or it is turned off.");
|
||||
}
|
||||
else
|
||||
{
|
||||
control.HasWirelessNetworkAdapter = true;
|
||||
control.NetworkSelected += Control_NetworkSelected;
|
||||
wifi.ConnectionStatusChanged += Wifi_ConnectionStatusChanged;
|
||||
|
||||
UpdateControl();
|
||||
|
||||
timer = new Timer(TWO_SECONDS);
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.AutoReset = true;
|
||||
timer.Start();
|
||||
|
||||
logger.Info("Started monitoring the wireless network adapter.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
timer?.Stop();
|
||||
control?.Close();
|
||||
|
||||
if (timer != null)
|
||||
{
|
||||
logger.Info("Stopped monitoring the wireless network adapter.");
|
||||
}
|
||||
}
|
||||
|
||||
private void Control_NetworkSelected(IWirelessNetwork network)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
UpdateControl();
|
||||
}
|
||||
|
||||
private void Wifi_ConnectionStatusChanged(object sender, WifiStatusEventArgs e)
|
||||
{
|
||||
control.NetworkStatus = ToStatus(e.NewStatus);
|
||||
}
|
||||
|
||||
private bool IsTurnedOff()
|
||||
{
|
||||
try
|
||||
{
|
||||
// See https://msdn.microsoft.com/en-us/library/aa394216(v=vs.85).aspx
|
||||
string query = @"
|
||||
SELECT *
|
||||
FROM Win32_NetworkAdapter";
|
||||
var searcher = new ManagementObjectSearcher(query);
|
||||
var adapters = searcher.Get();
|
||||
var interfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == NetworkInterfaceType.Wireless80211).ToList();
|
||||
|
||||
logger.Info("Interface count: " + interfaces.Count);
|
||||
|
||||
foreach (var i in interfaces)
|
||||
{
|
||||
logger.Info(i.Description);
|
||||
logger.Info(i.Id);
|
||||
logger.Info(i.Name);
|
||||
logger.Info(i.NetworkInterfaceType.ToString());
|
||||
logger.Info(i.OperationalStatus.ToString());
|
||||
logger.Info("-----");
|
||||
}
|
||||
|
||||
foreach (var adapter in adapters)
|
||||
{
|
||||
logger.Info("-------");
|
||||
|
||||
foreach (var property in adapter.Properties)
|
||||
{
|
||||
logger.Info($"{property.Name}: {property.Value} ({property.Type})");
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("Adapter count: " + adapters.Count);
|
||||
|
||||
return true;
|
||||
|
||||
using (var client = new WlanClient())
|
||||
{
|
||||
foreach (var @interface in client.Interfaces)
|
||||
{
|
||||
Trace.WriteLine($"[{@interface.InterfaceName}]");
|
||||
|
||||
foreach (var state in @interface.RadioState.PhyRadioState)
|
||||
{
|
||||
Trace.WriteLine($"PhyIndex: {state.dwPhyIndex}");
|
||||
Trace.WriteLine($"SoftwareRadioState: {state.dot11SoftwareRadioState}");
|
||||
Trace.WriteLine($"HardwareRadioState: {state.dot11HardwareRadioState}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Fail!", e);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateControl()
|
||||
{
|
||||
var networks = new List<IWirelessNetwork>();
|
||||
|
||||
control.NetworkStatus = ToStatus(wifi.ConnectionStatus);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var accessPoint in wifi.GetAccessPoints())
|
||||
{
|
||||
// The user may only connect to an already configured wireless network!
|
||||
if (accessPoint.HasProfile)
|
||||
{
|
||||
networks.Add(new WirelessNetworkDefinition
|
||||
{
|
||||
Name = accessPoint.Name,
|
||||
SignalStrength = Convert.ToInt32(accessPoint.SignalStrength),
|
||||
Status = accessPoint.IsConnected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to update the wireless network adapter status!", e);
|
||||
}
|
||||
|
||||
control.Update(networks);
|
||||
}
|
||||
|
||||
private WirelessNetworkStatus ToStatus(WifiStatus status)
|
||||
{
|
||||
return status == WifiStatus.Connected ? WirelessNetworkStatus.Connected : WirelessNetworkStatus.Disconnected;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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 SafeExamBrowser.Contracts.SystemComponents;
|
||||
|
||||
namespace SafeExamBrowser.SystemComponents
|
||||
{
|
||||
internal class WirelessNetworkDefinition : IWirelessNetwork
|
||||
{
|
||||
public Guid Id { get; }
|
||||
public string Name { get; set; }
|
||||
public int SignalStrength { get; set; }
|
||||
public WirelessNetworkStatus Status { get; set; }
|
||||
|
||||
public WirelessNetworkDefinition()
|
||||
{
|
||||
Id = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
4
SafeExamBrowser.SystemComponents/packages.config
Normal file
4
SafeExamBrowser.SystemComponents/packages.config
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="SimpleWifi" version="1.0.0.0" targetFramework="net452" />
|
||||
</packages>
|
|
@ -33,7 +33,7 @@
|
|||
</Grid>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="Transparent" Template="{StaticResource TaskbarButton}">
|
||||
<Button x:Name="Button" Background="Transparent" IsEnabled="False" Template="{StaticResource TaskbarButton}" ToolTipService.ShowOnDisabled="True">
|
||||
<Viewbox Stretch="Uniform" Width="Auto">
|
||||
<Canvas Height="40" Width="40">
|
||||
<Viewbox Stretch="Uniform" Width="40" Panel.ZIndex="2">
|
||||
|
|
|
@ -72,12 +72,14 @@ namespace SafeExamBrowser.UserInterface.Classic.Controls
|
|||
Popup.IsOpen = true;
|
||||
PopupText.Text = text;
|
||||
Background = Brushes.LightGray;
|
||||
Button.IsEnabled = true;
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
Background = Brushes.Transparent;
|
||||
Button.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Classic.Controls.WirelessNetworkButton"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="250">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Templates/Buttons.xaml" />
|
||||
<ResourceDictionary Source="../Templates/Colors.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Button x:Name="Button" Height="40" Padding="10,0" Template="{StaticResource TaskbarButton}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Name="IsCurrentTextBlock" Grid.Column="0" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden">•</TextBlock>
|
||||
<TextBlock x:Name="SignalStrengthTextBlock" Grid.Column="1" FontWeight="Bold" HorizontalAlignment="Left" Margin="10,0,5,0" VerticalAlignment="Center" />
|
||||
<TextBlock x:Name="NetworkNameTextBlock" Grid.Column="2" Foreground="Gray" HorizontalAlignment="Left" Margin="5,0,10,0" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Classic.Controls
|
||||
{
|
||||
public partial class WirelessNetworkButton : UserControl
|
||||
{
|
||||
public event RoutedEventHandler Click;
|
||||
|
||||
public bool IsCurrent
|
||||
{
|
||||
set { IsCurrentTextBlock.Visibility = value ? Visibility.Visible : Visibility.Hidden; }
|
||||
}
|
||||
|
||||
public string NetworkName
|
||||
{
|
||||
set { NetworkNameTextBlock.Text = value; }
|
||||
}
|
||||
|
||||
public int SignalStrength
|
||||
{
|
||||
set { SignalStrengthTextBlock.Text = $"{value}%"; }
|
||||
}
|
||||
|
||||
public WirelessNetworkButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Button.Click += (o, args) => Click?.Invoke(o, args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<UserControl x:Class="SafeExamBrowser.UserInterface.Classic.Controls.WirelessNetworkControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:s="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Classic.Controls"
|
||||
mc:Ignorable="d" d:DesignHeight="40" d:DesignWidth="40">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Templates/Buttons.xaml" />
|
||||
<ResourceDictionary Source="../Templates/Colors.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Popup x:Name="Popup" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Button}">
|
||||
<Border Background="LightGray" BorderBrush="Gray" BorderThickness="0.5,0.5,0.5,0">
|
||||
<ScrollViewer Background="{StaticResource BackgroundBrush}" MaxHeight="250" VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Resources>
|
||||
<s:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">5</s:Double>
|
||||
</ScrollViewer.Resources>
|
||||
<StackPanel x:Name="NetworksStackPanel" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Popup>
|
||||
<Button x:Name="Button" Background="Transparent" HorizontalContentAlignment="Stretch" Template="{StaticResource TaskbarButton}"
|
||||
ToolTipService.ShowOnDisabled="True" VerticalContentAlignment="Stretch" Width="40" />
|
||||
<TextBlock x:Name="NetworkStatusIcon" HorizontalAlignment="Right" Padding="6,2" Panel.ZIndex="10" VerticalAlignment="Bottom" />
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using SafeExamBrowser.Contracts.SystemComponents;
|
||||
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface.Classic.Controls
|
||||
{
|
||||
public partial class WirelessNetworkControl : UserControl, ISystemWirelessNetworkControl
|
||||
{
|
||||
public bool HasWirelessNetworkAdapter
|
||||
{
|
||||
set
|
||||
{
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
Button.IsEnabled = value;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public WirelessNetworkStatus NetworkStatus
|
||||
{
|
||||
set
|
||||
{
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
NetworkStatusIcon.Text = value == WirelessNetworkStatus.Connected ? "✔" : "❌";
|
||||
NetworkStatusIcon.Foreground = value == WirelessNetworkStatus.Connected ? Brushes.Green : Brushes.Red;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public event WirelessNetworkSelectedEventHandler NetworkSelected;
|
||||
|
||||
public WirelessNetworkControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeWirelessNetworkControl();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Popup.IsOpen = false;
|
||||
}
|
||||
|
||||
public void SetTooltip(string text)
|
||||
{
|
||||
Dispatcher.BeginInvoke(new Action(() => Button.ToolTip = text));
|
||||
}
|
||||
|
||||
public void Update(IEnumerable<IWirelessNetwork> networks)
|
||||
{
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
foreach (var network in networks)
|
||||
{
|
||||
var button = new WirelessNetworkButton();
|
||||
var isCurrent = network.Status == WirelessNetworkStatus.Connected;
|
||||
|
||||
button.Click += (o, args) =>
|
||||
{
|
||||
NetworkSelected?.Invoke(network);
|
||||
};
|
||||
button.IsCurrent = isCurrent;
|
||||
button.NetworkName = network.Name;
|
||||
button.SignalStrength = network.SignalStrength;
|
||||
|
||||
if (isCurrent)
|
||||
{
|
||||
NetworkStatus = network.Status;
|
||||
}
|
||||
|
||||
NetworksStackPanel.Children.Add(button);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private void InitializeWirelessNetworkControl()
|
||||
{
|
||||
var originalBrush = Button.Background;
|
||||
|
||||
Button.Click += (o, args) => Popup.IsOpen = !Popup.IsOpen;
|
||||
Button.MouseLeave += (o, args) => Popup.IsOpen = Popup.IsMouseOver;
|
||||
Popup.MouseLeave += (o, args) => Popup.IsOpen = IsMouseOver;
|
||||
|
||||
Popup.Opened += (o, args) =>
|
||||
{
|
||||
Background = Brushes.LightBlue;
|
||||
Button.Background = Brushes.LightBlue;
|
||||
};
|
||||
|
||||
Popup.Closed += (o, args) =>
|
||||
{
|
||||
Background = originalBrush;
|
||||
Button.Background = originalBrush;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -93,6 +93,12 @@
|
|||
<Compile Include="Controls\QuitButton.xaml.cs">
|
||||
<DependentUpon>QuitButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\WirelessNetworkButton.xaml.cs">
|
||||
<DependentUpon>WirelessNetworkButton.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Controls\WirelessNetworkControl.xaml.cs">
|
||||
<DependentUpon>WirelessNetworkControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="LogWindow.xaml.cs">
|
||||
<DependentUpon>LogWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -198,6 +204,14 @@
|
|||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Resource>
|
||||
<Page Include="Controls\WirelessNetworkButton.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Controls\WirelessNetworkControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="LogWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
|
|
@ -100,6 +100,11 @@ namespace SafeExamBrowser.UserInterface.Classic
|
|||
return splashScreen;
|
||||
}
|
||||
|
||||
public ISystemWirelessNetworkControl CreateWirelessNetworkControl()
|
||||
{
|
||||
return new WirelessNetworkControl();
|
||||
}
|
||||
|
||||
public void Show(string message, string title, MessageBoxAction action = MessageBoxAction.Confirm, MessageBoxIcon icon = MessageBoxIcon.Information)
|
||||
{
|
||||
MessageBox.Show(message, title, ToButton(action), ToImage(icon));
|
||||
|
|
|
@ -101,6 +101,12 @@ namespace SafeExamBrowser.UserInterface.Windows10
|
|||
return splashScreen;
|
||||
}
|
||||
|
||||
public ISystemWirelessNetworkControl CreateWirelessNetworkControl()
|
||||
{
|
||||
// TODO
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Show(string message, string title, MessageBoxAction action = MessageBoxAction.Confirm, MessageBoxIcon icon = MessageBoxIcon.Information)
|
||||
{
|
||||
MessageBox.Show(message, title, ToButton(action), ToImage(icon));
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace SafeExamBrowser
|
|||
private ISettings settings;
|
||||
private ISystemComponent<ISystemKeyboardLayoutControl> keyboardLayout;
|
||||
private ISystemComponent<ISystemPowerSupplyControl> powerSupply;
|
||||
private ISystemComponent<ISystemWirelessNetworkControl> wirelessNetwork;
|
||||
private ISystemInfo systemInfo;
|
||||
private IText text;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
@ -81,6 +82,7 @@ namespace SafeExamBrowser
|
|||
powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)), text);
|
||||
processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
|
||||
windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
|
||||
wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, typeof(WirelessNetwork)));
|
||||
|
||||
runtimeController = new RuntimeController(displayMonitor, new ModuleLogger(logger, typeof(RuntimeController)), processMonitor, Taskbar, windowMonitor);
|
||||
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
|
||||
|
@ -92,7 +94,7 @@ namespace SafeExamBrowser
|
|||
StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
|
||||
StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
|
||||
StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
|
||||
StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, systemInfo, Taskbar, text, uiFactory));
|
||||
StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, text, uiFactory));
|
||||
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
|
||||
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
|
||||
StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));
|
||||
|
|
Loading…
Reference in a new issue