示例#1
0
        public override string ForgeRawLine()
        {
            StringBuilder b = new StringBuilder();

            if (!string.IsNullOrWhiteSpace(Url))
            {
                b.Append(",");
                b.Append(StringEscaper.DoubleQuote(Url));
            }
            b.Append(base.ForgeRawLine());
            return(b.ToString());
        }
示例#2
0
        public override string ForgeRawLine()
        {
            StringBuilder b = new StringBuilder();

            b.Append(",");
            b.Append(StringEscaper.DoubleQuote(SectionName));
            b.Append(",");
            b.Append(Picture == null ? "0" : StringEscaper.DoubleQuote(Picture));
            b.Append(HideProgress ? ",True" : ",False");
            b.Append(base.ForgeRawLine());
            return(b.ToString());
        }
示例#3
0
        public static void Macro(EngineState s, CodeCommand cmd)
        {
            CodeInfo_Macro info = cmd.Info as CodeInfo_Macro;

            if (info == null)
            {
                throw new InvalidCodeCommandException("Command [Macro] should have [CodeInfo_Macro]", cmd);
            }

            CodeCommand macroCmd;

            if (s.Macro.MacroDict.ContainsKey(info.MacroType))
            {
                macroCmd         = s.Macro.MacroDict[info.MacroType];
                macroCmd.RawCode = cmd.RawCode;
            }
            else if (s.Macro.LocalDict.ContainsKey(info.MacroType))
            { // Try to find [infoMacroType] in [Variables] <- I hate undocumented behaviors!
                macroCmd         = s.Macro.LocalDict[info.MacroType];
                macroCmd.RawCode = cmd.RawCode;
            }
            else
            {
                throw new CodeCommandException($"Invalid Command [{info.MacroType}]", cmd);
            }

            Dictionary <int, string> paramDict = new Dictionary <int, string>();

            for (int i = 0; i < info.Args.Count; i++)
            {
                paramDict[i + 1] = StringEscaper.ExpandSectionParams(s, info.Args[i]);
            }

            s.CurSectionParams = paramDict;

            if (s.LogMacro)
            {
                s.InMacro = true;
                CommandBranch.RunExec(s, macroCmd, true);
                s.InMacro = false;
            }
            else // Do not log macro
            {
                s.Logger.Build_Write(s, new LogInfo(LogState.Info, $"Macro [{info.MacroType}] ({cmd.RawCode})", s.CurDepth + 1));
                s.Logger.TurnOff.Push(true);
                CommandBranch.RunExec(s, macroCmd, true);
                s.Logger.TurnOff.TryPop(out bool dummy);
            }
        }
示例#4
0
        public override string ForgeRawLine()
        {
            StringBuilder b = new StringBuilder();

            b.Append(Value ? ",True" : ",False");
            if (SectionName != null)
            {
                b.Append(",_");
                b.Append(StringEscaper.DoubleQuote(SectionName));
                b.Append("_");
                b.Append(HideProgress ? ",True" : ",False");
            }
            b.Append(base.ForgeRawLine());
            return(b.ToString());
        }
示例#5
0
        public static string PackRegMultiBinary(IEnumerable <string> multiStrs)
        {
            StringBuilder b = new StringBuilder();

            string[] list = multiStrs.ToArray();
            for (int i = 0; i < list.Length; i++)
            {
                byte[] bin = Encoding.Unicode.GetBytes(list[i]);
                b.Append(StringEscaper.PackRegBinary(bin));
                if (i + 1 < list.Length)
                {
                    b.Append(",00,00,");
                }
            }

            return(b.ToString());
        }
示例#6
0
        public override string ForgeRawLine()
        {
            StringBuilder b = new StringBuilder();

            foreach (string item in Items)
            {
                b.Append(",");
                b.Append(StringEscaper.DoubleQuote(item));
            }
            if (SectionName != null)
            {
                b.Append(",_");
                b.Append(StringEscaper.DoubleQuote(SectionName));
                b.Append("_");
                b.Append(HideProgress ? ",True" : ",False");
            }
            b.Append(ForgeToolTip());
            return(b.ToString());
        }
示例#7
0
        public string ForgeRawLine(bool includeKey)
        {
            StringBuilder b = new StringBuilder();

            if (includeKey)
            {
                b.Append(StringEscaper.QuoteEscape(Key));
                b.Append("=");
            }

            b.Append(StringEscaper.QuoteEscape(Text));
            b.Append(",");
            if (Visibility)
            {
                b.Append("1,");
            }
            else
            {
                b.Append("0,");
            }
            b.Append((int)Type);
            b.Append(",");
            b.Append(Rect.Left);
            b.Append(",");
            b.Append(Rect.Top);
            b.Append(",");
            b.Append(Rect.Width);
            b.Append(",");
            b.Append(Rect.Height);

            b.Append(Info.ForgeRawLine());

            /*
             * string optionalArgs = Info.ForgeRawLine();
             * if (0 < optionalArgs.Length) // Only if optionalArgs is not empty
             * {
             *  b.Append(",");
             *  b.Append(optionalArgs);
             * }
             */

            return(b.ToString());
        }
示例#8
0
        public override string ForgeRawLine()
        {
            StringBuilder b = new StringBuilder();

            for (int i = 0; i < Items.Count - 1; i++)
            {
                b.Append(",");
                b.Append(StringEscaper.QuoteEscape(Items[i]));
            }
            b.Append(",");
            b.Append(StringEscaper.QuoteEscape(Items.Last()));
            if (SectionName != null)
            {
                b.Append(",_");
                b.Append(SectionName);
                b.Append("_");
                b.Append(HideProgress ? ",True" : ",False");
            }
            b.Append(base.ForgeRawLine());
            return(b.ToString());
        }
示例#9
0
        public string ForgeRawLine(bool includeKey)
        {
            StringBuilder b = new StringBuilder();

            if (includeKey)
            {
                b.Append(Key);
                b.Append("=");
            }
            b.Append(StringEscaper.DoubleQuote(Text));
            b.Append(",");
            b.Append(Visibility ? "1," : "0,");
            b.Append((int)Type);
            b.Append(",");
            b.Append(X);
            b.Append(",");
            b.Append(Y);
            b.Append(",");
            b.Append(Width);
            b.Append(",");
            b.Append(Height);
            b.Append(Info.ForgeRawLine());
            return(b.ToString());
        }
示例#10
0
        public bool SetValue(string newValue, bool update, out List <LogInfo> logs)
        {
            logs = new List <LogInfo>(1);
            bool success = false;

            switch (Type)
            {
            case UIControlType.TextLabel:
                // Text
                Text = StringEscaper.Escape(newValue);

                logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [{newValue}]"));
                success = true;
                break;

            case UIControlType.TextBox:
            {         // Value
                UIInfo_TextBox uiInfo = Info.Cast <UIInfo_TextBox>();
                uiInfo.Value = StringEscaper.Escape(newValue);

                logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [{newValue}]"));
                success = true;
            }
            break;

            case UIControlType.NumberBox:
            {         // Value
                UIInfo_NumberBox uiInfo = Info.Cast <UIInfo_NumberBox>();

                // WB082 just write string value in case of error, but PEBakery will throw error
                if (!NumberHelper.ParseInt32(newValue, out int intVal))
                {
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] is not a valid integer"));
                    return(false);
                }

                if (uiInfo.Min <= intVal && intVal <= uiInfo.Max)
                {
                    uiInfo.Value = intVal;
                }
                else
                {
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] should be inside of [{uiInfo.Min}] ~ [{uiInfo.Max}]"));
                    return(false);
                }

                logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [{newValue}]"));
                success = true;
            }
            break;

            case UIControlType.CheckBox:
            {         // Value
                UIInfo_CheckBox uiInfo = Info.Cast <UIInfo_CheckBox>();

                if (newValue.Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    uiInfo.Value = true;

                    logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [True]"));
                    success = true;
                }
                else if (newValue.Equals("False", StringComparison.OrdinalIgnoreCase))
                {
                    uiInfo.Value = false;

                    logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [False]"));
                    success = true;
                }
                else
                {         // WB082 just write string value in case of error, but PEBakery will throw error
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] is not a valid boolean value"));
                    return(false);
                }
            }
            break;

            case UIControlType.ComboBox:
            {         // Text
                UIInfo_ComboBox uiInfo = Info.Cast <UIInfo_ComboBox>();

                int idx = uiInfo.Items.FindIndex(x => newValue.Equals(StringEscaper.Unescape(x), StringComparison.OrdinalIgnoreCase));
                if (idx == -1)
                {         // Invalid index
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] was not found in the item list"));
                    return(false);
                }

                uiInfo.Index = idx;
                Text         = uiInfo.Items[idx];

                logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [{Text}]"));
                success = true;
            }
            break;

            case UIControlType.RadioButton:
            {
                UIInfo_RadioButton uiInfo = Info.Cast <UIInfo_RadioButton>();

                if (newValue.Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    uiInfo.Selected = true;

                    logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [True]"));
                    success = true;
                }
                else if (newValue.Equals("False", StringComparison.OrdinalIgnoreCase))
                {
                    uiInfo.Selected = false;

                    logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [False]"));
                    success = true;
                }
                else
                {         // WB082 just write string value, but PEBakery will throw error
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] is not a valid boolean value"));
                    return(false);
                }
            }
            break;

            case UIControlType.FileBox:
                Text = StringEscaper.Escape(newValue);

                logs.Add(new LogInfo(LogState.Success, $"Interface Control [{Key}] set to [{newValue}]"));
                success = true;
                break;

            case UIControlType.RadioGroup:
            {
                UIInfo_RadioGroup uiInfo = Info.Cast <UIInfo_RadioGroup>();

                if (!NumberHelper.ParseInt32(newValue, out int idx))
                {
                    logs.Add(new LogInfo(LogState.Error, $"[{newValue}] is not a valid integer"));
                    return(false);
                }

                if (0 <= idx && idx < uiInfo.Items.Count)
                {
                    uiInfo.Selected = idx;
                }
                else
                {         // Invalid Index
                    logs.Add(new LogInfo(LogState.Error, $"Index [{newValue}] is invalid"));
                    return(false);
                }

                logs.Add(new LogInfo(LogState.Success, $"Interface control [{Key}] set to [{newValue}]"));
                success = true;
            }
            break;
            }

            if (success && update)
            {
                Update();
            }

            return(success);
        }
示例#11
0
        public string GetValue(bool strict)
        {
            string value = null;

            switch (Type)
            {
            case UIControlType.TextLabel:
                // Text
                if (strict)
                {
                    value = StringEscaper.Unescape(Text);
                }
                break;

            case UIControlType.TextBox:
            {         // Value
                UIInfo_TextBox info = Info.Cast <UIInfo_TextBox>();
                value = StringEscaper.Unescape(info.Value);
            }
            break;

            case UIControlType.NumberBox:
            {         // Value
                UIInfo_NumberBox info = Info.Cast <UIInfo_NumberBox>();
                value = info.Value.ToString();
            }
            break;

            case UIControlType.CheckBox:
            {         // Value
                UIInfo_CheckBox info = Info.Cast <UIInfo_CheckBox>();
                value = info.Value ? "True" : "False";
            }
            break;

            case UIControlType.ComboBox:
                // Text
                value = StringEscaper.Unescape(Text);
                break;

            case UIControlType.RadioButton:
            {         // Selected
                UIInfo_RadioButton info = Info.Cast <UIInfo_RadioButton>();
                value = info.Selected ? "True" : "False";
            }
            break;

            case UIControlType.FileBox:
                // Text
                value = StringEscaper.Unescape(Text);
                break;

            case UIControlType.RadioGroup:
            {         // Selected
                UIInfo_RadioGroup info = Info.Cast <UIInfo_RadioGroup>();
                value = info.Selected.ToString();
            }
            break;
            }

            return(value);
        }
示例#12
0
        private static UIInfo ParseUICommandInfo(UIType type, List <string> fullArgs)
        {
            // Only use fields starting from 8th operand
            List <string> args = fullArgs.Skip(6).ToList(); // Remove Text, Visibility, X, Y, width, height

            switch (type)
            {
                #region TextBox
            case UIType.TextBox:
            {
                const int minOpCount = 1;
                const int maxOpCount = 1;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))         // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                return(new UIInfo_TextBox(GetInfoTooltip(args, maxOpCount), StringEscaper.Unescape(args[0])));
            }

                #endregion
                #region TextLabel
            case UIType.TextLabel:
            {
                const int minOpCount = 1;
                const int maxOpCount = 2;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))         // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                NumberHelper.ParseInt32(args[0], out int fontSize);
                UIInfo_TextLabel_Style style = UIInfo_TextLabel_Style.Normal;
                if (args[1].Equals("Bold", StringComparison.OrdinalIgnoreCase))
                {
                    style = UIInfo_TextLabel_Style.Bold;
                }
                else if (args[1].Equals("Italic", StringComparison.OrdinalIgnoreCase))
                {
                    style = UIInfo_TextLabel_Style.Italic;
                }
                else if (args[1].Equals("Underline", StringComparison.OrdinalIgnoreCase))
                {
                    style = UIInfo_TextLabel_Style.Underline;
                }
                else if (args[1].Equals("Strike", StringComparison.OrdinalIgnoreCase))
                {
                    style = UIInfo_TextLabel_Style.Strike;
                }

                return(new UIInfo_TextLabel(GetInfoTooltip(args, maxOpCount), fontSize, style));
            }

                #endregion
                #region NumberBox
            case UIType.NumberBox:
            {
                const int minOpCount = 4;
                const int maxOpCount = 4;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))         // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                NumberHelper.ParseInt32(args[0], out int value);
                NumberHelper.ParseInt32(args[1], out int min);
                NumberHelper.ParseInt32(args[2], out int max);
                NumberHelper.ParseInt32(args[3], out int interval);

                return(new UIInfo_NumberBox(GetInfoTooltip(args, maxOpCount), value, min, max, interval));
            }

                #endregion
                #region CheckBox
            case UIType.CheckBox:
            {
                const int minOpCount = 1;
                const int maxOpCount = 3;                                                // +2 for [RunOptional]
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1)) // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                bool _checked = false;
                if (args[0].Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    _checked = true;
                }
                else if (args[0].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                {
                    throw new InvalidCommandException($"Invalid argument [{args[0]}], must be [True] or [False]");
                }

                string tooltip = null;
                if (args.Last().StartsWith("__", StringComparison.Ordinal))         // Has <ToolTip>
                {
                    tooltip = GetInfoTooltip(args, args.Count - 1);
                }

                string sectionName  = null;
                bool   hideProgress = false;
                if (3 <= args.Count &&
                    (args[2].Equals("True", StringComparison.OrdinalIgnoreCase) || args[2].Equals("False", StringComparison.OrdinalIgnoreCase)) &&
                    (args[1].StartsWith("_", StringComparison.Ordinal) && args[1].EndsWith("_", StringComparison.Ordinal)))
                {         // Has [RunOptinal] -> <SectionName>,<HideProgress>
                    if (args[2].Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        hideProgress = true;
                    }
                    else if (args[2].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        throw new InvalidCommandException($"Invalid argument [{args[2]}], must be [True] or [False]");
                    }

                    sectionName = args[1].Substring(1, args[1].Length - 2);
                }

                return(new UIInfo_CheckBox(tooltip, _checked, sectionName, hideProgress));
            }

                #endregion
                #region ComboBox
            case UIType.ComboBox:
            {         // Variable Length
                List <string> items = new List <string>();

                // Have ToolTip?
                string toolTip = null;
                int    cnt     = args.Count;
                if (args.Last().StartsWith("__", StringComparison.Ordinal))
                {
                    toolTip = args.Last();
                    cnt    -= 1;
                }

                string sectionName  = null;
                bool   hideProgress = false;
                if (2 <= cnt &&
                    (args[cnt - 1].Equals("True", StringComparison.OrdinalIgnoreCase) || args[cnt - 1].Equals("False", StringComparison.OrdinalIgnoreCase)) &&
                    (args[cnt - 2].StartsWith("_", StringComparison.Ordinal) && args[cnt - 2].EndsWith("_", StringComparison.Ordinal)))
                {         // Has [RunOptinal] -> <SectionName>,<HideProgress>
                    if (args[cnt - 1].Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        hideProgress = true;
                    }
                    else if (args[cnt - 1].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        throw new InvalidCommandException($"Invalid argument [{args[cnt - 1]}], must be [True] or [False]");
                    }

                    sectionName = args[cnt - 2].Substring(1, args[cnt - 2].Length - 2);
                    cnt        -= 2;
                }

                for (int i = 0; i < cnt; i++)
                {
                    items.Add(args[i]);
                }

                int idx = items.IndexOf(fullArgs[0]);
                if (idx == -1)
                {
                    throw new InvalidCommandException($"[{type}] has wrong selected value [{fullArgs[0]}]");
                }

                return(new UIInfo_ComboBox(toolTip, items, idx, sectionName, hideProgress));
            }

                #endregion
                #region Image
            case UIType.Image:
            {
                const int minOpCount = 0;
                const int maxOpCount = 1;                                                // [URL]
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1)) // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                string url = null;
                if (maxOpCount < args.Count)
                {
                    url = args[maxOpCount];
                }

                return(new UIInfo_Image(GetInfoTooltip(args, maxOpCount), url));
            }

                #endregion
                #region TextFile
            case UIType.TextFile:
            {
                const int minOpCount = 0;
                const int maxOpCount = 0;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                return(new UIInfo_TextFile(GetInfoTooltip(args, maxOpCount)));
            }

                #endregion
                #region Button
            case UIType.Button:
            {         // <SectionToRun>,<Picture>,[HideProgress]  +[UnknownBoolean] +[RunOptional]
                // Ex)
                // pButton1 =,1,8,382,47,24,24,Process-OpenDriver_x86,opendir.bmp,False,_Process-OpenDriver_x86,False,_Process-OpenDriver_x86_,False
                // Button_Download=,1,8,403,21,24,24,DownloadXXX,DoubleJDesignRavenna3dArrowDown0016016.bmp,False,False,_DownloadXXX_,False,"__DOWNLOAD Plugin"
                // OpendirSMFilesButton=,1,8,475,204,24,24,Opendir_SMFiles,opendir.bmp,"__Open Custom .ini Folder"
                // Button_HiveUnload_Target="HiveUnload: Target + ProjectTemp + MountFolders",1,8,15,17,293,46,HiveUnload_Launch_B,HiveUnload3232.bmp,0,"__UnLoad hives"
                // Button_Tools_Folder="Open Tools Folder",1,8,98,256,134,25,Open_Tools_Folder
                const int minOpCount = 1;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, -1))
                {
                    throw new InvalidCommandException($"[{type}] must have at least [{minOpCount}] arguments");
                }

                int    cnt     = args.Count;
                string tooltip = null;
                if (args.Last().StartsWith("__", StringComparison.Ordinal))         // Has <ToolTip>
                {
                    tooltip = GetInfoTooltip(args, cnt - 1);
                    cnt    -= 1;
                }

                string sectionName = args[0];

                string picture = null;
                if (2 <= cnt)
                {
                    if (args[1].Equals("0", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        picture = args[1];
                    }
                }

                bool hideProgress = false;
                if (3 <= cnt)
                {
                    if (args[2].Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        hideProgress = true;
                    }
                    else if (args[2].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        // WB082 Compability Shim
                        if (args[2].Equals("1", StringComparison.Ordinal))
                        {
                            hideProgress = true;
                        }
                        else if (args[2].Equals("0", StringComparison.Ordinal) == false)
                        {
                            throw new InvalidCommandException($"Invalid argument [{args[2]}], must be [True] or [False]");
                        }
                    }
                }

                // Ignore [UnknownBoolean] and [RunOptional]

                return(new UIInfo_Button(tooltip, args[0], picture, hideProgress));
            }

                #endregion
                #region WebLabel
            case UIType.WebLabel:
            {
                const int minOpCount = 1;
                const int maxOpCount = 1;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))         // +1 for tooltip
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                return(new UIInfo_WebLabel(GetInfoTooltip(args, maxOpCount), StringEscaper.Unescape(args[0])));
            }

                #endregion
                #region RadioButton
            case UIType.RadioButton:
            {
                const int minOpCount = 1;
                const int maxOpCount = 3;         // +2 for [RunOptional]
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                bool selected = false;
                if (args[0].Equals("True", StringComparison.OrdinalIgnoreCase))
                {
                    selected = true;
                }
                else if (args[0].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                {
                    throw new InvalidCommandException($"Invalid argument [{args[0]}], must be [True] or [False]");
                }

                string tooltip = null;
                if (args.Last().StartsWith("__", StringComparison.Ordinal))         // Has <ToolTip>
                {
                    tooltip = GetInfoTooltip(args, args.Count - 1);
                }

                string sectionName  = null;
                bool   hideProgress = false;
                if (3 <= args.Count &&
                    (args[2].Equals("True", StringComparison.OrdinalIgnoreCase) || args[2].Equals("False", StringComparison.OrdinalIgnoreCase)) &&
                    (args[1].StartsWith("_", StringComparison.Ordinal) && args[1].EndsWith("_", StringComparison.Ordinal)))
                {         // Has [RunOptinal] -> <SectionName>,<HideProgress>
                    if (args[2].Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        hideProgress = true;
                    }
                    else if (args[2].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        throw new InvalidCommandException($"Invalid argument [{args[2]}], must be [True] or [False]");
                    }

                    sectionName = args[1].Substring(1, args[1].Length - 2);
                }

                return(new UIInfo_RadioButton(tooltip, selected, sectionName, hideProgress));
            }

                #endregion
                #region Bevel
            case UIType.Bevel:
            {
                const int minOpCount = 0;
                const int maxOpCount = 0;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                return(new UIInfo_Bevel(GetInfoTooltip(args, maxOpCount)));
            }

                #endregion
                #region FileBox
            case UIType.FileBox:
            {
                const int minOpCount = 0;
                const int maxOpCount = 1;
                if (CodeParser.CheckInfoArgumentCount(args, minOpCount, maxOpCount + 1))
                {
                    throw new InvalidCommandException($"[{type}] can have [{minOpCount}] ~ [{maxOpCount + 1}] arguments");
                }

                bool isFile = false;
                if (0 < args.Count)
                {
                    if (args[0].Equals("file", StringComparison.OrdinalIgnoreCase))
                    {
                        isFile = true;
                    }
                    else if (args[0].Equals("dir", StringComparison.OrdinalIgnoreCase))
                    {
                        isFile = false;
                    }
                    else
                    {
                        throw new InvalidCommandException($"Argument [{type}] should be one of [file] or [dir]");
                    }
                }

                return(new UIInfo_FileBox(GetInfoTooltip(args, maxOpCount), isFile));
            }

                #endregion
                #region RadioGroup
            case UIType.RadioGroup:
            {         // Variable Length
                List <string> items = new List <string>();

                string sectionName  = null;
                bool   showProgress = false;

                int cnt = args.Count - 1;
                if (args.Last().StartsWith("__", StringComparison.Ordinal))         // Has <ToolTip>
                {
                    cnt -= 1;
                }

                if ((args[cnt].Equals("True", StringComparison.OrdinalIgnoreCase) || args[cnt].Equals("False", StringComparison.OrdinalIgnoreCase)) &&
                    (args[cnt - 1].StartsWith("_", StringComparison.Ordinal) && args[cnt - 1].EndsWith("_", StringComparison.Ordinal)))
                {         // Has [RunOptinal] -> <SectionName>,<HideProgress>
                    if (args[cnt].Equals("True", StringComparison.OrdinalIgnoreCase))
                    {
                        showProgress = true;
                    }
                    else if (args[cnt].Equals("False", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        throw new InvalidCommandException($"Invalid argument [{args[cnt]}], must be [True] or [False]");
                    }

                    sectionName = args[cnt - 1].Substring(1, args[cnt - 1].Length - 2);

                    cnt -= 2;
                }

                for (int i = 0; i < cnt; i++)
                {
                    items.Add(args[i]);
                }

                if (NumberHelper.ParseInt32(args[cnt], out int idx) == false)
                {
                    throw new InvalidCommandException($"Invalid argument [{args[cnt]}], must be integer");
                }

                return(new UIInfo_RadioGroup(GetInfoTooltip(args, args.Count), items, idx, sectionName, showProgress));
            }

                #endregion
                #region default
            default:
                Debug.Assert(false);
                break;
                #endregion
            }

            throw new InvalidCommandException($"Invalid UICommand [{type}]");
        }
示例#13
0
        /// <summary>
        /// Ready to run an plugin
        /// </summary>
        internal static void ReadyRunPlugin(EngineState s, Plugin p = null)
        {
            long buildId = s.BuildId;

            // Turn off System,ErrorOff
            s.ErrorOffStartLineIdx = -1;
            s.ErrorOffLineCount    = 0;
            // Turn off System,Log,Off
            s.Logger.SuspendLog = false;

            // Assert s.CurDepth == 1
            Debug.Assert(s.CurDepth == 1);

            // Set CurrentPlugin
            // Note: s.CurrentPluginIdx is not touched here
            if (p == null)
            {
                p = s.CurrentPlugin;
            }
            else
            {
                s.CurrentPlugin = p;
            }

            // Init Per-Plugin Log
            s.PluginId = s.Logger.Build_Plugin_Init(s, s.CurrentPlugin, s.CurrentPluginIdx + 1);

            // Log Plugin Build Start Message
            string msg;

            if (s.RunOnePlugin && s.EntrySection.Equals("Process", StringComparison.OrdinalIgnoreCase) == false)
            {
                msg = $"Processing Section [{s.EntrySection}] of plugin [{p.ShortPath}] ({s.CurrentPluginIdx + 1}/{s.Plugins.Count})";
            }
            else
            {
                msg = $"[{s.CurrentPluginIdx + 1}/{s.Plugins.Count}] Processing Plugin [{p.Title}] ({p.ShortPath})";
            }
            s.Logger.Build_Write(s, msg);
            s.Logger.Build_Write(s, Logger.LogSeperator);

            // Load Default Per-Plugin Variables
            s.Variables.ResetVariables(VarsType.Local);
            s.Logger.Build_Write(s, s.Variables.LoadDefaultPluginVariables(p));

            // Load Per-Plugin Macro
            s.Macro.ResetLocalMacros();
            s.Logger.Build_Write(s, s.Macro.LoadLocalMacroDict(p, false));

            // Reset Current Section Parameter
            s.CurSectionParams = new Dictionary <int, string>();

            // Clear Processed Section Hashes
            s.ProcessedSectionHashes.Clear();

            // Set Interface using MainWindow, MainViewModel
            if (s.RunOnePlugin)
            {
                s.MainViewModel.PluginTitleText = StringEscaper.Unescape(p.Title);
            }
            else
            {
                s.MainViewModel.PluginTitleText = $"({s.CurrentPluginIdx + 1}/{s.Plugins.Count}) {StringEscaper.Unescape(p.Title)}";
            }
            s.MainViewModel.PluginDescriptionText = StringEscaper.Unescape(p.Description);
            s.MainViewModel.PluginVersionText     = "v" + p.Version;
            if (MainWindow.PluginAuthorLenLimit < p.Author.Length)
            {
                s.MainViewModel.PluginAuthorText = p.Author.Substring(0, MainWindow.PluginAuthorLenLimit) + "...";
            }
            else
            {
                s.MainViewModel.PluginAuthorText = p.Author;
            }
            s.MainViewModel.BuildEchoMessage = $"Processing Section [{s.EntrySection}]...";

            long allLineCount = 0;

            foreach (var kv in s.CurrentPlugin.Sections.Where(x => x.Value.Type == SectionType.Code))
            {
                allLineCount += kv.Value.Lines.Count; // Why not Codes? PEBakery compiles code on-demand, so we have only Lines at this time.
            }
            s.MainViewModel.BuildPluginProgressBarMax   = allLineCount;
            s.MainViewModel.BuildPluginProgressBarValue = 0;
            s.MainViewModel.BuildFullProgressBarValue   = s.CurrentPluginIdx;

            if (Application.Current != null)
            {
                Application.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    MainWindow w = Application.Current.MainWindow as MainWindow;

                    w.DrawPluginLogo(p);

                    if (w.CurBuildTree != null)
                    {
                        w.CurBuildTree.BuildFocus = false;
                    }

                    w.CurBuildTree = s.MainViewModel.BuildTree.FindPluginByFullPath(s.CurrentPlugin.FullPath);

                    if (w.CurBuildTree != null)
                    {
                        w.CurBuildTree.BuildFocus = true;
                    }
                }));
            }
        }
示例#14
0
        private List <LogInfo> CheckInterfaceSection(ScriptSection section, string rawLine = null, int lineIdx = 0)
        {
            // If this section was already visited, return.
            if (_visitedSections.Contains(section.Name))
            {
                return(new List <LogInfo>());
            }
            _visitedSections.Add(section.Name);

            // Force parsing of code, bypassing caching by section.GetUICtrls()
            string[] lines = section.Lines;
            if (lines == null)
            {
                string msg = $"Section [{section.Name}] is not a valid interface section";
                if (rawLine != null)
                {
                    msg += $" ({rawLine})";
                }
                if (0 < lineIdx)
                {
                    msg += $" (Line {lineIdx})";
                }

                return(new List <LogInfo> {
                    new LogInfo(LogState.Error, msg)
                });
            }

            (List <UIControl> uiCtrls, List <LogInfo> logs) = UIParser.ParseStatements(lines, section);
            foreach (UIControl uiCtrl in uiCtrls)
            {
                switch (uiCtrl.Type)
                {
                case UIControlType.CheckBox:
                {
                    UIInfo_CheckBox info = uiCtrl.Info.Cast <UIInfo_CheckBox>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.ComboBox:
                {
                    UIInfo_ComboBox info = uiCtrl.Info.Cast <UIInfo_ComboBox>();

                    // Practically, this means info.Index is -1 -> uiCtrl.Text not being one of info.Items
                    if (info.Index < 0 || info.Items.Count <= info.Index)
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Incorrect selected value [{uiCtrl.Text}]", uiCtrl));
                    }
                }
                break;

                case UIControlType.Image:
                {
                    // Check encoded image
                    string imageSection = StringEscaper.Unescape(uiCtrl.Text);
                    if (!imageSection.Equals(UIInfo_Image.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, imageSection))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Image resource [{imageSection}] does not exist", uiCtrl));
                    }

                    UIInfo_Image info = uiCtrl.Info.Cast <UIInfo_Image>();

                    // Check if image control have empty or invalid url.
                    // Ex) Colors_Image=ThemeColors.jpg,1,5,11,228,260,80,
                    if (info.Url != null)
                    {
                        string url = StringEscaper.Unescape(info.Url);
                        if (!StringEscaper.IsUrlValid(url))
                        {
                            if (url.IndexOf("://", StringComparison.Ordinal) != -1)
                            {
                                logs.Add(new LogInfo(LogState.Warning, $"Incorrect URL [{url}]", uiCtrl));
                            }
                            else
                            {
                                logs.Add(new LogInfo(LogState.Warning, "URL does not have a scheme. Did you omit \"http(s)://\"?", uiCtrl));
                            }
                        }
                    }
                }
                break;

                case UIControlType.TextFile:
                {
                    string textSection = StringEscaper.Unescape(uiCtrl.Text);
                    if (!textSection.Equals(UIInfo_TextFile.NoResource, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, textSection))
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Text resource [{textSection}] does not exist", uiCtrl));
                    }
                }
                break;

                case UIControlType.Button:
                {
                    UIInfo_Button info = uiCtrl.Info.Cast <UIInfo_Button>();

                    string pictureSection = info.Picture;
                    if (pictureSection != null &&
                        !pictureSection.Equals(UIInfo_Button.NoPicture, StringComparison.OrdinalIgnoreCase) &&
                        !EncodedFile.ContainsInterface(_sc, pictureSection))
                    {
                        if (pictureSection.Length == 0)         // Due to quirks of WinBuilder's editor, many buttons have '' instead of '0' in the place of <Picture>.
                        {
                            logs.Add(new LogInfo(LogState.Warning, "Image resource entry is empty. Use [0] to represent not having an image resource.", uiCtrl));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"Image resource [{pictureSection}] does not exist", uiCtrl));
                        }
                    }

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.WebLabel:
                {
                    UIInfo_WebLabel info = uiCtrl.Info.Cast <UIInfo_WebLabel>();

                    // Sometime developers forget to put proper scheme in WebLabel's url.
                    // Ex) PStart_WebLabel="PStart Homepage",1,10,668,122,98,18,www.pegtop.de/start/
                    string url = StringEscaper.Unescape(info.Url);
                    if (!StringEscaper.IsUrlValid(url))
                    {
                        if (url.IndexOf("://", StringComparison.Ordinal) != -1)
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"Incorrect URL [{url}]", uiCtrl));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Warning, "URL does not have scheme. Did you omit \"http(s)://\"?", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioButton:
                {
                    UIInfo_RadioButton info = uiCtrl.Info.Cast <UIInfo_RadioButton>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.FileBox:
                {
                    UIInfo_FileBox info = uiCtrl.Info.Cast <UIInfo_FileBox>();

                    if (info.IsFile)
                    {         // Select File
                        if (info.Filter != null)
                        {
                            string filter = StringEscaper.Unescape(info.Filter);
                            if (StringEscaper.IsFileFilterValid(filter) == false)
                            {
                                logs.Add(new LogInfo(LogState.Warning, $"File filter pattern [{filter}] is invalid", uiCtrl));
                            }
                        }
                    }
                    else
                    {         // Select Folder
                        if (info.Filter != null)
                        {
                            logs.Add(new LogInfo(LogState.Warning, $"File filters cannot be used for folder selection", uiCtrl));
                        }
                    }
                }
                break;

                case UIControlType.RadioGroup:
                {
                    UIInfo_RadioGroup info = uiCtrl.Info.Cast <UIInfo_RadioGroup>();

                    if (info.SectionName != null)
                    {
                        if (_sc.Sections.ContainsKey(info.SectionName))         // Only if section exists
                        {
                            logs.AddRange(CheckCodeSection(_sc.Sections[info.SectionName], uiCtrl.RawLine, uiCtrl.LineIdx));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exist", uiCtrl));
                        }
                    }

                    // Practically, this means info.Index is -1 -> uiCtrl.Text not being one of info.Items
                    if (info.Selected < 0 || info.Items.Count <= info.Selected)
                    {
                        logs.Add(new LogInfo(LogState.Warning, $"Incorrect selected index [{info.Selected}]", uiCtrl));
                    }
                }
                break;
                }
            }
            return(logs);
        }
示例#15
0
        private void RecursiveFindCodeSection(IReadOnlyList <CodeCommand> codes, List <LogInfo> logs)
        {
            string targetCodeSection      = null;
            string targetInterfaceSection = null;

            foreach (CodeCommand cmd in codes)
            {
                switch (cmd.Type)
                {
                    #region Check CodeSections
                case CodeType.If:
                {
                    CodeInfo_If info = cmd.Info.Cast <CodeInfo_If>();

                    if (info.Condition.Type == BranchConditionType.ExistSection)
                    {
                        // For recursive section call
                        // Ex) If,ExistSection,%ScriptFile%,DoWork,Run,%ScriptFile%,DoWork
                        if (info.Condition.Arg1.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                            info.Embed.Type == CodeType.Run || info.Embed.Type == CodeType.RunEx || info.Embed.Type == CodeType.Exec)
                        {
                            CodeInfo_RunExec subInfo = info.Embed.Info.Cast <CodeInfo_RunExec>();
                            if (subInfo.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase))
                            {
                                if (info.Condition.Arg2.Equals(subInfo.SectionName, StringComparison.OrdinalIgnoreCase))
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    RecursiveFindCodeSection(info.Link, logs);
                }
                break;

                case CodeType.Else:
                {
                    CodeInfo_Else info = cmd.Info.Cast <CodeInfo_Else>();

                    RecursiveFindCodeSection(info.Link, logs);
                }
                break;

                case CodeType.Run:
                case CodeType.Exec:
                case CodeType.RunEx:
                {
                    CodeInfo_RunExec info = cmd.Info.Cast <CodeInfo_RunExec>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                case CodeType.Loop:
                case CodeType.LoopLetter:
                case CodeType.LoopEx:
                case CodeType.LoopLetterEx:
                {
                    CodeInfo_Loop info = cmd.Info.Cast <CodeInfo_Loop>();

                    if (info.Break)
                    {
                        continue;
                    }

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.SectionName))
                    {
                        targetCodeSection = info.SectionName;
                    }
                }
                break;

                case CodeType.UserInput:
                {
                    CodeInfo_UserInput info = cmd.Info.Cast <CodeInfo_UserInput>();

                    UserInputType type = info.Type;
                    switch (type)
                    {
                    case UserInputType.DirPath:
                    case UserInputType.FilePath:
                    {
                        UserInputInfo_DirFile subInfo = info.SubInfo.Cast <UserInputInfo_DirFile>();

                        if (info.Type == UserInputType.FilePath)
                        {                 // Select File
                            if (subInfo.Filter != null)
                            {
                                string filter = StringEscaper.Unescape(subInfo.Filter);
                                if (StringEscaper.IsFileFilterValid(filter) == false)
                                {
                                    logs.Add(new LogInfo(LogState.Error, $"File filter pattern [{filter}] is invalid", cmd));
                                }
                            }
                        }
                        else
                        {                 // Select Folder
                            if (subInfo.Filter != null)
                            {
                                logs.Add(new LogInfo(LogState.Warning, $"File filters cannot be used for folder selection", cmd));
                            }
                        }
                    }
                    break;
                    }
                }
                break;

                    #endregion
                    #region Check InterfaceSections
                case CodeType.AddInterface:
                {
                    CodeInfo_AddInterface info = cmd.Info.Cast <CodeInfo_AddInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.ReadInterface:
                {
                    CodeInfo_ReadInterface info = cmd.Info.Cast <CodeInfo_ReadInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.WriteInterface:
                {
                    CodeInfo_WriteInterface info = cmd.Info.Cast <CodeInfo_WriteInterface>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.ScriptFile.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Section))
                    {
                        targetInterfaceSection = info.Section;
                    }
                }
                break;

                case CodeType.IniWrite:
                {
                    // To detect multi-interface without `InterfaceList=`,
                    // Inspect pattern `IniWrite,%ScriptFile%,Main,Interface,<NewInterfaceSection>`
                    CodeInfo_IniWrite info = cmd.Info.Cast <CodeInfo_IniWrite>();

                    // CodeValidator does not have Variable information, so just check with predefined literal
                    if (info.FileName.Equals(Script.Const.ScriptFile, StringComparison.OrdinalIgnoreCase) &&
                        info.Section.Equals(ScriptSection.Names.Main, StringComparison.OrdinalIgnoreCase) &&
                        info.Key.Equals(ScriptSection.Names.Interface, StringComparison.OrdinalIgnoreCase) &&
                        !CodeParser.StringContainsVariable(info.Value))
                    {
                        targetInterfaceSection = info.Value;
                    }
                }
                break;
                    #endregion
                }

                if (targetCodeSection != null)
                {
                    if (_sc.Sections.ContainsKey(targetCodeSection))
                    {
                        logs.AddRange(CheckCodeSection(_sc.Sections[targetCodeSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetCodeSection}] does not exist", cmd));
                    }
                }

                if (targetInterfaceSection != null)
                {
                    if (_sc.Sections.ContainsKey(targetInterfaceSection))
                    {
                        logs.AddRange(CheckInterfaceSection(_sc.Sections[targetInterfaceSection], cmd.RawCode, cmd.LineIdx));
                    }
                    else
                    {
                        logs.Add(new LogInfo(LogState.Error, $"Section [{targetInterfaceSection}] does not exist", cmd));
                    }
                }
            }
        }
示例#16
0
        public static UICommand ParseUICommand(List <string> rawLines, SectionAddress addr, ref int idx)
        {
            UIType type    = UIType.None;
            string rawLine = rawLines[idx].Trim();

            // Check if rawCode is Empty
            if (rawLine.Equals(string.Empty))
            {
                return(new UICommand(rawLine, addr, string.Empty));
            }

            // Comment Format : starts with '//' or '#', ';'
            if (rawLine.StartsWith("//") || rawLine.StartsWith("#") || rawLine.StartsWith(";"))
            {
                return(new UICommand(rawLine, addr, string.Empty));
            }

            // Find key of interface control
            string key      = string.Empty;
            string rawValue = string.Empty;
            int    equalIdx = rawLine.IndexOf('=');

            if (equalIdx != -1)
            {
                key      = rawLine.Substring(0, equalIdx);
                rawValue = rawLine.Substring(equalIdx + 1);
            }
            else
            {
                throw new InvalidCommandException($"Interface control [{rawValue}] does not have name", rawLine);
            }

            // Parse Arguments
            List <string> args = new List <string>();

            try
            {
                string remainder = rawValue;
                while (remainder != null)
                {
                    Tuple <string, string> tuple = CodeParser.GetNextArgument(remainder);
                    args.Add(tuple.Item1);
                    remainder = tuple.Item2;
                }
            }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }

            // Check doublequote's occurence - must be 2n
            if (StringHelper.CountOccurrences(rawValue, "\"") % 2 == 1)
            {
                throw new InvalidCommandException($"Interface control [{rawValue}]'s doublequotes mismatch", rawLine);
            }

            // Check if last operand is \ - MultiLine check - only if one or more operands exists
            if (0 < args.Count)
            {
                while (args.Last().Equals(@"\", StringComparison.OrdinalIgnoreCase))
                {                              // Split next line and append to List<string> operands
                    if (rawLines.Count <= idx) // Section ended with \, invalid grammar!
                    {
                        throw new InvalidCommandException($@"Last interface control [{rawValue}] cannot end with '\' ", rawLine);
                    }
                    idx++;
                    args.AddRange(rawLines[idx].Trim().Split(','));
                }
            }

            // UICommand should have at least 7 operands
            //    Text, Visibility, Type, X, Y, width, height, [Optional]
            if (args.Count < 7)
            {
                throw new InvalidCommandException($"Interface control [{rawValue}] must have at least 7 arguments", rawLine);
            }

            // Parse opcode
            try { type = UIParser.ParseControlType(args[2]); }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }

            // Remove UIControlType from operands
            //   Leftover : Text, Visibility, X, Y, width, height, [Optional]
            args.RemoveAt(2);

            // Forge UICommand
            string text       = StringEscaper.Unescape(args[0]);
            bool   visibility = string.Equals(args[1], "1", StringComparison.Ordinal);

            NumberHelper.ParseInt32(args[2], out int x);
            NumberHelper.ParseInt32(args[3], out int y);
            NumberHelper.ParseInt32(args[4], out int width);
            NumberHelper.ParseInt32(args[5], out int height);
            Rect   rect = new Rect(x, y, width, height);
            UIInfo info;

            try { info = ParseUICommandInfo(type, args); }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }
            return(new UICommand(rawLine, addr, key, text, visibility, type, rect, info));
        }
示例#17
0
        public static UIControl ParseUIControl(IList <string> rawLines, ScriptSection section, ref int idx)
        {
            // UICommand's line number in physical file
            int lineIdx = section.LineIdx + 1 + idx;

            // Get rawLine
            string rawLine = rawLines[idx].Trim();

            // Check if rawLine is empty
            if (rawLine.Length == 0)
            {
                return(null);
            }

            // Line Comment Identifier : '//', '#', ';'
            if (rawLine.StartsWith("//", StringComparison.Ordinal) || rawLine[0] == '#' || rawLine[0] == ';')
            {
                return(null);
            }

            // Find key of interface control
            string key;
            string rawValue = string.Empty;
            int    equalIdx = rawLine.IndexOf('=');

            if (equalIdx != -1 && equalIdx != 0)
            {
                key      = rawLine.Substring(0, equalIdx);
                rawValue = rawLine.Substring(equalIdx + 1);
            }
            else
            {
                throw new InvalidCommandException($"Interface control [{rawValue}] must have a key", rawLine);
            }

            // Parse Arguments
            List <string> args = new List <string>();

            try
            {
                string remainder = rawValue;
                while (remainder != null)
                {
                    string next;
                    (next, remainder) = CodeParser.GetNextArgument(remainder);
                    args.Add(next);
                }
            }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }

            // Check double-quote's occurence - must be 2n
            if (StringHelper.CountSubStr(rawValue, "\"") % 2 == 1)
            {
                throw new InvalidCommandException("Doublequote's number should be even", rawLine);
            }

            // Check if last operand is \ - MultiLine check - only if one or more operands exists
            if (0 < args.Count)
            {
                while (args.Last().Equals(@"\", StringComparison.OrdinalIgnoreCase))
                {                              // Split next line and append to List<string> operands
                    if (rawLines.Count <= idx) // Section ended with \, invalid grammar!
                    {
                        throw new InvalidCommandException(@"Last interface control cannot end with '\'", rawLine);
                    }
                    idx++;
                    args.AddRange(rawLines[idx].Trim().Split(','));
                }
            }

            // UIControl should have at least 7 operands
            //    Text, Visibility, Type, X, Y, width, height, [Optional]
            if (args.Count < 7)
            {
                throw new InvalidCommandException($"Interface control [{rawValue}] must have at least 7 arguments", rawLine);
            }

            // Parse UIControlType
            UIControlType type;

            try { type = UIParser.ParseControlTypeVal(args[2]); }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }

            // Remove UIControlType from operands
            //   Leftover : Text, Visibility, X, Y, width, height, [Optional]
            args.RemoveAt(2);

            // Forge UIControl
            string text          = StringEscaper.Unescape(args[0]);
            string visibilityStr = args[1];
            bool   visibility;

            if (visibilityStr.Equals("1", StringComparison.Ordinal) ||
                visibilityStr.Equals("True", StringComparison.OrdinalIgnoreCase))
            {
                visibility = true;
            }
            else if (visibilityStr.Equals("0", StringComparison.Ordinal) ||
                     visibilityStr.Equals("False", StringComparison.OrdinalIgnoreCase))
            {
                visibility = false;
            }
            else
            {
                throw new InvalidCommandException($"Invalid value in [{visibilityStr}]", rawLine);
            }

            bool intParse = true;

            intParse &= NumberHelper.ParseInt32(args[2], out int x);
            intParse &= NumberHelper.ParseInt32(args[3], out int y);
            intParse &= NumberHelper.ParseInt32(args[4], out int width);
            intParse &= NumberHelper.ParseInt32(args[5], out int height);
            if (!intParse)
            {
                throw new InvalidCommandException($"Invalid integers in [{rawValue}]", rawLine);
            }

            UIInfo info;

            try { info = ParseUIControlInfo(type, args); }
            catch (InvalidCommandException e) { throw new InvalidCommandException(e.Message, rawLine); }
            return(new UIControl(rawLine, section, key, text, visibility, type, x, y, width, height, info, lineIdx));
        }