Exemplo n.º 1
0
        /// <summary>
        /// Tries to get a prefixed unit from a shortcut, considering all units in this environment.
        /// </summary>
        /// <param name="shortCut">The shortcut. Can be a compound of prefix and unit, e.g. 'mA'. An empty string is converted to <see cref="Altaxo.Units.Dimensionless.Unity.Instance"/></param>
        /// <param name="result">If successfully, the resulting prefixed unit.</param>
        /// <returns>True if the conversion was successful; false otherwise.</returns>
        /// <exception cref="ArgumentNullException">s</exception>
        public bool TryGetPrefixedUnitFromShortcut(string shortCut, out IPrefixedUnit result)
        {
            if (null == shortCut)
            {
                throw new ArgumentNullException(nameof(shortCut));
            }

            shortCut = shortCut.Trim();

            if ("" == shortCut) // If string is empty, we consider this as a dimensionless unit "Unity"
            {
                result = new PrefixedUnit(SIPrefix.None, Altaxo.Units.Dimensionless.Unity.Instance);
                return(true);
            }

            SIPrefix prefix = null;

            foreach (IUnit u in UnitsSortedByShortcutLengthDescending) // for each unit
            {
                if (string.IsNullOrEmpty(u.ShortCut) || (!shortCut.EndsWith(u.ShortCut)))
                {
                    continue;
                }

                var prefixString = shortCut.Substring(0, shortCut.Length - u.ShortCut.Length);

                if (prefixString.Length == 0) // if prefixString is empty, then it is the unit without prefix
                {
                    result = new PrefixedUnit(SIPrefix.None, u);
                    return(true);
                }

                prefix = SIPrefix.TryGetPrefixFromShortcut(prefixString);

                if (null != prefix) // we found a prefix, thus we can return prefix + unit
                {
                    result = new PrefixedUnit(prefix, u);
                    return(true);
                }
            }

            result = null;
            return(false);
        }
Exemplo n.º 2
0
        private ValidationResult ConvertValidate(string s, out DimensionfulQuantity result)
        {
            if (null != _lastConvertedQuantity && s == _lastConvertedString)
            {
                result = (DimensionfulQuantity)_lastConvertedQuantity;
                return(ValidateSuccessfullyConvertedQuantity(result));
            }

            result = new DimensionfulQuantity();
            double   parsedValue;
            SIPrefix prefix = null;

            s = s.Trim();

            if (_allowNaN && null != _representationOfNaN && s.Trim() == _representationOfNaN.Trim())
            {
                result = new DimensionfulQuantity(double.NaN, SIPrefix.None, _lastConvertedQuantity.HasValue ? _lastConvertedQuantity.Value.Unit : _unitEnvironment.DefaultUnit.Unit);
                return(ValidateSuccessfullyConvertedQuantity(result));
            }

            if (string.IsNullOrEmpty(s))
            {
                return(new ValidationResult(false, "The text box is empty. You have to enter a valid numeric quantity"));
            }

            foreach (IUnit u in _unitEnvironment.UnitsSortedByShortcutLengthDescending)
            {
                if (string.IsNullOrEmpty(u.ShortCut) || (!s.EndsWith(u.ShortCut)))
                {
                    continue;
                }

                s = s.Substring(0, s.Length - u.ShortCut.Length);

                if (!u.Prefixes.ContainsNonePrefixOnly && s.Length > 0)
                {
                    // try first prefixes of bigger length, then of smaller length
                    for (int pl = SIPrefix.MaxShortCutLength; pl > 0; --pl)
                    {
                        if (s.Length < pl)
                        {
                            continue;
                        }
                        prefix = SIPrefix.TryGetPrefixFromShortcut(s.Substring(s.Length - pl));
                        if (null != prefix)
                        {
                            s = s.Substring(0, s.Length - prefix.ShortCut.Length);
                            break;
                        }
                    }
                }

                if (double.TryParse(s, System.Globalization.NumberStyles.Float, _conversionCulture, out parsedValue))
                {
                    result = new DimensionfulQuantity(parsedValue, prefix, u);
                    return(ValidateSuccessfullyConvertedQuantity(result));
                }
                else
                {
                    string firstPart;
                    if (null != prefix)
                    {
                        firstPart = string.Format("The last part \"{0}\" of your entered text is recognized as prefixed unit, ", prefix.ShortCut + u.ShortCut);
                    }
                    else
                    {
                        firstPart = string.Format("The last part \"{0}\" of your entered text is recognized as unit, ", u.ShortCut);
                    }

                    string lastPart;
                    if (string.IsNullOrEmpty(s.Trim()))
                    {
                        lastPart = string.Format("but the first part is empty. You have to prepend a numeric value!");
                    }
                    else
                    {
                        lastPart = string.Format("but the first part \"{0}\" is not recognized as a numeric value!", s);
                    }

                    return(new ValidationResult(false, firstPart + lastPart));
                }
            }

            // if nothing is found in this way, we try to split the text
            var parts = s.Split(new char[] { ' ', '\t' }, 2, StringSplitOptions.RemoveEmptyEntries);

            // try to parse the first part as a number
            if (!double.TryParse(parts[0], System.Globalization.NumberStyles.Float, _conversionCulture, out parsedValue))
            {
                return(new ValidationResult(false, string.Format("The part \"{0}\" of your entered text was not recognized as a numeric value.", parts[0])));
            }

            string unitString = parts.Length >= 2 ? parts[1] : string.Empty;

            if (string.IsNullOrEmpty(unitString))
            {
                if (null != _lastConvertedQuantity)
                {
                    result = new DimensionfulQuantity(parsedValue, ((DimensionfulQuantity)_lastConvertedQuantity).Prefix, ((DimensionfulQuantity)_lastConvertedQuantity).Unit);
                    return(ValidateSuccessfullyConvertedQuantity(result));
                }
                else if (null != _unitEnvironment && null != _unitEnvironment.DefaultUnit)
                {
                    result = new DimensionfulQuantity(parsedValue, _unitEnvironment.DefaultUnit.Prefix, _unitEnvironment.DefaultUnit.Unit);
                    return(ValidateSuccessfullyConvertedQuantity(result));
                }
                else
                {
                    return(new ValidationResult(false, "No unit was given by you and no default unit could be deduced from the environment!"));
                }
            }
            else
            {
                return(new ValidationResult(false, GetErrorStringForUnrecognizedUnit(unitString)));
            }
        }