diff --git a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs index f7e6cf1e..b9ea7657 100644 --- a/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs +++ b/SolidDna/CADBooster.SolidDna/Errors/SolidDnaErrorCode.cs @@ -169,6 +169,11 @@ public enum SolidDnaErrorCode /// SolidWorksModelGetConfigurationError = 11014, + /// + /// Error occurred while trying to get a custom property value from a SolidWorks model + /// + SolidWorksModelGetPropertyError = 11030, + #endregion #region SolidWorks Command Manager (12,000) diff --git a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs index 71ba0c2b..e3245dc5 100644 --- a/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs +++ b/SolidDna/CADBooster.SolidDna/SolidWorks/CustomProperties/CustomPropertyEditor.cs @@ -1,6 +1,8 @@ using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; +using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; namespace CADBooster.SolidDna @@ -10,6 +12,12 @@ namespace CADBooster.SolidDna /// public class CustomPropertyEditor : SolidDnaObject { + /// + /// Gets or sets whether type checking is enabled when getting property values + /// When enabled, methods will verify the property type matches the expected type + /// By default is + /// + public bool IsTypeCheckEnabled { get; set; } = true; #region Constructor /// @@ -26,7 +34,7 @@ public CustomPropertyEditor(CustomPropertyManager model) : base(model) /// Checks if a custom property exists /// /// The name of the custom property - /// + /// If the property exists , otherwise public bool CustomPropertyExists(string name) { // TODO: Add error checking and exception catching @@ -39,18 +47,156 @@ public bool CustomPropertyExists(string name) /// /// The name of the custom property /// True to resolve the custom property value - /// + /// The property value as a string public string GetCustomProperty(string name, bool resolve = false) { // TODO: Add error checking and exception catching // Get custom property - BaseObject.Get5(name, false, out var val, out var resolvedVal, out var wasResolved); + _ = BaseObject.Get5(name, false, out var val, out var resolvedVal, out _); // Return desired result return resolve ? resolvedVal : val; } + /// + /// Gets a string value from a custom property + /// + /// The name of the custom property + /// Whether to resolve the value (evaluate equations/formulas) + /// The string value of the property + /// Thrown if type checking is enabled and the property is not of text type + public string GetStringCustomProperty(string name, bool resolve = false) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoText, true); + + _ = BaseObject.Get5(name, false, out var val, out var resolvedVal, out _); + + return resolve ? resolvedVal : val; + } + + /// + /// Gets a DateTime value from a date-type custom property + /// + /// The name of the custom property + /// The parsed DateTime value + /// Thrown if type checking is enabled and the property is not of date type + public DateTime GetDateCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoDate); + + + _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _); + + return DateTime.Parse(resolvedVal); + } + + /// + /// Gets an integer value from a number-type custom property + /// + /// The name of the custom property + /// The parsed integer value + /// Thrown if type checking is enabled and the property is not of number type + public int GetIntegerCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber); + + + _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _); + + return int.Parse(resolvedVal); + } + + /// + /// Gets a double value from a number-type custom property + /// + /// The name of the custom property + /// The parsed double value + /// Thrown if type checking is enabled and the property is not of number type + public double GetDoubleCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoNumber); + + + _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _); + + return double.Parse(resolvedVal, CultureInfo.InvariantCulture); + } + + /// + /// Gets a boolean value from a yes/no-type custom property + /// + /// The name of the custom property + /// The boolean value ( for "Yes", for "No") + /// Thrown if type checking is enabled and the property is not of yes/no type + public bool GetBooleanCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoYesOrNo); + + _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _); + + switch (resolvedVal) + { + case "Yes": + return true; + case "No": + return false; + default: + throw new InvalidOperationException(); + } + } + + /// + /// Gets the raw equation text from an equation-type custom property + /// + /// The name of the custom property + /// The raw equation text + /// Thrown if type checking is enabled and the property is not of equation type + public string GetRawEquationCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoEquation, true); + + _ = BaseObject.Get5(name, false, out var val, out _, out _); + + return val; + } + + /// + /// Gets the evaluated result of an equation-type custom property + /// + /// The name of the custom property + /// The evaluated numeric result + /// Thrown if type checking is enabled and the property is not of equation type + public double GetEvaluatedEquationCustomProperty(string name) + { + // TODO: Add error checking and exception catching + + if (IsTypeCheckEnabled) + ThrowIfExpectedTypeMismatch(name, swCustomInfoType_e.swCustomInfoEquation); + + _ = BaseObject.Get5(name, false, out _, out var resolvedVal, out _); + + return double.Parse(resolvedVal, CultureInfo.InvariantCulture); + } + /// /// Sets the value of a custom property by name /// @@ -72,9 +218,57 @@ public void SetCustomProperty(string name, string value, swCustomInfoType_e type // // Set new one - BaseObject.Add3(name, (int)type, value, (int)swCustomPropertyAddOption_e.swCustomPropertyReplaceValue); + _ = BaseObject.Add3(name, (int)type, value, (int)swCustomPropertyAddOption_e.swCustomPropertyReplaceValue); } + /// + /// Sets a string value to a text-type custom property + /// + /// The name of the custom property + /// The string value to set + public void SetStringCustomProperty(string name, string value) + => SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoText); + + /// + /// Sets a date value to a date-type custom property, time data is ignored + /// + /// The name of the custom property + /// The date value to set + public void SetDateCustomProperty(string name, DateTime value) + => SetCustomProperty(name, value.Date.ToShortDateString(), swCustomInfoType_e.swCustomInfoDate); + + /// + /// Sets an integer value to a number-type custom property + /// + /// The name of the custom property + /// The integer value to set + public void SetIntegerCustomProperty(string name, int value) + => SetCustomProperty(name, value.ToString(), swCustomInfoType_e.swCustomInfoNumber); + + /// + /// Sets a double value to a number-type custom property + /// + /// The name of the custom property + /// The double value to set + public void SetDoubleCustomProperty(string name, double value) + => SetCustomProperty(name, value.ToString(CultureInfo.InvariantCulture), swCustomInfoType_e.swCustomInfoDouble); + + /// + /// Sets a boolean value to a yes/no-type custom property ("Yes" for , "No" for ) + /// + /// The name of the custom property + /// The boolean value to set + public void SetBooleanCustomProperty(string name, bool value) + => SetCustomProperty(name, value ? "Yes" : "No", swCustomInfoType_e.swCustomInfoYesOrNo); + + /// + /// Sets an equation/formula to an equation-type custom property + /// + /// The name of the custom property + /// The equation text to set + public void SetEquationCustomProperty(string name, string value) + => SetCustomProperty(name, value, swCustomInfoType_e.swCustomInfoEquation); + /// /// Deletes a custom property by name /// @@ -107,5 +301,27 @@ public List GetCustomProperties() // Return the list return list; } + + /// + /// Throws an exception if the actual property type doesn't match the expected type + /// + /// The name of the property to check + /// The expected property type + /// Whether to allow unknown/untyped properties + /// Thrown if the property type doesn't match the expected type + private void ThrowIfExpectedTypeMismatch(string name, swCustomInfoType_e expectedType, bool allowUnknown = false) + { + var type = (swCustomInfoType_e)BaseObject.GetType2(name); + + if (allowUnknown && type == swCustomInfoType_e.swCustomInfoUnknown) + return; + + if (type != expectedType) + { + throw new SolidDnaException(SolidDnaErrors.CreateError( + SolidDnaErrorTypeCode.SolidWorksModel, SolidDnaErrorCode.SolidWorksModelError, + $"Property has different type that expected. Received: {type}, expected: {expectedType}")); + } + } } }