diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2018-02-17 15:49:27 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2018-02-19 09:22:35 +0100 |
commit | f26899be899f1a39ea1e6b5ad8b46bad9cf1216f (patch) | |
tree | 345407df73c3eb74fbd755209b9617aba24b2ec7 /editeng | |
parent | 04040bd9e4b8cf52dc75b7d4510c6fc1d104896a (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
Reviewed-on: https://gerrit.libreoffice.org/49909
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
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 | 16 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 12 | ||||
-rw-r--r-- | editeng/source/outliner/outliner.cxx | 10 |
6 files changed, 160 insertions, 12 deletions
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index 8048feabf131..b6da4d4a1a8d 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -26,6 +26,7 @@ #include "editeng/section.hxx" #include "editeng/editobj.hxx" #include "editeng/flditem.hxx" +#include <editeng/adjustitem.hxx> #include "svl/srchitem.hxx" #include <com/sun/star/text/textfield/Type.hpp> @@ -57,12 +58,16 @@ public: void testSectionAttributes(); + /// Test HoriAlignIgnoreTrailingWhitespace compatibility flag + void testHoriAlignIgnoreTrailingWhitespace(); + CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testConstruction); CPPUNIT_TEST(testUnoTextFields); CPPUNIT_TEST(testAutocorrect); CPPUNIT_TEST(testHyperlinkSearch); CPPUNIT_TEST(testSectionAttributes); + CPPUNIT_TEST(testHoriAlignIgnoreTrailingWhitespace); CPPUNIT_TEST_SUITE_END(); private: @@ -631,6 +636,112 @@ void Test::testSectionAttributes() } } +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( SVX_ADJUST_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( SVX_ADJUST_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( SVX_ADJUST_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( SVX_ADJUST_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 4c75a7e2930d..dca25cc94873 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -1434,13 +1434,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; } @@ -2791,6 +2791,16 @@ bool EditEngine::IsPageOverflow() { return pImpEditEngine->IsPageOverflow(); } +void EditEngine::SetHoriAlignIgnoreTrailingWhitespace(bool bEnabled) +{ + pImpEditEngine->SetHoriAlignIgnoreTrailingWhitespace(bEnabled); +} + +bool EditEngine::IsHoriAlignIgnoreTrailingWhitespace() const +{ + return pImpEditEngine->IsHoriAlignIgnoreTrailingWhitespace(); +} + EFieldInfo::EFieldInfo() { pFieldItem = nullptr; diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index ac27e46e4f73..c1bdddbece80 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -527,6 +527,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; // Methods... @@ -823,8 +824,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; @@ -1045,6 +1046,10 @@ public: mark (apostrophe) or not (default is on) */ void SetReplaceLeadingSingleQuotationMark( bool bReplace ) { mbReplaceLeadingSingleQuotationMark = bReplace; } bool IsReplaceLeadingSingleQuotationMark() const { return mbReplaceLeadingSingleQuotationMark; } + + // 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 c4448c40c55d..a6e3542547bd 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -102,7 +102,8 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) : bImpConvertFirstCall(false), bFirstWordCapitalization(true), mbLastTryMerge(false), - mbReplaceLeadingSingleQuotationMark(true) + mbReplaceLeadingSingleQuotationMark(true), + mbHoriAlignIgnoreTrailingWhitespace(false) { pEditEngine = pEE; pRefDev = nullptr; @@ -3041,7 +3042,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. @@ -3088,7 +3089,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; @@ -3101,7 +3102,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() ); @@ -3130,7 +3131,7 @@ sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, break; case PortionKind::TEXT: { - if ( ( eJustification != SVX_ADJUST_BLOCK ) || ( !bIgnoreExtraSpace ) ) + if ( (( eJustification != SVX_ADJUST_BLOCK ) || ( !bIgnoreExtraSpace )) && !bIgnoreTrailingWhiteSpaces ) { nWidth += rTextPortion.GetSize().Width(); } @@ -3140,7 +3141,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 4bf113d34374..7f53110bccd6 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -1469,7 +1469,11 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY ) { case SVX_ADJUST_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 ); } @@ -1478,7 +1482,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 9943efdb0d26..4df73c4a906b 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 > |