/// <summary> /// XXX: Wrong documentation = Selects preview lines in Gtk.TreeView based on a condtion like "episode=3 and contains(sub1, 'Bye')". /// </summary> /// <param name="conditionExpr">Condition expr.</param> /// <param name="isIncrementalSearch">Only change selection state for lines with matching expressions.</param> /// <param name="selectAction">true -> select matching lines, false -> deselect matching lines</param> public List <bool> EvaluateForEveryLine(String conditionExpr) { // select all if expression is null var resultsList = Enumerable.Repeat(false, m_cardInfos.Count).ToList(); if (String.IsNullOrWhiteSpace(conditionExpr)) { return(resultsList); } int currentCardIndex = 0; // card index which will be used for evaluation an expression in delegate Expression expr = new Expression(conditionExpr); // resolve certain parameters in expression expr.EvaluateParameter += delegate(string name, ParameterArgs args) { CardInfo infoSourceCard = m_cardInfos[currentCardIndex]; switch (name) { case "isActive": // fallthrough case "active": args.Result = infoSourceCard.isActive; break; case "number": case "episodeNumber": case "episode": args.Result = infoSourceCard.episodeInfo.Number; break; case "text": case "sub": args.Result = infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.TARGET) + " " + infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.NATIVE); break; case "sub1": case "text1": args.Result = infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.TARGET); break; case "sub2": case "text2": args.Result = infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.NATIVE); break; case "actor": case "actors": case "name": case "names": args.Result = infoSourceCard.GetActorString(); break; case "start": args.Result = infoSourceCard.startTimestamp; break; case "end": args.Result = infoSourceCard.endTimestamp; break; case "duration": args.Result = infoSourceCard.Duration; break; case "next_start": args.Result = currentCardIndex + 1 >= m_cardInfos.Count ? 1000000.0 : m_cardInfos[currentCardIndex + 1].StartTime; break; case "next_end": args.Result = currentCardIndex + 1 >= m_cardInfos.Count ? 1000000.0 : m_cardInfos[currentCardIndex + 1].EndTime; break; case "next_duration": args.Result = currentCardIndex + 1 >= m_cardInfos.Count ? 0 : m_cardInfos[currentCardIndex + 1].Duration; break; case "prev_start": args.Result = currentCardIndex <= 0 ? -1000000.0 : m_cardInfos[currentCardIndex - 1].StartTime; break; case "prev_end": args.Result = currentCardIndex <= 0 ? -1000000.0 : m_cardInfos[currentCardIndex - 1].EndTime; break; case "prev_duration": args.Result = currentCardIndex <= 0 ? 0 : m_cardInfos[currentCardIndex - 1].Duration; break; } }; // resolve certain functions in expression expr.EvaluateFunction += delegate(string name, FunctionArgs args) { CardInfo infoSourceCard = m_cardInfos[currentCardIndex]; switch (name) { // an exmple for this function is "contains(sub1, 'some text')" that selects all lines, where sub1 contains 'some text' case "c": case "contains": { // two string parameters are expected if (args.Parameters.Length < 1) { return; } object[] arguments = args.EvaluateParameters(); foreach (var argument in arguments) { if (!(argument is String)) { return; } } String substring = (String)arguments[arguments.Length - 1]; args.HasResult = true; args.Result = false; bool result = false; if (arguments.Length == 1) { result = infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.NATIVE).Contains(substring); if (result) { args.Result = result; goto contains_finished; } result = infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.TARGET).Contains(substring); if (result) { args.Result = result; goto contains_finished; } } else { // evaluate function for (int i = 0; i < arguments.Length - 1; i++) { String string0 = (String)arguments[i]; result = string0.Contains(substring); if (result) { args.Result = result; goto contains_finished; } } } contains_finished :; } break; // search for regex; for example: "r(text1, 'hi|hello')" // 'r('hi|hello')' searches both in sub1 and sub2 case "r": case "regex": { // two string parameters are expected if (args.Parameters.Length < 1) { return; } object[] arguments = args.EvaluateParameters(); foreach (var argument in arguments) { if (!(argument is String)) { return; } } String regex = (String)arguments[arguments.Length - 1]; args.HasResult = true; args.Result = false; if (arguments.Length == 1) { try { var match = Regex.Match(infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.NATIVE), regex, RegexOptions.Compiled | RegexOptions.IgnoreCase); args.Result = match.Success; if (match.Success) { goto finish_regex; } } catch { } try { var match = Regex.Match(infoSourceCard.ToSingleLine(UtilsCommon.LanguageType.TARGET), regex, RegexOptions.Compiled | RegexOptions.IgnoreCase); args.Result = match.Success; if (match.Success) { goto finish_regex; } } catch { } } else if (arguments.Length > 1) { // try to match any text before regex argument for (int i = 0; i < arguments.Length - 1; i++) { try { String str = (String)arguments[0]; var match = Regex.Match(str, regex, RegexOptions.Compiled | RegexOptions.IgnoreCase); args.Result = match.Success; if (match.Success) { goto finish_regex; } } catch { } } } finish_regex :; } break; // example: time('25:10.50') returns the number of seconds of 25min 10secs 50hsecs case "time": { if (args.Parameters.Length != 1) { return; } object argumentObject = args.EvaluateParameters()[0]; if (!(argumentObject is String)) { return; } String timeString = (String)argumentObject; args.Result = UtilsCommon.ParseTimeString(timeString); args.HasResult = true; } break; } }; for (int i = 0; i < m_cardInfos.Count; i++) { // provide infos for expr.Evaluate() currentCardIndex = i; object result = expr.Evaluate(); if (result is bool && result != null) { resultsList[i] = (bool)result; } } return(resultsList); }