sw/inc/editsh.hxx | 4 +++ sw/source/core/edit/eddel.cxx | 46 ++++++++++++++++++++++++++++++++++++ sw/source/core/edit/edlingu.cxx | 15 ----------- sw/source/uibase/shells/textsh1.cxx | 23 ++---------------- 4 files changed, 54 insertions(+), 34 deletions(-)
New commits: commit 6da9d629f7f17ec569e7fb6d0f1931dd410b1d28 Author: EMartinGube <martin.g...@web.de> AuthorDate: Thu Jul 20 23:33:37 2023 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sun Oct 15 07:42:07 2023 +0200 tdf#156250: sw: Keep comments when spell correction replaces a word New method SwEditShell:ReplaceKeepComments for comment preserving spell correction. Change-Id: Ifdb9d5664ab8d457a16ad8f7ec62dd968c89d580 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154761 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index 8fc1afb9483a..a3b181440237 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -172,6 +172,10 @@ public: --> "xx\t<Tab>..zzz..&" */ bool Replace( const OUString& rNewStr, bool bRegExpRplc ); + /** Replace a selected range in a TextNode by given string. + Possible comments will be kept (moved to the end of the selection). */ + bool ReplaceKeepComments( const OUString& rNewStr); + /** Delete content of all ranges. If whole nodes are selected, these nodes get deleted. */ bool Delete(bool isArtificialSelection = false); diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx index 10d086bbac63..989cddfd3a28 100644 --- a/sw/source/core/edit/eddel.cxx +++ b/sw/source/core/edit/eddel.cxx @@ -359,6 +359,52 @@ bool SwEditShell::Replace( const OUString& rNewStr, bool bRegExpRplc ) return bRet; } +/** Replace a selected area in a text node with a given string. + * + * Method to replace a text selection with a new string while + * keeping possible comments (they will be moved to the end + * of the selection). + * + * @param rNewStr the new string which the selected area is to be replaced with + * @return true, if something has been replaced, false otherwise. + */ +bool SwEditShell::ReplaceKeepComments( const OUString& rNewStr) +{ + bool bRet = false; + SwPaM *pCursor = GetCursor(); + + if(pCursor != nullptr) + { + // go sure that the text selection pointed to by pCursor is valid + if(pCursor->HasMark()) + { + // preserve comments inside of the number by deleting number portions starting from the back + OUString aSelectedText = pCursor->GetText(); + sal_Int32 nCommentPos(aSelectedText.lastIndexOf(CH_TXTATR_INWORD)); + // go sure that we have a valid selection and a comment has been found + while((nCommentPos > -1) && (aSelectedText.getLength() > 0) && (pCursor->HasMark())) + { + // select the part of the text after the last found comment + // selection start: + pCursor->GetPoint()->AdjustContent(nCommentPos + 1); + // selection end ist left where it is -> will be adjusted later on + // delete the part of the word after the last found comment + Replace(OUString(), false); + // put the selection start back to the beginning of the word + pCursor->GetPoint()->AdjustContent(-(nCommentPos + 1)); + // adjust the selection end, so that the last comment is no longer selected: + pCursor->GetMark()->AdjustContent(-1); + // search for the next possible comment + aSelectedText = pCursor->GetText(); + nCommentPos = aSelectedText.lastIndexOf(CH_TXTATR_INWORD); + } + bRet = Replace(rNewStr, false); + } + } + + return bRet; +} + /// special method for JOE's wizards bool SwEditShell::DelFullPara() { diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx index ab89fc5b7241..63ea37ba8233 100644 --- a/sw/source/core/edit/edlingu.cxx +++ b/sw/source/core/edit/edlingu.cxx @@ -1167,20 +1167,7 @@ void SwEditShell::ApplyChangedSentence(const svx::SpellPortions& rNewPortions, b // if there is a comment inside the original word, don't delete it: // but keep it at the end of the replacement - // TODO: keep all the comments with a recursive function - sal_Int32 nCommentPos(pCursor->GetText().indexOf(OUStringChar(CH_TXTATR_INWORD))); - if ( nCommentPos > -1 ) - { - // delete the original word after the comment - pCursor->GetPoint()->AdjustContent(nCommentPos + 1); - - mxDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, OUString(), false); - // and select only the remaining part before the comment - pCursor->GetPoint()->AdjustContent(-(nCommentPos + 1)); - pCursor->GetMark()->AdjustContent(-1); - } - - mxDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, aCurrentNewPortion->sText, false); + ReplaceKeepComments(aCurrentNewPortion->sText); } else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage) { diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index c92384dbd103..e93fa6613309 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -2128,26 +2128,9 @@ void SwTextShell::Execute(SfxRequest &rReq) rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter); rWrtSh.StartAction(); - // if there is a comment inside the original word, don't delete it: - // but keep it at the end of the replacement - // TODO: keep all the comments with a recursive function - - if (SwPaM *pPaM = rWrtSh.GetCursor()) - { - sal_Int32 nCommentPos(pPaM->GetText().indexOf(OUStringChar(CH_TXTATR_INWORD))); - if ( nCommentPos > -1 ) - { - - // delete the original word after the comment - pPaM->GetPoint()->AdjustContent(nCommentPos + 1); - rWrtSh.Replace(OUString(), false); - // and select only the remaining part before the comment - pPaM->GetPoint()->AdjustContent(-(nCommentPos + 1)); - pPaM->GetMark()->AdjustContent(-1); - } - } - - rWrtSh.Replace(aTmp, false); + // keep comments at the end of the replacement in case spelling correction is + // invoked via the context menu. The spell check dialog does the correction in edlingu.cxx. + rWrtSh.ReplaceKeepComments(aTmp); rWrtSh.EndAction(); rWrtSh.EndUndo();