예제 #1
0
        /// <summary>
        /// try to identify parameters and, if valid, generate the respective ParXXX and put into respective lists (see above)
        /// </summary>
        private void ClassifyParameters(Dictionary <string, ExeXml.Par> xmlParList, DefinitionAdmin.Fun funDef)
        {
            int dummyGroupNumber = -9999; // this is for placeholder-parameters, see below

            foreach (var xmlPar in xmlParList)
            {
                Description parDescription = new Description(description, xmlPar.Value, xmlPar.Key);
                string      xmlParName     = xmlPar.Value.Name;

                // first check if it is an 'ordinary' parameter ...
                DefinitionAdmin.Par parDef = funDef.GetParDef(xmlParName);
                if (parDef != null)
                {
                    string officialParName = funDef.GetOfficalParName(xmlParName); // is (in contrast to xmlParName) case-sensitive and
                                                                                   // corresponds to constants as defined in Common-library
                                                                                   // generate parameter ...
                    ParBase par = GeneratePar(xmlPar, parDef, parDescription);
                    // ... and put it into the list it belongs too ...
                    if (parDef.isFootnote) // ... footnote-list
                    {
                        if (GetGroupNumber(xmlPar.Value, parDescription, out int dummy))
                        {
                            if (!footnotePar.ContainsKey(xmlPar.Value.Group))
                            {
                                footnotePar.Add(xmlPar.Value.Group, new Dictionary <string, ParBase>());
                            }
                            if (!footnotePar[xmlPar.Value.Group].ContainsKey(officialParName))
                            {
                                footnotePar[xmlPar.Value.Group].Add(officialParName, par);
                            }
                            else
                            {
                                ReportDoubleDef(parDescription);
                            }
                        }
                    }
                    else if (parDef.maxCount == 1) // ... unique-parameter-list
                    {
                        if (!uniquePar.ContainsKey(officialParName))
                        {
                            uniquePar.Add(officialParName, par);
                            if (infoStore.runConfig.warnAboutUselessGroups && !string.IsNullOrEmpty(xmlPar.Value.Group))
                            {
                                ReportUselessGroup(parDescription);
                            }
                        }
                        else
                        {
                            ReportDoubleDef(parDescription);
                        }
                    }
                    else // ... non-unique-parameter-list
                    {
                        if (!nonUniquePar.ContainsKey(officialParName))
                        {
                            nonUniquePar.Add(officialParName, new List <ParBase>());
                        }
                        nonUniquePar[officialParName].Add(par);
                        if (infoStore.runConfig.warnAboutUselessGroups && !string.IsNullOrEmpty(xmlPar.Value.Group))
                        {
                            ReportUselessGroup(parDescription);
                        }
                    }
                    continue;
                }
                // ... if not successuful, check if it is a group parameter ...
                parDef = funDef.GetGroupParDef(xmlParName, out string groupName);
                if (parDef != null)
                {
                    if (GetGroupNumber(xmlPar.Value, parDescription, out int groupNo))
                    {
                        // generate parameter ...
                        ParBase par = GeneratePar(xmlPar, parDef, parDescription);
                        // ... and put it into group-parameter-list
                        if (!groupPar.ContainsKey(groupName))
                        {
                            groupPar.Add(groupName, new SortedList <int, List <ParBase> >());
                        }
                        if (!groupPar[groupName].ContainsKey(groupNo))
                        {
                            groupPar[groupName].Add(groupNo, new List <ParBase>());
                        }
                        if (parDef.maxCount > 1 || GetUniqueGroupPar <ParBase>(xmlPar.Value.Name, groupPar[groupName][groupNo]) == null)
                        {
                            groupPar[groupName][groupNo].Add(par);
                        }
                        else
                        {
                            ReportDoubleDef(parDescription);
                        }
                    }
                    continue;
                }
                // ... if still not successful, it could still be placehoder parameter ...
                if (funDef.AllowsForPlaceholders())
                {
                    parDef = funDef.GetPlaceholderDef(out string phGroupName);
                    ParBase par = GeneratePar(xmlPar, parDef, parDescription, true);
                    if (phGroupName == null) // non-group placeholder, as e.g. in SetDefault, DefIL
                    {
                        if (!placeholderPar.TryAdd(xmlParName, par))
                        {
                            infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                            {
                                isWarning = true, message = $" {parDescription.Get()}: {xmlParName} double definition (is ignored)"
                            });
                        }
                    }
                    else // group placeholder, as e.g. in DefVar (PH, IsGlobal, IsMonetary), Uprate (PH, FactorCond)
                    {
                        GetGroupNumber(xmlPar.Value, parDescription, // note that this returns a dummy-group if the user didn't indicate one
                                       out int groupNo, true); // as placeholders only actually need a group if they are "further specified" (e.g. uprating-factors: factor_condition)
                        if (!groupPar.ContainsKey(phGroupName))
                        {
                            groupPar.Add(phGroupName, new SortedList <int, List <ParBase> >());
                        }
                        if (!groupPar[phGroupName].ContainsKey(groupNo))
                        {
                            groupPar[phGroupName].Add(groupNo, new List <ParBase>());
                        }
                        groupPar[phGroupName][groupNo].Add(par);
                    }
                    continue;
                }
                // ... now we give up
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = true, message = $" {parDescription.Get()}: unknown parameter"
                });
            }

            if (infoStore.runConfig.warnAboutUselessGroups)
            {
                foreach (var groupType in groupPar)
                {
                    if (groupType.Key.ToLower() == DefPar.SchedCalc.Band_XXX.ToLower())
                    {
                        continue;
                    }
                    foreach (var group in groupType.Value)
                    {
                        if (group.Key >= 0 && group.Value.Count == 1)
                        {
                            ReportUselessGroup(group.Value[0].description);
                        }
                    }
                }
            }

            // internal function for generating parameters
            ParBase GeneratePar(KeyValuePair <string, ExeXml.Par> xmlPar, DefinitionAdmin.Par parDef,
                                Description parDescription, bool isPlaceholder = false)
            {
                ParBase par;

                switch (parDef.valueType)
                {
                case DefPar.PAR_TYPE.FORMULA: par = new ParFormula(infoStore); break;

                case DefPar.PAR_TYPE.CONDITION: par = new ParCond(infoStore); break;

                case DefPar.PAR_TYPE.BOOLEAN: par = new ParBool(infoStore); break;

                case DefPar.PAR_TYPE.NUMBER: par = new ParNumber(infoStore); break;

                case DefPar.PAR_TYPE.TEXT: par = new ParBase(infoStore); break;

                case DefPar.PAR_TYPE.VAR: par = new ParVar(infoStore); break;

                case DefPar.PAR_TYPE.OUTVAR: par = new ParOutVar(infoStore); break;

                case DefPar.PAR_TYPE.IL: par = new ParIL(infoStore); break;

                case DefPar.PAR_TYPE.TU: par = new ParTU(infoStore); break;

                case DefPar.PAR_TYPE.VARorIL: par = new ParVarIL(infoStore); break;

                case DefPar.PAR_TYPE.CATEG: par = new ParCateg(infoStore, parDef.categValues); break;

                case DefPar.PAR_TYPE.PLACEHOLDER: par = new ParBase(infoStore); break;

                default: throw new Exception($"Not yet properly implemented parameter value type {parDef.valueType}");
                }
                par.description = parDescription;
                par.xmlValue    = xmlPar.Value.val;
                par.description.isPlaceholder = isPlaceholder;
                return(par);
            }

            bool GetGroupNumber(ExeXml.Par p, Description parDescription, out int groupNumber, bool allowDummy = false)
            {
                groupNumber = dummyGroupNumber++;  // placeholders (e.g.uprating factors) only actually need a group
                if (string.IsNullOrEmpty(p.Group)) // if they are "further specified" (e.g.factor_condition)
                {
                    if (allowDummy)
                    {
                        return(true);
                    }
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = false, message = $" {parDescription.Get()}: missing group"
                    });
                    return(false);
                }
                if (int.TryParse(p.Group, out groupNumber))
                {
                    return(true);
                }
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = false, message = $" {parDescription.Get()}: invalid group {p.Group} (must be an integer number)"
                });
                return(false);
            }

            void ReportDoubleDef(Description parDescription)
            {
                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                {
                    isWarning = false, message = $" {parDescription.Get()}: defined more than once"
                });
            }

            void ReportUselessGroup(Description parDescription)
            {
                if (parDescription.GetFunName() != DefFun.Store)    // add a special exception for Store, as it has its own reporting
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = true, message = $" {parDescription.Get()}: group has no use"
                    });
                }
            }
        }
예제 #2
0
        /// <summary> check for compulsory parameters </summary>
        private void CheckForCompleteness(Dictionary <string, ExeXml.Par> xmlParList, DefinitionAdmin.Fun funDef)
        {
            // check if compulsory non-group parameters are available
            foreach (var p in funDef.GetParList())
            {
                string parName = p.Key; DefinitionAdmin.Par parDef = p.Value;
                if (parDef.minCount == 0)
                {
                    continue;                       // optional parameter (e.g. Allocate's Share_Between)
                }
                // (note that footnote-parameters are always optional)
                bool found = false;
                if (parDef.maxCount == 1) // check for unique compulsory parameter (e.g. ArithOp's Formula)
                {
                    if (GetUniquePar <ParBase>(parName) != null)
                    {
                        found = true;
                    }
                    else // could still be available as substitute (e.g. output_var not available, but output_add_var)
                    {
                        foreach (string substitute in parDef.substitutes)
                        {
                            if (GetUniquePar <ParBase>(substitute) != null)
                            {
                                found = true; break;
                            }
                        }
                        ;
                    }
                }
                if (parDef.maxCount > 1) // check for non-unique parameter, where at least one must be defined (e.g. SetDefault's Dataset)
                {
                    if (GetNonUniquePar <ParBase>(parName).Count > 0)
                    {
                        found = true;
                    }
                    else // unlikely, but could still be available as substitute
                    {
                        foreach (string substitute in parDef.substitutes)
                        {
                            if (GetNonUniquePar <ParBase>(substitute).Count > 0)
                            {
                                found = true; break;
                            }
                        }
                        ;
                    }
                }

                if (!found)
                {
                    infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                    {
                        isWarning = false, message = $" {description.Get()}: compulsory parameter {parName} is missing"
                    });
                }
            }

            // check if compulsory groups, and compulsory parameter within groups are available
            foreach (var groupDef in funDef.GetGroupParList())
            {
                if (groupDef.minCount > 0) // check for compulsory group, e.g. BenCalc's Comp_X-group
                {
                    if (!groupPar.ContainsKey(groupDef.groupName))
                    {
                        infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                        {
                            isWarning = false, message = $" {description.Get()}: compulsory group {groupDef.groupName} is missing"
                        });
                    }
                }

                // whether or not the group is compulsory it can (if existent) ask for completeness, i.e. have compulsory parts
                if (!groupPar.ContainsKey(groupDef.groupName))
                {
                    continue;                   // no such group exists
                }
                foreach (var p in groupDef.par) // loop over the group-definition's parameters (e.g. Comp_Cond, Comp_perTU, Comp_LowLim, ...)
                {
                    string parName = p.Key; DefinitionAdmin.Par parDef = p.Value;
                    if (parDef.minCount == 0)
                    {
                        continue;                       // optional parameter (e.g. Comp_LowLim)
                    }
                    // check for compulsory parameter (e.g. Comp_Cond)
                    foreach (var g in GetParGroups(groupDef.groupName)) // loop over all existent groups
                    {                                                   // (e.g. all components of an actual BenCalc)
                        int groupNo = g.Key; List <ParBase> groupPar = g.Value;
                        int found = 0;
                        if (parDef.maxCount == 1) // check for unique compulsory group-parameter (e.g. BenCalc's Comp_Cond)
                        {
                            if (GetUniqueGroupPar <ParBase>(parName, groupPar) != null)
                            {
                                ++found;
                            }
                            foreach (string substitute in parDef.substitutes)
                            {
                                if (GetUniqueGroupPar <ParBase>(substitute.ToLower(), groupPar) != null)
                                {
                                    ++found;
                                }
                            }
                            if (found > 1)
                            {
                                infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                                {
                                    isWarning = false, message = $" {description.Get()}: double definition of group-parameter {parName} (group {groupNo})"
                                });
                            }
                        }
                        if (parDef.maxCount > 1) // check for non-unique compulsory group-parameter (e.g. Uprate's AggVarPart)
                        {
                            if (GetNonUniqueGroupPar <ParBase>(parName, groupPar).Count > 0)
                            {
                                ++found;
                            }
                            foreach (string substitute in parDef.substitutes)
                            {
                                if (GetNonUniqueGroupPar <ParBase>(substitute.ToLower(), groupPar).Count > 0)
                                {
                                    ++found;
                                }
                            }
                        }
                        if (found == 0)
                        {
                            infoStore.communicator.ReportError(new Communicator.ErrorInfo()
                            {
                                isWarning = false, message = $" {description.Get()}: compulsory group-parameter {parName} (group {groupNo}) is missing"
                            });
                        }
                    }
                }
            }
        }
        void AddParameters()
        {
            //analyse all AddOn_Par functions
            foreach (CountryConfig.FunctionRow function_AddOnParameters in
                     _addOnCountryConfigFacade.GetFunctionRowsBySystemIDAndFunctionName(_addOnSystemRow.ID, DefFun.AddOn_Par))
            {
                if (function_AddOnParameters.Switch.ToLower() != DefPar.Value.ON.ToLower())
                {
                    continue;
                }

                //assess which parameters are to be merged and into which function by interpreting the AddOnPar-function's parameters
                CountryConfig.ParameterRow parameter_InsertFunctionID = _addOnCountryConfigFacade.GetParameterRowByName(function_AddOnParameters.ID, DefPar.AddOn_Par.Insert_Func);
                if (parameter_InsertFunctionID == null)
                {
                    _errorMessages += ImportExportHelper.GenerateErrorMessage(function_AddOnParameters, "Compulsory parameter '" + DefPar.AddOn_Par.Insert_Func + "' not defined.");
                    continue;
                }

                //search for the function where parameters are to be added in the just generated (copied) system
                CountryConfig.FunctionRow addOnParameters_InsertFunction = _mergeCountryConfigFacade.GetFunctionRowByID(parameter_InsertFunctionID.Value);
                if (addOnParameters_InsertFunction == null) //take account of 'symbolic' identifier, e.g. output_std_sl_#3
                {
                    addOnParameters_InsertFunction = ImportExportHelper.GetFunctionRowBySymbolicID(parameter_InsertFunctionID.Value, _mergeCountryConfigFacade, _mergeSystemRow.ID);
                }

                if (addOnParameters_InsertFunction == null)
                {
                    _errorMessages += ImportExportHelper.GenerateErrorMessage(function_AddOnParameters, "Unknown function '" + parameter_InsertFunctionID.Value + "'.");
                    continue;
                }

                //if everything is ok, insert the parameters (all other parameters than insert_func in AddOn_Par) into the function
                foreach (CountryConfig.ParameterRow addOnParameters_ParameterNameAndValue in function_AddOnParameters.GetParameterRows())
                {
                    if (addOnParameters_ParameterNameAndValue.Name.ToLower() == DefPar.AddOn_Par.Insert_Func.ToLower())
                    {
                        continue;
                    }

                    DefinitionAdmin.Par parDef = DefinitionAdmin.GetParDefinition(addOnParameters_InsertFunction.Name, addOnParameters_ParameterNameAndValue.Name, false);
                    if (parDef == null)
                    {
                        _errorMessages += ImportExportHelper.GenerateErrorMessage(function_AddOnParameters,
                                                                                  "Function '" + addOnParameters_InsertFunction.Name + "' does not allow for parameter '" + addOnParameters_ParameterNameAndValue.Name + "'.");
                        continue;
                    }

                    //add parameter, however if a respective parameter with value n/a exists, it can be used
                    //this is even necessary for single parameters (which may only exist once) if an add-on is added more than once (i.e. there is already the n/a parameter of the first adding-on)
                    CountryConfig.ParameterRow        parameterRow  = null;
                    List <CountryConfig.ParameterRow> parameterList = (from pR in addOnParameters_InsertFunction.GetParameterRows()
                                                                       where pR.Name.ToLower() == addOnParameters_ParameterNameAndValue.Name.ToLower() &&
                                                                       pR.Group == addOnParameters_ParameterNameAndValue.Group &&
                                                                       pR.Value == DefPar.Value.NA
                                                                       select pR).ToList();
                    if (parameterList.Count != 0)
                    {
                        parameterRow = parameterList.First();
                    }

                    if (parameterRow == null)
                    {
                        parameterRow = CountryConfigFacade.AddParameterRowAtTail(addOnParameters_InsertFunction, addOnParameters_ParameterNameAndValue.Name, parDef);
                    }
                    if (parameterRow.Name.ToLower() == DefinitionAdmin.ParTypeToString(DefPar.PAR_TYPE.PLACEHOLDER).ToLower())
                    {
                        parameterRow.Name = addOnParameters_ParameterNameAndValue.Name; //for adding parameters e.g. to function DefIL
                    }
                    parameterRow.Value   = addOnParameters_ParameterNameAndValue.Value;
                    parameterRow.Comment = addOnParameters_ParameterNameAndValue.Comment;

                    ImportExportHelper.ReplaceCountrySymbol(parameterRow, _mergeCountryConfigFacade.GetCountryShortName()); //replace all incidents of =cc= by country symbol
                }
            }
        }
        void btnApply_Click(object sender, EventArgs e)
        {
            List <DataGridViewRow> selectedRows = GetSelectedRows();

            if (selectedRows.Count == 0)
            {
                return;
            }

            ActionGroup actionGroup = new ActionGroup();
            List <KeyValuePair <string, string> > conflictParameters = new List <KeyValuePair <string, string> >(); //helper list for dedecting conflicts à la comp_perElig[grp1]/comp_perTU[grp1]

            foreach (DataGridViewRow selectedRow in selectedRows)
            {
                string countAsString = selectedRow.Cells[colCount.Index].Value == null ? "0" : selectedRow.Cells[colCount.Index].Value.ToString();
                uint   count = (countAsString != string.Empty && EM_Helpers.IsNonNegInteger(countAsString)) ? Convert.ToUInt32(countAsString) : 1;
                var    gon = selectedRow.Cells[colGroupNo.Index].Value; string groupOrNo = gon == null? string.Empty : gon.ToString();
                string initialGroupOrNo = groupOrNo;
                string substitute       = selectedRow.Cells[colReplaces.Index].Value.ToString();

                if (substitute != string.Empty)
                {
                    actionGroup.AddAction(new ChangeParameterNameAction((selectedRow.Tag as AddParameterTag)._parameterNode,
                                                                        selectedRow.Cells[colParameter.Index].Value.ToString()));
                    continue;
                }

                for (uint index = 0; index < count; ++index)
                {
                    DefinitionAdmin.Par      parDef   = (selectedRow.Tag as AddParameterTag)._parDef;
                    DefinitionAdmin.ParGroup parGroup = (selectedRow.Tag as AddParameterTag)._parGroup;
                    string parName = (selectedRow.Tag as AddParameterTag)._parName;

                    if (parDef.maxCount == 1 && (parGroup == null || parGroup.maxCount == 1) && count > 1)
                    {
                        count = 1;                 //if parameter is "single" make sure it is only added once!
                    }
                    if (groupOrNo != string.Empty) //group- or footnote-parameter
                    {
                        if (EM_Helpers.IsNonNegInteger(groupOrNo))
                        {
                            groupOrNo = (EM_Helpers.SaveConvertToInt(initialGroupOrNo) + index).ToString();
                        }

                        if (CountryConfigFacade.DoesParameterExist(_displayedFunctionRow, parName, groupOrNo))
                        {//may happen if user changes group or footnote number manually
                            UserInfoHandler.ShowError($"Parameter {parName} with Grp/No {groupOrNo} already exists. " +
                                                      "Please consider Grp/No and/or whether there is a conflict parameter.");
                            return;
                        }
                    }
                    if (parDef.substitutes.Count > 0)
                    {
                        foreach (string conflictPar in parDef.substitutes)
                        {
                            if (conflictParameters.Contains(new KeyValuePair <string, string>(conflictPar.ToLower(), groupOrNo)))
                            {//trying to add e.g. comp_perElig and comp_perTU with same group or output_var and output_add_var
                                string groupMessage = groupOrNo != string.Empty ? " with identical group " + groupOrNo : string.Empty;
                                UserInfoHandler.ShowError($"Cannot add parameter {parName} and parameter {conflictPar} {groupMessage}, as they are subsitudes.");
                                return;
                            }
                        }
                        conflictParameters.Add(new KeyValuePair <string, string>(parName.ToLower(), groupOrNo));
                    }

                    if ((_focusedNode.Tag as BaseTreeListTag).GetDefaultParameterRow() == null)
                    {
                        //if the dialog was opened via the function context menu, parameters are added at the end of the function
                        //thus they can be added simply one after the other, without changing the order ...
                        actionGroup.AddAction(new AddParameterAction(_focusedNode, parName, parDef, groupOrNo));
                    }
                    else
                    {
                        //if the dialog was opened via the parameter context menu, parameters are added after the selected parameter
                        //thus they have to be added in reverted order to keep the given order
                        actionGroup.InsertAction(0, new AddParameterAction(_focusedNode, parName, parDef, groupOrNo));
                    }
                }
            }

            _inApplyAction = true;

            TreeListNode   functionNode = (_focusedNode.Tag as BaseTreeListTag).GetDefaultParameterRow() == null ? _focusedNode : _focusedNode.ParentNode;
            EM_UI_MainForm mainForm     = EM_AppContext.Instance.GetCountryMainForm(_displayedFunctionRow.PolicyRow.SystemRow.CountryRow.ShortName);

            mainForm.PerformAction(actionGroup,
                                   true, false,
                                   functionNode); //performance optimisation Aug 13: update only the concerned function instead of the whole tree

            _inApplyAction = false;

            UpdateContent(functionNode);
        }
        internal void UpdateContent(TreeListNode focusedNode)
        {
            try
            {
                if (_inApplyAction)
                {
                    return;
                }

                _displayedFunctionRow = null;
                _focusedNode          = focusedNode; //needed to know where to put the parameters within the function

                if (_focusedNode != null && _focusedNode.Tag != null)
                {
                    _displayedFunctionRow = (_focusedNode.Tag as BaseTreeListTag).GetDefaultFunctionRow(); //selected function or function where selected parameter is part of (null if policy selelcted)
                }
                ClearContent();                                                                            //empty controls and activate/deactivate corresponding to whether a function is selected in the tree or not

                if (_displayedFunctionRow == null)
                {
                    return; //no function selected in tree
                }
                lblFunction.Text = _displayedFunctionRow.Name + " (order: " + _displayedFunctionRow.Order + ") in policy " + _displayedFunctionRow.PolicyRow.Name;

                Dictionary <string, string> groupList = new Dictionary <string, string>(); //helper list for group parameters

                foreach (AddParameterTag apt in GetFullParList(_displayedFunctionRow.Name))
                {
                    string parName = apt._parName; DefinitionAdmin.Par parDef = apt._parDef;
                    string groupName  = apt._parGroup == null ? string.Empty : apt._parGroup.groupName;
                    bool   isGroup    = apt._parGroup != null;        //parameter belongs/doesn't belong to a group; does: comp_Cond, comp_perTU
                    bool   isSingle   = parDef.maxCount == 1;         //parameter can/cannot be used more than once; can: DefOuput/Var, cannot: TAX_UNIT
                    bool   isFootnote = parDef.isFootnote;            //parameter is/isn't a footnote parameter; is: #_UpLim, #_Amount
                    bool   isConflict = parDef.substitutes.Count > 0; //parameter has/hasn't a Substitute; has: Output_Var / Output_Add_Var
                    bool   isIn       = false;                        //parameter isn't ...
                    foreach (CountryConfig.ParameterRow countryConfigParameterRow in _displayedFunctionRow.GetParameterRows())
                    {
                        if (countryConfigParameterRow.Name.ToLower() == parName.ToLower())
                        {
                            isIn = true; //.. is already used in the function
                            break;
                        }
                    }

                    string subsitude = string.Empty;
                    string groupOrNo = string.Empty;
                    string count     = string.Empty;

                    if (isSingle && !isGroup && !isFootnote && isIn)
                    {
                        continue; //parameter is already used (and multi use is not possible)
                    }
                    if (!isSingle || isGroup || isFootnote)
                    {
                        count = "1"; //as default multiple useable parameter is added once
                    }
                    if (isGroup)     //group parameter, e.g. comp_Cond, comp_perTU
                    {
                        //propse the likely group identifier, i.e. the next available number
                        if (groupList.Keys.Contains(groupName.ToLower()))
                        {
                            groupOrNo = groupList[groupName.ToLower()]; //for all group parameters of the same group the same group identifier is proposed
                        }
                        else
                        {
                            int maxGroup = GetMaxGroupUsedByFunction(_displayedFunctionRow, groupName) + 1;
                            groupOrNo = maxGroup.ToString();
                            groupList.Add(groupName.ToLower(), groupOrNo);
                        }
                    }

                    if (isFootnote) //footnote parameter, e.g. #_UpLim, #_Amount
                    {
                        //propse the likely footnote identifier, i.e. the next available number
                        groupOrNo = (CountryConfigFacade.GetMaxFootnoteUsedByFunction(_displayedFunctionRow, parName) + 1).ToString();
                    }

                    if (isConflict && !isGroup)
                    {//if e.g. output_var is already used, still show output_add_var, but put out_var in substitute column
                        TreeListNode functionNode = ((focusedNode.Tag as BaseTreeListTag).GetDefaultParameterRow() == null) ? focusedNode : focusedNode.ParentNode;

                        foreach (TreeListNode parameterNode in functionNode.Nodes)
                        {
                            string parameterName = parameterNode.GetDisplayText(TreeListBuilder._policyColumnName);
                            foreach (string conflictPar in parDef.substitutes)
                            {
                                if (parameterName.ToLower() == conflictPar.ToLower())
                                {
                                    subsitude          = parameterName;
                                    apt._parameterNode = parameterNode;
                                    break;
                                }
                            }
                            if (subsitude != string.Empty)
                            {
                                break;
                            }
                        }
                    }

                    int index = dgvParameter.Rows.Add(false, parName, subsitude, groupOrNo, count, parDef.description);
                    dgvParameter.Rows[index].Tag = apt;
                }

                ShowHideRows();
                dgvParameter.Select();
            }
            catch (Exception exception)
            {
                UserInfoHandler.ShowException(exception);
            }
        }
예제 #6
0
        //returns the footnote parameters which need to be added when a formula was changed
        //e.g. formula contains 'Amount#4711' (and did not contain that before the change): footnote parameter #Amount with group 4711 must be added
        internal static Dictionary <KeyValuePair <string, string>, DefinitionAdmin.Par> GetFootnoteParametersToAdd(TreeListNode node, ref string formulaText)
        {
            Dictionary <KeyValuePair <string, string>, DefinitionAdmin.Par> footnoteParametersToAdd =
                new Dictionary <KeyValuePair <string, string>,       //name and group of new footnote parameter
                                DefinitionAdmin.Par>();              //definition (from config file) of new parameter

            int    nextFootnote = TreeListManager.GetNextAvailableFootnoteCounter(node.ParentNode);
            string functionName = node.ParentNode.GetDisplayText(TreeListBuilder._policyColumnName);

            //search for Amount#xi (i.e Amount#x1, Amount#x2, etc.)
            for (int indexLabelAmount = formulaText.ToLower().IndexOf(DefPar.Value.AMOUNT.ToLower() + "#x"), indexNonDigit;
                 indexLabelAmount >= 0;
                 indexLabelAmount = formulaText.ToLower().IndexOf(DefPar.Value.AMOUNT.ToLower() + "#x"))
            {
                for (indexNonDigit = indexLabelAmount + DefPar.Value.AMOUNT.Length + 2;
                     indexNonDigit < formulaText.Length && EM_Helpers.IsDigit(formulaText.ElementAt(indexNonDigit));
                     ++indexNonDigit)
                {
                    ;                                              //search first non digit after Amount#x
                }
                string parameterName = "#_" + DefPar.Value.AMOUNT; //#_Amount
                DefinitionAdmin.Par           parDef = DefinitionAdmin.GetParDefinition(functionName, parameterName);
                KeyValuePair <string, string> parameterNameAndGroup = new KeyValuePair <string, string>(parameterName, nextFootnote.ToString());
                footnoteParametersToAdd.Add(parameterNameAndGroup, parDef);                           //put parameter into list of footnote parameters which need to be generated
                string toReplace = SubstringFromTo(formulaText, indexLabelAmount, indexNonDigit - 1); //Amount#xi (e.g. Amount#x1)
                string replaceBy = DefPar.Value.AMOUNT + "#" + nextFootnote.ToString();               //Amount#f (e.g. Amount#x3)
                formulaText = formulaText.Replace(toReplace, replaceBy);                              //replace all occurrences (there might be more than one)
                ++nextFootnote;
            }

            //search for #xi[_yyy] (i.e. #x1[_Level], #x2[_Level], #x1[_UpLim], etc.)
            for (int indexPlaceholder = formulaText.IndexOf("[_");
                 indexPlaceholder >= 0;
                 indexPlaceholder = formulaText.IndexOf("[_"))
            {
                int iStart = formulaText.Substring(0, indexPlaceholder).LastIndexOf("#x");
                int iEnd   = formulaText.Substring(indexPlaceholder).IndexOf("]") + indexPlaceholder;
                if (iStart >= 0 && iEnd >= 0 &&
                    EM_Helpers.IsNonNegInteger(SubstringFromTo(formulaText, iStart + 2, indexPlaceholder - 1)))
                {
                    string parameterName       = "#" + SubstringFromTo(formulaText, indexPlaceholder + 1, iEnd - 1); //#_yyy (e.g. #_Level)
                    DefinitionAdmin.Fun funDef = DefinitionAdmin.GetFunDefinition(functionName, false);              // check if function allows for this footnote
                    if (funDef != null && (from p in funDef.GetParList() where p.Value.isFootnote && p.Key.ToLower() == parameterName.ToLower() select p).Count() > 0)
                    {
                        DefinitionAdmin.Par           parDef = DefinitionAdmin.GetParDefinition(functionName, parameterName);
                        KeyValuePair <string, string> parameterNameAndGroup = new KeyValuePair <string, string>(parameterName, nextFootnote.ToString());
                        footnoteParametersToAdd.Add(parameterNameAndGroup, parDef);    //put parameter into list of footnote parameters which need to be generated
                        string toReplace = SubstringFromTo(formulaText, iStart, iEnd); //#xi_yyy (e.g. #x1[_Level])
                        string replaceBy = "#" + nextFootnote.ToString();              //#f_yyy (e.g. #4)
                        formulaText = formulaText.Replace(toReplace, replaceBy);       //replace all occurrences (there might be more than one)
                        ++nextFootnote;
                    }
                    else
                    {
                        break; //should not happen (though can), but to avoid infinite loop
                    }
                }
                else
                {
                    break; //should not happen (though can), but to avoid infinite loop
                }
            }

            //search for query#x (e.g. isNtoMchild#x)
            for (int indexPlaceholder = formulaText.IndexOf("#x");
                 indexPlaceholder >= 0;
                 indexPlaceholder = formulaText.IndexOf("#x"))
            {
                string theQuery = string.Empty;
                foreach (string queryName in DefinitionAdmin.GetQueryNamesAndDesc().Keys)
                {
                    string potQueryName = SubstringFromTo(formulaText, indexPlaceholder - (queryName.Length - 2), indexPlaceholder + 1).ToLower();
                    if (potQueryName == queryName.ToLower())
                    {
                        theQuery = queryName;
                        break;
                    }
                }
                if (theQuery == string.Empty)
                {
                    formulaText = formulaText.Substring(0, indexPlaceholder) + "#°" +
                                  formulaText.Substring(indexPlaceholder + 2);   //no query found, replace #x preliminary by #° (change back below)
                }
                else //add all parameters of the query
                {
                    Dictionary <string, DefinitionAdmin.Par> queryParameters = new Dictionary <string, DefinitionAdmin.Par>();
                    DefinitionAdmin.GetQueryDefinition(theQuery, out DefinitionAdmin.Query queryDef, out string dummy, false);
                    if (queryDef != null)
                    {
                        queryParameters = queryDef.par;
                    }
                    List <string> alreadyCoveredByAlias = new List <string>(); // avoid adding e.g. #_income as well as #_info
                    foreach (var q in queryParameters)
                    {
                        string queryParName = q.Key; DefinitionAdmin.Par queryParDef = q.Value;
                        if (alreadyCoveredByAlias.Contains(queryParName))
                        {
                            continue;
                        }
                        footnoteParametersToAdd.Add(new KeyValuePair <string, string>(queryParName, nextFootnote.ToString()), queryParDef); //put parameter into list of footnote parameters which need to be generated
                        alreadyCoveredByAlias.AddRange(queryParDef.substitutes);
                    }
                    formulaText = formulaText.Substring(0, indexPlaceholder) + "#" + nextFootnote.ToString() +
                                  formulaText.Substring(indexPlaceholder + 2); //replace #x by #f (e.g. #x by #5)
                    ++nextFootnote;
                }
            }
            formulaText = formulaText.Replace("#°", "#x");

            return(footnoteParametersToAdd);
        }
예제 #7
0
        internal override void PerformAction()
        {
            TreeListNode policyNode = _senderNode;

            if (_senderNode.ParentNode != null)
            {
                policyNode = _senderNode.ParentNode;
            }

            int newFunctionNodeIndex = -1;
            List <CountryConfig.FunctionRow> newFunctionRows = new List <CountryConfig.FunctionRow>();

            foreach (CountryConfig.PolicyRow policyRow in (policyNode.Tag as PolicyTreeListTag).GetPolicyRows()) //loop over systems
            {
                CountryConfig.FunctionRow newFunctionRow = null;

                //(1) add function
                //if the sender node is a policy node: insert as last function ('Add Function' was called from policy node or 'Add Function After' was called from last function node in policy)
                if (_senderNode == policyNode)
                {
                    newFunctionRow = CountryConfigFacade.AddFunctionRowAtTail(_functionName, policyRow,
                                                                              // the switch of a function inside an extension-policy cannot be changed, therefore add as on (otherwise one would need to remove the policy from the extension to be able to change the switch to on)
                                                                              ExtensionAndGroupManager.ShowExtensionSwitchEditor(policyRow) ? DefPar.Value.ON : DefPar.Value.NA);
                }

                //if the sender node is a function node: insert before ('Add Function Before' was called from function node)
                else
                {
                    CountryConfig.FunctionRow neighbourFunction = (_senderNode.Tag as FunctionTreeListTag).GetFunctionRowOfSystem(policyRow.SystemRow.ID);
                    newFunctionRow = CountryConfigFacade.AddFunctionRow(_functionName, neighbourFunction, true,
                                                                        ExtensionAndGroupManager.ShowExtensionSwitchEditor(policyRow) ? DefPar.Value.ON : DefPar.Value.NA); // see comment above
                    newFunctionNodeIndex = _mainForm.treeList.GetNodeIndex(_senderNode);
                }
                _addedFunctionsIDs.Add(newFunctionRow.ID);

                //(2) add compulsory parameters
                DefinitionAdmin.Fun fun = DefinitionAdmin.GetFunDefinition(_functionName, false);
                if (fun != null)
                {
                    for (short doCommon = 0; doCommon < 2; ++doCommon) // add function-specific parameters before common
                    {
                        foreach (var p in fun.GetParList())
                        {
                            AddPar(p, false);
                        }
                        foreach (var pg in fun.GetGroupParList())
                        {
                            if (pg.minCount > 0)
                            {
                                foreach (var p in pg.par)
                                {
                                    AddPar(p, true);
                                }
                            }
                        }

                        void AddPar(KeyValuePair <string, DefinitionAdmin.Par> p, bool group)
                        {
                            string parName = p.Key.ToUpper() == DefPar.PAR_TYPE.PLACEHOLDER.ToString().ToUpper() ? DefinitionAdmin.ParTypeToString(DefPar.PAR_TYPE.PLACEHOLDER) : p.Key;

                            DefinitionAdmin.Par parDef = p.Value;
                            if (parDef.minCount > 0 && ((doCommon == 0 && !parDef.isCommon) || (doCommon == 1 && parDef.isCommon)))
                            {
                                CountryConfigFacade.AddParameterRowAtTail(newFunctionRow, parName, parDef, group ? "1" : string.Empty);
                            }
                        }
                    }
                }
                newFunctionRows.Add(newFunctionRow);
            }

            _mainForm.GetTreeListBuilder().InsertFunctionNode(newFunctionRows, policyNode, newFunctionNodeIndex);
        }