diff --git a/Sources/AddOn/Helpers.cpp b/Sources/AddOn/Helpers.cpp index 30ce4ec..7cbb3b6 100644 --- a/Sources/AddOn/Helpers.cpp +++ b/Sources/AddOn/Helpers.cpp @@ -1385,53 +1385,50 @@ void ParamHelpers::SetParamValueSourseByName(ParamValue & pvalue) { if (pvalue.rawName.Contains("{@id")) pvalue.fromID = true; } -// ----------------------------------------------------------------------------- -// Добавление пустого значения в словарь ParamDictValue -// ----------------------------------------------------------------------------- -GS::UniString ParamHelpers::AddValueToParamDictValue(ParamDictValue & params, const GS::UniString & name) { - if (name.IsEmpty()) return ""; +GS::UniString ParamHelpers::NameToRawName (const GS::UniString& name, FormatString& formatstring) { + if(name.IsEmpty ()) return ""; GS::UniString rawname_prefix = ""; - GS::UniString name_ = name.ToLowerCase(); + GS::UniString name_ = name.ToLowerCase (); // Ищём строку с указанием формата вывода (метры/миллиметры) - GS::UniString stringformat = GetFormatString(name_); - name_ = GetPropertyENGName(name_).ToLowerCase(); + GS::UniString stringformat = GetFormatString (name_); + formatstring = PropertyHelpers::ParseFormatString (stringformat); + name_ = GetPropertyENGName (name_).ToLowerCase (); // Проверяем - есть ли указатель на тип параметра (GDL, Property, IFC) - if (name_.Contains(":")) { + if(name_.Contains (":")) { GS::Array partstring; - UInt32 n = StringSplt(name_, ":", partstring); - if (n > 1) { + UInt32 n = StringSplt (name_, ":", partstring); + if(n > 1) { rawname_prefix = partstring[0] + ":"; - name_ = partstring[1].ToLowerCase(); + name_ = partstring[1].ToLowerCase (); } } - if (rawname_prefix.IsEmpty()) rawname_prefix = "@gdl:"; - if (!rawname_prefix.Contains("@")) - { + if(rawname_prefix.IsEmpty ()) rawname_prefix = "@gdl:"; + if(!rawname_prefix.Contains ("@")) { rawname_prefix = "@" + rawname_prefix; } - // Ищём строку с указанием формата вывода (метры/миллиметры) GS::UniString rawName = "{" + rawname_prefix + name_ + "}"; - if (!params.ContainsKey(rawName)) { + return rawName; +} + + +// ----------------------------------------------------------------------------- +// Добавление пустого значения в словарь ParamDictValue +// ----------------------------------------------------------------------------- +void ParamHelpers::AddValueToParamDictValue (ParamDictValue& params, const GS::UniString& name) { + if(name.IsEmpty ()) return; + FormatString formatstring; + GS::UniString rawName = ParamHelpers::NameToRawName (name, formatstring); + if(!params.ContainsKey (rawName)) { ParamValue pvalue; + GS::UniString name_ = name.ToLowerCase (); pvalue.rawName = rawName; pvalue.name = name_; - if (!stringformat.IsEmpty()) { // Если строка не пустая - посмотрим количество знаков после запятой - Int32 n_zero = 3; - Int32 krat = 0; - double koeff = 1; - bool trim_zero = true; - PropertyHelpers::ParseFormatString(stringformat, n_zero, krat, koeff, trim_zero); - UNUSED_VARIABLE(krat); UNUSED_VARIABLE(koeff); UNUSED_VARIABLE(trim_zero); - pvalue.val.stringformat = stringformat; - pvalue.val.n_zero = n_zero; - } - params.Add(rawName, pvalue); - return rawName; + pvalue.val.formatstring = formatstring; + params.Add (rawName, pvalue); } - return rawName; } bool ParamHelpers::needAdd(ParamDictValue & params, GS::UniString & rawName) { @@ -1465,16 +1462,16 @@ void ParamHelpers::AddParamValue2ParamDictElement(const ParamValue & param, Para // -------------------------------------------------------------------- // Сопоставляет параметры // -------------------------------------------------------------------- -bool ParamHelpers::CompareParamValue(ParamValue & paramFrom, ParamValue & paramTo, GS::UniString stringformat) { +bool ParamHelpers::CompareParamValue(ParamValue & paramFrom, ParamValue & paramTo, FormatString stringformat) { if (!paramFrom.isValid) return false; if (paramTo.isValid || paramTo.fromProperty || paramTo.fromPropertyDefinition) { - if (stringformat.IsEmpty()) stringformat = paramTo.val.stringformat; - if (stringformat.IsEmpty()) stringformat = paramFrom.val.stringformat; + if (stringformat.isEmpty) stringformat = paramTo.val.formatstring; + if (stringformat.isEmpty) stringformat = paramFrom.val.formatstring; // Приводим к единому виду перед проверкой - if (!stringformat.IsEmpty()) { - paramTo.val.stringformat = stringformat; - paramFrom.val.stringformat = stringformat; + if (!stringformat.isEmpty) { + paramTo.val.formatstring = stringformat; + paramFrom.val.formatstring = stringformat; ParamHelpers::ConvertByFormatString(paramTo); ParamHelpers::ConvertByFormatString(paramFrom); } @@ -2171,8 +2168,11 @@ GS::UniString GetFormatString(GS::UniString & paramName) { GS::UniString meterString = RSGetIndString(ID_ADDON_STRINGS + isEng(), MeterStringID, ACAPI_GetOwnResModule()); if (n > 1) { formatstring = partstring[n - 1]; - if (partstring[n - 1].Contains('m') || partstring[n - 1].Contains(meterString)) { - formatstring = partstring[n - 1]; + if (formatstring.Contains('m') || formatstring.Contains(meterString)) { + if(formatstring.Contains (CharENTER)) { + UIndex attribinx = formatstring.FindLast(CharENTER); + formatstring = formatstring.GetSubstring(0, attribinx); + } paramName.ReplaceAll('.' + formatstring, ""); formatstring.ReplaceAll(meterString, "m"); meterString = RSGetIndString(ID_ADDON_STRINGS + isEng(), DMeterStringID, ACAPI_GetOwnResModule()); @@ -2277,12 +2277,30 @@ bool ParamHelpers::ParseParamName(GS::UniString & expression, ParamDictValue & p GS::UniString tempstring = expression; if (!tempstring.Contains('{')) return false; GS::UniString part = ""; - while (tempstring.Contains('{') && tempstring.Contains('}')) { + bool flag_change = true; + while (tempstring.Contains('{') && tempstring.Contains('}') && flag_change) { + GS::UniString expression_old = tempstring; part = tempstring.GetSubstring('{', '}', 0); + GS::UniString part_clean = part; // TODO Переписать всю эту хреноту - отделить парсинг от добавления в словарь - GS::UniString part_ = ParamHelpers::AddValueToParamDictValue(paramDict, part); + FormatString formatstring; + GS::UniString part_ = ParamHelpers::NameToRawName (part_clean, formatstring); + if(!paramDict.ContainsKey (part_)) { + ParamValue pvalue; + GS::UniString name_ = part_clean.ToLowerCase (); + pvalue.rawName = part_; + pvalue.name = name_; + pvalue.val.formatstring = formatstring; + paramDict.Add (part_, pvalue); + } + if(!formatstring.isEmpty) { + part_.ReplaceAll ("}", "."+ formatstring.stringformat+"}"); + } expression.ReplaceAll('{' + part + '}', part_); tempstring.ReplaceAll('{' + part + '}', ""); + if(expression_old.IsEqual (tempstring)) { + flag_change = false; + } } return true; } @@ -2302,14 +2320,21 @@ bool ParamHelpers::ReplaceParamInExpression(const ParamDictValue & pdictvalue, G GS::UniString partc = ""; GS::UniString parts = ""; GS::UniString val = ""; - while (expression.Contains('{') && expression.Contains('}')) { + bool flag_change = true; + while (expression.Contains('{') && expression.Contains('}') && flag_change) { + GS::UniString expression_old = expression; part = expression.GetSubstring('{', '}', 0); - partc = '{' + part + '}'; - parts = '{' + part + attribsuffix; + GS::UniString part_clean = part; + FormatString formatstring; + GS::UniString stringformat = GetFormatString (part_clean); + if(!stringformat.IsEmpty()) formatstring = PropertyHelpers::ParseFormatString (stringformat); + partc = '{' + part_clean + '}'; + parts = '{' + part_clean + attribsuffix; val = ""; if (pdictvalue.ContainsKey(parts)) { ParamValue pvalue = pdictvalue.Get(parts); if (pvalue.isValid) { + if(!formatstring.isEmpty) pvalue.val.formatstring = formatstring; val = ParamHelpers::ToString(pvalue); flag_find = true; } @@ -2318,12 +2343,14 @@ bool ParamHelpers::ReplaceParamInExpression(const ParamDictValue & pdictvalue, G if (pdictvalue.ContainsKey(partc)) { ParamValue pvalue = pdictvalue.Get(partc); if (pvalue.isValid) { + if(!formatstring.isEmpty) pvalue.val.formatstring = formatstring; val = ParamHelpers::ToString(pvalue); flag_find = true; } } } expression.ReplaceAll('{' + part + '}', val); + if(expression_old.IsEqual (expression)) flag_change = false; } return flag_find; } @@ -2397,12 +2424,22 @@ bool MenuInvertItemMark(short menuResID, short itemIndex) { return (bool)((itemFlags & API_MenuItemChecked) != 0); } -void PropertyHelpers::ParseFormatString(const GS::UniString & stringformat, Int32 & n_zero, Int32 & krat, double& koeff, bool& trim_zero) { - n_zero = 3; - krat = 0; - koeff = 1; - trim_zero = true; +//void PropertyHelpers::ParseFormatString (FormatString& stringformat) { +// if(!stringformat.isEmpty&& !stringformat.isRead) { +// GS::UniString f = stringformat.stringformat; +// stringformat = PropertyHelpers::ParseFormatString (f); +// } +//} + +FormatString PropertyHelpers::ParseFormatString(const GS::UniString & stringformat) { + int n_zero = 3; + Int32 krat = 0; // Крутность округления + double koeff = 1; //Коэфф. увеличения + bool trim_zero = true; //Требуется образать нули после запятой + FormatString format; + format.stringformat = stringformat; GS::UniString outstringformat = stringformat; + format.isEmpty = true; if (!stringformat.IsEmpty()) { if (stringformat.Contains("mm")) { n_zero = 0; @@ -2451,35 +2488,47 @@ void PropertyHelpers::ParseFormatString(const GS::UniString & stringformat, Int3 n_zero = std::atoi(outstringformat.ToCStr()); } } + format.isEmpty = false; + format.isRead = true; } + format.n_zero = n_zero; + format.krat = krat; + format.koeff = koeff; + format.trim_zero = trim_zero; + return format; } // TODO Придумать более изящную обработку округления -GS::UniString PropertyHelpers::NumToString(const double& var, const GS::UniString & stringformat) { +GS::UniString PropertyHelpers::NumToString(const double& var, const FormatString& stringformat) { if (fabs(var) < 0.00000001) return "0"; GS::UniString out = ""; - Int32 n_zero = 3; - Int32 krat = 0; - double koeff = 1; - bool trim_zero = true; - PropertyHelpers::ParseFormatString(stringformat, n_zero, krat, koeff, trim_zero); + Int32 n_zero = stringformat.n_zero; + Int32 krat = stringformat.krat; + double koeff = stringformat.koeff; + bool trim_zero = stringformat.trim_zero; + GS::UniString delimetr = stringformat.delimetr; double outvar = var * koeff; outvar = round(outvar * pow(10, n_zero)) / pow(10, n_zero); if (krat > 0) outvar = ceil_mod((GS::Int32)var, krat); out = GS::UniString::Printf("%f", outvar); - out.ReplaceAll(".", ","); + out.ReplaceAll(".", delimetr); + out.ReplaceAll (",", delimetr); out.TrimRight('0'); if (trim_zero) { - out.TrimRight(','); + out.TrimRight(delimetr.GetChar(0)); } else { - Int32 addzero = n_zero - (out.GetLength() - out.FindFirst(',') - 1); - if (addzero > 0) out = out + GS::UniString::Printf("%*s", addzero, "0"); + Int32 addzero = n_zero - (out.GetLength() - out.FindFirst(delimetr.GetChar (0)) - 1); + if(addzero > 0) { + for(Int32 i = 0; i < addzero; i++) { + out = out + "0"; + } + } } return out; } -GS::UniString PropertyHelpers::ToString(const API_Variant & variant, const GS::UniString & stringformat) { +GS::UniString PropertyHelpers::ToString(const API_Variant & variant, const FormatString& stringformat) { switch (variant.type) { case API_PropertyIntegerValueType: return NumToString(variant.intValue, stringformat); case API_PropertyRealValueType: return NumToString(variant.doubleValue, stringformat); @@ -2492,14 +2541,16 @@ GS::UniString PropertyHelpers::ToString(const API_Variant & variant, const GS::U } GS::UniString PropertyHelpers::ToString(const API_Variant & variant) { - return PropertyHelpers::ToString(variant, ""); + FormatString f; + return PropertyHelpers::ToString(variant, f); } GS::UniString PropertyHelpers::ToString(const API_Property & property) { - return PropertyHelpers::ToString(property, ""); + FormatString f; + return PropertyHelpers::ToString(property, f); } -GS::UniString PropertyHelpers::ToString(const API_Property & property, const GS::UniString & stringformat) { +GS::UniString PropertyHelpers::ToString(const API_Property & property, const FormatString& stringformat) { GS::UniString string; const API_PropertyValue* value; #if defined(AC_22) || defined(AC_23) @@ -3085,7 +3136,7 @@ void ParamHelpers::InfoWrite(ParamDictElement & paramToWrite) { for (GS::HashTable::PairIterator cIt = paramsinfo.EnumeratePairs(); cIt != NULL; ++cIt) { ParamValue& param = *cIt->value; GS::UniString dbKey = param.name; - GS::UniString value = ParamHelpers::ToString(param, param.val.stringformat); + GS::UniString value = ParamHelpers::ToString(param, param.val.formatstring); GSErrCode err = NoError; #ifdef AC_27 err = ACAPI_AutoText_SetAnAutoText(&dbKey, &value); @@ -3887,6 +3938,7 @@ bool ParamHelpers::ReadIDValues(const API_Elem_Head & elem_head, ParamDictValue param.val.intValue = !infoString.IsEmpty(); param.val.doubleValue = param.val.intValue * 1.0; } + param.val.rawDoubleValue = param.val.doubleValue; param.val.uniStringValue = infoString; params.Set(param.rawName, param); return true; @@ -4243,13 +4295,13 @@ bool ParamHelpers::ReadMaterial(const API_Element & element, ParamDictValue & pa GS::UniString layer_thickness = "{@material:layer thickness}"; if (params.ContainsKey(layer_thickness)) { double fillThick = param_composite.composite[indx].fillThick; - GS::UniString formatsting = params.Get(layer_thickness).val.stringformat; - if (formatsting.IsEmpty()) { - formatsting = "1mm"; - params.Get(layer_thickness).val.stringformat = formatsting; - params.Get(layer_thickness).val.n_zero = 1; + FormatString formatsting = params.Get(layer_thickness).val.formatstring; + if (formatsting.isEmpty) { + formatsting = PropertyHelpers::ParseFormatString ("1mm"); + params.Get(layer_thickness).val.formatstring = formatsting; } GS::UniString fillThickstring = PropertyHelpers::NumToString(fillThick, formatsting); + if(!formatsting.isEmpty) layer_thickness.ReplaceAll ("}", "." + formatsting.stringformat + "}"); templatestring.ReplaceAll(layer_thickness, fillThickstring); } templatestring.ReplaceAll("{@material:n}", GS::UniString::Printf("%d", i + 1)); @@ -4357,6 +4409,7 @@ void ParamHelpers::Array2ParamValue(GS::Array&pvalue, ParamValue } pvalrezult.boolValue = param_bool; pvalrezult.doubleValue = param_real; + pvalrezult.rawDoubleValue = param_real; pvalrezult.intValue = param_int; pvalrezult.canCalculate = canCalculate; } @@ -4410,11 +4463,9 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar param_string = GS::UniString::Printf("%d", param_int); pvalue.type = API_PropertyIntegerValueType; pvalue.canCalculate = true; - pvalue.n_zero = 0; - pvalue.stringformat = "0m"; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("0m"); break; case APIParT_Boolean: - pvalue.n_zero = 0; if (param_bool) { param_string = RSGetIndString(ID_ADDON_STRINGS + isEng(), TrueId, ACAPI_GetOwnResModule()); param_int = 1; @@ -4425,8 +4476,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar param_int = 0; param_real = 0.0; } - pvalue.stringformat = "0m"; - pvalue.n_zero = 0; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("0m"); pvalue.canCalculate = true; pvalue.type = API_PropertyBooleanValueType; break; @@ -4434,7 +4484,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar param_string = GS::UniString::Printf("%.0f", param_real * 1000); pvalue.canCalculate = true; pvalue.type = API_PropertyRealValueType; - pvalue.stringformat = "1mm"; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("1mm"); break; case APIParT_Angle: param_real = round((preal * 180.0 / PI) * 100000.0) / 100000.0; @@ -4444,13 +4494,13 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar param_string = GS::UniString::Printf("%.1f", param_real); pvalue.canCalculate = true; pvalue.type = API_PropertyRealValueType; - pvalue.stringformat = "2m"; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("2m"); break; case APIParT_RealNum: param_string = GS::UniString::Printf("%.3f", param_real); pvalue.canCalculate = true; pvalue.type = API_PropertyRealValueType; - pvalue.stringformat = "3m"; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("3m"); break; // Для реквезитов в текст выведем имена @@ -4485,7 +4535,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar param_int = attrInx; #endif param_real = param_int / 1.0; - pvalue.n_zero = 0; + pvalue.formatstring = PropertyHelpers::ParseFormatString ("0m"); } else { return false; @@ -4494,6 +4544,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValueData & pvalue, const API_AddPar } pvalue.boolValue = param_bool; pvalue.doubleValue = param_real; + pvalue.rawDoubleValue = param_real; pvalue.intValue = param_int; pvalue.uniStringValue = param_string; return true; @@ -4627,20 +4678,19 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_Property & if (!pvalue.isValid) { return false; } - pvalue.val.boolValue = false; - pvalue.val.intValue = 0; - pvalue.val.doubleValue = 0.0; - pvalue.val.uniStringValue = PropertyHelpers::ToString(property); + pvalue.val.uniStringValue = PropertyHelpers::ToString (property); std::string var = pvalue.val.uniStringValue.ToCStr(0, MaxUSize, GChCode).Get(); FormatStringDict formatstringdict; switch (property.definition.valueType) { case API_PropertyIntegerValueType: pvalue.val.intValue = property.value.singleVariant.variant.intValue; pvalue.val.doubleValue = property.value.singleVariant.variant.intValue * 1.0; + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; if (pvalue.val.intValue > 0) pvalue.val.boolValue = true; pvalue.val.type = API_PropertyIntegerValueType; pvalue.val.canCalculate = true; - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); + pvalue.val.uniStringValue = PropertyHelpers::ToString (property, pvalue.val.formatstring); break; case API_PropertyRealValueType: @@ -4651,23 +4701,27 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_Property & } else { pvalue.val.doubleValue = round(property.value.singleVariant.variant.doubleValue * 100000.0) / 100000.0; - if (property.value.singleVariant.variant.doubleValue - pvalue.val.doubleValue > 0.001) pvalue.val.doubleValue += 0.001; + if (property.value.singleVariant.variant.doubleValue - pvalue.val.rawDoubleValue > 0.001) pvalue.val.rawDoubleValue += 0.001; } pvalue.val.intValue = (GS::Int32)pvalue.val.doubleValue; if (pvalue.val.intValue / 1 < pvalue.val.doubleValue) pvalue.val.intValue += 1; if (fabs(pvalue.val.doubleValue) > std::numeric_limits::epsilon()) pvalue.val.boolValue = true; + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; pvalue.val.type = API_PropertyRealValueType; formatstringdict = GetFotmatStringForMeasureType(); if (formatstringdict.ContainsKey(property.definition.measureType)) { - if (formatstringdict.Get(property.definition.measureType).needRound && property.definition.measureType != API_PropertyLengthMeasureType) { - double l = pow(10, formatstringdict.Get(property.definition.measureType).n_zero); - pvalue.val.doubleValue = round(pvalue.val.doubleValue * pow(10, formatstringdict.Get(property.definition.measureType).n_zero)) / pow(10, formatstringdict.Get(property.definition.measureType).n_zero); + int n_zero = formatstringdict.Get (property.definition.measureType).n_zero; + GS::UniString stringformat = formatstringdict.Get (property.definition.measureType).stringformat; + bool needRound = formatstringdict.Get (property.definition.measureType).needRound; + if (needRound && property.definition.measureType != API_PropertyLengthMeasureType) { + double l = pow(10, n_zero); + pvalue.val.doubleValue = round(pvalue.val.doubleValue * pow(10, n_zero)) / pow(10, n_zero); pvalue.val.intValue = (GS::Int32)pvalue.val.doubleValue; if (fabs(pvalue.val.doubleValue) > std::numeric_limits::epsilon()) pvalue.val.boolValue = true; } - if (pvalue.val.stringformat.IsEmpty()) { - pvalue.val.stringformat = formatstringdict.Get(property.definition.measureType).stringformat; - pvalue.val.n_zero = formatstringdict.Get(property.definition.measureType).n_zero; + if (pvalue.val.formatstring.isEmpty) { + pvalue.val.formatstring = PropertyHelpers::ParseFormatString (stringformat); + pvalue.val.formatstring.needRound = needRound; } pvalue.val.uniStringValue = ParamHelpers::ToString(pvalue); } @@ -4681,10 +4735,13 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_Property & } pvalue.val.type = API_PropertyBooleanValueType; pvalue.val.canCalculate = true; - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; + pvalue.val.uniStringValue = PropertyHelpers::ToString (property); break; case API_PropertyStringValueType: case API_PropertyGuidValueType: + pvalue.val.uniStringValue = PropertyHelpers::ToString (property); pvalue.val.type = API_PropertyStringValueType; pvalue.val.boolValue = !pvalue.val.uniStringValue.IsEmpty(); if (UniStringToDouble(pvalue.val.uniStringValue, pvalue.val.doubleValue)) { @@ -4698,6 +4755,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_Property & pvalue.val.doubleValue = 1.0; } } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; case API_PropertyUndefinedValueType: return false; @@ -4770,6 +4828,7 @@ bool ParamHelpers::ConvertStringToParamValue(ParamValue & pvalue, const GS::UniS pvalue.val.doubleValue = 1.0; } } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; pvalue.val.type = API_PropertyStringValueType; pvalue.type = API_PropertyStringValueType; pvalue.isValid = true; @@ -4796,9 +4855,10 @@ bool ParamHelpers::ConvertBoolToParamValue(ParamValue & pvalue, const GS::UniStr pvalue.val.intValue = 0; pvalue.val.doubleValue = 0.0; } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; pvalue.val.canCalculate = true; pvalue.isValid = true; - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); return true; } @@ -4813,10 +4873,11 @@ bool ParamHelpers::ConvertIntToParamValue(ParamValue & pvalue, const GS::UniStri pvalue.val.canCalculate = true; pvalue.val.intValue = intValue; pvalue.val.doubleValue = intValue * 1.0; + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; if (pvalue.val.intValue > 0) pvalue.val.boolValue = true; pvalue.val.uniStringValue = GS::UniString::Printf("%d", intValue); pvalue.isValid = true; - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); return true; } @@ -4831,6 +4892,7 @@ bool ParamHelpers::ConvertDoubleToParamValue(ParamValue & pvalue, const GS::UniS pvalue.val.canCalculate = true; pvalue.val.intValue = (GS::Int32)doubleValue; pvalue.val.doubleValue = doubleValue; + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; pvalue.val.boolValue = false; if (fabs(pvalue.val.doubleValue) > std::numeric_limits::epsilon()) pvalue.val.boolValue = true; pvalue.val.uniStringValue = GS::UniString::Printf("%.3f", doubleValue); @@ -4865,6 +4927,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert pvalue.val.doubleValue = 1.0; } } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; case API_IFCPropertyAnyValueRealType: pvalue.val.canCalculate = true; @@ -4875,6 +4938,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert if (pvalue.val.intValue / 1 < pvalue.val.doubleValue) pvalue.val.intValue += 1; if (fabs(pvalue.val.doubleValue) > std::numeric_limits::epsilon()) pvalue.val.boolValue = true; pvalue.val.uniStringValue = GS::UniString::Printf("%.3f", pvalue.val.doubleValue); + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; case API_IFCPropertyAnyValueIntegerType: pvalue.val.canCalculate = true; @@ -4883,7 +4947,8 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert pvalue.val.doubleValue = pvalue.val.intValue * 1.0; if (pvalue.val.intValue > 0) pvalue.val.boolValue = true; pvalue.val.uniStringValue = GS::UniString::Printf("%d", pvalue.val.intValue); - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; case API_IFCPropertyAnyValueBooleanType: pvalue.val.canCalculate = true; @@ -4899,9 +4964,10 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert pvalue.val.intValue = 0; pvalue.val.doubleValue = 0.0; } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; case API_IFCPropertyAnyValueLogicalType: - pvalue.val.n_zero = 0; + pvalue.val.formatstring = PropertyHelpers::ParseFormatString ("0m"); pvalue.val.type = API_PropertyBooleanValueType; if (property.singleValue.nominalValue.value.intValue == 0) pvalue.val.boolValue = false; if (property.singleValue.nominalValue.value.intValue == 1) pvalue.isValid = false; @@ -4916,6 +4982,7 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert pvalue.val.intValue = 0; pvalue.val.doubleValue = 0.0; } + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; break; default: pvalue.val.canCalculate = false; @@ -4928,35 +4995,33 @@ bool ParamHelpers::ConvertToParamValue(ParamValue & pvalue, const API_IFCPropert } void ParamHelpers::ConvertByFormatString(ParamValue & pvalue) { if (pvalue.val.type == API_PropertyRealValueType || pvalue.val.type == API_PropertyIntegerValueType) { - Int32 n_zero = 3; - Int32 krat = 0; - double koeff = 1; - bool trim_zero = true; - PropertyHelpers::ParseFormatString(pvalue.val.stringformat, n_zero, krat, koeff, trim_zero); - UNUSED_VARIABLE(krat); UNUSED_VARIABLE(trim_zero); + Int32 n_zero = pvalue.val.formatstring.n_zero; + Int32 krat = pvalue.val.formatstring.krat; + double koeff = pvalue.val.formatstring.koeff; + bool trim_zero = pvalue.val.formatstring.koeff; pvalue.val.uniStringValue = ParamHelpers::ToString(pvalue); if (koeff != 1) n_zero = n_zero + (GS::Int32)log10(koeff); pvalue.val.doubleValue = round(pvalue.val.doubleValue * pow(10, n_zero)) / pow(10, n_zero); pvalue.val.intValue = (GS::Int32)pvalue.val.doubleValue; if (fabs(pvalue.val.doubleValue) > std::numeric_limits::epsilon()) pvalue.val.boolValue = true; + pvalue.val.rawDoubleValue = pvalue.val.doubleValue; } } GS::UniString ParamHelpers::ToString(const ParamValue & pvalue) { - GS::UniString stringformat = pvalue.val.stringformat; - switch (pvalue.val.type) { - case API_PropertyIntegerValueType: return PropertyHelpers::NumToString(pvalue.val.intValue, stringformat); - case API_PropertyRealValueType: return PropertyHelpers::NumToString(pvalue.val.doubleValue, stringformat); - case API_PropertyStringValueType: return pvalue.val.uniStringValue; - case API_PropertyBooleanValueType: return GS::ValueToUniString(pvalue.val.boolValue); - default: DBBREAK(); return "Invalid Value"; - } + FormatString stringformat = pvalue.val.formatstring; + return ParamHelpers::ToString (pvalue, stringformat); } -GS::UniString ParamHelpers::ToString(const ParamValue & pvalue, const GS::UniString stringformat) { +GS::UniString ParamHelpers::ToString(const ParamValue & pvalue, const FormatString stringformat) { switch (pvalue.val.type) { case API_PropertyIntegerValueType: return PropertyHelpers::NumToString(pvalue.val.intValue, stringformat); - case API_PropertyRealValueType: return PropertyHelpers::NumToString(pvalue.val.doubleValue, stringformat); + case API_PropertyRealValueType: + if(stringformat.needRound) { + return PropertyHelpers::NumToString (pvalue.val.doubleValue, stringformat); + } else { + return PropertyHelpers::NumToString (pvalue.val.rawDoubleValue, stringformat); + } case API_PropertyStringValueType: return pvalue.val.uniStringValue; case API_PropertyBooleanValueType: return GS::ValueToUniString(pvalue.val.boolValue); default: DBBREAK(); return "Invalid Value"; diff --git a/Sources/AddOn/Helpers.hpp b/Sources/AddOn/Helpers.hpp index 58a0c1f..0b4263d 100644 --- a/Sources/AddOn/Helpers.hpp +++ b/Sources/AddOn/Helpers.hpp @@ -93,6 +93,18 @@ typedef struct Point2D start; } OrientedSegments; +typedef struct { + int n_zero = 2; //Количество нулей после запятой + GS::UniString stringformat = ""; // Формат строки (задаётся с помощью .mm или .0) + bool needRound = false; + Int32 krat = 0; // Крутность округления + double koeff = 1; //Коэфф. увеличения + bool trim_zero = true; //Требуется образать нули после запятой + bool isRead = false; // Строка успешно распарсена + bool isEmpty = true; //Строка не задана + GS::UniString delimetr = ","; +} FormatString; + // Хранение данных параметра // type - API_VariantType (как у свойств) // name - имя для поиска @@ -106,10 +118,10 @@ typedef struct GS::UniString uniStringValue = ""; GS::Int32 intValue = 0; bool boolValue = false; - double doubleValue = 0.0; + double doubleValue = 0.0; //дробное значение, округлённое + double rawDoubleValue = 0.0; bool canCalculate = false; // Может ли быть использован в формулах? - GS::UniString stringformat = ""; // Формат строки (задаётся с помощью .mm или .0) - int n_zero = 2; // Количество нулей после запятой + FormatString formatstring; // Формат строки (задаётся с помощью .mm или .0) int array_row_start = 0; // Начальная строка массива int array_row_end = 0; // Последняя строка массива int array_column_start = 0; // Начальный столбец массива @@ -127,13 +139,6 @@ typedef struct int num = 0; } ParamValueComposite; -typedef struct -{ - int n_zero = 2; - GS::UniString stringformat = ""; // Формат строки (задаётся с помощью .mm или .0) - bool needRound = false; -} FormatString; - // Словарь с форматированием и округлением typedef GS::HashTable FormatStringDict; @@ -429,11 +434,12 @@ bool MenuInvertItemMark(short menuResID, short itemIndex); namespace PropertyHelpers { - void ParseFormatString(const GS::UniString& stringformat, Int32& n_zero, Int32& krat, double& koeff, bool& trim_zero); - GS::UniString NumToString(const double& var, const GS::UniString& stringformat); - GS::UniString ToString(const API_Variant& variant, const GS::UniString& stringformat); + void ParseFormatString (FormatString& stringformat); + FormatString ParseFormatString(const GS::UniString& stringformat); + GS::UniString NumToString(const double& var, const FormatString& stringformat); + GS::UniString ToString(const API_Variant& variant, const FormatString& stringformat); GS::UniString ToString(const API_Variant& variant); - GS::UniString ToString(const API_Property& property, const GS::UniString& stringformat); + GS::UniString ToString(const API_Property& property, const FormatString& stringformat); GS::UniString ToString(const API_Property& property); } @@ -442,6 +448,11 @@ namespace PropertyHelpers // ----------------------------------------------------------------------------- namespace ParamHelpers { + // ----------------------------------------------------------------------------- + // Возвращает строку в формате rawname + // Очищает от единиц измерения, добавляет скобки + // ----------------------------------------------------------------------------- + GS::UniString NameToRawName (const GS::UniString& name, FormatString& formatstring); // ----------------------------------------------------------------------------- // Получение размеров Морфа // Формирует словарь ParamDictValue& pdictvalue со значениями @@ -480,9 +491,8 @@ namespace ParamHelpers // ----------------------------------------------------------------------------- // Добавление пустого значения в словарь ParamDictValue - // Возвращает rawName // ----------------------------------------------------------------------------- - GS::UniString AddValueToParamDictValue(ParamDictValue& params, const GS::UniString& name); + void AddValueToParamDictValue(ParamDictValue& params, const GS::UniString& name); bool needAdd(ParamDictValue& params, GS::UniString& rawName); @@ -504,7 +514,7 @@ namespace ParamHelpers // -------------------------------------------------------------------- // Сопоставляет параметры // -------------------------------------------------------------------- - bool CompareParamValue(ParamValue& paramFrom, ParamValue& paramTo, GS::UniString stringformat); + bool CompareParamValue(ParamValue& paramFrom, ParamValue& paramTo, FormatString stringformat); // -------------------------------------------------------------------- // Запись словаря ParamDictValue в словарь элементов ParamDictElement @@ -759,7 +769,7 @@ namespace ParamHelpers // ----------------------------------------------------------------------------- // Перевод значения в строку в соответсвии с stringformat // ----------------------------------------------------------------------------- - GS::UniString ToString(const ParamValue& pvalue, const GS::UniString stringformat); + GS::UniString ToString(const ParamValue& pvalue, const FormatString stringformat); // ----------------------------------------------------------------------------- // Перевод значения в строку в соответсвии с stringformat diff --git a/Sources/AddOn/Summ.cpp b/Sources/AddOn/Summ.cpp index b0674f6..32edb6d 100644 --- a/Sources/AddOn/Summ.cpp +++ b/Sources/AddOn/Summ.cpp @@ -268,7 +268,7 @@ void Sum_OneRule (const SumRule& rule, ParamDictElement& paramToReadelem, ParamD param.isValid = true; summ.val.type = param.val.type; if(rule.sum_type != TextSum) { - summ.val.stringformat = param.val.stringformat; + summ.val.formatstring = param.val.formatstring; summ.val.uniStringValue = ParamHelpers::ToString (summ); } diff --git a/Sources/AddOn/Sync.cpp b/Sources/AddOn/Sync.cpp index 207912a..b28a31b 100644 --- a/Sources/AddOn/Sync.cpp +++ b/Sources/AddOn/Sync.cpp @@ -504,10 +504,10 @@ void SyncCalcRule(const WriteDict& syncRules, const GS::Array& subelem if (paramsTo.ContainsKey(rawNameTo) && paramsFrom.ContainsKey(rawNameFrom)) { ParamValue paramFrom = paramsFrom.Get(rawNameFrom); ParamValue paramTo = paramsTo.Get(rawNameTo); - GS::UniString stringformat = writeSub.stringformat; + FormatString formatstring = writeSub.formatstring; //Сопоставляем и записываем, если значения отличаются - if (ParamHelpers::CompareParamValue(paramFrom, paramTo, stringformat)) { + if (ParamHelpers::CompareParamValue(paramFrom, paramTo, formatstring)) { ParamHelpers::AddParamValue2ParamDictElement(paramTo, paramToWrite); } } @@ -612,7 +612,7 @@ bool ParseSyncString(const API_Guid& elemGuid, const API_ElemTypeID& elementTyp int syncdirection = SYNC_NO; // Направление синхронизации GS::UniString rawparamName = ""; //Имя параметра/свойства с указанием типа синхронизации, для ключа словаря GS::Array ignorevals; //Игнорируемые значения - GS::UniString stringformat = ""; //Строка с форматом числа + FormatString stringformat; GS::UniString rulestring_one = rulestring[i]; API_Guid elemGuidfrom = elemGuid; @@ -638,7 +638,7 @@ bool ParseSyncString(const API_Guid& elemGuid, const API_ElemTypeID& elementTyp ParamHelpers::ConvertToParamValue(paramdef, definition); paramdef.fromGuid = elemGuid; WriteData writeOne; - writeOne.stringformat = stringformat; + writeOne.formatstring = stringformat; writeOne.ignorevals = ignorevals; if (param.fromCoord && param.rawName.Contains("north_dir")) { ParamDictValue paramDict; @@ -778,7 +778,7 @@ bool Name2Rawname(GS::UniString& name, GS::UniString& rawname) { // ----------------------------------------------------------------------------- // Парсит описание свойства // ----------------------------------------------------------------------------- -bool SyncString(const API_ElemTypeID& elementType, GS::UniString rulestring_one, int& syncdirection, ParamValue& param, GS::Array& ignorevals, GS::UniString& stringformat) { +bool SyncString(const API_ElemTypeID& elementType, GS::UniString rulestring_one, int& syncdirection, ParamValue& param, GS::Array& ignorevals, FormatString& stringformat) { syncdirection = SYNC_NO; // Выбор направления синхронизации @@ -949,7 +949,8 @@ bool SyncString(const API_ElemTypeID& elementType, GS::UniString rulestring_one // Параметры не найдены - выходим if (nparam == 0) return false; GS::UniString paramName = params.Get(0); - stringformat = GetFormatString(paramName); + GS::UniString stringformat_raw = GetFormatString (paramName); + stringformat = PropertyHelpers::ParseFormatString (stringformat_raw); paramName.ReplaceAll("\\/", "/"); param.rawName = paramNamePrefix + paramName.ToLowerCase () + "}"; param.name = paramName; diff --git a/Sources/AddOn/Sync.hpp b/Sources/AddOn/Sync.hpp index 10ada08..a048875 100644 --- a/Sources/AddOn/Sync.hpp +++ b/Sources/AddOn/Sync.hpp @@ -45,7 +45,7 @@ typedef struct { ParamValue paramFrom; ParamValue paramTo; GS::Array ignorevals; - GS::UniString stringformat = ""; //Формат строки (задаётся с помощью #mm или #0) + FormatString formatstring; //Формат строки (задаётся с помощью #mm или #0) bool toSub = false; bool fromSub = false; } WriteData; @@ -134,6 +134,6 @@ bool Name2Rawname(GS::UniString& name, GS::UniString& rawname); // ----------------------------------------------------------------------------- // Парсит описание свойства // ----------------------------------------------------------------------------- -bool SyncString(const API_ElemTypeID& elementType, GS::UniString rulestring_one, int& syncdirection, ParamValue& param, GS::Array& ignorevals, GS::UniString& stringformat); +bool SyncString(const API_ElemTypeID& elementType, GS::UniString rulestring_one, int& syncdirection, ParamValue& param, GS::Array& ignorevals, FormatString& stringformat); #endif \ No newline at end of file