/// <summary> /// Creates a placeholder from a specified full qualifier. /// </summary> /// <param name="fullQualifier">Full qualifier. /// <para>It is in the format of [ThreatsManagerPlatform:ModelTest:parameter1#parameter2], where /// <list type="bullet"> /// <item><description>ThreatsManagerPlatform is fixed.</description></item> /// <item><description>ModelTest represents the Qualifier which identifies the specific Placeholder.</description></item> /// <item><description>parameter1#parameter2 represent the parameters for the Placeholder, separated by #.</description></item> /// </list> /// </para></param> /// <param name="priority">[out] Integer representing the priority of the placeholder.</param> /// <returns>Generated Placeholder. It may be null, if no suitable placeholder has been found.</returns> public static IPlaceholder Create([Required] string fullQualifier, out int priority) { IPlaceholder result = null; priority = 100; var factories = ExtensionUtils.GetExtensions <IPlaceholderFactory>()?.ToArray(); if (factories?.Any() ?? false) { var regex = new Regex( @"\[ThreatsManagerPlatform:(?<qualifier>[\w]+):?(?<params>[\S ]*)?\]"); var match = regex.Match(fullQualifier); if (match.Success) { var factory = factories.FirstOrDefault(x => string.CompareOrdinal(x.Qualifier, match.Groups["qualifier"]?.Value) == 0); if (factory != null) { priority = factory.GetExtensionPriority(); result = factory.Create(match.Groups["params"]?.Value); } } } return(result); }
public static void UpdatePlaceholderColor(this TextBox textBox, IPlaceholder placeholder) { var brush = placeholder.PlaceholderColor?.ToNative(); if (brush is null) { // Windows.Foundation.UniversalApiContract < 5 textBox.Resources.Remove("TextControlPlaceholderForeground"); textBox.Resources.Remove("TextControlPlaceholderForegroundPointerOver"); textBox.Resources.Remove("TextControlPlaceholderForegroundFocused"); textBox.Resources.Remove("TextControlPlaceholderForegroundDisabled"); // Windows.Foundation.UniversalApiContract >= 5 textBox.ClearValue(TextBox.PlaceholderForegroundProperty); } else { // Windows.Foundation.UniversalApiContract < 5 textBox.Resources["TextControlPlaceholderForeground"] = brush; textBox.Resources["TextControlPlaceholderForegroundPointerOver"] = brush; textBox.Resources["TextControlPlaceholderForegroundFocused"] = brush; textBox.Resources["TextControlPlaceholderForegroundDisabled"] = brush; // Windows.Foundation.UniversalApiContract >= 5 textBox.PlaceholderForeground = brush; } }
/// <summary> /// Compares whether two strings have equal placeholders. /// </summary> /// <param name="str1"></param> /// <param name="str2"></param> /// <returns></returns> static bool EqualPlaceholders(IString str1, IString str2) { if (str1 == null && str2 == null) { return(true); } if (str1 == null || str2 == null) { return(false); } if (str1.Placeholders.Length != str2.Placeholders.Length) { return(false); } int c = str1.Placeholders.Length; for (int i = 0; i < c; i++) { IPlaceholder ph1 = str1.Placeholders[i], ph2 = str2.Placeholders[i]; if (!PlaceholderExpressionEquals.Equals(ph1.Expression, ph2.Expression)) { return(false); } } return(true); }
public static void UpdatePlaceholder(this AppCompatEditText editText, IPlaceholder textInput) { if (editText.Hint == textInput.Placeholder) { return; } editText.Hint = textInput.Placeholder; }
public static void UpdatePlaceholderColor(this MauiTextBox textBox, IPlaceholder placeholder, Brush?defaultPlaceholderColorBrush, Brush?defaultPlaceholderColorFocusBrush) { Color placeholderColor = placeholder.PlaceholderColor; BrushHelpers.UpdateColor(placeholderColor, ref defaultPlaceholderColorBrush, () => textBox.PlaceholderForegroundBrush, brush => textBox.PlaceholderForegroundBrush = brush); BrushHelpers.UpdateColor(placeholderColor, ref defaultPlaceholderColorFocusBrush, () => textBox.PlaceholderForegroundFocusBrush, brush => textBox.PlaceholderForegroundFocusBrush = brush); }
/// <summary> /// Evaluate placeholders into string values. /// </summary> /// <param name="line">original requesting line</param> /// <param name="resolvedLine">(optional Line that was matched from IAsset or inlines</param> /// <param name="pluralLine">(optional) Line that was matched from IAsset or inlines for plural value</param> /// <param name="placeholders"></param> /// <param name="features">contextual data</param> /// <param name="placeholder_values">collection where strings are placed, one for each placeholder</param> /// <param name="culture">the culture in which to evaluate</param> void EvaluatePlaceholderValues(ILine line, ILine resolvedLine, ILine pluralLine, IPlaceholder[] placeholders, ref LineFeatures features, ref StructList12 <string> placeholder_values, CultureInfo culture) { PlaceholderExpressionEvaluator placeholder_evaluator = new PlaceholderExpressionEvaluator(); placeholder_evaluator.Args = features.ValueArgs; placeholder_evaluator.FunctionEvaluationCtx.Culture = culture; placeholder_evaluator.FunctionEvaluationCtx.Line = line; placeholder_evaluator.FunctionEvaluationCtx.ResolvedLine = resolvedLine; placeholder_evaluator.FunctionEvaluationCtx.PluralLine = pluralLine; placeholder_evaluator.FunctionEvaluationCtx.StringResolver = this; placeholder_evaluator.FunctionEvaluationCtx.EnumResolver = EnumResolver; if (features.FormatProviders.Count == 1) { placeholder_evaluator.FunctionEvaluationCtx.FormatProvider = features.FormatProviders[0]; } else if (features.FormatProviders.Count > 1) { placeholder_evaluator.FunctionEvaluationCtx.FormatProvider = new FormatProviderComposition(features.FormatProviders.ToArray()); } if (features.Functions.Count == 1) { placeholder_evaluator.FunctionEvaluationCtx.Functions = features.Functions[0]; } else if (features.Functions.Count > 1) { placeholder_evaluator.FunctionEvaluationCtx.Functions = new FunctionsMap(features.Functions); } for (int i = 0; i < placeholders.Length; i++) { try { // Get placeholder IPlaceholder ph = placeholders[i]; // Evaluate value string ph_value = placeholder_evaluator.toString(placeholder_evaluator.Evaluate(ph.Expression)); // Add to array placeholder_values.Add(ph_value); // Update code features.Status.UpPlaceholder(placeholder_evaluator.Status); } catch (Exception e) { // Log exceptions features.Log(e); // Mark error features.Status.UpPlaceholder(LineStatus.PlaceholderErrorExpressionEvaluation); // Put empty value placeholder_values.Add(null); } } }
public void SetValue(string value) { value = value.CleanUpMetadataName().Replace("= =", "=="); var match = Regex.Match(value, @"(.*) (==|!=) (.*)"); if (!match.Success) { _checkPlaceholder = new Placeholder(Metadata, value, 0); _operation = "!="; _expected = "NULL"; } else { _checkPlaceholder = new Placeholder(Metadata, match.Groups[1].Value, 0); _operation = match.Groups[2].Value; _expected = match.Groups[3].Value; } }
private void OnMouseMove(object sender, MouseEventArgs e) { if (isDragging) { var control = GetTargetControl() as IPlaceholder; if (lastControl != control && lastControl != null) { lastControl.OnLeave(this); } lastControl = control.With(_ => _.OnOver(this)); var pos = Cursor.Position; Top = Top + (pos.Y - oldPos.Y); Left = Left + (pos.X - oldPos.X); oldPos = Cursor.Position; } }
public static void UpdatePlaceholderColor(this TextBox textBox, IPlaceholder placeholder) { var brush = placeholder.PlaceholderColor?.ToPlatform(); if (brush is null) { // Windows.Foundation.UniversalApiContract < 5 textBox.Resources.RemoveKeys(PlaceholderColorResourceKeys); // Windows.Foundation.UniversalApiContract >= 5 textBox.ClearValue(TextBox.PlaceholderForegroundProperty); } else { // Windows.Foundation.UniversalApiContract < 5 textBox.Resources.SetValueForAllKey(PlaceholderColorResourceKeys, brush); // Windows.Foundation.UniversalApiContract >= 5 textBox.PlaceholderForeground = brush; } textBox.RefreshThemeResources(); }
public static void UpdatePlaceholder(this TextBox textBox, IPlaceholder placeholder) { textBox.PlaceholderText = placeholder.Placeholder ?? string.Empty; }
public static void UpdatePlaceholderColor(this AppCompatEditText editText, IPlaceholder placeholder, ColorStateList?defaultColor) { editText.UpdatePlaceholderColor(placeholder.PlaceholderColor, defaultColor); }
public static void UpdatePlaceholderColor(this EditText editText, IPlaceholder placeholder) { editText.UpdatePlaceholderColor(placeholder.PlaceholderColor); }
/// <summary> /// Add placeholder and cases that apply to that placeholder. /// </summary> /// <param name="placeholder"></param> /// <param name="placeholderValue"></param> /// <param name="pluralRules"></param> /// <param name="culture"></param> public void AddPlaceholder(IPlaceholder placeholder, IPluralNumber placeholderValue, IPluralRules pluralRules, string culture) { IExpression e = placeholder?.Expression; if (e == null) { return; } // Query cases PluralRuleInfo query = new PluralRuleInfo(null, placeholder.PluralCategory, culture, null, -1); IPluralRule[] cases = pluralRules.Evaluate(query, placeholderValue); if (cases == null || cases.Length == 0) { return; } int optionalCount = cases.Length == 1 ? 0 : cases.Length - 1; int requiredCount = cases.Length > 0 ? 1 : 0; // Scan arguments StructList4 <int> argIndices = new StructList4 <int>(); GetArguments(e, ref argIndices); // Add and unify cases for (int ix = 0; ix < argIndices.Count; ix++) { int argIx = argIndices[ix]; // Find if argument already exists int prevIx = -1; for (int j = 0; j < arguments.Count; j++) { if (arguments[j].ArgumentIndex == argIx) { prevIx = j; break; } } if (prevIx < 0) { // Add argument Entry entry = new Entry { Cases = cases, ArgumentIndex = argIx, OptionalCases = optionalCount, RequiredCases = requiredCount }; arguments.Add(entry); this.Count *= (1 + cases.Length); this.count1 *= cases.Length; } else { // Previous entry Entry entry = arguments[prevIx]; // Unify entries StructList8 <IPluralRule> optionalCases = new StructList8 <IPluralRule>(IPluralRuleComparer.Default); StructList8 <IPluralRule> requiredCases = new StructList8 <IPluralRule>(IPluralRuleComparer.Default); foreach (var c in entry.Cases) { if (c.Info.Optional == 1) { optionalCases.AddIfNew(c); } else if (c.Info.Optional == 0) { requiredCases.AddIfNew(c); } } foreach (var c in cases) { if (c.Info.Optional == 1) { optionalCases.AddIfNew(c); } else if (c.Info.Optional == 0) { requiredCases.AddIfNew(c); } } StructList8 <IPluralRule> allCases = new StructList8 <IPluralRule>(IPluralRuleComparer.Default); for (int i = 0; i < optionalCases.Count; i++) { allCases.Add(optionalCases[i]); } for (int i = 0; i < requiredCases.Count; i++) { allCases.Add(requiredCases[i]); } // Create new entry Entry newEntry = new Entry { Cases = allCases.ToArray(), ArgumentIndex = argIx, OptionalCases = optionalCases.Count, RequiredCases = requiredCases.Count }; // Update arguments[prevIx] = newEntry; this.Count /= (1 + entry.Cases.Length); this.Count *= (1 + newEntry.Cases.Length); this.count1 /= entry.Cases.Length; this.count1 *= newEntry.Cases.Length; } } }
/// <summary> /// Resolve <paramref name="key"/> into <see cref="IString"/>, but without applying format arguments. /// /// If the <see cref="IString"/> contains plural categories, then matches into the applicable plurality case. /// </summary> /// <param name="key"></param> /// <returns>format string</returns> public IString ResolveFormatString(ILine key) { // Extract parameters from line LineFeatures features = new LineFeatures { Resolvers = Resolvers }; // Scan features try { features.ScanFeatures(key); } catch (Exception e) { features.Log(e); features.Status.UpResolve(LineStatus.ResolveFailedException); return(new StatusString(null, features.Status)); } // Resolve key to line CultureInfo culture = features.Culture; ILine line = ResolveKeyToLine(key, ref features, ref culture); // No line or value if (line == null || !features.HasValue) { features.Status.UpResolve(LineStatus.ResolveFailedNoValue); LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(new StatusString(null, features.Status)); } // Parse value IString value = features.EffectiveString; features.Status.Up(value.Status); // Value has error if (value.Parts == null || value.Status.Failed()) { LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(new StatusString(null, features.Status)); } // Plural Rules if (value.HasPluralRules()) { if (features.PluralRules != null) { // Evaluate expressions in placeholders into strings StructList12 <string> placeholder_values = new StructList12 <string>(); CultureInfo culture_for_format = features.Culture; if (culture_for_format == null && features.CulturePolicy != null) { CultureInfo[] cultures = features.CulturePolicy.Cultures; if (cultures != null && cultures.Length > 0) { culture_for_format = cultures[0]; } } if (culture_for_format == null) { culture_for_format = CultureInfo.InvariantCulture; } EvaluatePlaceholderValues(key, line, null, value.Placeholders, ref features, ref placeholder_values, culture_for_format); // Create permutation configuration PluralCasePermutations permutations = new PluralCasePermutations(line); for (int i = 0; i < value.Placeholders.Length; i++) { // Get placeholder IPlaceholder placeholder = value.Placeholders[i]; // No plural category in this placeholder if (placeholder.PluralCategory == null) { continue; } // Placeholder value after evaluation string ph_value = placeholder_values[i]; // Placeholder evaluated value IPluralNumber placeholderValue = ph_value == null ? DecimalNumber.Empty : new DecimalNumber.Text(ph_value?.ToString(), culture); // Add placeholder to permutation configuration permutations.AddPlaceholder(placeholder, placeholderValue, features.PluralRules, culture?.Name ?? ""); } // Find first value that matches permutations features.CulturePolicy = null; features.String = null; features.StringText = null; for (int i = 0; i < permutations.Count - 1; i++) { // Create key with plurality cases ILine key_with_plurality = permutations[i]; // Search line with the key ILine line_for_plurality_arguments = ResolveKeyToLine(key_with_plurality, ref features, ref culture); // Got no match if (line_for_plurality_arguments == null) { continue; } // Parse value IString value_for_plurality = line_for_plurality_arguments.GetString(Resolvers); // Add status from parsing the value features.Status.Up(value_for_plurality.Status); // Value has error if (value_for_plurality.Parts == null || value_for_plurality.Status.Failed()) { LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(new StatusString(null, features.Status)); } // Return with match features.Status.UpPlurality(LineStatus.PluralityOkMatched); // Update status codes features.Status.Up(value_for_plurality.Status); // Return values value = value_for_plurality; line = line_for_plurality_arguments; break; } } else { // Plural rules were not found features.Status.Up(LineStatus.PluralityErrorRulesNotFound); } } else { // Plurality feature was not used. features.Status.UpPlurality(LineStatus.PluralityOkNotUsed); } return(value); }
/// <summary> /// Resolve <paramref name="key"/> into <see cref="LineString"/> with format arguments applied. /// </summary> /// <param name="key"></param> /// <returns></returns> public LineString ResolveString(ILine key) { // Extract parameters from line LineFeatures features = new LineFeatures { Resolvers = Resolvers }; // Scan features try { features.ScanFeatures(key); } catch (Exception e) { features.Log(e); features.Status.UpResolve(LineStatus.ResolveFailedException); return(new LineString(key, e, features.Status)); } try { // Resolve key to line CultureInfo culture = features.Culture; ILine line = ResolveKeyToLine(key, ref features, ref culture); // No line or value if (line == null || !features.HasValue) { features.Status.UpResolve(LineStatus.ResolveFailedNoValue); LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(str); } // Parse value IString value = features.EffectiveString; features.Status.Up(value.Status); // Value has error if (value.Parts == null || value.Status.Failed()) { LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(str); } // Evaluate expressions in placeholders into strings StructList12 <string> placeholder_values = new StructList12 <string>(); CultureInfo culture_for_format = features.Culture; if (culture_for_format == null && features.CulturePolicy != null) { CultureInfo[] cultures = features.CulturePolicy.Cultures; if (cultures != null && cultures.Length > 0) { culture_for_format = cultures[0]; } } if (culture_for_format == null) { culture_for_format = CultureInfo.InvariantCulture; } EvaluatePlaceholderValues(key, line, null, value.Placeholders, ref features, ref placeholder_values, culture_for_format); // Plural Rules if (value.HasPluralRules()) { if (features.PluralRules != null) { // Create permutation configuration PluralCasePermutations permutations = new PluralCasePermutations(line); for (int i = 0; i < value.Placeholders.Length; i++) { // Get placeholder IPlaceholder placeholder = value.Placeholders[i]; // No plural category in this placeholder if (placeholder.PluralCategory == null) { continue; } // Placeholder value after evaluation string ph_value = placeholder_values[i]; // Placeholder evaluated value IPluralNumber placeholderValue = ph_value == null ? DecimalNumber.Empty : new DecimalNumber.Text(ph_value?.ToString(), culture); // Add placeholder to permutation configuration permutations.AddPlaceholder(placeholder, placeholderValue, features.PluralRules, culture?.Name ?? ""); } if (permutations.ArgumentCount <= MaxPluralArguments) { // Find first value that matches permutations features.CulturePolicy = null; features.String = null; features.StringText = null; for (int i = 0; i < permutations.Count - 1; i++) { // Create key with plurality cases ILine key_with_plurality = permutations[i]; // Search line with the key ILine line_for_plurality_arguments = ResolveKeyToLine(key_with_plurality, ref features, ref culture); // Got no match if (line_for_plurality_arguments == null) { continue; } // Scan value try { features.ScanValueFeature(line_for_plurality_arguments); } catch (Exception e) { features.Log(e); features.Status.Up(LineStatus.FailedUnknownReason); return(new LineString(key, e, features.Status)); } // Parse value IString value_for_plurality = features.EffectiveString; // Add status from parsing the value features.Status.Up(value_for_plurality.Status); // Value has error if (value_for_plurality.Parts == null || value_for_plurality.Status.Failed()) { LineString str = new LineString(key, (Exception)null, features.Status); features.Log(str); return(str); } // Return with match features.Status.UpPlurality(LineStatus.PluralityOkMatched); // Evaluate placeholders again if (!EqualPlaceholders(value, value_for_plurality)) { placeholder_values.Clear(); EvaluatePlaceholderValues(key, line, line_for_plurality_arguments, value_for_plurality.Placeholders, ref features, ref placeholder_values, culture); } // Update status codes features.Status.Up(value_for_plurality.Status); // Return values value = value_for_plurality; line = line_for_plurality_arguments; break; } } else { features.Status.UpPlaceholder(LineStatus.PluralityErrorMaxPluralArgumentsExceeded); } } else { // Plural rules were not found features.Status.Up(LineStatus.PluralityErrorRulesNotFound); } } else { // Plurality feature was not used. features.Status.UpPlurality(LineStatus.PluralityOkNotUsed); } // Put string together string text = null; if (value == null || value.Parts == null) { text = null; } // Only one part else if (value.Parts.Length == 1) { if (value.Parts[0].Kind == StringPartKind.Text) { text = value.Parts[0].Text; features.Status.UpStringFormat(LineStatus.StringFormatOkString); } else if (value.Parts[0].Kind == StringPartKind.Placeholder) { text = placeholder_values[0]; features.Status.UpStringFormat(LineStatus.StringFormatOkString); } } // Compile multiple parts else { // Calculate length int length = 0; for (int i = 0; i < value.Parts.Length; i++) { IStringPart part = value.Parts[i]; string partText = part.Kind switch { StringPartKind.Text => part.Text, StringPartKind.Placeholder => placeholder_values[((IPlaceholder)part).PlaceholderIndex], _ => null }; if (partText != null) { length += partText.Length; } } // Copy characters char[] arr = new char[length]; int ix = 0; for (int i = 0; i < value.Parts.Length; i++) { IStringPart part = value.Parts[i]; string str = part.Kind switch { StringPartKind.Text => part.Text, StringPartKind.Placeholder => placeholder_values[((IPlaceholder)part).PlaceholderIndex], _ => null }; if (str != null) { str.CopyTo(0, arr, ix, str.Length); ix += str.Length; } } // String text = new string(arr); features.Status.UpStringFormat(LineStatus.StringFormatOkString); } // Create result LineString result = new LineString(key, text, features.Status); // Log features.Log(result); // Return return(result); } catch (Exception e) { // Capture unexpected error features.Log(e); features.Status.UpResolve(LineStatus.ResolveFailedException); LineString lineString = new LineString(key, e, features.Status); features.Log(lineString); return(lineString); } }
/// <summary> /// Get default value (as " ?? value" expression at the end) , if has one. /// </summary> /// <param name="placeholder"></param> /// <returns>Default value or null</returns> public static object DefaultValue(this IPlaceholder placeholder) => placeholder.Expression is IBinaryOpExpression bop && bop.Op == BinaryOp.Coalesce ? bop.Right is IConstantExpression ce ? ce.Value : null : null;