Kaydet (Commit) 6c86ae2f authored tarafından Vitaliy Anderson's avatar Vitaliy Anderson Kaydeden (comit) Aron Budea

tdf#104349, tdf#104668 MS Word compatibility trailing blanks option

The commits: 1c1747ac and 4a410dd1
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

Reviewed-on: https://gerrit.libreoffice.org/33046Reviewed-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
Tested-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 7fa20da8)

Change-Id: I5a86359c52d18e50bbb54b9f37c79b672591c369
üst 38d2aa02
...@@ -460,6 +460,9 @@ public: ...@@ -460,6 +460,9 @@ public:
// Transfer IFace // Transfer IFace
bool IsAbortingImport() const; bool IsAbortingImport() const;
void FinishedLoading( SfxLoadedFlags nWhich = SfxLoadedFlags::ALL ); 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(); void TemplateDisconnectionAfterLoad();
bool IsLoading() const; bool IsLoading() const;
bool IsLoadingFinished() const; bool IsLoadingFinished() const;
......
...@@ -1128,6 +1128,12 @@ void SfxObjectShell::InitOwnModel_Impl() ...@@ -1128,6 +1128,12 @@ void SfxObjectShell::InitOwnModel_Impl()
void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags ) void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags )
{ {
std::shared_ptr<const SfxFilter> pFlt = pMedium->GetFilter();
if( pFlt )
{
SetFormatSpecificCompatibilityOptions( pFlt->GetTypeName() );
}
bool bSetModifiedTRUE = false; bool bSetModifiedTRUE = false;
const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false); const SfxStringItem* pSalvageItem = SfxItemSet::GetItem<SfxStringItem>(pMedium->GetItemSet(), SID_DOC_SALVAGE, false);
if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) if( ( nFlags & SfxLoadedFlags::MAINDOCUMENT ) && !(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )
...@@ -1216,7 +1222,6 @@ void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags ) ...@@ -1216,7 +1222,6 @@ void SfxObjectShell::FinishedLoading( SfxLoadedFlags nFlags )
} }
} }
void SfxObjectShell::TemplateDisconnectionAfterLoad() void SfxObjectShell::TemplateDisconnectionAfterLoad()
{ {
// document is created from a template // document is created from a template
......
...@@ -62,6 +62,9 @@ enum class DocumentSettingId ...@@ -62,6 +62,9 @@ enum class DocumentSettingId
IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION,
CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME, CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME,
// tdf#104349 tdf#104668
MS_WORD_COMP_TRAILING_BLANKS,
UNIX_FORCE_ZERO_EXT_LEADING, UNIX_FORCE_ZERO_EXT_LEADING,
TABS_RELATIVE_TO_INDENT, TABS_RELATIVE_TO_INDENT,
PROTECT_FORM, PROTECT_FORM,
......
...@@ -267,6 +267,7 @@ public: ...@@ -267,6 +267,7 @@ public:
the load of document being finished. */ the load of document being finished. */
void LoadingFinished(); void LoadingFinished();
virtual void SetFormatSpecificCompatibilityOptions( const OUString& rFilterTypeName ) override;
/// Cancel transfer (called from SFX). /// Cancel transfer (called from SFX).
virtual void CancelTransfers() override; virtual void CancelTransfers() override;
......
...@@ -416,6 +416,8 @@ public: ...@@ -416,6 +416,8 @@ public:
void SetProtectForm( bool _bProtectForm ); void SetProtectForm( bool _bProtectForm );
void SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks );
void SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys); void SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys);
// DOCUMENT COMPATIBILITY FLAGS END // DOCUMENT COMPATIBILITY FLAGS END
......
...@@ -73,6 +73,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) ...@@ -73,6 +73,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc)
mbUnixForceZeroExtLeading(false), mbUnixForceZeroExtLeading(false),
mbTabRelativeToIndent(true), mbTabRelativeToIndent(true),
mbProtectForm(false), // i#78591# mbProtectForm(false), // i#78591#
mbMsWordCompTrailingBlanks(false), // tdf#104349 tdf#104668
mbInvertBorderSpacing (false), mbInvertBorderSpacing (false),
mbCollapseEmptyCellPara(true), mbCollapseEmptyCellPara(true),
mbTabAtLeftIndentForParagraphsInList(false), //#i89181# mbTabAtLeftIndentForParagraphsInList(false), //#i89181#
...@@ -168,6 +169,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const ...@@ -168,6 +169,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const
case DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading; case DocumentSettingId::UNIX_FORCE_ZERO_EXT_LEADING: return mbUnixForceZeroExtLeading;
case DocumentSettingId::TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent; case DocumentSettingId::TABS_RELATIVE_TO_INDENT : return mbTabRelativeToIndent;
case DocumentSettingId::PROTECT_FORM: return mbProtectForm; case DocumentSettingId::PROTECT_FORM: return mbProtectForm;
// tdf#104349 tdf#104668
case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS: return mbMsWordCompTrailingBlanks;
// #i89181# // #i89181#
case DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList; case DocumentSettingId::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST: return mbTabAtLeftIndentForParagraphsInList;
case DocumentSettingId::INVERT_BORDER_SPACING: return mbInvertBorderSpacing; case DocumentSettingId::INVERT_BORDER_SPACING: return mbInvertBorderSpacing;
...@@ -306,6 +309,11 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo ...@@ -306,6 +309,11 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo
mbProtectForm = value; mbProtectForm = value;
break; break;
// tdf#140349
case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS:
mbMsWordCompTrailingBlanks = value;
break;
case DocumentSettingId::TABS_RELATIVE_TO_INDENT: case DocumentSettingId::TABS_RELATIVE_TO_INDENT:
mbTabRelativeToIndent = value; mbTabRelativeToIndent = value;
break; break;
...@@ -558,6 +566,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti ...@@ -558,6 +566,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti
mbUnixForceZeroExtLeading = rSource.mbUnixForceZeroExtLeading; mbUnixForceZeroExtLeading = rSource.mbUnixForceZeroExtLeading;
mbTabRelativeToIndent = rSource.mbTabRelativeToIndent; mbTabRelativeToIndent = rSource.mbTabRelativeToIndent;
mbTabAtLeftIndentForParagraphsInList = rSource.mbTabAtLeftIndentForParagraphsInList; mbTabAtLeftIndentForParagraphsInList = rSource.mbTabAtLeftIndentForParagraphsInList;
mbMsWordCompTrailingBlanks = rSource.mbMsWordCompTrailingBlanks;
} }
sal_uInt32 sw::DocumentSettingManager::Getn32DummyCompatibilityOptions1() const sal_uInt32 sw::DocumentSettingManager::Getn32DummyCompatibilityOptions1() const
......
...@@ -139,6 +139,7 @@ class DocumentSettingManager : ...@@ -139,6 +139,7 @@ class DocumentSettingManager :
bool mbUnixForceZeroExtLeading : 1; // #i60945# bool mbUnixForceZeroExtLeading : 1; // #i60945#
bool mbTabRelativeToIndent : 1; // #i24363# tab stops relative to indent bool mbTabRelativeToIndent : 1; // #i24363# tab stops relative to indent
bool mbProtectForm : 1; bool mbProtectForm : 1;
bool mbMsWordCompTrailingBlanks : 1; // tdf#104349 tdf#104668
bool mbInvertBorderSpacing : 1; bool mbInvertBorderSpacing : 1;
bool mbCollapseEmptyCellPara : 1; bool mbCollapseEmptyCellPara : 1;
bool mbTabAtLeftIndentForParagraphsInList; // #i89181# - see above bool mbTabAtLeftIndentForParagraphsInList; // #i89181# - see above
......
...@@ -75,23 +75,30 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, ...@@ -75,23 +75,30 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
const SvxAdjust& rAdjust = rInf.GetTextFrame()->GetTextNode()->GetSwAttrSet().GetAdjust().GetAdjust(); const SvxAdjust& rAdjust = rInf.GetTextFrame()->GetTextNode()->GetSwAttrSet().GetAdjust().GetAdjust();
// tdf#104668 space chars at the end should be cut // tdf#104668 space chars at the end should be cut if the compatibility option is enabled
if ( rAdjust == SVX_ADJUST_RIGHT || rAdjust == SVX_ADJUST_CENTER ) // for LTR mode only
if ( !rInf.GetTextFrame()->IsRightToLeft() )
{ {
sal_Int32 nSpaceCnt = 0; if ( rInf.GetTextFrame()->GetNode()->getIDocumentSettingAccess()->get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ) )
for ( int i = (rInf.GetText().getLength() - 1); i >= rInf.GetIdx(); --i )
{ {
sal_Unicode cChar = rInf.GetText()[i]; if ( rAdjust == SVX_ADJUST_RIGHT || rAdjust == SVX_ADJUST_CENTER )
if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK ) {
break; sal_Int32 nSpaceCnt = 0;
++nSpaceCnt; for ( int i = (rInf.GetText().getLength() - 1); i >= rInf.GetIdx(); --i )
} {
sal_Int32 nCharsCnt = nMaxLen - nSpaceCnt; sal_Unicode cChar = rInf.GetText()[i];
if ( nSpaceCnt && nCharsCnt < rPor.GetLen() ) if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK )
{ break;
nMaxLen = nCharsCnt; ++nSpaceCnt;
if ( !nMaxLen ) }
return true; sal_Int32 nCharsCnt = nMaxLen - nSpaceCnt;
if ( nSpaceCnt && nCharsCnt < rPor.GetLen() )
{
nMaxLen = nCharsCnt;
if ( !nMaxLen )
return true;
}
}
} }
} }
......
...@@ -1184,71 +1184,78 @@ void SwTextPaintInfo::DrawBackBrush( const SwLinePortion &rPor ) const ...@@ -1184,71 +1184,78 @@ void SwTextPaintInfo::DrawBackBrush( const SwLinePortion &rPor ) const
aFillColor = *m_pFnt->GetBackColor(); aFillColor = *m_pFnt->GetBackColor();
} }
// tdf#104349 do not hightlight portions of space chars before end of line // tdf#104349 do not hightlight portions of space chars before end of line if the compatibility option is enabled
bool draw = false; // for LTR mode only
bool full = false; if ( !GetTextFrame()->IsRightToLeft() )
SwLinePortion *pPos = const_cast<SwLinePortion *>(&rPor);
sal_Int32 nIdx = GetIdx();
sal_Int32 nLen;
do
{ {
nLen = pPos->GetLen(); if ( GetTextFrame()->GetNode()->getIDocumentSettingAccess()->get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ) )
for ( int i = nIdx; i < (nIdx + nLen); ++i )
{ {
if (i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE) bool draw = false;
{ bool full = false;
if ( i >= (GetIdx() + rPor.GetLen()) ) SwLinePortion *pPos = const_cast<SwLinePortion *>(&rPor);
{ sal_Int32 nIdx = GetIdx();
goto drawcontinue; sal_Int32 nLen;
}
} do
if (i >= GetText().getLength() || GetText()[i] != CH_BLANK)
{ {
draw = true; nLen = pPos->GetLen();
if ( i >= (GetIdx() + rPor.GetLen()) ) for ( int i = nIdx; i < (nIdx + nLen); ++i )
{ {
full = true; if ( i < GetText().getLength() && GetText()[i] == CH_TXTATR_NEWLINE )
goto drawcontinue; {
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();
nIdx += nLen; } while ( pPos );
pPos = pPos->GetPortion();
} while ( pPos );
drawcontinue: drawcontinue:
if ( !draw ) if ( !draw )
return; return;
if ( !full )
{
pPos = const_cast<SwLinePortion *>(&rPor);
nIdx = GetIdx();
nLen = pPos->GetLen(); if ( !full )
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)
{ {
sal_uInt16 nOldWidth = rPor.Width(); pPos = const_cast<SwLinePortion *>(&rPor);
sal_uInt16 nNewWidth = GetTextSize( m_pOut, nullptr, GetText(), nIdx, (i + 1 - nIdx) ).Width(); nIdx = GetIdx();
const_cast<SwLinePortion&>(rPor).Width( nNewWidth );
CalcRect( rPor, nullptr, &aIntersect, true );
const_cast<SwLinePortion&>(rPor).Width( nOldWidth );
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;
}
}
} }
} }
} }
......
...@@ -899,6 +899,17 @@ void SwViewShell::SetProtectForm( bool _bProtectForm ) ...@@ -899,6 +899,17 @@ void SwViewShell::SetProtectForm( bool _bProtectForm )
rIDSA.set(DocumentSettingId::PROTECT_FORM, _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::SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys) void SwViewShell::SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys)
{ {
......
...@@ -1163,6 +1163,20 @@ void SwDocShell::LoadingFinished() ...@@ -1163,6 +1163,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) // a Transfer is cancelled (is called from SFX)
void SwDocShell::CancelTransfers() void SwDocShell::CancelTransfers()
{ {
......
...@@ -1262,12 +1262,14 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > ...@@ -1262,12 +1262,14 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >
sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns(); sal_Int16 nViewLayoutColumns = pVOpt->GetViewLayoutColumns();
bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ), bool bSelectedFrame = ( m_pWrtShell->GetSelFrameType() != FrameTypeFlags::NONE ),
bMsWordCompTrailingBlanks = false,
bGotVisibleLeft = false, bGotVisibleLeft = false,
bGotVisibleTop = false, bGotVisibleRight = false, bGotVisibleTop = false, bGotVisibleRight = false,
bGotVisibleBottom = false, bGotZoomType = false, bGotVisibleBottom = false, bGotZoomType = false,
bGotZoomFactor = false, bGotIsSelectedFrame = false, bGotZoomFactor = false, bGotIsSelectedFrame = false,
bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false, bGotViewLayoutColumns = false, bGotViewLayoutBookMode = false,
bBrowseMode = false, bGotBrowseMode = false; bBrowseMode = false, bGotBrowseMode = false,
bGotMsWordCompTrailingBlanks = false;
for (sal_Int32 i = 0 ; i < nLength; i++) for (sal_Int32 i = 0 ; i < nLength; i++)
{ {
...@@ -1335,6 +1337,11 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > ...@@ -1335,6 +1337,11 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >
pValue->Value >>= bBrowseMode; pValue->Value >>= bBrowseMode;
bGotBrowseMode = true; bGotBrowseMode = true;
} }
else if ( pValue->Name == "MsWordCompTrailingBlanks" )
{
pValue->Value >>= bMsWordCompTrailingBlanks;
bGotMsWordCompTrailingBlanks = true;
}
// Fallback to common SdrModel processing // Fallback to common SdrModel processing
else GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(pValue); else GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->ReadUserDataSequenceValue(pValue);
pValue++; pValue++;
...@@ -1466,6 +1473,10 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue > ...@@ -1466,6 +1473,10 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < beans::PropertyValue >
m_pWrtShell->EnableSmooth( true ); m_pWrtShell->EnableSmooth( true );
} }
} }
if ( bGotMsWordCompTrailingBlanks )
{
GetDocShell()->GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, bMsWordCompTrailingBlanks );
}
} }
} }
...@@ -1505,6 +1516,8 @@ void SwView::WriteUserDataSequence ( uno::Sequence < beans::PropertyValue >& rSe ...@@ -1505,6 +1516,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("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); rSequence = comphelper::containerToSequence(aVector);
// Common SdrModel processing // Common SdrModel processing
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment