diff options
author | Vitaliy Anderson <vanderson@smartru.com> | 2017-01-13 05:26:07 -0800 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2017-01-17 10:51:59 +0000 |
commit | 7fa20da88a4778bdf20d6ca0491fe97ae03ab554 (patch) | |
tree | 7cf8f9c1ee1777401c2c200cf0f5be3bcace7f1e | |
parent | 49bfc59272f8482ca37abc631d2c3777518fd1d5 (diff) |
tdf#104349, tdf#104668 MS Word compatibility trailing blanks option
The commits: 1c1747ac13a9d895df0fcba2fbb1bd266dccd74b and 4a410dd147f7160c1d62e3e0b67388a178d5136c
make trailing spaces and their highlighting compatible with the Ms Word.
The option is enabled by default for imported MS Word formats: .doc, .docx, .rtf
For the ODF files the option is disabled by default
Also it allows saving and loading the option state to the ODF UserData.
It may be manually set in Tools->Options->LibreOffice Writer->Compatibility
Change-Id: I5a86359c52d18e50bbb54b9f37c79b672591c369
Reviewed-on: https://gerrit.libreoffice.org/33046
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | include/sfx2/objsh.hxx | 3 | ||||
-rw-r--r-- | sfx2/source/doc/objmisc.cxx | 7 | ||||
-rw-r--r-- | sw/inc/IDocumentSettingAccess.hxx | 3 | ||||
-rw-r--r-- | sw/inc/docsh.hxx | 1 | ||||
-rw-r--r-- | sw/inc/viewsh.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentSettingManager.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentSettingManager.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/text/guess.cxx | 37 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.cxx | 113 | ||||
-rw-r--r-- | sw/source/core/view/viewsh.cxx | 11 | ||||
-rw-r--r-- | sw/source/uibase/app/docsh.cxx | 14 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view.cxx | 15 |
12 files changed, 146 insertions, 70 deletions
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index 5a47988f1e14..bf69c21d58c4 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -461,6 +461,9 @@ public: // Transfer IFace bool IsAbortingImport() const; void FinishedLoading( SfxLoadedFlags nWhich = SfxLoadedFlags::ALL ); + + virtual void SetFormatSpecificCompatibilityOptions( const OUString& /*rFilterTypeName*/ ) { /* Do not do anything here; Derived classes must overload to do actual work */ }; + void TemplateDisconnectionAfterLoad(); bool IsLoading() const; bool IsLoadingFinished() const; diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index dfed530ee3a1..806228e86a21 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -1083,6 +1083,12 @@ void SfxObjectShell::InitOwnModel_Impl() void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags ) { + std::shared_ptr<const SfxFilter> pFlt = pMedium->GetFilter(); + if( pFlt ) + { + SetFormatSpecificCompatibilityOptions( pFlt->GetTypeName() ); + } + bool bSetModifiedTRUE = false; const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false); if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) @@ -1171,7 +1177,6 @@ void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags ) } } - void SfxObjectShell::TemplateDisconnectionAfterLoad() { // document is created from a template diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index f16ae42f30dc..e85e7d796f48 100644 --- a/sw/inc/IDocumentSettingAccess.hxx +++ b/sw/inc/IDocumentSettingAccess.hxx @@ -61,6 +61,9 @@ enum class DocumentSettingId IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME, + // tdf#104349 tdf#104668 + MS_WORD_COMP_TRAILING_BLANKS, + UNIX_FORCE_ZERO_EXT_LEADING, TABS_RELATIVE_TO_INDENT, PROTECT_FORM, diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx index 879c367631b5..afc451f9eb95 100644 --- a/sw/inc/docsh.hxx +++ b/sw/inc/docsh.hxx @@ -265,6 +265,7 @@ public: the load of document being finished. */ void LoadingFinished(); + virtual void SetFormatSpecificCompatibilityOptions( const OUString& rFilterTypeName ) override; /// Cancel transfer (called from SFX). virtual void CancelTransfers() override; diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx index 1d5a34b6c343..96ddd10c6d3b 100644 --- a/sw/inc/viewsh.hxx +++ b/sw/inc/viewsh.hxx @@ -416,6 +416,8 @@ public: void SetProtectForm( bool _bProtectForm ); + void SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks ); + // DOCUMENT COMPATIBILITY FLAGS END // Calls Idle-formatter of Layout. diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index 5cf29c0a4e8a..f0066826b810 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -72,6 +72,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbUnixForceZeroExtLeading(false), mbTabRelativeToIndent(true), mbProtectForm(false), // i#78591# + mbMsWordCompTrailingBlanks(false), // tdf#104349 tdf#104668 mbInvertBorderSpacing (false), mbCollapseEmptyCellPara(true), mbTabAtLeftIndentForParagraphsInList(false), //#i89181# @@ -166,6 +167,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading; case DocumentSettingId::TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent; case DocumentSettingId::PROTECT_FORM: return mbProtectForm; + // tdf#104349 tdf#104668 + case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS: return mbMsWordCompTrailingBlanks; // #i89181# case DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList; case DocumentSettingId::INVERT_BORDER_SPACING: return mbInvertBorderSpacing; @@ -301,6 +304,11 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo mbProtectForm = value; break; + // tdf#140349 + case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS: + mbMsWordCompTrailingBlanks = value; + break; + case DocumentSettingId::TABS_RELATIVE_TO_INDENT: mbTabRelativeToIndent = value; break; @@ -553,6 +561,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti mbUnixForceZeroExtLeading = rSource.mbUnixForceZeroExtLeading; mbTabRelativeToIndent = rSource.mbTabRelativeToIndent; mbTabAtLeftIndentForParagraphsInList = rSource.mbTabAtLeftIndentForParagraphsInList; + mbMsWordCompTrailingBlanks = rSource.mbMsWordCompTrailingBlanks; } sal_uInt32 sw::DocumentSettingManager::Getn32DummyCompatibilityOptions1() const diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index ba52cbfacd83..c4dcd473e274 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -138,6 +138,7 @@ class DocumentSettingManager : bool mbUnixForceZeroExtLeading : 1; // #i60945# bool mbTabRelativeToIndent : 1; // #i24363# tab stops relative to indent bool mbProtectForm : 1; + bool mbMsWordCompTrailingBlanks : 1; // tdf#104349 tdf#104668 bool mbInvertBorderSpacing : 1; bool mbCollapseEmptyCellPara : 1; bool mbTabAtLeftIndentForParagraphsInList; // #i89181# - see above diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index a13ed2466d08..b3dfd58a253f 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -75,23 +75,30 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, const SvxAdjust& rAdjust = rInf.GetTextFrame()->GetTextNode()->GetSwAttrSet().GetAdjust().GetAdjust(); - // tdf#104668 space chars at the end should be cut - if ( rAdjust == SVX_ADJUST_RIGHT || rAdjust == SVX_ADJUST_CENTER ) + // tdf#104668 space chars at the end should be cut if the compatibility option is enabled + // for LTR mode only + if ( !rInf.GetTextFrame()->IsRightToLeft() ) { - sal_Int32 nSpaceCnt = 0; - for ( int i = (rInf.GetText().getLength() - 1); i >= rInf.GetIdx(); --i ) + if ( rInf.GetTextFrame()->GetNode()->getIDocumentSettingAccess()->get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ) ) { - sal_Unicode cChar = rInf.GetText()[i]; - if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK ) - break; - ++nSpaceCnt; - } - sal_Int32 nCharsCnt = nMaxLen - nSpaceCnt; - if ( nSpaceCnt && nCharsCnt < rPor.GetLen() ) - { - nMaxLen = nCharsCnt; - if ( !nMaxLen ) - return true; + if ( rAdjust == SVX_ADJUST_RIGHT || rAdjust == SVX_ADJUST_CENTER ) + { + sal_Int32 nSpaceCnt = 0; + for ( int i = (rInf.GetText().getLength() - 1); i >= rInf.GetIdx(); --i ) + { + sal_Unicode cChar = rInf.GetText()[i]; + if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK ) + break; + ++nSpaceCnt; + } + sal_Int32 nCharsCnt = nMaxLen - nSpaceCnt; + if ( nSpaceCnt && nCharsCnt < rPor.GetLen() ) + { + nMaxLen = nCharsCnt; + if ( !nMaxLen ) + return true; + } + } } } diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index b4709f2461d3..58ee0c40904a 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -1182,71 +1182,78 @@ void SwTextPaintInfo::DrawBackBrush( const SwLinePortion &rPor ) const aFillColor = *m_pFnt->GetBackColor(); } - // tdf#104349 do not hightlight portions of space chars before end of line - bool draw = false; - bool full = false; - SwLinePortion *pPos = const_cast<SwLinePortion *>(&rPor); - sal_Int32 nIdx = GetIdx(); - sal_Int32 nLen; - - do + // tdf#104349 do not hightlight portions of space chars before end of line if the compatibility option is enabled + // for LTR mode only + if ( !GetTextFrame()->IsRightToLeft() ) { - nLen = pPos->GetLen(); - for ( int i = nIdx; i < (nIdx + nLen); ++i ) + if ( GetTextFrame()->GetNode()->getIDocumentSettingAccess()->get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ) ) { - if (i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE) - { - if ( i >= (GetIdx() + rPor.GetLen()) ) - { - goto drawcontinue; - } - } - if (i >= GetText().getLength() || GetText()[i] != CH_BLANK) + bool draw = false; + bool full = false; + SwLinePortion *pPos = const_cast<SwLinePortion *>(&rPor); + sal_Int32 nIdx = GetIdx(); + sal_Int32 nLen; + + do { - draw = true; - if ( i >= (GetIdx() + rPor.GetLen()) ) + nLen = pPos->GetLen(); + for ( int i = nIdx; i < (nIdx + nLen); ++i ) { - full = true; - goto drawcontinue; + if ( i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE ) + { + if ( i >= (GetIdx() + rPor.GetLen()) ) + { + goto drawcontinue; + } + } + if ( i >= GetText().getLength() || GetText()[i] != CH_BLANK ) + { + draw = true; + if ( i >= (GetIdx() + rPor.GetLen()) ) + { + full = true; + goto drawcontinue; + } + } } - } - } - nIdx += nLen; - pPos = pPos->GetPortion(); - } while ( pPos ); + nIdx += nLen; + pPos = pPos->GetPortion(); + } while ( pPos ); - drawcontinue: + drawcontinue: - if ( !draw ) - return; - - if ( !full ) - { - pPos = const_cast<SwLinePortion *>(&rPor); - nIdx = GetIdx(); + if ( !draw ) + return; - nLen = pPos->GetLen(); - for ( int i = (nIdx + nLen - 1); i >= nIdx; --i ) - { - if (i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE) - { - continue; - } - if (i >= GetText().getLength() || GetText()[i] != CH_BLANK) + if ( !full ) { - sal_uInt16 nOldWidth = rPor.Width(); - sal_uInt16 nNewWidth = GetTextSize( m_pOut, nullptr, GetText(), nIdx, (i + 1 - nIdx) ).Width(); - - const_cast<SwLinePortion&>(rPor).Width( nNewWidth ); - CalcRect( rPor, nullptr, &aIntersect, true ); - const_cast<SwLinePortion&>(rPor).Width( nOldWidth ); + pPos = const_cast<SwLinePortion *>(&rPor); + nIdx = GetIdx(); - if ( ! aIntersect.HasArea() ) + nLen = pPos->GetLen(); + for ( int i = (nIdx + nLen - 1); i >= nIdx; --i ) { - return; - } + if ( i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE ) + { + continue; + } + if ( i >= GetText().getLength() || GetText()[i] != CH_BLANK ) + { + sal_uInt16 nOldWidth = rPor.Width(); + sal_uInt16 nNewWidth = GetTextSize( m_pOut, nullptr, GetText(), nIdx, (i + 1 - nIdx) ).Width(); - break; + const_cast<SwLinePortion&>(rPor).Width( nNewWidth ); + CalcRect( rPor, nullptr, &aIntersect, true ); + const_cast<SwLinePortion&>(rPor).Width( nOldWidth ); + + if ( !aIntersect.HasArea() ) + { + return; + } + + break; + } + } } } } diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 5a5b1adef23b..e0ef02b2c4b6 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -904,6 +904,17 @@ void SwViewShell::SetProtectForm( bool _bProtectForm ) rIDSA.set(DocumentSettingId::PROTECT_FORM, _bProtectForm ); } +void SwViewShell::SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks ) +{ + IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess(); + if (rIDSA.get(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS) != _bMsWordCompTrailingBlanks) + { + SwWait aWait(*GetDoc()->GetDocShell(), true); + rIDSA.set(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, _bMsWordCompTrailingBlanks); + const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section; + lcl_InvalidateAllContent(*this, nInv); + } +} void SwViewShell::Reformat() { diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx index 8ebdc5483630..3077decb1f3d 100644 --- a/sw/source/uibase/app/docsh.cxx +++ b/sw/source/uibase/app/docsh.cxx @@ -1156,6 +1156,20 @@ void SwDocShell::LoadingFinished() } } +void SwDocShell::SetFormatSpecificCompatibilityOptions( const OUString& rFilterTypeName ) +{ + //Enable MS Word-compatibility trailing blanks option for MS Word files + if ( rFilterTypeName == "writer_MS_Word_95" || + rFilterTypeName == "writer_MS_Word_97" || + rFilterTypeName == "writer_MS_Word_2003_XML" || + rFilterTypeName == "writer_MS_Word_2007" || + rFilterTypeName == "writer_MS_Word_2007_Template" || + rFilterTypeName == "writer_Rich_Text_Format" ) + { + GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, true ); + } +} + // a Transfer is cancelled (is called from SFX) void SwDocShell::CancelTransfers() { diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx index 305c4f400f53..6de7d5b5995f 100644 --- a/sw/source/uibase/uiview/view.cxx +++ b/sw/source/uibase/uiview/view.cxx @@ -1259,11 +1259,13 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns(); bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ), + bMsWordCompTrailingBlanks = false, bGotVisibleLeft = false, bGotVisibleTop = false, bGotVisibleRight = false, bGotVisibleBottom = false, bGotZoomType = false, bGotZoomFactor = false, bGotIsSelectedFrame = false, - bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false; + bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false, + bGotMsWordCompTrailingBlanks = false; for (sal_Int32 i = 0 ; i < nLength; i++) { @@ -1326,6 +1328,11 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > pValue->Value >>= bSelectedFrame; bGotIsSelectedFrame = true; } + else if ( pValue->Name == "MsWordCompTrailingBlanks" ) + { + pValue->Value >>= bMsWordCompTrailingBlanks; + bGotMsWordCompTrailingBlanks = true; + } // Fallback to common SdrModel processing else GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(pValue); pValue++; @@ -1452,6 +1459,10 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > m_pWrtShell->EnableSmooth( true ); } } + if ( bGotMsWordCompTrailingBlanks ) + { + GetDocShell()->GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, bMsWordCompTrailingBlanks ); + } } } @@ -1491,6 +1502,8 @@ void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSe aVector.push_back(comphelper::makePropertyValue("IsSelectedFrame", FrameTypeFlags::NONE != m_pWrtShell->GetSelFrameType())); + aVector.push_back(comphelper::makePropertyValue("MsWordCompTrailingBlanks", GetDocShell()->GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ))); + rSequence = comphelper::containerToSequence(aVector); // Common SdrModel processing |