/// <summary>
        /// Creates the translation unit as it is later shown in the Translation Results
        /// window of SDL Trados Studio.
        /// </summary>
        /// <param name="searchSegment"></param>
        /// <param name="translation"></param>
        /// <param name="sourceSegment"></param>
        /// <returns></returns>
        #region "CreateSearchResult"
        private SearchResult CreateSearchResult(Segment searchSegment, Segment translation, int score)
        {
            TranslationUnit tu = new TranslationUnit();

            tu.SourceSegment = searchSegment.Duplicate();
            tu.TargetSegment = translation;

            tu.ResourceId = new PersistentObjectToken(tu.GetHashCode(), Guid.Empty);
            tu.Origin     = TranslationUnitOrigin.MachineTranslation;
            //tu.SystemFields.CreationDate = DateTime.UtcNow;
            //tu.SystemFields.ChangeDate = tu.SystemFields.CreationDate;

            SearchResult searchResult = new SearchResult(tu);

            searchResult.ScoringResult           = new ScoringResult();
            searchResult.TranslationProposal     = tu.Duplicate();
            searchResult.ScoringResult.BaseScore = score;


            return(searchResult);
        }
예제 #2
0
        public SearchResults[] SearchSegmentsMasked(SearchSettings settings, Segment[] segments, bool[] mask)
        {
            IEnumerable <Segment> toTranslate = mask != null?segments.Where((x, i) => mask[i]) : segments;

            List <string> sources = toTranslate.Select(x => x.ToHtml()).ToList();
            List <string> translations;

            try
            {
                translations = _client.Translate(sources, src, trg).Result;
            }
            catch (AggregateException e)
            {
                var apiException = e.InnerException as SimpleHttpResponseException <GenericResponse> ?? throw e.InnerException;
                if (apiException.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                {
                    throw new TranslationProviderAuthenticationException("Invalid Consumer API Token", apiException);
                }
                throw new Exception($"{apiException.Content.Error.Message} ({apiException.Content.Error.Code})");
            }

            IEnumerable <SearchResults> nonMaskedResults = toTranslate.Zip(translations,
                                                                           // Converting a translation string to SearchResults is quite involved
                                                                           (Segment sourceSegment, string translation) => {
                var targetSegment = translation.ToSegment(sourceSegment);

                var tu        = new TranslationUnit(sourceSegment.Duplicate(), targetSegment);
                tu.Origin     = TranslationUnitOrigin.MachineTranslation;
                tu.ResourceId = new PersistentObjectToken(tu.GetHashCode(), Guid.Empty);     // TODO: is this needed?

                var res = new SearchResult(tu)
                {
                    TranslationProposal = tu.Duplicate(),
                    ScoringResult       = new ScoringResult()
                    {
                        BaseScore = 85
                    }                                                          // Although we do not support scoring, returning some kind of a score is mandatory, else Trados freezes
                };
                var results = new SearchResults {
                    SourceSegment = sourceSegment.Duplicate()
                };
                results.Add(res);
                return(results);
            });

            IEnumerable <SearchResults> allResults()
            {
                var enumerator = nonMaskedResults.GetEnumerator();

                foreach (var item in segments.Select((value, i) => new { i, value }))
                {
                    if (mask == null || mask[item.i])
                    {
                        enumerator.MoveNext();
                        yield return(enumerator.Current);

                        continue;
                    }
                    yield return(null);
                }
            }

            var resArray = allResults().ToArray();

            return(resArray);
        }
        //#region Methods abstract

        ///// <summary>
        ///// Performs a segment search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="segment">The segment to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchSegment(SearchSettings settings, Segment segment);

        ///// <summary>
        ///// Performs a text search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="segment">The text to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchText(SearchSettings settings, string segment);

        ///// <summary>
        ///// Performs a translation unit search.
        ///// </summary>
        ///// <param name="settings">The settings that define the search parameters.</param>
        ///// <param name="translationUnit">The translation unit to search for.</param>
        ///// <returns>
        ///// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        ///// </returns>
        //public abstract SearchResults SearchTranslationUnit(SearchSettings settings, TranslationUnit translationUnit);

        //#endregion // Methods abstract

        #region Virtual methods

        #region Methods

        /// <summary>
        /// Performs a segment search.
        /// </summary>
        /// <param name="settings">The settings that define the search parameters.</param>
        /// <param name="segment">The segment to search for.</param>
        /// <returns>
        /// A <see cref="T:Sdl.LanguagePlatform.TranslationMemory.SearchResults"/> object containing the results or an empty object if no results were found.
        /// </returns>
        public virtual SearchResults SearchSegment(SearchSettings settings, Segment segment)
        {
            lock (this.locker)
            {
                string segmentText = SegmentParser.ExtractSegmentText(segment);

                Trados.Interop.TMAccess.SearchResult tradosSegments = GetMatchSegments(settings, segmentText);

                if (tradosSegments == null)
                {
                    return(null);
                }

                var searchResults = new SearchResults
                {
                    SourceSegment = segment.Duplicate(),
                    SourceHash    = segment.GetHashCode(),
                };

                int id = 0;

                foreach (TmMatch match in tradosSegments.TmMatches)
                {
                    // form ScoringResult via applying penalties
                    var scoringResult = new ScoringResult
                    {
                        AppliedPenalties        = new List <AppliedPenalty>(),
                        BaseScore               = match.ScoreValues.GetMatchPercent(),
                        IsStructureContextMatch = false,
                    };
                    this.ApplyPenalties(match, scoringResult, settings);

                    // convert trados 2007 format segments into Studio 2011 ones
                    string translationSource = match.GetSource(settings.IsConcordanceSearch);
                    string translationTarget = match.GetTarget(settings.IsConcordanceSearch);

                    var sourceSegment = SegmentParser.CreateSegment(
                        scoringResult, settings, translationSource, this.SourceLanguage);
                    var targetSegment = SegmentParser.CreateSegment(
                        scoringResult, settings, translationTarget, this.TargetLanguage);

                    // tokenize segments
                    SegmentParser.TokenizeSegment(ref sourceSegment);
                    SegmentParser.TokenizeSegment(ref targetSegment);

                    // create Translation Unit
                    var unit = new TranslationUnit(sourceSegment, targetSegment)
                    {
                        Origin       = TranslationUnitOrigin.TM,
                        Format       = TranslationUnitFormat.TradosTranslatorsWorkbench,
                        SystemFields = new SystemFields(),
                        ResourceId   = new PersistentObjectToken(id++, Guid.NewGuid()),
                    };

                    // set custom attributes
                    this.SetMetaData(match, unit, settings);

                    // form SearchResult
                    var searchResult = new SearchResult(unit)
                    {
                        ScoringResult       = scoringResult,
                        TranslationProposal = unit.Duplicate()
                    };

                    scoringResult.EditDistance = ComputeEditDistance(segment, searchResult, settings);

                    // set "yellow" fileds for concordance
                    if (settings.Mode == SearchMode.ConcordanceSearch || settings.Mode == SearchMode.TargetConcordanceSearch)
                    {
                        this.AnnotateConcordanceHit(segment, searchResult, settings.Mode);
                    }

                    // finally...
                    searchResults.Add(searchResult);
                }


                searchResults.CheckForMultipleTranslations(settings);
                searchResults.RemoveDuplicates();

                //if "Search fo fuzzy matches even if exact match found" is OFF
                //and exact matches are present then also remove fuzzy matches
                //According to LanguagePlatform description for enum SearchMode, exact match should return only exact matches,
                //normal search should return exact matches OR fuzzy matches if no exact matches found
                if (settings.Mode == SearchMode.ExactSearch ||
                    (settings.Mode == SearchMode.NormalSearch && searchResults.Results.Any(i => i.ScoringResult.IsExactMatch)))
                {
                    searchResults.Results.RemoveAll(r => !r.ScoringResult.IsExactMatch);
                }

                //Determine placebles in the searched segment
                if (settings.Mode != SearchMode.TargetConcordanceSearch && !settings.IsConcordanceSearch)
                {
                    searchResults.DocumentPlaceables = PlaceableComputer.ComputePlaceables(searchResults.SourceSegment, null);
                }

                return(searchResults);
            }
        }