void AspellAdapterImpl::getSuggestionsForLastWord( SuggestionsList & suggestionsList, const std::string & word ) { const AspellWordList * suggestions = aspell_speller_suggest( aspellSpeller_, word.c_str(), -1); AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); const char * currentWordSuggestion; while ( (currentWordSuggestion = aspell_string_enumeration_next(elements)) != NULL ) { if (limitCandidates_ && (limitCandidates_ <= suggestionsList.size())) { break; } suggestionsList.push_back(std::string(currentWordSuggestion)); } delete_aspell_string_enumeration(elements); return; }
void SuggestionsSidebarBlock::UpdateSuggestions(const SuggestionsList& hits) { wxWindowUpdateLocker lock(m_parent); m_suggestions.insert(m_suggestions.end(), hits.begin(), hits.end()); std::stable_sort(m_suggestions.begin(), m_suggestions.end(), [](const Suggestion& a, const Suggestion& b){ if (std::fabs(a.score - b.score) <= std::numeric_limits<double>::epsilon()) return a.timestamp > b.timestamp; else return a.score > b.score; }); // create any necessary controls: while (m_suggestions.size() > m_suggestionsWidgets.size()) { auto w = new SuggestionWidget(m_parent); m_suggestionsSizer->Add(w, wxSizerFlags().Expand()); m_suggestionsWidgets.push_back(w); } m_innerSizer->Layout(); // update shown suggestions: bool isRTL = m_parent->GetCurrentLanguage().IsRTL(); for (size_t i = 0; i < m_suggestions.size(); ++i) { auto s = m_suggestions[i]; m_suggestionsWidgets[i]->SetValue((int)i, s, isRTL, GetIconForSuggestion(s), GetTooltipForSuggestion(s)); } m_innerSizer->Layout(); UpdateVisibility(); m_parent->Layout(); UpdateSuggestionsMenu(); }
SuggestionsList TranslationMemoryImpl::Search(const Language& srclang, const Language& lang, const std::wstring& source) { try { // TODO: query by srclang too! auto srclangQ = newLucene<TermQuery>(newLucene<Term>(L"srclang", srclang.WCode())); const Lucene::String fullLang = lang.WCode(); const Lucene::String shortLang = StringUtils::toUnicode(lang.Lang()); QueryPtr langPrimary = newLucene<TermQuery>(newLucene<Term>(L"lang", fullLang)); QueryPtr langSecondary; if (fullLang == shortLang) { // for e.g. 'cs', search also 'cs_*' (e.g. 'cs_CZ') langSecondary = newLucene<PrefixQuery>(newLucene<Term>(L"lang", shortLang + L"_")); } else { // search short variants of the language too langSecondary = newLucene<TermQuery>(newLucene<Term>(L"lang", shortLang)); } langSecondary->setBoost(0.85); auto langQ = newLucene<BooleanQuery>(); langQ->add(langPrimary, BooleanClause::SHOULD); langQ->add(langSecondary, BooleanClause::SHOULD); SuggestionsList results; const Lucene::String sourceField(L"source"); auto boolQ = newLucene<BooleanQuery>(); auto phraseQ = newLucene<PhraseQuery>(); auto stream = m_analyzer->tokenStream(sourceField, newLucene<StringReader>(source)); int sourceTokensCount = 0; int sourceTokenPosition = -1; while (stream->incrementToken()) { sourceTokensCount++; auto word = stream->getAttribute<TermAttribute>()->term(); sourceTokenPosition += stream->getAttribute<PositionIncrementAttribute>()->getPositionIncrement(); auto term = newLucene<Term>(sourceField, word); boolQ->add(newLucene<TermQuery>(term), BooleanClause::SHOULD); phraseQ->add(term, sourceTokenPosition); } auto searcher = m_mng->Searcher(); // Try exact phrase first: PerformSearch(searcher.ptr(), srclangQ, langQ, source, phraseQ, results, QUALITY_THRESHOLD, /*scoreScaling=*/1.0); if (!results.empty()) return results; // Then, if no matches were found, permit being a bit sloppy: phraseQ->setSlop(1); PerformSearch(searcher.ptr(), srclangQ, langQ, source, phraseQ, results, QUALITY_THRESHOLD, /*scoreScaling=*/0.9); if (!results.empty()) return results; // As the last resort, try terms search. This will almost certainly // produce low-quality results, but hopefully better than nothing. boolQ->setMinimumNumberShouldMatch(std::max(1, boolQ->getClauses().size() - MAX_ALLOWED_LENGTH_DIFFERENCE)); PerformSearchWithBlock ( searcher.ptr(), srclangQ, langQ, source, boolQ, QUALITY_THRESHOLD, /*scoreScaling=*/0.8, [=,&results](DocumentPtr doc, double score) { auto s = get_text_field(doc, sourceField); auto t = get_text_field(doc, L"trans"); auto stream2 = m_analyzer->tokenStream(sourceField, newLucene<StringReader>(s)); int tokensCount2 = 0; while (stream2->incrementToken()) tokensCount2++; if (std::abs(tokensCount2 - sourceTokensCount) <= MAX_ALLOWED_LENGTH_DIFFERENCE && !ContainsResult(results, t)) { time_t ts = DateField::stringToTime(doc->get(L"created")); Suggestion r {t, score, int(ts)}; r.id = StringUtils::toUTF8(doc->get(L"uuid")); results.push_back(r); } } ); std::stable_sort(results.begin(), results.end()); return results; } catch (LuceneException&) { return SuggestionsList(); } }