/// <summary> /// Загружает новые данные переводов /// </summary> /// <param name="path">Путь к файлу переводов</param> /// <param name="containerType">Тип контейнера</param> /// <param name="onTranslationConflict"> /// Вызывается при конфликтах перевода. /// Получает текущую запись и конликтующий перевод. /// </param> public static void LoadTranslations(string path, Type containerType, Action <IMapRecordFull, string> onTranslationConflict) { var container = Activator.CreateInstance(containerType) as ITranslationContainer; var data = container.Load(path, encoding).OrderBy(itm => itm.Value).ToArray(); var lst = new SortedItems <IMapRecordFull>(); int repeatCnt = 0; int conflictsCnt = 0; foreach (var item in data) { var recItem = (IMapValueRecord)MappedData.GetValueRecord(item.Value); if (lst.Contain(recItem)) { if (string.Equals(recItem.Translation, item.Translation)) { repeatCnt++; } else { conflictsCnt++; Helpers.ConsoleWrite("Конфликтующая запись перевода:", ConsoleColor.Yellow); Helpers.ConsoleWrite(recItem.Value, ConsoleColor.White); Helpers.ConsoleWrite(recItem.Translation, ConsoleColor.White); Helpers.ConsoleWrite(item.Translation, ConsoleColor.Gray); if (onTranslationConflict != null) { onTranslationConflict(recItem, item.Translation); } } continue; } recItem.Translation = item.Translation; lst.Add(recItem); } Helpers.ConsoleWrite(string.Format("Повторяющихся записей: {0}\r\nДублирующих записей: {1}", repeatCnt, conflictsCnt), ConsoleColor.Yellow); foreach (IMapValueRecord itm in lst) { OriginalData.Add(new BaseTranslationItem(itm.Value, itm.Translation)); } _TranslatesDictionary.Reset(lst); }
/// <summary> /// Поиск в словаре. Использует регулярку /// </summary> /// <param name="expr"> /// Искомое выражение, в начале можно указать параметры поиска в фармате и фильтры по методам #[filter]:?[params]:[expr] /// </param> /// <remarks> /// <para>?e:[expr] - выражению должна соответствовать строка</para> /// <para>?t:[expr] - выражению должен соответствовать перевод</para> /// <para>?et:[expr] - выражению должны соответствовать и строка и её перевод</para> /// <para>?n: - разрешает поиск пустого выражения, для использования совместно с другими фильтрами</para> /// <para><welcome:> - разрешает поиск пустого выражения, для использования совместно с другими фильтрами</para> /// </remarks> /// <example><welcome:>#tr:error - выполнит поиск в файле welcome текст error в методе tr</example> /// <returns>Список совпадающих записей словаря</returns> public static ICollection <IMapRecordFull> Exec(string expr, CancellationToken ct) { var lexpr = expr; string fExpr = null; if (lexpr.StartsWith("<")) { var i = lexpr.IndexOf(":>"); if (i < 0) { return(null); } fExpr = lexpr.Substring(1, i - 1); lexpr = lexpr.Substring(i + 2); } var methodsFilter = new Dictionary <IMapRecordFull, bool>(); if (lexpr.StartsWith("#")) { var i = lexpr.IndexOf(':'); if (i < 0) { return(null); } var prms = lexpr.Substring(1, i - 1).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var p in prms) { var prm = p; if (p[0] == '!') { prm = p.Substring(1); } var m = MappedData.GetMethodRecord(prm); if (m == null) { Helpers.ConsoleWrite($"Запись {prm} не найдена."); return(null); } methodsFilter[m] = p[0] != '!'; } lexpr = lexpr.Substring(i + 1); } ICollection <IMapRecordFull> filterResult = null; if (lexpr.StartsWith("?")) { var i = lexpr.IndexOf(':'); if (i < 0) { return(null); } SearchParams param = SearchParams.EngOrTrans; var prm = lexpr.Substring(0, i).ToLower(); if (prm.Contains('e')) { param |= SearchParams.Eng; } if (prm.Contains('t')) { param |= SearchParams.Trans; } filterResult = Exec <IMapRecordFull>(lexpr.Substring(i + 1), param, !prm.Contains('a'), prm.Contains('n')); } else { filterResult = Exec <IMapRecordFull>(lexpr, SearchParams.EngOrTrans, true, false); } if (fExpr != null) { filterResult = ExtraFilter(fExpr, filterResult, ct); } return(MethodsFilter(methodsFilter, filterResult, ct)); }