mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
356 lines
13 KiB
C#
356 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Windows.Forms;
|
|
using mRemoteNG.App;
|
|
using mRemoteNG.Connection;
|
|
using mRemoteNG.Connection.Protocol;
|
|
using mRemoteNG.Connection.Protocol.RDP;
|
|
using mRemoteNG.Connection.Protocol.VNC;
|
|
using mRemoteNG.Messages;
|
|
using mRemoteNG.Security;
|
|
using mRemoteNG.Tools;
|
|
using mRemoteNG.Tools.Attributes;
|
|
using mRemoteNG.Tree.Root;
|
|
|
|
namespace mRemoteNG.UI.Controls.ConnectionInfoPropertyGrid
|
|
{
|
|
public partial class ConnectionInfoPropertyGrid : FilteredPropertyGrid.FilteredPropertyGrid
|
|
{
|
|
private readonly Dictionary<Type, IEnumerable<PropertyInfo>> _propertyCache = new Dictionary<Type, IEnumerable<PropertyInfo>>();
|
|
private ConnectionInfo _selectedConnectionInfo;
|
|
private PropertyMode _propertyMode;
|
|
|
|
/// <summary>
|
|
/// The <see cref="ConnectionInfo"/> currently being shown by this
|
|
/// property grid.
|
|
/// </summary>
|
|
public ConnectionInfo SelectedConnectionInfo
|
|
{
|
|
get => _selectedConnectionInfo;
|
|
set
|
|
{
|
|
if (_selectedConnectionInfo == value)
|
|
return;
|
|
|
|
_selectedConnectionInfo = value;
|
|
RootNodeSelected = SelectedConnectionInfo is RootNodeInfo;
|
|
SetGridObject();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines which set of properties this grid will display.
|
|
/// </summary>
|
|
public PropertyMode PropertyMode
|
|
{
|
|
get => _propertyMode;
|
|
set
|
|
{
|
|
if (_propertyMode == value)
|
|
return;
|
|
_propertyMode = value;
|
|
SetGridObject();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Is the property grid showing the selected connection's
|
|
/// inheritance info? If false, the connection's normal
|
|
/// properties are shown instead.
|
|
/// </summary>
|
|
public bool IsShowingInheritance => PropertyMode == PropertyMode.Inheritance ||
|
|
PropertyMode == PropertyMode.DefaultInheritance;
|
|
|
|
/// <summary>
|
|
/// This indicates whether the current <see cref="SelectedConnectionInfo"/>
|
|
/// is a <see cref="DefaultConnectionInfo"/>.
|
|
/// </summary>
|
|
public bool IsShowingDefaultProperties => PropertyMode == PropertyMode.DefaultConnection ||
|
|
PropertyMode == PropertyMode.DefaultInheritance;
|
|
|
|
/// <summary>
|
|
/// True when the <see cref="SelectedConnectionInfo"/> is
|
|
/// of type <see cref="RootNodeInfo"/>.
|
|
/// </summary>
|
|
public bool RootNodeSelected { get; private set; }
|
|
|
|
public ConnectionInfoPropertyGrid()
|
|
{
|
|
InitializeComponent();
|
|
PropertyValueChanged += pGrid_PropertyValueChanged;
|
|
}
|
|
|
|
private void SetGridObject()
|
|
{
|
|
ClearFilters();
|
|
|
|
switch (PropertyMode)
|
|
{
|
|
case PropertyMode.Connection:
|
|
default:
|
|
SelectedObject = SelectedConnectionInfo;
|
|
break;
|
|
case PropertyMode.Inheritance:
|
|
SelectedObject = SelectedConnectionInfo?.Inheritance;
|
|
break;
|
|
case PropertyMode.DefaultConnection:
|
|
SelectedObject = DefaultConnectionInfo.Instance;
|
|
break;
|
|
case PropertyMode.DefaultInheritance:
|
|
SelectedObject = DefaultConnectionInheritance.Instance;
|
|
break;
|
|
}
|
|
|
|
if (SelectedObject != null)
|
|
ShowHideGridItems();
|
|
}
|
|
|
|
private void ShowHideGridItems()
|
|
{
|
|
try
|
|
{
|
|
if (SelectedConnectionInfo == null)
|
|
return;
|
|
|
|
if (RootNodeSelected && PropertyMode == PropertyMode.Connection)
|
|
{
|
|
if (SelectedConnectionInfo is RootPuttySessionsNodeInfo)
|
|
{
|
|
BrowsableProperties = new[]
|
|
{
|
|
nameof(RootPuttySessionsNodeInfo.Name)
|
|
};
|
|
}
|
|
else if (SelectedConnectionInfo is RootNodeInfo)
|
|
{
|
|
BrowsableProperties = new[]
|
|
{
|
|
nameof(RootNodeInfo.Name),
|
|
nameof(RootNodeInfo.Password)
|
|
};
|
|
}
|
|
|
|
Refresh();
|
|
return;
|
|
}
|
|
|
|
// set all browsable properties valid for this connection's protocol
|
|
BrowsableProperties =
|
|
GetPropertiesForGridObject(SelectedObject)
|
|
.Where(property =>
|
|
IsValidForProtocol(property, SelectedConnectionInfo.Protocol, IsShowingInheritance))
|
|
.Select(property => property.Name)
|
|
.ToArray();
|
|
|
|
var strHide = new List<string>();
|
|
|
|
if (PropertyMode == PropertyMode.Connection)
|
|
{
|
|
// hide any inherited properties
|
|
strHide.AddRange(SelectedConnectionInfo.Inheritance.GetEnabledInheritanceProperties());
|
|
|
|
// ReSharper disable once SwitchStatementMissingSomeCases
|
|
switch (SelectedConnectionInfo.Protocol)
|
|
{
|
|
case ProtocolType.RDP:
|
|
strHide.AddRange(SpecialRdpExclusions());
|
|
break;
|
|
case ProtocolType.VNC:
|
|
strHide.AddRange(SpecialVncExclusions());
|
|
break;
|
|
}
|
|
|
|
if (SelectedConnectionInfo.IsContainer)
|
|
strHide.Add(nameof(AbstractConnectionRecord.Hostname));
|
|
|
|
if (SelectedConnectionInfo is PuttySessionInfo)
|
|
strHide.Add(nameof(AbstractConnectionRecord.Favorite));
|
|
}
|
|
else if (PropertyMode == PropertyMode.DefaultConnection)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.Hostname));
|
|
strHide.Add(nameof(AbstractConnectionRecord.Name));
|
|
}
|
|
|
|
HiddenProperties = strHide.ToArray();
|
|
Refresh();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Runtime.MessageCollector.AddMessage(
|
|
MessageClass.ErrorMsg,
|
|
Language.strConfigPropertyGridHideItemsFailed +
|
|
Environment.NewLine + ex.Message, true);
|
|
}
|
|
}
|
|
|
|
private IEnumerable<PropertyInfo> GetPropertiesForGridObject(object currentGridObject)
|
|
{
|
|
if (_propertyCache.TryGetValue(currentGridObject.GetType(), out var properties))
|
|
return properties;
|
|
|
|
var type = currentGridObject.GetType();
|
|
var props = type.GetProperties();
|
|
_propertyCache.Add(type, props);
|
|
|
|
return props;
|
|
}
|
|
|
|
private bool IsValidForProtocol(PropertyInfo property, ProtocolType protocol, bool skipProtocolCheck)
|
|
{
|
|
return
|
|
property.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false &&
|
|
(skipProtocolCheck || property.GetCustomAttribute<UsedInProtocolAttribute>()?
|
|
.SupportedProtocolTypes
|
|
.Contains(protocol) != false);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private List<string> SpecialRdpExclusions()
|
|
{
|
|
var strHide = new List<string>();
|
|
|
|
if (SelectedConnectionInfo.RDPMinutesToIdleTimeout <= 0)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDPAlertIdleTimeout));
|
|
}
|
|
|
|
if (SelectedConnectionInfo.RDGatewayUsageMethod == RDGatewayUsageMethod.Never)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayDomain));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayHostname));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayPassword));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUseConnectionCredentials));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUsername));
|
|
}
|
|
else if (SelectedConnectionInfo.RDGatewayUseConnectionCredentials ==
|
|
RDGatewayUseConnectionCredentials.Yes)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayDomain));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayPassword));
|
|
strHide.Add(nameof(AbstractConnectionRecord.RDGatewayUsername));
|
|
}
|
|
|
|
if (!(SelectedConnectionInfo.Resolution == RDPResolutions.FitToWindow ||
|
|
SelectedConnectionInfo.Resolution == RDPResolutions.Fullscreen))
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.AutomaticResize));
|
|
}
|
|
|
|
if (SelectedConnectionInfo.RedirectSound != RDPSounds.BringToThisComputer)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.SoundQuality));
|
|
}
|
|
|
|
if (!SelectedConnectionInfo.UseVmId)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.VmId));
|
|
}
|
|
|
|
return strHide;
|
|
}
|
|
|
|
private List<string> SpecialVncExclusions()
|
|
{
|
|
var strHide = new List<string>();
|
|
if (SelectedConnectionInfo.VNCAuthMode == ProtocolVNC.AuthMode.AuthVNC)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.Username));
|
|
strHide.Add(nameof(AbstractConnectionRecord.Domain));
|
|
}
|
|
|
|
if (SelectedConnectionInfo.VNCProxyType == ProtocolVNC.ProxyType.ProxyNone)
|
|
{
|
|
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyIP));
|
|
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyPassword));
|
|
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyPort));
|
|
strHide.Add(nameof(AbstractConnectionRecord.VNCProxyUsername));
|
|
}
|
|
|
|
return strHide;
|
|
}
|
|
|
|
private void UpdateConnectionInfoNode(PropertyValueChangedEventArgs e)
|
|
{
|
|
if (IsShowingInheritance)
|
|
return;
|
|
|
|
if (e.ChangedItem.Label == Language.strPropertyNameProtocol)
|
|
{
|
|
SelectedConnectionInfo.SetDefaultPort();
|
|
}
|
|
else if (e.ChangedItem.Label == Language.strPropertyNameName)
|
|
{
|
|
if (Settings.Default.SetHostnameLikeDisplayName)
|
|
{
|
|
if (!string.IsNullOrEmpty(SelectedConnectionInfo.Name))
|
|
SelectedConnectionInfo.Hostname = SelectedConnectionInfo.Name;
|
|
}
|
|
}
|
|
|
|
if (IsShowingDefaultProperties)
|
|
DefaultConnectionInfo.Instance.SaveTo(Settings.Default, a => "ConDefault" + a);
|
|
}
|
|
|
|
private void UpdateRootInfoNode(PropertyValueChangedEventArgs e)
|
|
{
|
|
if (!(SelectedObject is RootNodeInfo rootInfo))
|
|
return;
|
|
|
|
if (e.ChangedItem.PropertyDescriptor?.Name != "Password")
|
|
return;
|
|
|
|
if (rootInfo.Password)
|
|
{
|
|
var passwordName = Settings.Default.UseSQLServer
|
|
? Language.strSQLServer.TrimEnd(':')
|
|
: Path.GetFileName(Runtime.ConnectionsService.GetStartupConnectionFileName());
|
|
|
|
var password = MiscTools.PasswordDialog(passwordName);
|
|
|
|
// operation cancelled, dont set a password
|
|
if (!password.Any() || password.First().Length == 0)
|
|
{
|
|
rootInfo.Password = false;
|
|
return;
|
|
}
|
|
|
|
rootInfo.PasswordString = password.First().ConvertToUnsecureString();
|
|
}
|
|
else
|
|
{
|
|
rootInfo.PasswordString = "";
|
|
}
|
|
}
|
|
|
|
private void UpdateInheritanceNode()
|
|
{
|
|
if (IsShowingDefaultProperties && IsShowingInheritance)
|
|
DefaultConnectionInheritance.Instance.SaveTo(Settings.Default, a => "InhDefault" + a);
|
|
}
|
|
|
|
private void pGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
UpdateConnectionInfoNode(e);
|
|
UpdateRootInfoNode(e);
|
|
UpdateInheritanceNode();
|
|
ShowHideGridItems();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg,
|
|
Language.strConfigPropertyGridValueFailed + Environment.NewLine +
|
|
ex.Message, true);
|
|
}
|
|
}
|
|
}
|
|
}
|