Example #1
0
        /// <summary>
        /// Delete a variable by the passed in name and all of its uses from this
        /// workspace.May prompt the user for confirmation.
        /// </summary>
        /// <param name="name"> Name of variable to delete.</param>
        public void DeleteVariable(string name)
        {
            // Check wether this variable is a function parameter before deleting.
            var uses = this.GetVariableUses(name);

            foreach (var block in uses)
            {
                if (string.Equals(block.Type, Define.DEFINE_NO_RETURN_BLOCK_TYPE) ||
                    string.Equals(block.Type, Define.DEFINE_WITH_RETURN_BLOCK_TYPE))
                {
                    var procedureName = block.GetFieldValue("NAME");
                    Debug.LogError("Alert:" + I18n.Get(MsgDefine.CANNOT_DELETE_VARIABLE_PROCEDURE).
                                   Replace("%1", name).
                                   Replace("%2", procedureName));
                    return;
                }
            }

            var workspace = this;
            var variable  = workspace.GetVariable(name);

            if (uses.Count > 1)
            {
                // Confirm before deleting multiple blocks.
                Debug.Log("confirm:" + I18n.Get(MsgDefine.DELETE_VARIABLE_CONFIRMATION)
                          .Replace("%1", uses.Count.ToString()).Replace("%2", name));
                workspace.DeleteVariableInternal(variable);
            }
            else
            {
                // No confirmation necessary for a single block.
                this.DeleteVariableInternal(variable);
            }
        }
Example #2
0
        /// <summary>
        /// A new set of Inputs reflecting the current Procedure state.
        /// </summary>
        protected override List <Input> BuildUpdatedInputs()
        {
            List <string> args     = mProcedure.Arguments;
            int           argCount = args.Count;
            List <Input>  inputs   = new List <Input>();

            // Procedure name
            inputs.Add(mBlock.InputList[0]);

            // Argument inputs
            for (int i = 0; i < argCount; ++i)
            {
                Input stackInput = InputFactory.Create(Define.EConnection.InputValue, "ARG" + i, Define.EAlign.Right, null);

                // add "with: " label
                if (i == 0)
                {
                    FieldLabel withLabel = new FieldLabel("WITH", I18n.Get(MsgDefine.PROCEDURES_CALL_BEFORE_PARAMS));
                    stackInput.AppendField(withLabel);
                }

                // add argument's label
                FieldLabel label = new FieldLabel(null, args[i]);
                stackInput.AppendField(label);

                inputs.Add(stackInput);
            }
            return(inputs);
        }
Example #3
0
        /// <summary>
        /// maoling: private method, please call GetOptions() in FieldDropdown instead!!!
        /// Return a sorted list of variable names for variable dropdown menus.
        /// Include a special option at the end for creating a new variable name.
        /// </summary>
        private FieldDropdownMenu[] DropdownCreate()
        {
            List <VariableModel> varModels = null;

            string name = GetText();
            // Don't create a new variable if there is nothing selected.
            var       createSelectedVariable = !string.IsNullOrEmpty(name);
            Workspace workspace = SourceBlock != null ? SourceBlock.Workspace : null;

            if (workspace != null)
            {
                // Get a copy of the list, so that adding rename and new variable options
                // doesn't modify the workspace's list.
                varModels = workspace.GetVariablesOfType("");
                varModels.Sort(VariableModel.CompareByName);
            }

            if (varModels == null)
            {
                varModels = new List <VariableModel>();
            }

            List <FieldDropdownMenu> options = new List <FieldDropdownMenu>();

            for (int i = 0; i < varModels.Count; i++)
            {
                options.Add(new FieldDropdownMenu()
                {
                    Text  = varModels[i].Name,
                    Value = varModels[i].ID
                });
            }

            if (Define.FIELD_VARIABLE_ADD_MANIPULATION_OPTIONS)
            {
                options.Add(new FieldDropdownMenu()
                {
                    Text  = I18n.Get(MsgDefine.RENAME_VARIABLE),
                    Value = MsgDefine.RENAME_VARIABLE
                });
                options.Add(new FieldDropdownMenu()
                {
                    Text  = I18n.Get(MsgDefine.DELETE_VARIABLE),
                    Value = MsgDefine.DELETE_VARIABLE
                });
            }

            return(options.ToArray());
        }
Example #4
0
        /// <summary>
        /// A human-readable string describing the procedure's parameters.
        /// </summary>
        protected String GetParametersListDescription()
        {
            if (mProcedure == null)
            {
                return("");
            }

            StringBuilder sb        = new StringBuilder();
            List <String> arguments = mProcedure.Arguments;

            if (arguments.Count > 0)
            {
                sb.Append(I18n.Get(MsgDefine.PROCEDURES_BEFORE_PARAMS));
                for (int i = 0; i < arguments.Count; ++i)
                {
                    sb.Append(i == 0 ? " " : ", ");
                    sb.Append(arguments[i]);
                }
            }
            return(sb.ToString());
        }
Example #5
0
        /// <summary>
        /// Performs the model changes for the given count. This will reuse as many inputs as possible,
        /// creating new inputs if necessary. Leftover inputs will be disconnected and thrown away.
        /// </summary>
        private void UpdateInternal()
        {
            List <Input> oldInputs = new List <Input>(mBlock.InputList);
            List <Input> newInputs = new List <Input>();

            // Set aside the else input for the end.
            Input elseInput = mBlock.GetInput(ELSE_INPUT_NAME);

            if (elseInput != null)
            {
                oldInputs.Remove(elseInput);
            }

            // Move the first if/do block into the new input list
            newInputs.Add(oldInputs[0]);    //IF0
            newInputs.Add(oldInputs[1]);    //DO0
            oldInputs.RemoveRange(0, 2);

            // Copy over existing inputs if we have them, make new ones if we don't.
            for (int i = 1; i <= mElseIfCount; i++)
            {
                if (oldInputs.Count >= 2)
                {
                    newInputs.Add(oldInputs[0]);    //IFi
                    newInputs.Add(oldInputs[1]);    //DOi
                    oldInputs.RemoveRange(0, 2);
                }
                else
                {
                    // IFi value input
                    Input inputValue = InputFactory.Create(Define.EConnection.InputValue, IF_INPUT_PREFIX + i, ALIGN, new List <string>()
                    {
                        CHECK
                    });
                    inputValue.AppendField(new FieldLabel(null, I18n.Get(MsgDefine.CONTROLS_IF_MSG_ELSEIF)));

                    // DOi statement input
                    Input inputStatement = InputFactory.Create(Define.EConnection.NextStatement, DO_INPUT_PREFIX + i, ALIGN, null);
                    inputStatement.AppendField(new FieldLabel(null, I18n.Get(MsgDefine.CONTROLS_IF_MSG_THEN)));

                    newInputs.Add(inputValue);
                    newInputs.Add(inputStatement);
                }
            }

            // Add the else clause if we need it
            if (mHasElse)
            {
                if (elseInput == null)
                {
                    elseInput = InputFactory.Create(Define.EConnection.NextStatement, ELSE_INPUT_NAME, ALIGN, null);
                    elseInput.AppendField(new FieldLabel(null, I18n.Get(MsgDefine.CONTROLS_IF_MSG_ELSE)));
                }
                newInputs.Add(elseInput);
            }
            else if (elseInput != null)
            {
                // dispose the else statement
                elseInput.Dispose();
            }

            // Clean up extra inputs
            foreach (Input input in oldInputs)
            {
                input.Dispose();
            }
            oldInputs.Clear();

            mBlock.Reshape(newInputs);
        }
Example #6
0
        /// <summary>
        /// Internal implemention of the message reference and interpolation token
        /// Parsing used by tokenizeInterpolation() and replaceMessageReferences().
        /// </summary>
        public static List <string> TokenizeInterpolation(string message, bool parseInterpolationTokens = true)
        {
            var tokens = new List <string>();
            var chars  = message.ToCharArray().ToList();
            // Parse the message with a finite state machine.
            // 0 - Base case.
            // 1 - % found
            // 2 - Digit found.
            // 3 - Message ref found
            var    state  = 0;
            var    buffer = new List <string>();
            string number = "";

            for (var i = 0; i < chars.Count + 1; i++)
            {
                var c = i == chars.Count ? ' ' : chars[i];
                if (state == 0 && i != chars.Count)
                {
                    if (c == '%')
                    {
                        var text = string.Join("", buffer.ToArray());
                        if (!string.IsNullOrEmpty(text))
                        {
                            tokens.Add(text);
                        }
                        buffer.Clear();
                        state = 1; // Start escape.
                    }
                    else
                    {
                        buffer.Add(c.ToString()); // Regular char
                    }
                }
                else if (state == 1)
                {
                    if (c == '%')
                    {
                        buffer.Add(c.ToString()); // Escaped %: %%
                        state = 0;
                    }
                    else if (parseInterpolationTokens && '0' <= c && c <= '9')
                    {
                        state  = 2;
                        number = c.ToString();
                        buffer.Add("");
                        var text = string.Join("", buffer.ToArray());
                        if (!string.IsNullOrEmpty(text))
                        {
                            tokens.Add(text);
                        }
                        buffer.Clear();
                    }
                    else if (c == '{')
                    {
                        state = 3;
                    }
                    else
                    {
                        buffer.Add("%"); // Not recognized. Return as literal.
                        if (i != chars.Count)
                        {
                            buffer.Add(c.ToString());
                        }
                        state = 0; // add parse as string literl
                    }
                }
                else if (state == 2)
                {
                    if ('0' <= c && c <= '9')
                    {
                        number += c; // Multi-digit number.
                    }
                    else
                    {
                        tokens.Add(int.Parse(number).ToString());
                        i--; // Parse this char agian.
                        state = 0;
                    }
                }
                else if (state == 3)
                {
                    if (i == chars.Count)
                    {
                        // Premature end before closing '}'
                        buffer.Insert(0, "%{"); // Re-insert leading delimiter
                        i--;                    // Parse this char again.
                        state = 0;              // add parse as string literal.
                    }
                    else if (c != '}')
                    {
                        buffer.Add(c.ToString());
                    }
                    else
                    {
                        var rawKey = string.Join("", buffer.ToArray());
                        if (new Regex("[a-zA-Z][a-zAZ0-9_]").Match(rawKey).Success) // Strict matching
                        {
                            // Found a valied string key. Attempt case insensitive match.
                            var keyUpper = rawKey.ToUpper();

                            // BKY_ is the prefix used to namespace the string s used in Blockly
                            // core files adn the predefined blocks in ../blocks/. These strings
                            // are defined in ../msgs/ files.
                            var bklyKey = keyUpper.StartsWith("BKY_") ? keyUpper.Substring(4) : null;
                            if (!string.IsNullOrEmpty(bklyKey) && I18n.Contains(bklyKey))
                            {
                                var rawValue = I18n.Get(bklyKey);
                                tokens.AddRange(TokenizeInterpolation(rawValue));
                            }
                            else
                            {
                                tokens.Add("%{" + rawKey + "}");
                            }

                            buffer.Clear(); // Clear the array
                            state = 0;
                        }
                        else
                        {
                            tokens.Add("%{" + rawKey + "}");
                            buffer.Clear();
                            state = 0; // and parse as string literal.
                        }
                    }
                }
            }

            var text1 = string.Join("", buffer.ToArray());

            if (!string.IsNullOrEmpty(text1))
            {
                tokens.Add(text1);
            }

            // Merge adjacent text tokens into a single string.
            var mergedTokens = new List <string>();

            buffer.Clear();
            for (int i = 0; i < tokens.Count; i++)
            {
                int tokenNum = 0;

                if (int.TryParse(tokens[i], out tokenNum))
                {
                    text1 = string.Join("", buffer.ToArray());
                    if (!string.IsNullOrEmpty(text1))
                    {
                        mergedTokens.Add(text1);
                    }
                    buffer.Clear();
                    mergedTokens.Add(tokens[i]);
                }
                else
                {
                    buffer.Add(tokens[i]);
                }
            }

            text1 = string.Join("", buffer.ToArray());

            if (!string.IsNullOrEmpty(text1))
            {
                mergedTokens.Add(text1);
            }
            buffer.Clear();

            // remove last
            return(mergedTokens);
        }