From 918da6e0eec71b208d2e5b252d37c73d6e6bc8e3 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 28 Dec 2018 16:51:36 -0500 Subject: [PATCH 01/11] minor code clean up --- mRemoteV1/Connection/ConnectionInitiator.cs | 2 +- .../Connection/Protocol/RDP/RdpProtocol.cs | 46 ++++++------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/mRemoteV1/Connection/ConnectionInitiator.cs b/mRemoteV1/Connection/ConnectionInitiator.cs index 62099995..77dccaac 100644 --- a/mRemoteV1/Connection/ConnectionInitiator.cs +++ b/mRemoteV1/Connection/ConnectionInitiator.cs @@ -134,7 +134,7 @@ namespace mRemoteNG.Connection private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force) { - var connectionPanel = ""; + string connectionPanel; if (connectionInfo.Panel == "" || force.HasFlag(ConnectionInfo.Force.OverridePanel) || Settings.Default.AlwaysShowPanelSelectionDlg) { var frmPnl = new FrmChoosePanel(); diff --git a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs index 5420315a..a4e4a90d 100644 --- a/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs +++ b/mRemoteV1/Connection/Protocol/RDP/RdpProtocol.cs @@ -36,10 +36,7 @@ namespace mRemoteNG.Connection.Protocol.RDP #region Properties public bool SmartSize { - get - { - return _rdpClient.AdvancedSettings2.SmartSizing; - } + get => _rdpClient.AdvancedSettings2.SmartSizing; private set { _rdpClient.AdvancedSettings2.SmartSizing = value; @@ -49,10 +46,7 @@ namespace mRemoteNG.Connection.Protocol.RDP public bool Fullscreen { - get - { - return _rdpClient.FullScreen; - } + get => _rdpClient.FullScreen; private set { _rdpClient.FullScreen = value; @@ -681,12 +675,8 @@ namespace mRemoteNG.Connection.Protocol.RDP { Close(); //Simply close the RDP Session if the idle timeout has been triggered. - if (_alertOnIdleDisconnect) - { - string message = "The " + _connectionInfo.Name + " session was disconnected due to inactivity"; - const string caption = "Session Disconnected"; - MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); - } + if (!_alertOnIdleDisconnect) return; + MessageBox.Show($"The {_connectionInfo.Name} session was disconnected due to inactivity", "Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information); } @@ -749,15 +739,9 @@ namespace mRemoteNG.Connection.Protocol.RDP public event LeaveFullscreenEventHandler LeaveFullscreen { - add - { - _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value); - } - remove - { - _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); - } - } + add => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value); + remove => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value); + } #endregion #region Enums @@ -927,15 +911,13 @@ namespace mRemoteNG.Connection.Protocol.RDP var srvReady = PortScanner.IsPortOpen(_connectionInfo.Hostname, Convert.ToString(_connectionInfo.Port)); ReconnectGroup.ServerReady = srvReady; - - if (ReconnectGroup.ReconnectWhenReady && srvReady) - { - tmrReconnect.Enabled = false; - ReconnectGroup.DisposeReconnectGroup(); - //SetProps() - _rdpClient.Connect(); - } - } + + if (!ReconnectGroup.ReconnectWhenReady || !srvReady) return; + tmrReconnect.Enabled = false; + ReconnectGroup.DisposeReconnectGroup(); + //SetProps() + _rdpClient.Connect(); + } catch (Exception ex) { Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.AutomaticReconnectError, _connectionInfo.Hostname), From fc4b33f7f04ec1c025aa9a8e9030b1fa94031e01 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Fri, 28 Dec 2018 17:08:25 -0500 Subject: [PATCH 02/11] changelog update --- CHANGELOG.TXT | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index 06a305bb..c7375563 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -2,20 +2,23 @@ Features/Enhancements: ---------------------- -#1238: Connection panel not translated until opened for the first time #1223: Open External Links in Default Web Browser -#1186: Fixed several dialog boxes to use localized button text -#1170: Prevent Options window from showing up in taskbar #1141: 'Copy Hostname' option added to connection tree context menu #1129: Spanish translation improvements #1072: Russian translation improvements -#1064: "Esc" button does does not close some dialogs -#1044: Dragging (grabbing) the program window requires 2 clicks #1016: Chinese (simplified) translation improvements #951: Added property to Enable/Disable Clipboard Sharing for RDP connections #928: Add context menu items to 'Close all but this' and 'Close all tabs to the right' #765: Port Scan Issues (single port scan option now available) +Fixes: +------ +#1238: Connection panel not translated until opened for the first time +#1186: Fixed several dialog boxes to use localized button text +#1170: Prevent Options window from showing up in taskbar +#1064: "Esc" button does does not close some dialogs +#1044: Dragging (grabbing) the program window requires 2 clicks + 1.76.12 (2018-11-08): From 6629faa4d5efa4e930908a63ef347683a3f87222 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sun, 30 Dec 2018 15:32:32 -0600 Subject: [PATCH 03/11] ngcheckbox now scales correctly with dpi --- mRemoteV1/UI/Controls/Base/NGCheckBox.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs index fb75a651..1ee95df2 100644 --- a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs @@ -8,10 +8,17 @@ namespace mRemoteNG.UI.Controls.Base public class NGCheckBox : CheckBox { private ThemeManager _themeManager; + private readonly Size _checkboxSize; + private readonly int _checkboxYCoord; + private readonly int _textXCoord; public NGCheckBox() { ThemeManager.getInstance().ThemeChanged += OnCreateControl; + var display = new DisplayProperties(); + _checkboxSize = new Size(display.ScaleWidth(11), display.ScaleHeight(11)); + _checkboxYCoord = Height / 2 - 7; + _textXCoord = _checkboxSize.Width + display.ScaleWidth(2); } public enum MouseState @@ -100,7 +107,7 @@ namespace mRemoteNG.UI.Controls.Base using (var p = new Pen(checkBorder)) { - var boxRect = new Rectangle(0, Height / 2 - 7, 11, 11); + var boxRect = new Rectangle(0, _checkboxYCoord, _checkboxSize.Width, _checkboxSize.Height); e.Graphics.FillRectangle(new SolidBrush(back), boxRect); e.Graphics.DrawRectangle(p, boxRect); } @@ -110,12 +117,9 @@ namespace mRemoteNG.UI.Controls.Base e.Graphics.DrawString("\u2714", new Font(Font.FontFamily, 7f), new SolidBrush(glyph), -1, 1); } - var textRect = new Rectangle(16, 0, Width - 16, Height); + var textRect = new Rectangle(_textXCoord, 0, Width - 16, Height); TextRenderer.DrawText(e.Graphics, Text, Font, textRect, fore, Parent.BackColor, TextFormatFlags.PathEllipsis); - - } - } } From e6e4ecacaf272fd214edee98d4ddbcc679bb9e12 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 31 Dec 2018 08:48:44 -0600 Subject: [PATCH 04/11] improved display of ngcheckbox on hidpi devices --- mRemoteV1/UI/Controls/Base/NGCheckBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs index 1ee95df2..1902e382 100644 --- a/mRemoteV1/UI/Controls/Base/NGCheckBox.cs +++ b/mRemoteV1/UI/Controls/Base/NGCheckBox.cs @@ -17,7 +17,7 @@ namespace mRemoteNG.UI.Controls.Base ThemeManager.getInstance().ThemeChanged += OnCreateControl; var display = new DisplayProperties(); _checkboxSize = new Size(display.ScaleWidth(11), display.ScaleHeight(11)); - _checkboxYCoord = Height / 2 - 7; + _checkboxYCoord = (display.ScaleHeight(Height) - _checkboxSize.Height) / 2 - display.ScaleHeight(5); _textXCoord = _checkboxSize.Width + display.ScaleWidth(2); } From 0e804d0bba924f49fab181fdea775a7ce04d97d9 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Mon, 31 Dec 2018 09:23:26 -0600 Subject: [PATCH 05/11] ngradiobutton now scales correctly for hidpi --- mRemoteV1/UI/Controls/Base/NGRadioButton.cs | 27 +++++++++++---------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mRemoteV1/UI/Controls/Base/NGRadioButton.cs b/mRemoteV1/UI/Controls/Base/NGRadioButton.cs index 6b480f5e..e4a7949c 100644 --- a/mRemoteV1/UI/Controls/Base/NGRadioButton.cs +++ b/mRemoteV1/UI/Controls/Base/NGRadioButton.cs @@ -10,14 +10,18 @@ namespace mRemoteNG.UI.Controls.Base class NGRadioButton : RadioButton { private ThemeManager _themeManager; - private Rectangle circle; - private Rectangle circle_small; + private readonly Rectangle _circle; + private readonly Rectangle _circleSmall; + private readonly int _textXCoord; + // Constructor public NGRadioButton() { - // Init - circle_small = new Rectangle(4, 4, 6, 6 ); - circle = new Rectangle(1, 1, 12, 12 ); + var display = new DisplayProperties(); + + _circleSmall = new Rectangle(display.ScaleWidth(4), display.ScaleHeight(4), display.ScaleWidth(6), display.ScaleHeight(6)); + _circle = new Rectangle(display.ScaleWidth(1), display.ScaleHeight(1), display.ScaleWidth(12), display.ScaleHeight(12)); + _textXCoord = display.ScaleWidth(16); ThemeManager.getInstance().ThemeChanged += OnCreateControl; } @@ -88,8 +92,7 @@ namespace mRemoteNG.UI.Controls.Base e.Graphics.Clear(Parent.BackColor); if (Enabled) { - - if(Checked) + if (Checked) { center = _themeManager.ActiveTheme.ExtendedPalette.getColor("CheckBox_Glyph"); } @@ -109,14 +112,12 @@ namespace mRemoteNG.UI.Controls.Base fore = _themeManager.ActiveTheme.ExtendedPalette.getColor("CheckBox_Text_Disabled"); } - var textRect = new Rectangle(16, Padding.Top, Width - 16, Height); + var textRect = new Rectangle(_textXCoord, Padding.Top, Width - 16, Height); TextRenderer.DrawText(e.Graphics, Text, Font, textRect, fore, Parent.BackColor, TextFormatFlags.PathEllipsis); - g.FillEllipse(new SolidBrush(centerBack), circle); - g.FillEllipse(new SolidBrush(center), circle_small); - g.DrawEllipse(new Pen(outline), circle); - + g.FillEllipse(new SolidBrush(centerBack), _circle); + g.FillEllipse(new SolidBrush(center), _circleSmall); + g.DrawEllipse(new Pen(outline), _circle); } - } } From 82808be0c70100fabb5cf48645f80e67ce32bba3 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 1 Jan 2019 13:43:03 -0600 Subject: [PATCH 06/11] deleted confcons 2.8 schema since this version doesnt exist --- mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd | 141 ------------------ mRemoteV1/mRemoteV1.csproj | 4 - 2 files changed, 145 deletions(-) delete mode 100644 mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd diff --git a/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd b/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd deleted file mode 100644 index 1c08ef98..00000000 --- a/mRemoteV1/Schemas/mremoteng_confcons_v2_8.xsd +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 734b439c..a6a173ea 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -981,10 +981,6 @@ Designer PreserveNewest - - Designer - PreserveNewest - Designer PreserveNewest From ce371e45aeb59becc462c0afdd023dfe3ea34aea Mon Sep 17 00:00:00 2001 From: David Sparer Date: Tue, 1 Jan 2019 13:50:00 -0600 Subject: [PATCH 07/11] xml deserialization can now tolerate missing attributes --- .../Xml/XmlConnectionsDeserializer.cs | 277 +++++++++--------- .../Xml/XmlExtensions.cs | 48 +++ mRemoteV1/mRemoteV1.csproj | 1 + 3 files changed, 184 insertions(+), 142 deletions(-) create mode 100644 mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs index 270f5fb1..2ddf4532 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs @@ -18,6 +18,7 @@ using System.Globalization; using System.Security; using System.Windows.Forms; using System.Xml; +using mRemoteNG.Config.Serializers.ConnectionSerializers.Xml; namespace mRemoteNG.Config.Serializers.Xml { @@ -67,8 +68,8 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 2.6) { - var fullFileEncryptionValue = rootXmlElement?.Attributes["FullFileEncryption"].Value ?? ""; - if (bool.Parse(fullFileEncryptionValue)) + var fullFileEncryptionValue = rootXmlElement.GetAttributeAsBool("FullFileEncryption"); + if (fullFileEncryptionValue) { var decryptedContent = _decryptor.Decrypt(rootXmlElement.InnerText); rootXmlElement.InnerXml = decryptedContent; @@ -139,14 +140,9 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion >= 2.6) { - BlockCipherEngines engine; - Enum.TryParse(connectionsRootElement?.Attributes["EncryptionEngine"].Value, true, out engine); - - BlockCipherModes mode; - Enum.TryParse(connectionsRootElement?.Attributes["BlockCipherMode"].Value, true, out mode); - - int keyDerivationIterations; - int.TryParse(connectionsRootElement?.Attributes["KdfIterations"].Value, out keyDerivationIterations); + var engine = connectionsRootElement.GetAttributeAsEnum("EncryptionEngine"); + var mode = connectionsRootElement.GetAttributeAsEnum("BlockCipherMode"); + var keyDerivationIterations = connectionsRootElement.GetAttributeAsInt("KdfIterations"); _decryptor = new XmlConnectionsDecryptor(engine, mode, rootNodeInfo) { @@ -167,8 +163,7 @@ namespace mRemoteNG.Config.Serializers.Xml if (!parentXmlNode.HasChildNodes) return; foreach (XmlNode xmlNode in parentXmlNode.ChildNodes) { - var treeNodeTypeString = xmlNode.Attributes?["Type"].Value ?? "connection"; - var nodeType = (TreeNodeType)Enum.Parse(typeof(TreeNodeType), treeNodeTypeString, true); + var nodeType = xmlNode.GetAttributeAsEnum("Type", TreeNodeType.Connection); // ReSharper disable once SwitchStatementMissingSomeCases switch (nodeType) @@ -184,8 +179,7 @@ namespace mRemoteNG.Config.Serializers.Xml containerInfo.CopyFrom(GetConnectionInfoFromXml(xmlNode)); if (_confVersion >= 0.8) { - var expandedValue = xmlNode.Attributes?["Expanded"].Value ?? ""; - containerInfo.IsExpanded = bool.Parse(expandedValue); + containerInfo.IsExpanded = xmlNode.GetAttributeAsBool("Expanded"); } parentContainer.AddChild(containerInfo); @@ -203,9 +197,10 @@ namespace mRemoteNG.Config.Serializers.Xml private ConnectionInfo GetConnectionInfoFromXml(XmlNode xmlnode) { - if (xmlnode.Attributes == null) return null; + if (xmlnode?.Attributes == null) + return null; - var connectionId = xmlnode.Attributes["Id"]?.Value; + var connectionId = xmlnode.GetAttributeAsString("Id"); if (string.IsNullOrWhiteSpace(connectionId)) connectionId = Guid.NewGuid().ToString(); var connectionInfo = new ConnectionInfo(connectionId); @@ -214,16 +209,16 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion >= 0.2) { - connectionInfo.Name = xmlnode.Attributes["Name"].Value; - connectionInfo.Description = xmlnode.Attributes["Descr"].Value; - connectionInfo.Hostname = xmlnode.Attributes["Hostname"].Value; - connectionInfo.DisplayWallpaper = bool.Parse(xmlnode.Attributes["DisplayWallpaper"].Value); - connectionInfo.DisplayThemes = bool.Parse(xmlnode.Attributes["DisplayThemes"].Value); - connectionInfo.CacheBitmaps = bool.Parse(xmlnode.Attributes["CacheBitmaps"].Value); + connectionInfo.Name = xmlnode.GetAttributeAsString("Name"); + connectionInfo.Description = xmlnode.GetAttributeAsString("Descr"); + connectionInfo.Hostname = xmlnode.GetAttributeAsString("Hostname"); + connectionInfo.DisplayWallpaper = xmlnode.GetAttributeAsBool("DisplayWallpaper"); + connectionInfo.DisplayThemes = xmlnode.GetAttributeAsBool("DisplayThemes"); + connectionInfo.CacheBitmaps = xmlnode.GetAttributeAsBool("CacheBitmaps"); if (_confVersion < 1.1) //1.0 - 0.1 { - connectionInfo.Resolution = Convert.ToBoolean(xmlnode.Attributes["Fullscreen"].Value) + connectionInfo.Resolution = xmlnode.GetAttributeAsBool("Fullscreen") ? RdpProtocol.RDPResolutions.Fullscreen : RdpProtocol.RDPResolutions.FitToWindow; } @@ -231,9 +226,9 @@ namespace mRemoteNG.Config.Serializers.Xml if (!Runtime.UseCredentialManager || _confVersion <= 2.6) // 0.2 - 2.6 { #pragma warning disable 618 - connectionInfo.Username = xmlnode.Attributes["Username"].Value; - connectionInfo.Password = _decryptor.Decrypt(xmlnode.Attributes["Password"].Value); - connectionInfo.Domain = xmlnode.Attributes["Domain"].Value; + connectionInfo.Username = xmlnode.GetAttributeAsString("Username"); + connectionInfo.Password = _decryptor.Decrypt(xmlnode.GetAttributeAsString("Password")); + connectionInfo.Domain = xmlnode.GetAttributeAsString("Domain"); #pragma warning restore 618 } } @@ -242,10 +237,10 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion < 0.7) { - if (Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value)) + if (xmlnode.GetAttributeAsBool("UseVNC")) { connectionInfo.Protocol = ProtocolType.VNC; - connectionInfo.Port = Convert.ToInt32(xmlnode.Attributes["VNCPort"].Value); + connectionInfo.Port = xmlnode.GetAttributeAsInt("VNCPort"); } else { @@ -263,18 +258,18 @@ namespace mRemoteNG.Config.Serializers.Xml { if (_confVersion < 0.7) { - connectionInfo.Port = Convert.ToInt32(Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value) - ? xmlnode.Attributes["VNCPort"].Value - : xmlnode.Attributes["RDPPort"].Value); + connectionInfo.Port = xmlnode.GetAttributeAsBool("UseVNC") + ? xmlnode.GetAttributeAsInt("VNCPort") + : xmlnode.GetAttributeAsInt("RDPPort"); } - connectionInfo.UseConsoleSession = bool.Parse(xmlnode.Attributes["ConnectToConsole"].Value); + connectionInfo.UseConsoleSession = xmlnode.GetAttributeAsBool("ConnectToConsole"); } else { if (_confVersion < 0.7) { - if (Convert.ToBoolean(xmlnode.Attributes["UseVNC"].Value)) + if (xmlnode.GetAttributeAsBool("UseVNC")) connectionInfo.Port = (int)ProtocolVNC.Defaults.Port; else connectionInfo.Port = (int)RdpProtocol.Defaults.Port; @@ -284,10 +279,10 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 0.5) { - connectionInfo.RedirectDiskDrives = bool.Parse(xmlnode.Attributes["RedirectDiskDrives"].Value); - connectionInfo.RedirectPrinters = bool.Parse(xmlnode.Attributes["RedirectPrinters"].Value); - connectionInfo.RedirectPorts = bool.Parse(xmlnode.Attributes["RedirectPorts"].Value); - connectionInfo.RedirectSmartCards = bool.Parse(xmlnode.Attributes["RedirectSmartCards"].Value); + connectionInfo.RedirectDiskDrives = xmlnode.GetAttributeAsBool("RedirectDiskDrives"); + connectionInfo.RedirectPrinters = xmlnode.GetAttributeAsBool("RedirectPrinters"); + connectionInfo.RedirectPorts = xmlnode.GetAttributeAsBool("RedirectPorts"); + connectionInfo.RedirectSmartCards = xmlnode.GetAttributeAsBool("RedirectSmartCards"); } else { @@ -299,31 +294,29 @@ namespace mRemoteNG.Config.Serializers.Xml if (_confVersion >= 0.7) { - ProtocolType protocolType; - Enum.TryParse(xmlnode.Attributes["Protocol"].Value, true, out protocolType); - connectionInfo.Protocol = protocolType; - connectionInfo.Port = Convert.ToInt32(xmlnode.Attributes["Port"].Value); + connectionInfo.Protocol = xmlnode.GetAttributeAsEnum("Protocol"); + connectionInfo.Port = xmlnode.GetAttributeAsInt("Port"); } if (_confVersion >= 1.0) { - connectionInfo.RedirectKeys = bool.Parse(xmlnode.Attributes["RedirectKeys"].Value); + connectionInfo.RedirectKeys = xmlnode.GetAttributeAsBool("RedirectKeys"); } if (_confVersion >= 1.2) { - connectionInfo.PuttySession = xmlnode.Attributes["PuttySession"].Value; + connectionInfo.PuttySession = xmlnode.GetAttributeAsString("PuttySession"); } if (_confVersion >= 1.3) { - connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors), xmlnode.Attributes["Colors"].Value, true); - connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), xmlnode.Attributes["Resolution"].Value, true); - connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Enum.Parse(typeof(RdpProtocol.RDPSounds), xmlnode.Attributes["RedirectSound"].Value, true); + connectionInfo.Colors = xmlnode.GetAttributeAsEnum("Colors"); + connectionInfo.Resolution = xmlnode.GetAttributeAsEnum("Resolution"); + connectionInfo.RedirectSound = xmlnode.GetAttributeAsEnum("RedirectSound"); } else { - switch (Convert.ToInt32(xmlnode.Attributes["Colors"].Value)) + switch (xmlnode.GetAttributeAsInt("Colors")) { case 0: connectionInfo.Colors = RdpProtocol.RDPColors.Colors256; @@ -344,171 +337,171 @@ namespace mRemoteNG.Config.Serializers.Xml break; } - connectionInfo.RedirectSound = (RdpProtocol.RDPSounds)Convert.ToInt32(xmlnode.Attributes["RedirectSound"].Value); + connectionInfo.RedirectSound = xmlnode.GetAttributeAsEnum("RedirectSound"); } if (_confVersion >= 1.3) { - connectionInfo.Inheritance.CacheBitmaps = bool.Parse(xmlnode.Attributes["InheritCacheBitmaps"].Value); - connectionInfo.Inheritance.Colors = bool.Parse(xmlnode.Attributes["InheritColors"].Value); - connectionInfo.Inheritance.Description = bool.Parse(xmlnode.Attributes["InheritDescription"].Value); - connectionInfo.Inheritance.DisplayThemes = bool.Parse(xmlnode.Attributes["InheritDisplayThemes"].Value); - connectionInfo.Inheritance.DisplayWallpaper = bool.Parse(xmlnode.Attributes["InheritDisplayWallpaper"].Value); - connectionInfo.Inheritance.Icon = bool.Parse(xmlnode.Attributes["InheritIcon"].Value); - connectionInfo.Inheritance.Panel = bool.Parse(xmlnode.Attributes["InheritPanel"].Value); - connectionInfo.Inheritance.Port = bool.Parse(xmlnode.Attributes["InheritPort"].Value); - connectionInfo.Inheritance.Protocol = bool.Parse(xmlnode.Attributes["InheritProtocol"].Value); - connectionInfo.Inheritance.PuttySession = bool.Parse(xmlnode.Attributes["InheritPuttySession"].Value); - connectionInfo.Inheritance.RedirectDiskDrives = bool.Parse(xmlnode.Attributes["InheritRedirectDiskDrives"].Value); - connectionInfo.Inheritance.RedirectKeys = bool.Parse(xmlnode.Attributes["InheritRedirectKeys"].Value); - connectionInfo.Inheritance.RedirectPorts = bool.Parse(xmlnode.Attributes["InheritRedirectPorts"].Value); - connectionInfo.Inheritance.RedirectPrinters = bool.Parse(xmlnode.Attributes["InheritRedirectPrinters"].Value); - connectionInfo.Inheritance.RedirectSmartCards = bool.Parse(xmlnode.Attributes["InheritRedirectSmartCards"].Value); - connectionInfo.Inheritance.RedirectSound = bool.Parse(xmlnode.Attributes["InheritRedirectSound"].Value); - connectionInfo.Inheritance.Resolution = bool.Parse(xmlnode.Attributes["InheritResolution"].Value); - connectionInfo.Inheritance.UseConsoleSession = bool.Parse(xmlnode.Attributes["InheritUseConsoleSession"].Value); + connectionInfo.Inheritance.CacheBitmaps = xmlnode.GetAttributeAsBool("InheritCacheBitmaps"); + connectionInfo.Inheritance.Colors = xmlnode.GetAttributeAsBool("InheritColors"); + connectionInfo.Inheritance.Description = xmlnode.GetAttributeAsBool("InheritDescription"); + connectionInfo.Inheritance.DisplayThemes = xmlnode.GetAttributeAsBool("InheritDisplayThemes"); + connectionInfo.Inheritance.DisplayWallpaper = xmlnode.GetAttributeAsBool("InheritDisplayWallpaper"); + connectionInfo.Inheritance.Icon = xmlnode.GetAttributeAsBool("InheritIcon"); + connectionInfo.Inheritance.Panel = xmlnode.GetAttributeAsBool("InheritPanel"); + connectionInfo.Inheritance.Port = xmlnode.GetAttributeAsBool("InheritPort"); + connectionInfo.Inheritance.Protocol = xmlnode.GetAttributeAsBool("InheritProtocol"); + connectionInfo.Inheritance.PuttySession = xmlnode.GetAttributeAsBool("InheritPuttySession"); + connectionInfo.Inheritance.RedirectDiskDrives = xmlnode.GetAttributeAsBool("InheritRedirectDiskDrives"); + connectionInfo.Inheritance.RedirectKeys = xmlnode.GetAttributeAsBool("InheritRedirectKeys"); + connectionInfo.Inheritance.RedirectPorts = xmlnode.GetAttributeAsBool("InheritRedirectPorts"); + connectionInfo.Inheritance.RedirectPrinters = xmlnode.GetAttributeAsBool("InheritRedirectPrinters"); + connectionInfo.Inheritance.RedirectSmartCards = xmlnode.GetAttributeAsBool("InheritRedirectSmartCards"); + connectionInfo.Inheritance.RedirectSound = xmlnode.GetAttributeAsBool("InheritRedirectSound"); + connectionInfo.Inheritance.Resolution = xmlnode.GetAttributeAsBool("InheritResolution"); + connectionInfo.Inheritance.UseConsoleSession = xmlnode.GetAttributeAsBool("InheritUseConsoleSession"); if (!Runtime.UseCredentialManager || _confVersion <= 2.6) // 1.3 - 2.6 { - connectionInfo.Inheritance.Domain = bool.Parse(xmlnode.Attributes["InheritDomain"].Value); - connectionInfo.Inheritance.Password = bool.Parse(xmlnode.Attributes["InheritPassword"].Value); - connectionInfo.Inheritance.Username = bool.Parse(xmlnode.Attributes["InheritUsername"].Value); + connectionInfo.Inheritance.Domain = xmlnode.GetAttributeAsBool("InheritDomain"); + connectionInfo.Inheritance.Password = xmlnode.GetAttributeAsBool("InheritPassword"); + connectionInfo.Inheritance.Username = xmlnode.GetAttributeAsBool("InheritUsername"); } - connectionInfo.Icon = xmlnode.Attributes["Icon"].Value; - connectionInfo.Panel = xmlnode.Attributes["Panel"].Value; + connectionInfo.Icon = xmlnode.GetAttributeAsString("Icon"); + connectionInfo.Panel = xmlnode.GetAttributeAsString("Panel"); } else { - if (Convert.ToBoolean(xmlnode.Attributes["Inherit"].Value)) + if (xmlnode.GetAttributeAsBool("Inherit")) connectionInfo.Inheritance.TurnOnInheritanceCompletely(); - connectionInfo.Icon = Convert.ToString(xmlnode.Attributes["Icon"].Value.Replace(".ico", "")); + connectionInfo.Icon = xmlnode.GetAttributeAsString("Icon").Replace(".ico", ""); connectionInfo.Panel = Language.strGeneral; } if (_confVersion >= 1.5) { - connectionInfo.PleaseConnect = bool.Parse(xmlnode.Attributes["Connected"].Value); + connectionInfo.PleaseConnect = xmlnode.GetAttributeAsBool("Connected"); } if (_confVersion >= 1.6) { - connectionInfo.ICAEncryptionStrength = (IcaProtocol.EncryptionStrength)Enum.Parse(typeof(IcaProtocol.EncryptionStrength), xmlnode.Attributes["ICAEncryptionStrength"].Value, true); - connectionInfo.Inheritance.ICAEncryptionStrength = bool.Parse(xmlnode.Attributes["InheritICAEncryptionStrength"].Value); - connectionInfo.PreExtApp = xmlnode.Attributes["PreExtApp"].Value; - connectionInfo.PostExtApp = xmlnode.Attributes["PostExtApp"].Value; - connectionInfo.Inheritance.PreExtApp = bool.Parse(xmlnode.Attributes["InheritPreExtApp"].Value); - connectionInfo.Inheritance.PostExtApp = bool.Parse(xmlnode.Attributes["InheritPostExtApp"].Value); + connectionInfo.ICAEncryptionStrength = xmlnode.GetAttributeAsEnum("ICAEncryptionStrength"); + connectionInfo.Inheritance.ICAEncryptionStrength = xmlnode.GetAttributeAsBool("InheritICAEncryptionStrength"); + connectionInfo.PreExtApp = xmlnode.GetAttributeAsString("PreExtApp"); + connectionInfo.PostExtApp = xmlnode.GetAttributeAsString("PostExtApp"); + connectionInfo.Inheritance.PreExtApp = xmlnode.GetAttributeAsBool("InheritPreExtApp"); + connectionInfo.Inheritance.PostExtApp = xmlnode.GetAttributeAsBool("InheritPostExtApp"); } if (_confVersion >= 1.7) { - connectionInfo.VNCCompression = (ProtocolVNC.Compression)Enum.Parse(typeof(ProtocolVNC.Compression), xmlnode.Attributes["VNCCompression"].Value, true); - connectionInfo.VNCEncoding = (ProtocolVNC.Encoding)Enum.Parse(typeof(ProtocolVNC.Encoding), xmlnode.Attributes["VNCEncoding"].Value, true); - connectionInfo.VNCAuthMode = (ProtocolVNC.AuthMode)Enum.Parse(typeof(ProtocolVNC.AuthMode), xmlnode.Attributes["VNCAuthMode"].Value, true); - connectionInfo.VNCProxyType = (ProtocolVNC.ProxyType)Enum.Parse(typeof(ProtocolVNC.ProxyType), xmlnode.Attributes["VNCProxyType"].Value, true); - connectionInfo.VNCProxyIP = xmlnode.Attributes["VNCProxyIP"].Value; - connectionInfo.VNCProxyPort = Convert.ToInt32(xmlnode.Attributes["VNCProxyPort"].Value); - connectionInfo.VNCProxyUsername = xmlnode.Attributes["VNCProxyUsername"].Value; - connectionInfo.VNCProxyPassword = _decryptor.Decrypt(xmlnode.Attributes["VNCProxyPassword"].Value); - connectionInfo.VNCColors = (ProtocolVNC.Colors)Enum.Parse(typeof(ProtocolVNC.Colors), xmlnode.Attributes["VNCColors"].Value, true); - connectionInfo.VNCSmartSizeMode = (ProtocolVNC.SmartSizeMode)Enum.Parse(typeof(ProtocolVNC.SmartSizeMode), xmlnode.Attributes["VNCSmartSizeMode"].Value, true); - connectionInfo.VNCViewOnly = bool.Parse(xmlnode.Attributes["VNCViewOnly"].Value); - connectionInfo.Inheritance.VNCCompression = bool.Parse(xmlnode.Attributes["InheritVNCCompression"].Value); - connectionInfo.Inheritance.VNCEncoding = bool.Parse(xmlnode.Attributes["InheritVNCEncoding"].Value); - connectionInfo.Inheritance.VNCAuthMode = bool.Parse(xmlnode.Attributes["InheritVNCAuthMode"].Value); - connectionInfo.Inheritance.VNCProxyType = bool.Parse(xmlnode.Attributes["InheritVNCProxyType"].Value); - connectionInfo.Inheritance.VNCProxyIP = bool.Parse(xmlnode.Attributes["InheritVNCProxyIP"].Value); - connectionInfo.Inheritance.VNCProxyPort = bool.Parse(xmlnode.Attributes["InheritVNCProxyPort"].Value); - connectionInfo.Inheritance.VNCProxyUsername = bool.Parse(xmlnode.Attributes["InheritVNCProxyUsername"].Value); - connectionInfo.Inheritance.VNCProxyPassword = bool.Parse(xmlnode.Attributes["InheritVNCProxyPassword"].Value); - connectionInfo.Inheritance.VNCColors = bool.Parse(xmlnode.Attributes["InheritVNCColors"].Value); - connectionInfo.Inheritance.VNCSmartSizeMode = bool.Parse(xmlnode.Attributes["InheritVNCSmartSizeMode"].Value); - connectionInfo.Inheritance.VNCViewOnly = bool.Parse(xmlnode.Attributes["InheritVNCViewOnly"].Value); + connectionInfo.VNCCompression = xmlnode.GetAttributeAsEnum("VNCCompression"); + connectionInfo.VNCEncoding = xmlnode.GetAttributeAsEnum("VNCEncoding"); + connectionInfo.VNCAuthMode = xmlnode.GetAttributeAsEnum("VNCAuthMode"); + connectionInfo.VNCProxyType = xmlnode.GetAttributeAsEnum("VNCProxyType"); + connectionInfo.VNCProxyIP = xmlnode.GetAttributeAsString("VNCProxyIP"); + connectionInfo.VNCProxyPort = xmlnode.GetAttributeAsInt("VNCProxyPort"); + connectionInfo.VNCProxyUsername = xmlnode.GetAttributeAsString("VNCProxyUsername"); + connectionInfo.VNCProxyPassword = _decryptor.Decrypt(xmlnode.GetAttributeAsString("VNCProxyPassword")); + connectionInfo.VNCColors = xmlnode.GetAttributeAsEnum("VNCColors"); + connectionInfo.VNCSmartSizeMode = xmlnode.GetAttributeAsEnum("VNCSmartSizeMode"); + connectionInfo.VNCViewOnly = xmlnode.GetAttributeAsBool("VNCViewOnly"); + connectionInfo.Inheritance.VNCCompression = xmlnode.GetAttributeAsBool("InheritVNCCompression"); + connectionInfo.Inheritance.VNCEncoding = xmlnode.GetAttributeAsBool("InheritVNCEncoding"); + connectionInfo.Inheritance.VNCAuthMode = xmlnode.GetAttributeAsBool("InheritVNCAuthMode"); + connectionInfo.Inheritance.VNCProxyType = xmlnode.GetAttributeAsBool("InheritVNCProxyType"); + connectionInfo.Inheritance.VNCProxyIP = xmlnode.GetAttributeAsBool("InheritVNCProxyIP"); + connectionInfo.Inheritance.VNCProxyPort = xmlnode.GetAttributeAsBool("InheritVNCProxyPort"); + connectionInfo.Inheritance.VNCProxyUsername = xmlnode.GetAttributeAsBool("InheritVNCProxyUsername"); + connectionInfo.Inheritance.VNCProxyPassword = xmlnode.GetAttributeAsBool("InheritVNCProxyPassword"); + connectionInfo.Inheritance.VNCColors = xmlnode.GetAttributeAsBool("InheritVNCColors"); + connectionInfo.Inheritance.VNCSmartSizeMode = xmlnode.GetAttributeAsBool("InheritVNCSmartSizeMode"); + connectionInfo.Inheritance.VNCViewOnly = xmlnode.GetAttributeAsBool("InheritVNCViewOnly"); } if (_confVersion >= 1.8) { - connectionInfo.RDPAuthenticationLevel = (RdpProtocol.AuthenticationLevel)Enum.Parse(typeof(RdpProtocol.AuthenticationLevel), xmlnode.Attributes["RDPAuthenticationLevel"].Value, true); - connectionInfo.Inheritance.RDPAuthenticationLevel = bool.Parse(xmlnode.Attributes["InheritRDPAuthenticationLevel"].Value); + connectionInfo.RDPAuthenticationLevel = xmlnode.GetAttributeAsEnum("RDPAuthenticationLevel"); + connectionInfo.Inheritance.RDPAuthenticationLevel = xmlnode.GetAttributeAsBool("InheritRDPAuthenticationLevel"); } if (_confVersion >= 1.9) { - connectionInfo.RenderingEngine = (HTTPBase.RenderingEngine)Enum.Parse(typeof(HTTPBase.RenderingEngine), xmlnode.Attributes["RenderingEngine"].Value, true); - connectionInfo.MacAddress = xmlnode.Attributes["MacAddress"].Value; - connectionInfo.Inheritance.RenderingEngine = bool.Parse(xmlnode.Attributes["InheritRenderingEngine"].Value); - connectionInfo.Inheritance.MacAddress = bool.Parse(xmlnode.Attributes["InheritMacAddress"].Value); + connectionInfo.RenderingEngine = xmlnode.GetAttributeAsEnum("RenderingEngine"); + connectionInfo.MacAddress = xmlnode.GetAttributeAsString("MacAddress"); + connectionInfo.Inheritance.RenderingEngine = xmlnode.GetAttributeAsBool("InheritRenderingEngine"); + connectionInfo.Inheritance.MacAddress = xmlnode.GetAttributeAsBool("InheritMacAddress"); } if (_confVersion >= 2.0) { - connectionInfo.UserField = xmlnode.Attributes["UserField"].Value; - connectionInfo.Inheritance.UserField = bool.Parse(xmlnode.Attributes["InheritUserField"].Value); + connectionInfo.UserField = xmlnode.GetAttributeAsString("UserField"); + connectionInfo.Inheritance.UserField = xmlnode.GetAttributeAsBool("InheritUserField"); } if (_confVersion >= 2.1) { - connectionInfo.ExtApp = xmlnode.Attributes["ExtApp"].Value; - connectionInfo.Inheritance.ExtApp = bool.Parse(xmlnode.Attributes["InheritExtApp"].Value); + connectionInfo.ExtApp = xmlnode.GetAttributeAsString("ExtApp"); + connectionInfo.Inheritance.ExtApp = xmlnode.GetAttributeAsBool("InheritExtApp"); } if (_confVersion >= 2.2) { // Get settings - connectionInfo.RDGatewayUsageMethod = (RdpProtocol.RDGatewayUsageMethod)Enum.Parse(typeof(RdpProtocol.RDGatewayUsageMethod), xmlnode.Attributes["RDGatewayUsageMethod"].Value, true); - connectionInfo.RDGatewayHostname = xmlnode.Attributes["RDGatewayHostname"].Value; - connectionInfo.RDGatewayUseConnectionCredentials = (RdpProtocol.RDGatewayUseConnectionCredentials)Enum.Parse(typeof(RdpProtocol.RDGatewayUseConnectionCredentials), xmlnode.Attributes["RDGatewayUseConnectionCredentials"].Value, true); - connectionInfo.RDGatewayUsername = xmlnode.Attributes["RDGatewayUsername"].Value; - connectionInfo.RDGatewayPassword = _decryptor.Decrypt(Convert.ToString(xmlnode.Attributes["RDGatewayPassword"].Value)); - connectionInfo.RDGatewayDomain = xmlnode.Attributes["RDGatewayDomain"].Value; + connectionInfo.RDGatewayUsageMethod = xmlnode.GetAttributeAsEnum("RDGatewayUsageMethod"); + connectionInfo.RDGatewayHostname = xmlnode.GetAttributeAsString("RDGatewayHostname"); + connectionInfo.RDGatewayUseConnectionCredentials = xmlnode.GetAttributeAsEnum("RDGatewayUseConnectionCredentials"); + connectionInfo.RDGatewayUsername = xmlnode.GetAttributeAsString("RDGatewayUsername"); + connectionInfo.RDGatewayPassword = _decryptor.Decrypt(xmlnode.GetAttributeAsString("RDGatewayPassword")); + connectionInfo.RDGatewayDomain = xmlnode.GetAttributeAsString("RDGatewayDomain"); // Get inheritance settings - connectionInfo.Inheritance.RDGatewayUsageMethod = bool.Parse(xmlnode.Attributes["InheritRDGatewayUsageMethod"].Value); - connectionInfo.Inheritance.RDGatewayHostname = bool.Parse(xmlnode.Attributes["InheritRDGatewayHostname"].Value); - connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = bool.Parse(xmlnode.Attributes["InheritRDGatewayUseConnectionCredentials"].Value); - connectionInfo.Inheritance.RDGatewayUsername = bool.Parse(xmlnode.Attributes["InheritRDGatewayUsername"].Value); - connectionInfo.Inheritance.RDGatewayPassword = bool.Parse(xmlnode.Attributes["InheritRDGatewayPassword"].Value); - connectionInfo.Inheritance.RDGatewayDomain = bool.Parse(xmlnode.Attributes["InheritRDGatewayDomain"].Value); + connectionInfo.Inheritance.RDGatewayUsageMethod = xmlnode.GetAttributeAsBool("InheritRDGatewayUsageMethod"); + connectionInfo.Inheritance.RDGatewayHostname = xmlnode.GetAttributeAsBool("InheritRDGatewayHostname"); + connectionInfo.Inheritance.RDGatewayUseConnectionCredentials = xmlnode.GetAttributeAsBool("InheritRDGatewayUseConnectionCredentials"); + connectionInfo.Inheritance.RDGatewayUsername = xmlnode.GetAttributeAsBool("InheritRDGatewayUsername"); + connectionInfo.Inheritance.RDGatewayPassword = xmlnode.GetAttributeAsBool("InheritRDGatewayPassword"); + connectionInfo.Inheritance.RDGatewayDomain = xmlnode.GetAttributeAsBool("InheritRDGatewayDomain"); } if (_confVersion >= 2.3) { // Get settings - connectionInfo.EnableFontSmoothing = bool.Parse(xmlnode.Attributes["EnableFontSmoothing"].Value); - connectionInfo.EnableDesktopComposition = bool.Parse(xmlnode.Attributes["EnableDesktopComposition"].Value); + connectionInfo.EnableFontSmoothing = xmlnode.GetAttributeAsBool("EnableFontSmoothing"); + connectionInfo.EnableDesktopComposition = xmlnode.GetAttributeAsBool("EnableDesktopComposition"); // Get inheritance settings - connectionInfo.Inheritance.EnableFontSmoothing = bool.Parse(xmlnode.Attributes["InheritEnableFontSmoothing"].Value); - connectionInfo.Inheritance.EnableDesktopComposition = bool.Parse(xmlnode.Attributes["InheritEnableDesktopComposition"].Value); + connectionInfo.Inheritance.EnableFontSmoothing = xmlnode.GetAttributeAsBool("InheritEnableFontSmoothing"); + connectionInfo.Inheritance.EnableDesktopComposition = xmlnode.GetAttributeAsBool("InheritEnableDesktopComposition"); } if (_confVersion >= 2.4) { - connectionInfo.UseCredSsp = bool.Parse(xmlnode.Attributes["UseCredSsp"].Value); - connectionInfo.Inheritance.UseCredSsp = bool.Parse(xmlnode.Attributes["InheritUseCredSsp"].Value); + connectionInfo.UseCredSsp = xmlnode.GetAttributeAsBool("UseCredSsp"); + connectionInfo.Inheritance.UseCredSsp = xmlnode.GetAttributeAsBool("InheritUseCredSsp"); } if (_confVersion >= 2.5) { - connectionInfo.LoadBalanceInfo = xmlnode.Attributes["LoadBalanceInfo"].Value; - connectionInfo.AutomaticResize = bool.Parse(xmlnode.Attributes["AutomaticResize"].Value); - connectionInfo.Inheritance.LoadBalanceInfo = bool.Parse(xmlnode.Attributes["InheritLoadBalanceInfo"].Value); - connectionInfo.Inheritance.AutomaticResize = bool.Parse(xmlnode.Attributes["InheritAutomaticResize"].Value); + connectionInfo.LoadBalanceInfo = xmlnode.GetAttributeAsString("LoadBalanceInfo"); + connectionInfo.AutomaticResize = xmlnode.GetAttributeAsBool("AutomaticResize"); + connectionInfo.Inheritance.LoadBalanceInfo = xmlnode.GetAttributeAsBool("InheritLoadBalanceInfo"); + connectionInfo.Inheritance.AutomaticResize = xmlnode.GetAttributeAsBool("InheritAutomaticResize"); } if (_confVersion >= 2.6) { - connectionInfo.SoundQuality = (RdpProtocol.RDPSoundQuality)Enum.Parse(typeof(RdpProtocol.RDPSoundQuality), xmlnode.Attributes["SoundQuality"].Value, true); - connectionInfo.Inheritance.SoundQuality = bool.Parse(xmlnode.Attributes["InheritSoundQuality"].Value); - connectionInfo.RDPMinutesToIdleTimeout = Convert.ToInt32(xmlnode.Attributes["RDPMinutesToIdleTimeout"]?.Value ?? "0"); - connectionInfo.Inheritance.RDPMinutesToIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPMinutesToIdleTimeout"]?.Value ?? "False"); - connectionInfo.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["RDPAlertIdleTimeout"]?.Value ?? "False"); - connectionInfo.Inheritance.RDPAlertIdleTimeout = bool.Parse(xmlnode.Attributes["InheritRDPAlertIdleTimeout"]?.Value ?? "False"); + connectionInfo.SoundQuality = xmlnode.GetAttributeAsEnum("SoundQuality"); + connectionInfo.Inheritance.SoundQuality = xmlnode.GetAttributeAsBool("InheritSoundQuality"); + connectionInfo.RDPMinutesToIdleTimeout = xmlnode.GetAttributeAsInt("RDPMinutesToIdleTimeout"); + connectionInfo.Inheritance.RDPMinutesToIdleTimeout = xmlnode.GetAttributeAsBool("InheritRDPMinutesToIdleTimeout"); + connectionInfo.RDPAlertIdleTimeout = xmlnode.GetAttributeAsBool("RDPAlertIdleTimeout"); + connectionInfo.Inheritance.RDPAlertIdleTimeout = xmlnode.GetAttributeAsBool("InheritRDPAlertIdleTimeout"); } if(_confVersion >= 2.7) { - connectionInfo.RedirectClipboard = bool.Parse(xmlnode.Attributes["RedirectClipboard"].Value); - connectionInfo.Inheritance.RedirectClipboard = bool.Parse(xmlnode.Attributes["InheritRedirectClipboard"].Value); + connectionInfo.RedirectClipboard = xmlnode.GetAttributeAsBool("RedirectClipboard"); + connectionInfo.Inheritance.RedirectClipboard = xmlnode.GetAttributeAsBool("InheritRedirectClipboard"); } } catch (Exception ex) diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs new file mode 100644 index 00000000..71ecbff7 --- /dev/null +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlExtensions.cs @@ -0,0 +1,48 @@ +using System; +using System.Xml; + +namespace mRemoteNG.Config.Serializers.ConnectionSerializers.Xml +{ + public static class XmlExtensions + { + public static string GetAttributeAsString(this XmlNode xmlNode, string attribute, string defaultValue = "") + { + var value = xmlNode?.Attributes?[attribute]?.Value; + return value ?? defaultValue; + } + + public static bool GetAttributeAsBool(this XmlNode xmlNode, string attribute, bool defaultValue = false) + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return bool.TryParse(value, out var valueAsBool) + ? valueAsBool + : defaultValue; + } + + public static int GetAttributeAsInt(this XmlNode xmlNode, string attribute, int defaultValue = 0) + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return int.TryParse(value, out var valueAsBool) + ? valueAsBool + : defaultValue; + } + + public static T GetAttributeAsEnum(this XmlNode xmlNode, string attribute, T defaultValue = default(T)) + where T : struct + { + var value = xmlNode?.Attributes?[attribute]?.Value; + if (string.IsNullOrWhiteSpace(value)) + return defaultValue; + + return Enum.TryParse(value, true, out var valueAsEnum) + ? valueAsEnum + : defaultValue; + } + } +} diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index a6a173ea..05c5e4a9 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -164,6 +164,7 @@ + From d3e40d7c3d964a0a47d89f53345389888880ac7a Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 2 Jan 2019 10:43:33 -0500 Subject: [PATCH 08/11] Speed up Theme Option Page load Fixes #1245 The CheckChanged event was causing load settings to be called more than once on form load. --- mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs index b26c59c7..6035a071 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs @@ -3,7 +3,6 @@ using System.Windows.Forms; using mRemoteNG.Themes; using System.Linq; using System.Collections.Generic; -using System.Drawing; using BrightIdeasSoftware; using mRemoteNG.UI.Forms.Input; @@ -56,6 +55,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages public override void LoadSettings() { + themeEnableCombo.CheckedChanged -= themeEnableCombo_CheckedChanged; base.SaveSettings(); //At first we cannot create or delete themes, depends later on the type of selected theme btnThemeNew.Enabled = false; @@ -81,6 +81,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages // reset to the default theme when disabling theme support _themeManager.ActiveTheme = _themeManager.DefaultTheme; } + themeEnableCombo.CheckedChanged += themeEnableCombo_CheckedChanged; } private void ListPalette_FormatCell(object sender, FormatCellEventArgs e) From 166cec0483504d1a34f5c7f84663234d9d4daee8 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 2 Jan 2019 12:48:47 -0500 Subject: [PATCH 09/11] minor clean up --- mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs | 32 +++-- .../UI/Forms/OptionsPages/ThemePage.resx | 120 ++++++++++++++++++ mRemoteV1/mRemoteV1.csproj | 3 + 3 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 mRemoteV1/UI/Forms/OptionsPages/ThemePage.resx diff --git a/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs index 6035a071..722ff462 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.cs @@ -12,10 +12,10 @@ namespace mRemoteNG.UI.Forms.OptionsPages { #region Private Fields - private ThemeManager _themeManager; - private ThemeInfo _oriTheme; - private bool _oriActiveTheming; - List modifiedThemes = new List(); + private readonly ThemeManager _themeManager; + private readonly ThemeInfo _oriTheme; + private readonly bool _oriActiveTheming; + private readonly List modifiedThemes = new List(); #endregion public ThemePage() @@ -173,21 +173,19 @@ namespace mRemoteNG.UI.Forms.OptionsPages private void btnThemeNew_Click(object sender, EventArgs e) { var name = _themeManager.ActiveTheme.Name; - using (FrmInputBox frmInputBox = new FrmInputBox(Language.strOptionsThemeNewThemeCaption, Language.strOptionsThemeNewThemeText, ref name)) + using (var frmInputBox = new FrmInputBox(Language.strOptionsThemeNewThemeCaption, Language.strOptionsThemeNewThemeText, ref name)) { - DialogResult dr = frmInputBox.ShowDialog(); - if (dr == DialogResult.OK) + var dr = frmInputBox.ShowDialog(); + if (dr != DialogResult.OK) return; + if (_themeManager.isThemeNameOk(frmInputBox.returnValue)) { - if (_themeManager.isThemeNameOk(frmInputBox.returnValue)) - { - var addedTheme = _themeManager.addTheme(_themeManager.ActiveTheme, frmInputBox.returnValue); - _themeManager.ActiveTheme = addedTheme; - LoadSettings(); - } - else - { - TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strErrors, Language.strOptionsThemeNewThemeError, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.Ok, TaskDialog.ESysIcons.Error, TaskDialog.ESysIcons.Information, 0); - } + var addedTheme = _themeManager.addTheme(_themeManager.ActiveTheme, frmInputBox.returnValue); + _themeManager.ActiveTheme = addedTheme; + LoadSettings(); + } + else + { + TaskDialog.CTaskDialog.ShowTaskDialogBox(this, Language.strErrors, Language.strOptionsThemeNewThemeError, "", "", "", "", "", "", TaskDialog.ETaskDialogButtons.Ok, TaskDialog.ESysIcons.Error, TaskDialog.ESysIcons.Information, 0); } } } diff --git a/mRemoteV1/UI/Forms/OptionsPages/ThemePage.resx b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/mRemoteV1/UI/Forms/OptionsPages/ThemePage.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 05c5e4a9..997e8117 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -816,6 +816,9 @@ FrmInputBox.cs + + ThemePage.cs + PasswordForm.cs Designer From 67420e5416dfd37fbc55ddc590a4befbc0b1d538 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 2 Jan 2019 15:39:53 -0500 Subject: [PATCH 10/11] Segoe UI font on Connections Option page --- .../OptionsPages/ConnectionsPage.Designer.cs | 29 +++-- .../Forms/OptionsPages/ConnectionsPage.resx | 120 ++++++++++++++++++ mRemoteV1/UI/Forms/frmOptions.Designer.cs | 4 +- mRemoteV1/mRemoteV1.csproj | 3 + 4 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.resx diff --git a/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.Designer.cs b/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.Designer.cs index 8aaed446..263a249c 100644 --- a/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.Designer.cs +++ b/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.Designer.cs @@ -71,7 +71,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages 0, 0}); this.numRDPConTimeout.Name = "numRDPConTimeout"; - this.numRDPConTimeout.Size = new System.Drawing.Size(53, 20); + this.numRDPConTimeout.Size = new System.Drawing.Size(53, 22); this.numRDPConTimeout.TabIndex = 1; this.numRDPConTimeout.Value = new decimal(new int[] { 20, @@ -109,7 +109,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages 0, 0}); this.numRdpReconnectionCount.Name = "numRdpReconnectionCount"; - this.numRdpReconnectionCount.Size = new System.Drawing.Size(53, 20); + this.numRdpReconnectionCount.Size = new System.Drawing.Size(53, 22); this.numRdpReconnectionCount.TabIndex = 1; this.numRdpReconnectionCount.Value = new decimal(new int[] { 5, @@ -123,7 +123,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkSingleClickOnConnectionOpensIt.AutoSize = true; this.chkSingleClickOnConnectionOpensIt.Location = new System.Drawing.Point(3, 3); this.chkSingleClickOnConnectionOpensIt.Name = "chkSingleClickOnConnectionOpensIt"; - this.chkSingleClickOnConnectionOpensIt.Size = new System.Drawing.Size(191, 17); + this.chkSingleClickOnConnectionOpensIt.Size = new System.Drawing.Size(206, 17); this.chkSingleClickOnConnectionOpensIt.TabIndex = 0; this.chkSingleClickOnConnectionOpensIt.Text = "Single click on connection opens it"; this.chkSingleClickOnConnectionOpensIt.UseVisualStyleBackColor = true; @@ -134,7 +134,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkHostnameLikeDisplayName.AutoSize = true; this.chkHostnameLikeDisplayName.Location = new System.Drawing.Point(3, 49); this.chkHostnameLikeDisplayName.Name = "chkHostnameLikeDisplayName"; - this.chkHostnameLikeDisplayName.Size = new System.Drawing.Size(328, 17); + this.chkHostnameLikeDisplayName.Size = new System.Drawing.Size(355, 17); this.chkHostnameLikeDisplayName.TabIndex = 2; this.chkHostnameLikeDisplayName.Text = "Set hostname like display name when creating new connections"; this.chkHostnameLikeDisplayName.UseVisualStyleBackColor = true; @@ -145,7 +145,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkSingleClickOnOpenedConnectionSwitchesToIt.AutoSize = true; this.chkSingleClickOnOpenedConnectionSwitchesToIt.Location = new System.Drawing.Point(3, 26); this.chkSingleClickOnOpenedConnectionSwitchesToIt.Name = "chkSingleClickOnOpenedConnectionSwitchesToIt"; - this.chkSingleClickOnOpenedConnectionSwitchesToIt.Size = new System.Drawing.Size(457, 17); + this.chkSingleClickOnOpenedConnectionSwitchesToIt.Size = new System.Drawing.Size(490, 17); this.chkSingleClickOnOpenedConnectionSwitchesToIt.TabIndex = 1; this.chkSingleClickOnOpenedConnectionSwitchesToIt.Text = global::mRemoteNG.Language.strSingleClickOnOpenConnectionSwitchesToIt; this.chkSingleClickOnOpenedConnectionSwitchesToIt.UseVisualStyleBackColor = true; @@ -170,7 +170,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages 0, 0}); this.numAutoSave.Name = "numAutoSave"; - this.numAutoSave.Size = new System.Drawing.Size(53, 20); + this.numAutoSave.Size = new System.Drawing.Size(53, 22); this.numAutoSave.TabIndex = 1; // // pnlConfirmCloseConnection @@ -190,7 +190,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.lblClosingConnections.AutoSize = true; this.lblClosingConnections.Location = new System.Drawing.Point(3, 12); this.lblClosingConnections.Name = "lblClosingConnections"; - this.lblClosingConnections.Size = new System.Drawing.Size(136, 13); + this.lblClosingConnections.Size = new System.Drawing.Size(147, 13); this.lblClosingConnections.TabIndex = 0; this.lblClosingConnections.Text = "When closing connections:"; // @@ -199,7 +199,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.radCloseWarnAll.AutoSize = true; this.radCloseWarnAll.Location = new System.Drawing.Point(16, 34); this.radCloseWarnAll.Name = "radCloseWarnAll"; - this.radCloseWarnAll.Size = new System.Drawing.Size(194, 17); + this.radCloseWarnAll.Size = new System.Drawing.Size(209, 17); this.radCloseWarnAll.TabIndex = 1; this.radCloseWarnAll.TabStop = true; this.radCloseWarnAll.Text = "Warn me when closing connections"; @@ -210,7 +210,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.radCloseWarnMultiple.AutoSize = true; this.radCloseWarnMultiple.Location = new System.Drawing.Point(16, 57); this.radCloseWarnMultiple.Name = "radCloseWarnMultiple"; - this.radCloseWarnMultiple.Size = new System.Drawing.Size(254, 17); + this.radCloseWarnMultiple.Size = new System.Drawing.Size(279, 17); this.radCloseWarnMultiple.TabIndex = 2; this.radCloseWarnMultiple.TabStop = true; this.radCloseWarnMultiple.Text = "Warn me only when closing multiple connections"; @@ -221,7 +221,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.radCloseWarnExit.AutoSize = true; this.radCloseWarnExit.Location = new System.Drawing.Point(16, 80); this.radCloseWarnExit.Name = "radCloseWarnExit"; - this.radCloseWarnExit.Size = new System.Drawing.Size(216, 17); + this.radCloseWarnExit.Size = new System.Drawing.Size(233, 17); this.radCloseWarnExit.TabIndex = 3; this.radCloseWarnExit.TabStop = true; this.radCloseWarnExit.Text = "Warn me only when exiting mRemoteNG"; @@ -232,7 +232,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.radCloseWarnNever.AutoSize = true; this.radCloseWarnNever.Location = new System.Drawing.Point(16, 103); this.radCloseWarnNever.Name = "radCloseWarnNever"; - this.radCloseWarnNever.Size = new System.Drawing.Size(226, 17); + this.radCloseWarnNever.Size = new System.Drawing.Size(246, 17); this.radCloseWarnNever.TabIndex = 4; this.radCloseWarnNever.TabStop = true; this.radCloseWarnNever.Text = "Do not warn me when closing connections"; @@ -244,7 +244,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkSaveConnectionsAfterEveryEdit.AutoSize = true; this.chkSaveConnectionsAfterEveryEdit.Location = new System.Drawing.Point(3, 72); this.chkSaveConnectionsAfterEveryEdit.Name = "chkSaveConnectionsAfterEveryEdit"; - this.chkSaveConnectionsAfterEveryEdit.Size = new System.Drawing.Size(185, 17); + this.chkSaveConnectionsAfterEveryEdit.Size = new System.Drawing.Size(194, 17); this.chkSaveConnectionsAfterEveryEdit.TabIndex = 7; this.chkSaveConnectionsAfterEveryEdit.Text = "Save connections after every edit"; this.chkSaveConnectionsAfterEveryEdit.UseVisualStyleBackColor = true; @@ -255,7 +255,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkUseFilterSearch.AutoSize = true; this.chkUseFilterSearch.Location = new System.Drawing.Point(3, 95); this.chkUseFilterSearch.Name = "chkUseFilterSearch"; - this.chkUseFilterSearch.Size = new System.Drawing.Size(214, 17); + this.chkUseFilterSearch.Size = new System.Drawing.Size(230, 17); this.chkUseFilterSearch.TabIndex = 8; this.chkUseFilterSearch.Text = "Filter search matches in connection tree"; this.chkUseFilterSearch.UseVisualStyleBackColor = true; @@ -286,7 +286,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.chkPlaceSearchBarAboveConnectionTree.AutoSize = true; this.chkPlaceSearchBarAboveConnectionTree.Location = new System.Drawing.Point(3, 118); this.chkPlaceSearchBarAboveConnectionTree.Name = "chkPlaceSearchBarAboveConnectionTree"; - this.chkPlaceSearchBarAboveConnectionTree.Size = new System.Drawing.Size(216, 17); + this.chkPlaceSearchBarAboveConnectionTree.Size = new System.Drawing.Size(226, 17); this.chkPlaceSearchBarAboveConnectionTree.TabIndex = 8; this.chkPlaceSearchBarAboveConnectionTree.Text = "Place search bar above connection tree"; this.chkPlaceSearchBarAboveConnectionTree.UseVisualStyleBackColor = true; @@ -303,6 +303,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages this.Controls.Add(this.chkHostnameLikeDisplayName); this.Controls.Add(this.chkSingleClickOnOpenedConnectionSwitchesToIt); this.Controls.Add(this.pnlConfirmCloseConnection); + this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Name = "ConnectionsPage"; this.Size = new System.Drawing.Size(610, 490); ((System.ComponentModel.ISupportInitialize)(this.numRDPConTimeout)).EndInit(); diff --git a/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.resx b/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/mRemoteV1/UI/Forms/frmOptions.Designer.cs b/mRemoteV1/UI/Forms/frmOptions.Designer.cs index 658526aa..9858aad7 100644 --- a/mRemoteV1/UI/Forms/frmOptions.Designer.cs +++ b/mRemoteV1/UI/Forms/frmOptions.Designer.cs @@ -135,7 +135,7 @@ this.PageName.ImageAspectName = "IconImage"; this.PageName.IsEditable = false; // - // frmOptions + // FrmOptions // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; @@ -150,7 +150,7 @@ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; - this.Name = "frmOptions"; + this.Name = "FrmOptions"; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "mRemoteNG Options"; diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 997e8117..c6c63fd5 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -816,6 +816,9 @@ FrmInputBox.cs + + ConnectionsPage.cs + ThemePage.cs From 1ad46b484f36eb2059f8af617beb216624319de3 Mon Sep 17 00:00:00 2001 From: Sean Kaim Date: Wed, 2 Jan 2019 15:40:46 -0500 Subject: [PATCH 11/11] NGNumericUpDown Theming fix Fixes #1240 --- mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs index 4b6cec61..8a6ae2a2 100644 --- a/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs +++ b/mRemoteV1/UI/Controls/Base/NGNumericUpDown.cs @@ -11,7 +11,7 @@ namespace mRemoteNG.UI.Controls.Base internal class NGNumericUpDown : NumericUpDown { - private ThemeManager _themeManager; + private readonly ThemeManager _themeManager; private NGButton Up; private NGButton Down; @@ -28,23 +28,42 @@ namespace mRemoteNG.UI.Controls.Base ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Foreground"); BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TextBox_Background"); SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true); - //Hide those nonthemable butons + if (Controls.Count > 0) - Controls[0].Hide(); + { + for (var i = 0; i < Controls.Count; i++) + { + //Remove those non-themable buttons + if (Controls[i].GetType().ToString().Equals("System.Windows.Forms.UpDownBase+UpDownButtons")) + Controls.Remove(Controls[i]); + + /* This is a bit of a hack. + * But if we have the buttons that we created already, redraw/return and don't add any more... + * + * OptionsPages are an example where the control is potentially created twice: + * AddOptionsPagesToListView and then LstOptionPages_SelectedIndexChanged + */ + if (!(Controls[i] is NGButton)) continue; + if (!Controls[i].Text.Equals("\u25B2") && !Controls[i].Text.Equals("\u25BC")) continue; + Invalidate(); + return; + } + } + //Add new themable buttons Up = new NGButton { Text = "\u25B2", - Font = new Font(Font.FontFamily, 6f) + Font = new Font(Font.FontFamily, 5f) }; - Up.SetBounds(Width - 17, 1, 16, Height / 2 - 1); + Up.SetBounds(Controls.Owner.Width - 17, 2, 16, Controls.Owner.Height / 2 - 1); Up.Click += Up_Click; Down = new NGButton { Text = "\u25BC", - Font = new Font(Font.FontFamily, 6f) + Font = new Font(Font.FontFamily, 5f) }; - Down.SetBounds(Width - 17, Height/2, 16, Height / 2 - 1); + Down.SetBounds(Controls.Owner.Width - 17, Controls.Owner.Height /2 + 1, 16, Controls.Owner.Height / 2 - 1); Down.Click += Down_Click; Controls.Add(Up); Controls.Add(Down);