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()); }
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()); }
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); } }
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()); }
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()); }
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()); }
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()); }
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()); }
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()); }
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); }
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); }
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}]"); }
/// <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; } })); } }
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); }
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)); } } } }
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)); }
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)); }