diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2018-02-17 06:35:29 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2018-03-25 20:10:48 +0200 |
commit | 2a664263d043f0327a92d5d5f7507bd10143fd31 (patch) | |
tree | 5503172b1265628545547d70a1a218a747766e31 /editeng | |
parent | a4c6b3fa56ef6b8310f94eac90384243355046f6 (diff) |
tdf#115639: Align right/center with trailing spaces the same as MS PowerPoint
* Add HoriAlignIgnoreTrailingWhitespace compatibility option.
** For MSO file formats it is set to true
** For ODP format it's set to false by default
** The flag is saved to ODP format as user data if the document
comes from an MSO format.
Reviewed-on: https://gerrit.libreoffice.org/49889
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
(cherry picked from commit 1da3a3cb74a415a76fa547ef0c8f61780e260e7f)
Change-Id: Ie22233d33a25e605de46120bfc2195038dffd63c
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/qa/unit/core-test.cxx | 111 | ||||
-rw-r--r-- | editeng/source/editeng/editeng.cxx | 14 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 9 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 14 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 12 | ||||
-rw-r--r-- | editeng/source/outliner/outliner.cxx | 10 |
6 files changed, 159 insertions, 11 deletions
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index 5e18be53aa17..dbd169f50b94 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -33,6 +33,7 @@ #include <svl/srchitem.hxx> #include <editeng/fontitem.hxx> #include <editeng/fhgtitem.hxx> +#include <editeng/adjustitem.hxx> #include <com/sun/star/text/textfield/Type.hpp> @@ -95,6 +96,9 @@ public: void testLargeParaCopyPaste(); + /// Test HoriAlignIgnoreTrailingWhitespace compatibility flag + void testHoriAlignIgnoreTrailingWhitespace(); + DECL_STATIC_LINK( Test, CalcFieldValueHdl, EditFieldInfo*, void ); CPPUNIT_TEST_SUITE(Test); @@ -114,6 +118,7 @@ public: CPPUNIT_TEST(testParaStartCopyPaste); CPPUNIT_TEST(testSectionAttributes); CPPUNIT_TEST(testLargeParaCopyPaste); + CPPUNIT_TEST(testHoriAlignIgnoreTrailingWhitespace); CPPUNIT_TEST_SUITE_END(); private: @@ -1833,6 +1838,112 @@ void Test::testLargeParaCopyPaste() CPPUNIT_ASSERT_EQUAL( aTenthPara, rDoc.GetParaAsString(sal_Int32(11)) ); } +void Test::testHoriAlignIgnoreTrailingWhitespace() +{ + // Create EditEngine's instance + EditEngine aEditEngine(mpItemPool); + + // Get EditDoc for current EditEngine's instance + EditDoc &rDoc = aEditEngine.GetEditDoc(); + + // Initially no text should be there + CPPUNIT_ASSERT_EQUAL(sal_uLong(0), rDoc.GetTextLen()); + CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetParaAsString(sal_Int32(0))); + + // Set initial text + OUString aText = "Some text "; + sal_Int32 aTextLen = aText.getLength(); + aEditEngine.SetText(aText); + + // Assert changes - text insertion + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uLong>(aTextLen), rDoc.GetTextLen()); + CPPUNIT_ASSERT_EQUAL(aText, rDoc.GetParaAsString(static_cast<sal_Int32>(0))); + + // First test case: center alignment with compatibility option enabled + { + aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(true); + std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet())); + pSet->Put(SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST )); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count()); + + // Select all paragraphs and apply changes + ESelection aSelection(0, 0, 0, aTextLen); + aEditEngine.QuickSetAttribs(*pSet, aSelection); + + // Use a one line paragraph + aEditEngine.SetPaperSize(Size(10000, 6000)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0)); + + // Check horizontal position + ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0]; + EditLine* pLine = &pParaPortion->GetLines()[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4527), pLine->GetStartPosX(), 10); + } + + // Second test case: center alignment with compatibility option disabled + { + aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(false); + std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet())); + pSet->Put(SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST )); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count()); + + // Select all paragraphs and apply changes + ESelection aSelection(0, 0, 0, aTextLen); + aEditEngine.QuickSetAttribs(*pSet, aSelection); + + // Use a one line paragraph + aEditEngine.SetPaperSize(Size(10000, 6000)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0)); + + // Check horizontal position + ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0]; + EditLine* pLine = &pParaPortion->GetLines()[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(4407), pLine->GetStartPosX(), 10); + } + + // Third test case: right alignment with compatibility option enabled + { + aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(true); + std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet())); + pSet->Put(SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST )); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count()); + + // Select all paragraphs and apply changes + ESelection aSelection(0, 0, 0, aTextLen); + aEditEngine.QuickSetAttribs(*pSet, aSelection); + + // Use a one line paragraph + aEditEngine.SetPaperSize(Size(10000, 6000)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0)); + + // Check horizontal position + ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0]; + EditLine* pLine = &pParaPortion->GetLines()[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(9054), pLine->GetStartPosX(), 10); + } + + // Fourth test case: right alignment with compatibility option disabled + { + aEditEngine.SetHoriAlignIgnoreTrailingWhitespace(false); + std::unique_ptr<SfxItemSet> pSet(new SfxItemSet(aEditEngine.GetEmptyItemSet())); + pSet->Put(SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST )); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), pSet->Count()); + + // Select all paragraphs and apply changes + ESelection aSelection(0, 0, 0, aTextLen); + aEditEngine.QuickSetAttribs(*pSet, aSelection); + + // Use a one line paragraph + aEditEngine.SetPaperSize(Size(10000, 6000)); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEditEngine.GetLineCount(0)); + + // Check horizontal position + ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0]; + EditLine* pLine = &pParaPortion->GetLines()[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(8815), pLine->GetStartPosX(), 10); + } +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); } diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx index a3679f5809b1..54d07d3dd9ec 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -1432,13 +1432,13 @@ sal_uInt32 EditEngine::GetTextHeightNTP() const return pImpEditEngine->GetTextHeightNTP(); } -sal_uInt32 EditEngine::CalcTextWidth() +sal_uInt32 EditEngine::CalcTextWidth(bool bIgnoreTrailingWhiteSpaces) { if ( !pImpEditEngine->IsFormatted() ) pImpEditEngine->FormatDoc(); - sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true ) : pImpEditEngine->GetTextHeight(); + sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true, bIgnoreTrailingWhiteSpaces ) : pImpEditEngine->GetTextHeight(); return nWidth; } @@ -2804,6 +2804,16 @@ bool EditEngine::IsPageOverflow() { return pImpEditEngine->IsPageOverflow(); } +void EditEngine::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled) +{ + pImpEditEngine->SetHoriAlignIgnoreTrailingWhitespace(bEnabled); +} + +bool EditEngine::IsHoriAlignIgnoreTrailingWhitespace() const +{ + return pImpEditEngine->IsHoriAlignIgnoreTrailingWhitespace(); +} + EFieldInfo::EFieldInfo() { } diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index d9ec9a17136a..808d92248d2a 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -535,6 +535,7 @@ private: bool bFirstWordCapitalization:1; // specifies if auto-correction should capitalize the first word or not bool mbLastTryMerge:1; bool mbReplaceLeadingSingleQuotationMark:1; + bool mbHoriAlignIgnoreTrailingWhitespace:1; bool mbNbspRunNext; // can't be a bitfield as it is passed as bool& @@ -831,8 +832,8 @@ public: sal_uInt32 CalcTextHeight( sal_uInt32* pHeightNTP ); sal_uInt32 GetTextHeight() const; sal_uInt32 GetTextHeightNTP() const; - sal_uInt32 CalcTextWidth( bool bIgnoreExtraSpace ); - sal_uInt32 CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace ); + sal_uInt32 CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false ); + sal_uInt32 CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces = false ); sal_Int32 GetLineCount( sal_Int32 nParagraph ) const; sal_Int32 GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const; void GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const; @@ -1063,6 +1064,10 @@ public: bool IsNbspRunNext() const { return mbNbspRunNext; } void Dispose(); + + // tdf#115639 compatibility flag + void SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled) { mbHoriAlignIgnoreTrailingWhitespace = bEnabled; } + bool IsHoriAlignIgnoreTrailingWhitespace() const { return mbHoriAlignIgnoreTrailingWhitespace; } }; inline EPaM ImpEditEngine::CreateEPaM( const EditPaM& rPaM ) diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index 41fec1bf80b3..8c67172db098 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -108,6 +108,7 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) : bFirstWordCapitalization(true), mbLastTryMerge(false), mbReplaceLeadingSingleQuotationMark(true), + mbHoriAlignIgnoreTrailingWhitespace(false), mbNbspRunNext(false) { pEditEngine = pEE; @@ -3092,7 +3093,7 @@ sal_uInt32 ImpEditEngine::GetTextHeight() const return nCurTextHeight; } -sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace ) +sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces ) { // If still not formatted and not in the process. // Will be brought in the formatting for AutoPageSize. @@ -3139,7 +3140,7 @@ sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace ) } } nCurWidth += GetXValue( rLRItem.GetRight() ); - nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace ); + nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace, bIgnoreTrailingWhiteSpaces ); if ( nCurWidth > nMaxWidth ) { nMaxWidth = nCurWidth; @@ -3152,7 +3153,7 @@ sal_uInt32 ImpEditEngine::CalcTextWidth( bool bIgnoreExtraSpace ) return (sal_uInt32)nMaxWidth; } -sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace ) +sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, bool bIgnoreExtraSpace, bool bIgnoreTrailingWhiteSpaces ) { sal_Int32 nPara = GetEditDoc().GetPos( pPortion->GetNode() ); @@ -3181,7 +3182,7 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, break; case PortionKind::TEXT: { - if ( ( eJustification != SvxAdjust::Block ) || ( !bIgnoreExtraSpace ) ) + if ( (( eJustification != SvxAdjust::Block ) || ( !bIgnoreExtraSpace )) && !bIgnoreTrailingWhiteSpaces ) { nWidth += rTextPortion.GetSize().Width(); } @@ -3191,7 +3192,10 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, SeekCursor( pPortion->GetNode(), nPos+1, aTmpFont ); aTmpFont.SetPhysFont( GetRefDevice() ); ImplInitDigitMode(GetRefDevice(), aTmpFont.GetLanguage()); - nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen() ).Width(); + if (bIgnoreTrailingWhiteSpaces) + nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString().trim(), nPos, rTextPortion.GetLen() ).Width(); + else + nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nPos, rTextPortion.GetLen() ).Width(); } } break; diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 7058233308ee..609ff154eb85 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -1512,7 +1512,11 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) { case SvxAdjust::Center: { - long n = ( nMaxLineWidth - aTextSize.Width() ) / 2; + long n; + if(IsHoriAlignIgnoreTrailingWhitespace()) + n = ( nMaxLineWidth - CalcTextWidth( true, true ) ) / 2; + else + n = ( nMaxLineWidth - aTextSize.Width() ) / 2; n += nStartX; // Indentation is kept. pLine->SetStartPosX( n ); } @@ -1521,7 +1525,11 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) { // For automatically wrapped lines, which has a blank at the end // the blank must not be displayed! - long n = nMaxLineWidth - aTextSize.Width(); + long n; + if(IsHoriAlignIgnoreTrailingWhitespace()) + n = nMaxLineWidth - CalcTextWidth( true, true ); + else + n = nMaxLineWidth - aTextSize.Width(); n += nStartX; // Indentation is kept. pLine->SetStartPosX( n ); } diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx index 27ffe02353db..7e65100b03f7 100644 --- a/editeng/source/outliner/outliner.cxx +++ b/editeng/source/outliner/outliner.cxx @@ -366,6 +366,16 @@ sal_Int32 Outliner::GetBulletsNumberingStatus() const : 2; } +void Outliner::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled) +{ + pEditEngine->SetHoriAlignIgnoreTrailingWhitespace( bEnabled ); +} + +bool Outliner::IsHoriAlignIgnoreTrailingWhitespace() const +{ + return pEditEngine->IsHoriAlignIgnoreTrailingWhitespace(); +} + OutlinerParaObject* Outliner::CreateParaObject( sal_Int32 nStartPara, sal_Int32 nCount ) const { if ( static_cast<sal_uLong>(nStartPara) + nCount > |