From 1af2f810624c0e772880d5fafd27cdefa6c88d2c Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Thu, 6 Jun 2013 20:51:05 +0200 Subject: sw: fix AutoCorrect bold/underline regression The horrible SvxAutoCorrect::AutoCorrect() inserts the character into the document half-way through, and then _expects_ this inserted character to show up in its rTxt parameter. This broke in Writer when SwTxtNode::m_Text was converted to OUString, because now a temporary String copy is created. Work around this disaster area for now. (regression from 0295c8a34e39326414c1b98cf4da905802f061b0) Change-Id: I1cb11a20cb0c2577036176e605426105631f3311 (cherry picked from commit e2b9946022c2a286ebac625ccb45f5ddddd5a5d6) --- editeng/qa/unit/core-test.cxx | 45 ++++++++++++++++++++++++------------- editeng/source/editeng/impedit2.cxx | 6 +++-- editeng/source/misc/svxacorr.cxx | 3 ++- include/editeng/svxacorr.hxx | 5 ++++- sw/source/core/edit/edws.cxx | 6 +++-- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index 889f1cc9aaed..a4bd7f73a6c1 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -212,28 +212,29 @@ void Test::testUnoTextFields() class TestAutoCorrDoc : public SvxAutoCorrDoc { public: - TestAutoCorrDoc(const OUString &rText, LanguageType eLang) - : m_sText(rText) + /// just like the real thing, this dummy modifies the rText parameter :( + TestAutoCorrDoc(OUString &rText, LanguageType eLang) + : m_rText(rText) , m_eLang(eLang) { } - OUString getResult() const + OUString const& getResult() const { - return m_sText.toString(); + return m_rText; } private: - OUStringBuffer m_sText; + OUString & m_rText; LanguageType m_eLang; virtual sal_Bool Delete( xub_StrLen nStt, xub_StrLen nEnd ) { //fprintf(stderr, "TestAutoCorrDoc::Delete\n"); - m_sText.remove(nStt, nEnd-nStt); + m_rText = m_rText.replaceAt(nStt, nEnd-nStt, ""); return true; } virtual sal_Bool Insert( xub_StrLen nPos, const String& rTxt ) { //fprintf(stderr, "TestAutoCorrDoc::Insert\n"); - m_sText.insert(nPos, rTxt); + m_rText = m_rText.replaceAt(nPos, 0, rTxt); return true; } virtual sal_Bool Replace( xub_StrLen nPos, const String& rTxt ) @@ -244,8 +245,7 @@ private: virtual sal_Bool ReplaceRange( xub_StrLen nPos, xub_StrLen nLen, const String& rTxt ) { //fprintf(stderr, "TestAutoCorrDoc::ReplaceRange %d %d %s\n", nPos, nLen, OUStringToOString(rTxt, RTL_TEXTENCODING_UTF8).getStr()); - m_sText.remove(nPos, nLen); - m_sText.insert(nPos, rTxt); + m_rText = m_rText.replaceAt(nPos, nLen, rTxt); return true; } virtual sal_Bool SetAttr( xub_StrLen, xub_StrLen, sal_uInt16, SfxPoolItem& ) @@ -269,14 +269,14 @@ private: { //fprintf(stderr, "TestAutoCorrDoc::ChgAutoCorrWord\n"); - if (m_sText.isEmpty()) + if (m_rText.isEmpty()) return false; - const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(m_sText.toString(), rSttPos, nEndPos, *this, m_eLang); + const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList( + m_rText, rSttPos, nEndPos, *this, m_eLang); if (pFnd && pFnd->IsTextOnly()) { - m_sText.remove(rSttPos, nEndPos); - m_sText.insert(rSttPos, pFnd->GetLong()); + m_rText = m_rText.replaceAt(rSttPos, nEndPos, pFnd->GetLong()); if( ppPara ) *ppPara = NULL;//&pCurNode->GetString(); return true; @@ -301,7 +301,7 @@ void Test::testAutocorrect() OUString sExpected("Test-Test "); TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.AutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected); } @@ -312,10 +312,25 @@ void Test::testAutocorrect() OUString sExpected("Test/Test "); TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.AutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected); } + + { + // test auto-bolding with '*' + OUString sInput("*foo"); + sal_Unicode cNextChar('*'); + OUString sExpected("foo"); + + TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); + aAutoCorrect.DoAutoCorrect(aFoo, + reinterpret_cast(sInput), + sInput.getLength(), cNextChar, true); + + CPPUNIT_ASSERT_EQUAL(sExpected, aFoo.getResult()); + } + } CPPUNIT_TEST_SUITE_REGISTRATION(Test); diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 8bd73063b646..4bc6d7082cdb 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -2493,8 +2493,10 @@ EditPaM ImpEditEngine::AutoCorrect( const EditSelection& rCurSel, sal_Unicode c, ContentNode* pNode = aSel.Max().GetNode(); sal_uInt16 nIndex = aSel.Max().GetIndex(); EdtAutoCorrDoc aAuto(pEditEngine, pNode, nIndex, c); - pAutoCorrect->AutoCorrect( - aAuto, pNode->GetString(), nIndex, c, !bOverwrite, pFrameWin ); + // FIXME: this _must_ be called with reference to the actual node text! + String const& rNodeString(pNode->GetString()); + pAutoCorrect->DoAutoCorrect( + aAuto, rNodeString, nIndex, c, !bOverwrite, pFrameWin ); aSel.Max().SetIndex( aAuto.GetCursor() ); // #i78661 since the SvxAutoCorrect object used here is diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index bb8f0896c587..965016377d98 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -1207,7 +1207,8 @@ String SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, xub_StrLen nInsPos, return sRet; } -sal_uLong SvxAutoCorrect::AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt, +sal_uLong +SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt, xub_StrLen nInsPos, sal_Unicode cChar, sal_Bool bInsert, Window* pFrameWin ) { diff --git a/include/editeng/svxacorr.hxx b/include/editeng/svxacorr.hxx index 9d5774a12464..85bf3e913768 100644 --- a/include/editeng/svxacorr.hxx +++ b/include/editeng/svxacorr.hxx @@ -290,7 +290,10 @@ public: // Execute an AutoCorrect. // Returns what has been executed, according to the above flags - sal_uLong AutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt, + // FIXME: this has the horrible flaw that the rTxt must be a reference + // to the actual SwTxtNode/EditNode string because it inserts the character + // in rDoc and expects that to side-effect rTxt + sal_uLong DoAutoCorrect( SvxAutoCorrDoc& rDoc, const String& rTxt, xub_StrLen nPos, sal_Unicode cInsChar, sal_Bool bInsert, Window* pFrameWin = NULL ); // Return for the autotext expansion the previous word, diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx index c99ea28290e9..48a7eaba531f 100644 --- a/sw/source/core/edit/edws.cxx +++ b/sw/source/core/edit/edws.cxx @@ -308,8 +308,10 @@ void SwEditShell::AutoCorrect( SvxAutoCorrect& rACorr, sal_Bool bInsert, SwTxtNode* pTNd = pCrsr->GetNode()->GetTxtNode(); SwAutoCorrDoc aSwAutoCorrDoc( *this, *pCrsr, cChar ); - rACorr.AutoCorrect( aSwAutoCorrDoc, - pTNd->GetTxt(), pCrsr->GetPoint()->nContent.GetIndex(), + // FIXME: this _must_ be called with reference to the actual node text! + String const& rNodeText(reinterpret_cast(pTNd->GetTxt())); + rACorr.DoAutoCorrect( aSwAutoCorrDoc, + rNodeText, pCrsr->GetPoint()->nContent.GetIndex(), cChar, bInsert, GetWin() ); if( cChar ) SaveTblBoxCntnt( pCrsr->GetPoint() ); -- cgit v1.2.3