// Copyright Keysight Technologies 2012-2019
// 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.Globalization;
using System.Linq;
using OpenTap.Translation;
namespace OpenTap
{
///
/// Defines how a property, class, enum, or other item is presented to the user.
/// Also configures the description and allows items to be grouped and ordered.
///
public class DisplayAttribute : Attribute, IDisplayAnnotation
{
internal const string GroupSeparator = " \\ ";
/// Optional text that provides a description of the item.
/// Consider using HelpLinkAttribute if a link to documentation is needed.
///
public string Description { get; }
/// Optional text used to group displayed items.
/// Use 'Groups' if more than one level of grouping is needed.
///
public string[] Group { get; }
/// Name displayed by the UI.
public string Name { get; }
/// The language of this attribute..
public CultureInfo Language { get; }
/// Optional double that ranks items and groups in ascending order relative to other items/groups.
/// Default is -10000. For a group, the order is the average order of the elements inside the group.
/// Any double value is allowed. Items with same order are ranked alphabetically.
///
///
/// This applies only to properties. Classes will ignore this setting and be ordered alphabetically.
///
public double Order { get; }
/// Boolean setting that indicates whether a group's default appearance is collapsed.
/// Default is 'false' (group is expanded).
///
public bool Collapsed { get; }
/// If the owning DisplayAttribute is a translated display attribute, this property will be set to the neutral (non-translated) variant.
/// If the owning DisplayAttribute is not translated, this will be null.
///
public DisplayAttribute NeutralDisplayAttribute { get; internal set; }
string fullName = null;
/// Gets the Group (or Groups) and Name concatenated with a backslash (\).
public string GetFullName()
{
if(fullName == null)
{
if (Group.Length == 0)
fullName = Name;
else
fullName = string.Join(GroupSeparator, Group.Append(Name));
}
return fullName;
}
///
/// The default order for display attribute. This is set in this way to highlight the fact that
/// an order is not set and out of the range of normally selected order values. '0' for example
/// is a commonly selected value for order, so it could not be that.
///
public const double DefaultOrder = -10000.0;
///
/// Creates a new instance of . Ensures that Name is never null.
///
/// Name displayed by the UI.
/// Optional text that provides a description of the item. Consider using HelpLinkAttribute if a link to documentation is needed.
/// Optional text used to group displayed items. Use 'Groups' if more than one level of grouping is needed.
/// Optional double that ranks items and groups in ascending order relative to other items/groups. Default is defined by DisplayAttribute.DefaultOrder.
/// For a group, the order is the average order of the elements inside the group. Any double value is allowed. Items with same order are ranked alphabetically.
/// Boolean setting that indicates whether a group's default appearance is collapsed. Default is 'false' (group is expanded).
/// Optional array of text strings to specify multiple levels of grouping. Use 'Group' if only one level of grouping is needed.
public DisplayAttribute(string Name, string Description = null, string Group = null, double Order = DefaultOrder, bool Collapsed = false, string[] Groups = null)
{
this.Name = Name ?? throw new ArgumentNullException(nameof(Name));
this.Description = Description;
if (Groups != null)
this.Group = Groups;
else if (Group != null)
this.Group = new[] { Group };
else this.Group = Array.Empty();
this.Order = Order;
this.Collapsed = Collapsed;
this.Language = TranslationManager.NeutralLanguage;
}
///
/// Creates a new instance of . Ensures that Name is never null.
///
/// Name displayed by the UI.
/// Optional text that provides a description of the item. Consider using HelpLinkAttribute if a link to documentation is needed.
/// Optional text used to group displayed items. Use 'Groups' if more than one level of grouping is needed.
/// Optional double that ranks items and groups in ascending order relative to other items/groups. Default is defined by DisplayAttribute.DefaultOrder.
/// For a group, the order is the average order of the elements inside the group. Any double value is allowed. Items with same order are ranked alphabetically.
/// Boolean setting that indicates whether a group's default appearance is collapsed. Default is 'false' (group is expanded).
/// Optional array of text strings to specify multiple levels of grouping. Use 'Group' if only one level of grouping is needed.
/// The language of this attribute.
public DisplayAttribute(CultureInfo Language, string Name, string Description = null, string Group = null, double Order = DefaultOrder, bool Collapsed = false, string[] Groups = null) : this(Name, Description, Group, Order, Collapsed, Groups)
{
this.Language = Language;
}
/// Overriding Equals to fix strange equality issues between instances of DisplayAttribute.
public override bool Equals(object obj)
{
if(object.ReferenceEquals(this, obj)) return true;
if (obj is DisplayAttribute other)
return other.Name == Name && Group.SequenceEqual(other.Group) && other.Description == Description && other.Order == Order;
return false;
}
/// Generates a hash code based on the display attribute values.
public override int GetHashCode()
{
int h = Name.GetHashCode();
foreach (var elem in Group)
h = h * 31241231 + elem.GetHashCode();
return h;
}
}
}