From 992c2e82e29ed68e40fe61303d16762604003121 Mon Sep 17 00:00:00 2001 From: Andreas Heinisch Date: Sat, 11 Jan 2020 11:54:52 +0100 Subject: tdf#57879 - Expand word boundaries to include connector punctuations In the IDE expand word boundaries for strings in order to fully select names for double clicks and Ctrl+Shft+Left/Right. Change-Id: I4662b2170fdd5891dc020c08b9a9d8db8d477541 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86597 Tested-by: Jenkins Tested-by: Noel Grandin Reviewed-by: Noel Grandin --- vcl/source/edit/texteng.cxx | 27 ++++++++++++++++++++++++++- vcl/source/edit/textview.cxx | 31 +++++++++++++++++-------------- 2 files changed, 43 insertions(+), 15 deletions(-) (limited to 'vcl/source/edit') diff --git a/vcl/source/edit/texteng.cxx b/vcl/source/edit/texteng.cxx index 9ceb0c83542e..8e0f7a1616b9 100644 --- a/vcl/source/edit/texteng.cxx +++ b/vcl/source/edit/texteng.cxx @@ -2350,7 +2350,7 @@ bool TextEngine::CreateLines( sal_uInt32 nPara ) return nOldLineCount != pTEParaPortion->GetLines().size(); } -OUString TextEngine::GetWord( const TextPaM& rCursorPos, TextPaM* pStartOfWord ) +OUString TextEngine::GetWord( const TextPaM& rCursorPos, TextPaM* pStartOfWord, TextPaM* pEndOfWord ) { OUString aWord; if ( rCursorPos.GetPara() < mpDoc->GetNodes().size() ) @@ -2359,11 +2359,36 @@ OUString TextEngine::GetWord( const TextPaM& rCursorPos, TextPaM* pStartOfWord ) TextNode* pNode = mpDoc->GetNodes()[ rCursorPos.GetPara() ].get(); uno::Reference < i18n::XBreakIterator > xBI = GetBreakIterator(); i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), rCursorPos.GetIndex(), GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true ); + // tdf#57879 - expand selection to the left to include connector punctuations and search for additional word boundaries + if (aBoundary.startPos > 0 && aBoundary.startPos < pNode->GetText().getLength() && u_charType(pNode->GetText()[aBoundary.startPos]) == U_CONNECTOR_PUNCTUATION) + { + aBoundary.startPos = xBI->getWordBoundary(pNode->GetText(), aBoundary.startPos - 1, + GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true).startPos; + } + while (aBoundary.startPos > 0 && u_charType(pNode->GetText()[aBoundary.startPos - 1]) == U_CONNECTOR_PUNCTUATION) + { + aBoundary.startPos = std::min(aBoundary.startPos, + xBI->getWordBoundary( pNode->GetText(), aBoundary.startPos - 2, + GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true).startPos); + } + // tdf#57879 - expand selection to the right to include connector punctuations and search for additional word boundaries + if (aBoundary.endPos < pNode->GetText().getLength() && u_charType(pNode->GetText()[aBoundary.endPos - 1]) == U_CONNECTOR_PUNCTUATION) + { + aBoundary.endPos = xBI->getWordBoundary(pNode->GetText(), aBoundary.endPos, + GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true).endPos; + } + while (aBoundary.endPos < pNode->GetText().getLength() && u_charType(pNode->GetText()[aBoundary.endPos]) == U_CONNECTOR_PUNCTUATION) + { + aBoundary.endPos = xBI->getWordBoundary(pNode->GetText(), aBoundary.endPos + 1, + GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true).endPos; + } aSel.GetStart().GetIndex() = aBoundary.startPos; aSel.GetEnd().GetIndex() = aBoundary.endPos; aWord = pNode->GetText().copy( aSel.GetStart().GetIndex(), aSel.GetEnd().GetIndex() - aSel.GetStart().GetIndex() ); if ( pStartOfWord ) *pStartOfWord = aSel.GetStart(); + if (pEndOfWord) + *pEndOfWord = aSel.GetEnd(); } return aWord; } diff --git a/vcl/source/edit/textview.cxx b/vcl/source/edit/textview.cxx index 6d5921662598..02cfa74f83ac 100644 --- a/vcl/source/edit/textview.cxx +++ b/vcl/source/edit/textview.cxx @@ -730,12 +730,9 @@ void TextView::MouseButtonDown( const MouseEvent& rMouseEvent ) if ( mpImpl->maSelection.GetEnd().GetIndex() < mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection.GetEnd().GetPara() ) ) { HideSelection(); - TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ mpImpl->maSelection.GetEnd().GetPara() ].get(); - css::uno::Reference < css::i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator(); - css::i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true ); - TextSelection aNewSel( mpImpl->maSelection ); - aNewSel.GetStart().GetIndex() = aBoundary.startPos; - aNewSel.GetEnd().GetIndex() = aBoundary.endPos; + // tdf#57879 - expand selection to include connector punctuations + TextSelection aNewSel; + mpImpl->mpTextEngine->GetWord( mpImpl->maSelection.GetEnd(), &aNewSel.GetStart(), &aNewSel.GetEnd() ); ImpSetSelection( aNewSel ); ShowSelection(); ShowCursor(); @@ -1251,12 +1248,18 @@ TextPaM TextView::CursorWordLeft( const TextPaM& rPaM ) if ( aPaM.GetIndex() ) { - TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ].get(); - css::uno::Reference < css::i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator(); - css::i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, true ); - if ( aBoundary.startPos >= rPaM.GetIndex() ) - aBoundary = xBI->previousWord( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ); - aPaM.GetIndex() = ( aBoundary.startPos != -1 ) ? aBoundary.startPos : 0; + // tdf#57879 - expand selection to the left to include connector punctuations + mpImpl->mpTextEngine->GetWord( rPaM, &aPaM ); + if ( aPaM.GetIndex() >= rPaM.GetIndex() ) + { + TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ].get(); + css::uno::Reference < css::i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator(); + aPaM.GetIndex() = xBI->previousWord( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ).startPos; + if ( aPaM.GetIndex() > 0 ) + mpImpl->mpTextEngine->GetWord( aPaM, &aPaM ); + else + aPaM.GetIndex() = 0; + } } else if ( aPaM.GetPara() ) { @@ -1275,8 +1278,8 @@ TextPaM TextView::CursorWordRight( const TextPaM& rPaM ) if ( aPaM.GetIndex() < pNode->GetText().getLength() ) { css::uno::Reference < css::i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator(); - css::i18n::Boundary aBoundary = xBI->nextWord( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ); - aPaM.GetIndex() = aBoundary.startPos; + aPaM.GetIndex() = xBI->nextWord( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), css::i18n::WordType::ANYWORD_IGNOREWHITESPACES ).endPos; + mpImpl->mpTextEngine->GetWord( aPaM, nullptr, &aPaM ); } else if ( aPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().size()-1) ) { -- cgit