diff options
Diffstat (limited to 'sw/source/core')
-rw-r--r-- | sw/source/core/doc/DocumentSettingManager.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/doc/doc.cxx | 128 | ||||
-rw-r--r-- | sw/source/core/doc/doctxm.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentSettingManager.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/text/txtfrm.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/txtnode/atrfld.cxx | 26 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 65 | ||||
-rw-r--r-- | sw/source/core/view/viewsh.cxx | 20 |
9 files changed, 168 insertions, 95 deletions
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index 77de92017537..c900a985dee2 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -114,6 +114,8 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbProtectForm = aOptions.GetDefault( SvtCompatibilityEntry::Index::ProtectForm ); mbMsWordCompTrailingBlanks = aOptions.GetDefault( SvtCompatibilityEntry::Index::MsWordTrailingBlanks ); mbSubtractFlys = aOptions.GetDefault( SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ); + mbEmptyDbFieldHidesPara + = aOptions.GetDefault(SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara); } else { @@ -131,6 +133,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc) mbProtectForm = false; mbMsWordCompTrailingBlanks = false; mbSubtractFlys = false; + mbEmptyDbFieldHidesPara = true; } // COMPATIBILITY FLAGS END @@ -204,6 +207,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::EMBED_SYSTEM_FONTS: return mEmbedSystemFonts; case DocumentSettingId::APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING: return mApplyParagraphMarkFormatToNumbering; case DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING: return mbDisableOffPagePositioning; + case DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA: return mbEmptyDbFieldHidesPara; default: OSL_FAIL("Invalid setting id"); } @@ -421,6 +425,9 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo case DocumentSettingId::DISABLE_OFF_PAGE_POSITIONING: mbDisableOffPagePositioning = value; break; + case DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA: + mbEmptyDbFieldHidesPara = value; + break; default: OSL_FAIL("Invalid setting id"); } @@ -562,6 +569,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti mbTabRelativeToIndent = rSource.mbTabRelativeToIndent; mbTabAtLeftIndentForParagraphsInList = rSource.mbTabAtLeftIndentForParagraphsInList; mbMsWordCompTrailingBlanks = rSource.mbMsWordCompTrailingBlanks; + mbEmptyDbFieldHidesPara = rSource.mbEmptyDbFieldHidesPara; } sal_uInt32 sw::DocumentSettingManager::Getn32DummyCompatibilityOptions1() const diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 9f4a08b7bd42..5fbd8f84271d 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1318,6 +1318,73 @@ void SwDoc::Summary( SwDoc* pExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, bool bIm } } +namespace +{ +void RemoveOrDeleteContents(SwTextNode* pTextNd, IDocumentContentOperations& xOperations) +{ + SwPaM aPam(*pTextNd, 0, *pTextNd, pTextNd->GetText().getLength()); + + // Remove hidden paragraph or delete contents: + // Delete contents if + // 1. removing the paragraph would result in an empty section or + // 2. if the paragraph is the last paragraph in the section and + // there is no paragraph in front of the paragraph: + if ((2 == pTextNd->EndOfSectionIndex() - pTextNd->StartOfSectionIndex()) + || (1 == pTextNd->EndOfSectionIndex() - pTextNd->GetIndex() + && !pTextNd->GetNodes()[pTextNd->GetIndex() - 1]->GetTextNode())) + { + xOperations.DeleteRange(aPam); + } + else + { + aPam.DeleteMark(); + xOperations.DelFullPara(aPam); + } +} +// Returns if the data was actually modified +bool HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes, + IDocumentContentOperations& xOperations) +{ + SwTextNode* pTextNd; + if (rFormatField.GetTextField() + && nullptr != (pTextNd = rFormatField.GetTextField()->GetpTextNode()) + && pTextNd->GetpSwpHints() && pTextNd->IsHiddenByParaField() + && &pTextNd->GetNodes() == &rNodes) + { + RemoveOrDeleteContents(pTextNd, xOperations); + return true; + } + return false; +} +} + +bool SwDoc::FieldCanHidePara(SwFieldIds eFieldId) const +{ + switch (eFieldId) + { + case SwFieldIds::HiddenPara: + return true; + case SwFieldIds::Database: + return GetDocumentSettingManager().get( + DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA); + default: + return false; + } +} + +bool SwDoc::FieldHidesPara(const SwField& rField) const +{ + switch (rField.GetTyp()->Which()) + { + case SwFieldIds::HiddenPara: + return static_cast<const SwHiddenParaField&>(rField).IsHidden(); + case SwFieldIds::Database: + return FieldCanHidePara(SwFieldIds::Database) && rField.ExpandField(true).isEmpty(); + default: + return false; + } +} + /// Remove the invisible content from the document e.g. hidden areas, hidden paragraphs bool SwDoc::RemoveInvisibleContent() { @@ -1325,35 +1392,22 @@ bool SwDoc::RemoveInvisibleContent() GetIDocumentUndoRedo().StartUndo( SwUndoId::UI_DELETE_INVISIBLECNTNT, nullptr ); { - SwTextNode* pTextNd; - SwIterator<SwFormatField,SwFieldType> aIter( *getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenPara ) ); - for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() ) + // Removing some nodes for one SwFieldIds::Database type might remove the type from + // document's field types, invalidating iterators. So, we need to create own list of + // matching types prior to processing them. + std::vector<const SwFieldType*> aHidingFieldTypes; + for (const auto* pType : *getIDocumentFieldsAccess().GetFieldTypes()) { - if( pFormatField->GetTextField() && - nullptr != ( pTextNd = pFormatField->GetTextField()->GetpTextNode() ) && - pTextNd->GetpSwpHints() && pTextNd->HasHiddenParaField() && - &pTextNd->GetNodes() == &GetNodes() ) - { - bRet = true; - SwPaM aPam(*pTextNd, 0, *pTextNd, pTextNd->GetText().getLength()); - - // Remove hidden paragraph or delete contents: - // Delete contents if - // 1. removing the paragraph would result in an empty section or - // 2. if the paragraph is the last paragraph in the section and - // there is no paragraph in front of the paragraph: - if ( ( 2 == pTextNd->EndOfSectionIndex() - pTextNd->StartOfSectionIndex() ) || - ( 1 == pTextNd->EndOfSectionIndex() - pTextNd->GetIndex() && - !GetNodes()[ pTextNd->GetIndex() - 1 ]->GetTextNode() ) ) - { - getIDocumentContentOperations().DeleteRange( aPam ); - } - else - { - aPam.DeleteMark(); - getIDocumentContentOperations().DelFullPara( aPam ); - } - } + if (FieldCanHidePara(pType->Which())) + aHidingFieldTypes.push_back(pType); + } + for (const auto* pType : aHidingFieldTypes) + { + SwIterator<SwFormatField, SwFieldType> aIter(*pType); + for (SwFormatField* pFormatField = aIter.First(); pFormatField; + pFormatField = aIter.Next()) + bRet |= HandleHidingField(*pFormatField, GetNodes(), + getIDocumentContentOperations()); } } @@ -1369,23 +1423,7 @@ bool SwDoc::RemoveInvisibleContent() { bRemoved = true; bRet = true; - - // Remove hidden paragraph or delete contents: - // Delete contents if - // 1. removing the paragraph would result in an empty section or - // 2. if the paragraph is the last paragraph in the section and - // there is no paragraph in front of the paragraph: - if ( ( 2 == pTextNd->EndOfSectionIndex() - pTextNd->StartOfSectionIndex() ) || - ( 1 == pTextNd->EndOfSectionIndex() - pTextNd->GetIndex() && - !GetNodes()[ pTextNd->GetIndex() - 1 ]->GetTextNode() ) ) - { - getIDocumentContentOperations().DeleteRange( aPam ); - } - else - { - aPam.DeleteMark(); - getIDocumentContentOperations().DelFullPara( aPam ); - } + RemoveOrDeleteContents(pTextNd, getIDocumentContentOperations()); } else if ( pTextNd->HasHiddenCharAttribute( false ) ) { diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index 34cdce1fee6c..4d7741fdb402 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -1152,7 +1152,7 @@ void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl, pTOXSrc->GetText().getLength() && pTOXSrc->HasWriterListeners() && pTOXSrc->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) && (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc ) == pOwnChapterNode ) && - !pTOXSrc->HasHiddenParaField() && + !pTOXSrc->IsHiddenByParaField() && !SwScriptInfo::IsInHiddenRange( *pTOXSrc, pTextMark->GetStart() ) ) { SwTOXSortTabBase* pBase = nullptr; @@ -1205,7 +1205,7 @@ void SwTOXBaseSection::UpdateOutline( const SwTextNode* pOwnChapterNode ) if( pTextNd && pTextNd->Len() && pTextNd->HasWriterListeners() && sal_uInt16( pTextNd->GetAttrOutlineLevel()) <= GetLevel() && pTextNd->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) && - !pTextNd->HasHiddenParaField() && + !pTextNd->IsHiddenByParaField() && !pTextNd->HasHiddenCharAttribute( true ) && ( !IsFromChapter() || ::lcl_FindChapterNode( *pTextNd ) == pOwnChapterNode )) diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index 5f762d099ca8..1cf9a9d9fea9 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -155,6 +155,7 @@ class DocumentSettingManager : bool mbLastBrowseMode : 1; bool mbDisableOffPagePositioning; // tdf#112443 + bool mbEmptyDbFieldHidesPara; public: diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index c1e953725fc8..227f802e6135 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -459,12 +459,11 @@ bool SwTextFrame::IsHiddenNow() const return true; } - const bool bHiddenCharsHidePara = GetTextNode()->HasHiddenCharAttribute( true ); - const bool bHiddenParaField = GetTextNode()->HasHiddenParaField(); - const SwViewShell* pVsh = getRootFrame()->GetCurrShell(); - - if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) ) + if ( const SwViewShell* pVsh = getRootFrame()->GetCurrShell() ) { + const bool bHiddenCharsHidePara = GetTextNode()->HasHiddenCharAttribute(true); + const bool bHiddenParaField = GetTextNode()->IsHiddenByParaField(); + if ( ( bHiddenParaField && ( !pVsh->GetViewOptions()->IsShowHiddenPara() && diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx index 36c39618074a..8ebffec8b24c 100644 --- a/sw/source/core/txtnode/atrfld.cxx +++ b/sw/source/core/txtnode/atrfld.cxx @@ -380,18 +380,26 @@ void SwTextField::ExpandTextField(const bool bForceNotify) const const SwField* pField = GetFormatField().GetField(); const OUString aNewExpand( pField->ExpandField(m_pTextNode->GetDoc()->IsClipBoard()) ); + const SwFieldIds nWhich = pField->GetTyp()->Which(); + const bool bSameExpandSimpleNotification + = SwFieldIds::Chapter != nWhich && SwFieldIds::PageNumber != nWhich + && SwFieldIds::RefPageGet != nWhich + // Page count fields to not use aExpand during formatting, + // therefore an invalidation of the text frame has to be triggered even if aNewExpand == aExpand: + && (SwFieldIds::DocStat != nWhich + || DS_PAGE != static_cast<const SwDocStatField*>(pField)->GetSubType()) + && (SwFieldIds::GetExp != nWhich + || static_cast<const SwGetExpField*>(pField)->IsInBodyText()); + + bool bHiddenParaChanged = false; + if (aNewExpand != m_aExpand || bSameExpandSimpleNotification) + bHiddenParaChanged = m_pTextNode->CalcHiddenParaField(); + if (aNewExpand == m_aExpand) { - const SwFieldIds nWhich = pField->GetTyp()->Which(); - if ( SwFieldIds::Chapter != nWhich - && SwFieldIds::PageNumber != nWhich - && SwFieldIds::RefPageGet != nWhich - // Page count fields to not use aExpand during formatting, - // therefore an invalidation of the text frame has to be triggered even if aNewExpand == aExpand: - && ( SwFieldIds::DocStat != nWhich || DS_PAGE != static_cast<const SwDocStatField*>(pField)->GetSubType() ) - && ( SwFieldIds::GetExp != nWhich || static_cast<const SwGetExpField*>(pField)->IsInBodyText() ) ) + if ( bSameExpandSimpleNotification ) { - if( m_pTextNode->CalcHiddenParaField() ) + if( bHiddenParaChanged ) { m_pTextNode->ModifyNotification( nullptr, nullptr ); } diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 389e2320c613..98ababf17492 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -4111,7 +4111,7 @@ void SwTextNode::CalcHiddenCharFlags() const // #i12836# enhanced pdf export bool SwTextNode::IsHidden() const { - if ( HasHiddenParaField() || HasHiddenCharAttribute( true ) ) + if ( IsHiddenByParaField() || HasHiddenCharAttribute( true ) ) return true; const SwSectionNode* pSectNd = FindSectionNode(); diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 2db0657c3fe1..32bb7841f9cd 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -19,6 +19,7 @@ #include <sal/config.h> +#include <DocumentSettingManager.hxx> #include <hintids.hxx> #include <editeng/xmlcnitm.hxx> #include <editeng/rsiditem.hxx> @@ -89,11 +90,12 @@ using namespace ::com::sun::star::i18n; -SwpHints::SwpHints() - : m_pHistory(nullptr) +SwpHints::SwpHints(const SwTextNode& rParent) + : m_rParent(rParent) + , m_pHistory(nullptr) , m_bInSplitNode(false) , m_bCalcHiddenParaField(false) - , m_bHasHiddenParaField(false) + , m_bHiddenByParaField(false) , m_bFootnote(false) , m_bDDEFields(false) { @@ -1144,19 +1146,21 @@ void SwTextNode::DestroyAttr( SwTextAttr* pAttr ) if( !pDoc->IsInDtor() ) { SwTextField *const pTextField(static_txtattr_cast<SwTextField*>(pAttr)); - const SwField* pField = pAttr->GetFormatField().GetField(); + SwFieldType* pFieldType = pAttr->GetFormatField().GetField()->GetTyp(); //JP 06-08-95: DDE-fields are an exception - assert(SwFieldIds::Dde == pField->GetTyp()->Which() || + assert(SwFieldIds::Dde == pFieldType->Which() || this == pTextField->GetpTextNode()); // certain fields must update the SwDoc's calculation flags - switch( pField->GetTyp()->Which() ) + + // Certain fields (like HiddenParaField) must trigger recalculation of visible flag + if (FieldCanHidePara(pFieldType->Which())) + SetCalcHiddenParaField(); + + switch( pFieldType->Which() ) { case SwFieldIds::HiddenPara: - // HiddenParaField must trigger recalculation of visible flag - SetCalcHiddenParaField(); - SAL_FALLTHROUGH; case SwFieldIds::DbSetNumber: case SwFieldIds::GetExp: case SwFieldIds::Database: @@ -1169,7 +1173,7 @@ void SwTextNode::DestroyAttr( SwTextAttr* pAttr ) break; case SwFieldIds::Dde: if (GetNodes().IsDocNodes() && pTextField->GetpTextNode()) - static_cast<SwDDEFieldType*>(pField->GetTyp())->DecRefCnt(); + static_cast<SwDDEFieldType*>(pFieldType)->DecRefCnt(); break; case SwFieldIds::Postit: { @@ -1460,8 +1464,8 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode ) case RES_TXTATR_FIELD: { - // trigger notification for HiddenParaFields - if( SwFieldIds::HiddenPara == pAttr->GetFormatField().GetField()->GetTyp()->Which() ) + // trigger notification for relevant fields, like HiddenParaFields + if (FieldCanHidePara(pAttr->GetFormatField().GetField()->GetTyp()->Which())) { bHiddenPara = true; } @@ -2581,38 +2585,32 @@ void SwpHints::CalcFlags() } } -bool SwpHints::CalcHiddenParaField() +bool SwpHints::CalcHiddenParaField() const { m_bCalcHiddenParaField = false; - bool bOldHasHiddenParaField = m_bHasHiddenParaField; - bool bNewHasHiddenParaField = false; + const bool bOldHiddenByParaField = m_bHiddenByParaField; + bool bNewHiddenByParaField = false; const size_t nSize = Count(); - const SwTextAttr *pTextHt; + const SwTextAttr* pTextHt; - for( size_t nPos = 0; nPos < nSize; ++nPos ) + for (size_t nPos = 0; nPos < nSize; ++nPos) { pTextHt = Get(nPos); const sal_uInt16 nWhich = pTextHt->Which(); - if( RES_TXTATR_FIELD == nWhich ) + if (RES_TXTATR_FIELD == nWhich) { const SwFormatField& rField = pTextHt->GetFormatField(); - if( SwFieldIds::HiddenPara == rField.GetField()->GetTyp()->Which() ) + if (m_rParent.FieldCanHidePara(rField.GetField()->GetTyp()->Which()) + && !(bNewHiddenByParaField = m_rParent.FieldHidesPara(*rField.GetField()))) { - if( !static_cast<const SwHiddenParaField*>(rField.GetField())->IsHidden() ) - { - SetHiddenParaField(false); - return bOldHasHiddenParaField != bNewHasHiddenParaField; - } - else - { - bNewHasHiddenParaField = true; - } + // If there's at least one field telling not to hide, so be it + break; } } } - SetHiddenParaField( bNewHasHiddenParaField ); - return bOldHasHiddenParaField != bNewHasHiddenParaField; + SetHiddenByParaField(bNewHiddenByParaField); + return bOldHiddenByParaField != bNewHiddenByParaField; } void SwpHints::NoteInHistory( SwTextAttr *pAttr, const bool bNew ) @@ -3280,7 +3278,8 @@ void SwpHints::DeleteAtPos( const size_t nPos ) if( pHint->Which() == RES_TXTATR_FIELD ) { SwTextField *const pTextField(static_txtattr_cast<SwTextField*>(pHint)); - const SwFieldType* pFieldTyp = pTextField->GetFormatField().GetField()->GetTyp(); + const SwField* pField = pTextField->GetFormatField().GetField(); + const SwFieldType* pFieldTyp = pField->GetTyp(); if( SwFieldIds::Dde == pFieldTyp->Which() ) { const SwTextNode* pNd = pTextField->GetpTextNode(); @@ -3288,8 +3287,8 @@ void SwpHints::DeleteAtPos( const size_t nPos ) const_cast<SwDDEFieldType*>(static_cast<const SwDDEFieldType*>(pFieldTyp))->DecRefCnt(); pTextField->ChgTextNode(nullptr); } - else if ( m_bHasHiddenParaField && - SwFieldIds::HiddenPara == pFieldTyp->Which() ) + else if (m_bHiddenByParaField + && m_rParent.FieldCanHidePara(pField->GetTyp()->Which())) { m_bCalcHiddenParaField = true; } diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 609afdfa7170..76435e704cd9 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -924,6 +924,26 @@ void SwViewShell::SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys rIDSA.set(DocumentSettingId::SUBTRACT_FLYS, bSubtractFlysAnchoredAtFlys); } +void SwViewShell::SetEmptyDbFieldHidesPara(bool bEmptyDbFieldHidesPara) +{ + IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess(); + if (rIDSA.get(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA) != bEmptyDbFieldHidesPara) + { + SwWait aWait(*GetDoc()->GetDocShell(), true); + rIDSA.set(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA, bEmptyDbFieldHidesPara); + StartAction(); + GetDoc()->getIDocumentState().SetModified(); + for (auto* pFieldType : *GetDoc()->getIDocumentFieldsAccess().GetFieldTypes()) + { + if (pFieldType->Which() == SwFieldIds::Database) + { + pFieldType->ModifyNotification(nullptr, nullptr); + } + } + EndAction(); + } +} + void SwViewShell::Reformat() { SwWait aWait( *GetDoc()->GetDocShell(), true ); |