From 5f6d27711a297d1851dc6bc713fd16c44014cf5c Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 25 Apr 2023 16:44:25 +0200 Subject: Resolves: tdf#144547 ScRangeFindList: handle references in multi-line formula Also fix a color attribution error if when dragging the reference the new reference string is longer (colored too short) or shorter (colored too much including the next characters/operator/...) than the old reference string. Change-Id: I1b39fd5778d75290a0233f51a4198753fa858f48 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150979 Reviewed-by: Eike Rathke Tested-by: Jenkins --- sc/source/ui/app/inputhdl.cxx | 72 ++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 25 deletions(-) (limited to 'sc/source/ui/app/inputhdl.cxx') diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index c0ee11966887..00fc7e429eb4 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -341,6 +341,20 @@ void ScInputHandler::SendReferenceMarks( const SfxViewShell* pViewShell, LOK_CALLBACK_REFERENCE_MARKS, aPayload ); } +static inline void incPos( const sal_Unicode c, sal_Int32& rPos, ESelection& rSel ) +{ + ++rPos; + if (c == '\n') + { + ++rSel.nEndPara; + rSel.nEndPos = 0; + } + else + { + ++rSel.nEndPos; + } +} + void ScInputHandler::InitRangeFinder( const OUString& rFormula ) { DeleteRangeFinder(); @@ -350,7 +364,7 @@ void ScInputHandler::InitRangeFinder( const OUString& rFormula ) ScDocument& rDoc = pDocSh->GetDocument(); const sal_Unicode cSheetSep = rDoc.GetSheetSeparator(); - OUString aDelimiters = ScEditUtil::ModifyDelimiters(" !~\""); + OUString aDelimiters = ScEditUtil::ModifyDelimiters(" !~\"\t\n"); // delimiters (in addition to ScEditUtil): only characters that are // allowed in formulas next to references and the quotation mark (so // string constants can be skipped) @@ -366,6 +380,7 @@ void ScInputHandler::InitRangeFinder( const OUString& rFormula ) sal_Int32 nLen = rFormula.getLength(); sal_Int32 nPos = 0; sal_Int32 nStart = 0; + ESelection aSel; sal_uInt16 nCount = 0; ScRange aRange; while ( nPos < nLen && nCount < RANGEFIND_MAX ) @@ -375,14 +390,16 @@ void ScInputHandler::InitRangeFinder( const OUString& rFormula ) { if ( pChar[nPos] == '"' ) // String { - ++nPos; + incPos( pChar[nPos], nPos, aSel); while (nPosGetTitle() )); } - Color nColor = pRangeFindList->Insert( ScRangeFindData( aRange, nFlags, nStart, nPos ) ); + Color nColor = pRangeFindList->Insert( ScRangeFindData( aRange, nFlags, aSel)); - ESelection aSel( 0, nStart, 0, nPos ); SfxItemSet aSet( mpEditEngine->GetEmptyItemSet() ); aSet.Put( SvxColorItem( nColor, EE_CHAR_COLOR ) ); mpEditEngine->QuickSetAttribs( aSet, aSel ); @@ -620,8 +636,9 @@ static void lcl_Replace( EditView* pView, const OUString& rNewStr, const ESelect // To do that we need to cancel the selection from above (before QuickInsertText) pView->InsertText( OUString() ); - sal_Int32 nLen = pEngine->GetTextLen(0); - ESelection aSel( 0, nLen, 0, nLen ); + const sal_Int32 nPara = pEngine->GetParagraphCount() - 1; + const sal_Int32 nLen = pEngine->GetTextLen(nPara); + ESelection aSel( nPara, nLen, nPara, nLen ); pView->SetSelection( aSel ); // Set cursor to the end } @@ -631,8 +648,6 @@ void ScInputHandler::UpdateRange( sal_uInt16 nIndex, const ScRange& rNew ) if ( pDocView && pRangeFindList && nIndex < pRangeFindList->Count() ) { ScRangeFindData& rData = pRangeFindList->GetObject( nIndex ); - sal_Int32 nOldStart = rData.nSelStart; - sal_Int32 nOldEnd = rData.nSelEnd; Color nNewColor = pRangeFindList->FindColor( rNew, nIndex ); ScRange aJustified = rNew; @@ -640,32 +655,39 @@ void ScInputHandler::UpdateRange( sal_uInt16 nIndex, const ScRange& rNew ) ScDocument& rDoc = pDocView->GetViewData().GetDocument(); const ScAddress::Details aAddrDetails( rDoc, aCursorPos ); OUString aNewStr(aJustified.Format(rDoc, rData.nFlags, aAddrDetails)); - ESelection aOldSel( 0, nOldStart, 0, nOldEnd ); SfxItemSet aSet( mpEditEngine->GetEmptyItemSet() ); DataChanging(); - lcl_Replace( pTopView, aNewStr, aOldSel ); - lcl_Replace( pTableView, aNewStr, aOldSel ); + lcl_Replace( pTopView, aNewStr, rData.maSel ); + lcl_Replace( pTableView, aNewStr, rData.maSel ); + + // We are within one paragraph. + const sal_Int32 nDiff = aNewStr.getLength() - (rData.maSel.nEndPos - rData.maSel.nStartPos); + rData.maSel.nEndPos += nDiff; + aSet.Put( SvxColorItem( nNewColor, EE_CHAR_COLOR ) ); - mpEditEngine->QuickSetAttribs( aSet, aOldSel ); + mpEditEngine->QuickSetAttribs( aSet, rData.maSel ); bInRangeUpdate = true; DataChanged(); bInRangeUpdate = false; - tools::Long nDiff = aNewStr.getLength() - static_cast(nOldEnd-nOldStart); - rData.aRef = rNew; - rData.nSelEnd = rData.nSelEnd + nDiff; rData.nColor = nNewColor; - sal_uInt16 nCount = static_cast(pRangeFindList->Count()); - for (sal_uInt16 i=nIndex+1; iGetObject( i ); - rNext.nSelStart = rNext.nSelStart + nDiff; - rNext.nSelEnd = rNext.nSelEnd + nDiff; + const size_t nCount = pRangeFindList->Count(); + for (size_t i = nIndex + 1; i < nCount; ++i) + { + ScRangeFindData& rNext = pRangeFindList->GetObject( i ); + if (rNext.maSel.nStartPara != rData.maSel.nStartPara) + break; + + rNext.maSel.nStartPos += nDiff; + rNext.maSel.nEndPos += nDiff; + } } EditView* pActiveView = pTopView ? pTopView : pTableView; -- cgit