diff --git a/mRemoteNG/Connection/AbstractConnectionRecord.cs b/mRemoteNG/Connection/AbstractConnectionRecord.cs index 873d8caa..c354a553 100644 --- a/mRemoteNG/Connection/AbstractConnectionRecord.cs +++ b/mRemoteNG/Connection/AbstractConnectionRecord.cs @@ -23,6 +23,7 @@ namespace mRemoteNG.Connection private string _description; private string _icon; private string _panel; + private string _color; private string _tabColor; private string _hostname; @@ -156,6 +157,14 @@ namespace mRemoteNG.Connection } [LocalizedAttributes.LocalizedCategory(nameof(Language.Display)), + LocalizedAttributes.LocalizedDisplayName(nameof(Language.Color)), + LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionColor)), + Editor(typeof(System.Drawing.Design.ColorEditor), typeof(System.Drawing.Design.UITypeEditor)), + TypeConverter(typeof(System.Drawing.ColorConverter))] + public virtual string Color + { + get => GetPropertyValue("Color", _color); + set => SetField(ref _color, value, "Color"); LocalizedAttributes.LocalizedDisplayName(nameof(Language.TabColor)), LocalizedAttributes.LocalizedDescription(nameof(Language.PropertyDescriptionTabColor)), TypeConverter(typeof(MiscTools.TabColorConverter))] diff --git a/mRemoteNG/Connection/ConnectionInfo.cs b/mRemoteNG/Connection/ConnectionInfo.cs index 13d0ad24..5e35c122 100644 --- a/mRemoteNG/Connection/ConnectionInfo.cs +++ b/mRemoteNG/Connection/ConnectionInfo.cs @@ -292,7 +292,8 @@ namespace mRemoteNG.Connection Description = Settings.Default.ConDefaultDescription; Icon = Settings.Default.ConDefaultIcon; Panel = Language.General; - TabColor = ""; + Color = string.Empty; + TabColor = string.Empty; } private void SetConnectionDefaults() diff --git a/mRemoteNG/Connection/ConnectionInfoInheritance.cs b/mRemoteNG/Connection/ConnectionInfoInheritance.cs index ec2ca3ea..1e0a2848 100644 --- a/mRemoteNG/Connection/ConnectionInfoInheritance.cs +++ b/mRemoteNG/Connection/ConnectionInfoInheritance.cs @@ -51,6 +51,10 @@ namespace mRemoteNG.Connection public bool Panel { get; set; } [LocalizedAttributes.LocalizedCategory(nameof(Language.Display), 2), + LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.Color)), + LocalizedAttributes.LocalizedDescriptionInherit(nameof(Language.PropertyDescriptionColor)), + TypeConverter(typeof(MiscTools.YesNoTypeConverter))] + public bool Color { get; set; } LocalizedAttributes.LocalizedDisplayNameInherit(nameof(Language.TabColor)), LocalizedAttributes.LocalizedDescriptionInherit(nameof(Language.PropertyDescriptionTabColor)), TypeConverter(typeof(MiscTools.YesNoTypeConverter))] diff --git a/mRemoteNG/Language/Language.Designer.cs b/mRemoteNG/Language/Language.Designer.cs index ca13aaa6..8b75827c 100644 --- a/mRemoteNG/Language/Language.Designer.cs +++ b/mRemoteNG/Language/Language.Designer.cs @@ -609,6 +609,15 @@ namespace mRemoteNG.Resources.Language { } } + /// + /// Looks up a localized string similar to Color. + /// + internal static string Color { + get { + return ResourceManager.GetString("Color", resourceCulture); + } + } + /// /// Looks up a localized string similar to Cannot start Port Scan, incorrect IP format!. /// @@ -3774,6 +3783,15 @@ namespace mRemoteNG.Resources.Language { } } + /// + /// Looks up a localized string similar to Sets the color for the connection or folder in the connections tree. Connections inherit this color from their parent folder.. + /// + internal static string PropertyDescriptionColor { + get { + return ResourceManager.GetString("PropertyDescriptionColor", resourceCulture); + } + } + /// /// Looks up a localized string similar to Select the color quality to be used.. /// diff --git a/mRemoteNG/Language/Language.resx b/mRemoteNG/Language/Language.resx index 9a51b4b8..fe2cd457 100644 --- a/mRemoteNG/Language/Language.resx +++ b/mRemoteNG/Language/Language.resx @@ -1023,6 +1023,8 @@ If you run into such an error, please create a new connection file! Sets the panel in which the connection will open. + + Sets the color for the connection or folder in the connections tree. Connections inherit this color from their parent folder. Sets the color of the connection tab. Leave empty for default theme color. @@ -1143,6 +1145,9 @@ If you run into such an error, please create a new connection file! Cache Bitmaps + + Color + Colors diff --git a/mRemoteNG/UI/Controls/ConnectionTree/ConnectionTree.cs b/mRemoteNG/UI/Controls/ConnectionTree/ConnectionTree.cs index eda16cc7..b5d38574 100644 --- a/mRemoteNG/UI/Controls/ConnectionTree/ConnectionTree.cs +++ b/mRemoteNG/UI/Controls/ConnectionTree/ConnectionTree.cs @@ -166,6 +166,7 @@ namespace mRemoteNG.UI.Controls.ConnectionTree ModelDropped += _dragAndDropHandler.HandleEvent_ModelDropped; BeforeLabelEdit += OnBeforeLabelEdit; AfterLabelEdit += OnAfterLabelEdit; + FormatCell += ConnectionTree_FormatCell; } /// @@ -512,6 +513,27 @@ namespace mRemoteNG.UI.Controls.ConnectionTree _contextMenu.DisableShortcutKeys(); } + private void ConnectionTree_FormatCell(object sender, FormatCellEventArgs e) + { + if (e.Model is not ConnectionInfo connectionInfo) + return; + + string colorString = connectionInfo.Color; + if (string.IsNullOrEmpty(colorString)) + return; + + try + { + System.Drawing.ColorConverter converter = new(); + System.Drawing.Color color = (System.Drawing.Color)converter.ConvertFromString(colorString); + e.SubItem.ForeColor = color; + } + catch + { + // If color parsing fails, just ignore and use default color + } + } + private void OnAfterLabelEdit(object sender, LabelEditEventArgs e) { if (!_nodeInEditMode) diff --git a/mRemoteNGDocumentation/folders_and_inheritance.rst b/mRemoteNGDocumentation/folders_and_inheritance.rst index f9345fdb..4805420c 100644 --- a/mRemoteNGDocumentation/folders_and_inheritance.rst +++ b/mRemoteNGDocumentation/folders_and_inheritance.rst @@ -57,3 +57,22 @@ Only the Name and Hostname/IP properties are left over, everything else will be inherited from the parent folder. Of course you can also only let some of the properties be inherited. Just play around with this a bit and you'll get the hang of it. + +Color Property +============== +You can set a color for each connection or folder in the connections list. +This makes things clearer when you have many connections. + +To set a color: + +1. Select a connection or folder in the connections tree +2. In the properties panel, find the **Color** property under the Display category +3. Click on the color value and select a color from the color picker + +When you set a color on a folder, all connections under that folder can inherit the same color +if their Color inheritance is enabled. This provides a visual way to group and identify +related connections in the tree view. + +.. note:: + The Color property can be inherited just like other properties. Enable inheritance + in the inheritance view to have connections automatically use their parent folder's color. diff --git a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs index ec9c865c..6accecac 100644 --- a/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs +++ b/mRemoteNGTests/IntegrationTests/ConnectionInheritanceIntegrationTests.cs @@ -68,5 +68,29 @@ namespace mRemoteNGTests.IntegrationTests folder3.AddChild(connection); Assert.That(connection.Icon, Is.EqualTo(folder1.Icon)); } + + [Test] + public void ConnectionInheritsColorFromFolder() + { + var folder = new ContainerInfo { Color = "Red" }; + var connection = new ConnectionInfo { Inheritance = { Color = true } }; + _rootNode.AddChild(folder); + folder.AddChild(connection); + Assert.That(connection.Color, Is.EqualTo(folder.Color)); + } + + [Test] + public void CanInheritColorThroughMultipleFolderLevels() + { + var folder1 = new ContainerInfo { Color = "Blue" }; + var folder2 = new ContainerInfo { Inheritance = { Color = true } }; + var folder3 = new ContainerInfo { Inheritance = { Color = true } }; + var connection = new ConnectionInfo { Inheritance = { Color = true } }; + _rootNode.AddChild(folder1); + folder1.AddChild(folder2); + folder2.AddChild(folder3); + folder3.AddChild(connection); + Assert.That(connection.Color, Is.EqualTo(folder1.Color)); + } } } \ No newline at end of file