| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| #include <stdlib.h> |
| #include <hintids.hxx> |
| #include <svl/intitem.hxx> |
| #include <svl/stritem.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/docfilt.hxx> |
| #include <editeng/protitem.hxx> |
| #include <sfx2/linkmgr.hxx> |
| #include <tools/urlobj.hxx> |
| #include <sfx2/sfxsids.hrc> |
| #include <sfx2/fcontnr.hxx> |
| #include <docary.hxx> |
| #include <fmtcntnt.hxx> |
| #include <fmtpdsc.hxx> |
| #include <errhdl.hxx> |
| #include <doc.hxx> |
| #include <IDocumentUndoRedo.hxx> |
| #include <node.hxx> |
| #include <pam.hxx> |
| #include <frmtool.hxx> |
| #include <editsh.hxx> |
| #include <hints.hxx> |
| #include <docsh.hxx> |
| #include <ndtxt.hxx> |
| #include <section.hxx> |
| #include <swserv.hxx> |
| #include <shellio.hxx> |
| #include <poolfmt.hxx> |
| #include <expfld.hxx> |
| #include <swbaslnk.hxx> |
| #include <mvsave.hxx> |
| #include <sectfrm.hxx> |
| #include <fmtftntx.hxx> |
| #include <ftnidx.hxx> |
| #include <doctxm.hxx> |
| #include <fmteiro.hxx> |
| #include <swerror.h> |
| #include <unosection.hxx> |
| #include <switerator.hxx> |
| #include <svl/smplhint.hxx> |
| |
| using namespace ::com::sun::star; |
| |
| |
| SV_IMPL_REF( SwServerObject ) |
| |
| //static const char __FAR_DATA sSectionFmtNm[] = "Section"; |
| #define sSectionFmtNm aEmptyStr |
| |
| class SwIntrnlSectRefLink : public SwBaseLink |
| { |
| SwSectionFmt& rSectFmt; |
| public: |
| SwIntrnlSectRefLink( SwSectionFmt& rFmt, sal_uInt16 nUpdateType, sal_uInt16 nFmt ) |
| : SwBaseLink( nUpdateType, nFmt ), |
| rSectFmt( rFmt ) |
| {} |
| |
| virtual void Closed(); |
| virtual void DataChanged( const String& rMimeType, |
| const uno::Any & rValue ); |
| |
| virtual const SwNode* GetAnchor() const; |
| virtual sal_Bool IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, xub_StrLen nStt = 0, |
| xub_StrLen nEnd = STRING_NOTFOUND ) const; |
| |
| // --> OD 2007-02-14 #b6521322# |
| inline SwSectionNode* GetSectNode() |
| { |
| const SwNode* pSectNd( const_cast<SwIntrnlSectRefLink*>(this)->GetAnchor() ); |
| return const_cast<SwSectionNode*>( dynamic_cast<const SwSectionNode*>( pSectNd ) ); |
| } |
| // <-- |
| }; |
| |
| |
| TYPEINIT1(SwSectionFmt,SwFrmFmt ); |
| TYPEINIT1(SwSection,SwClient ); |
| |
| typedef SwSection* SwSectionPtr; |
| |
| SV_IMPL_PTRARR( SwSections, SwSection*) |
| SV_IMPL_PTRARR(SwSectionFmts,SwSectionFmt*) |
| |
| |
| SwSectionData::SwSectionData(SectionType const eType, String const& rName) |
| : m_eType(eType) |
| , m_sSectionName(rName) |
| , m_bHiddenFlag(false) |
| , m_bProtectFlag(false) |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| , m_bEditInReadonlyFlag(false) |
| // <-- |
| , m_bHidden(false) |
| , m_bCondHiddenFlag(true) |
| , m_bConnectFlag(true) |
| { |
| } |
| |
| // this must have the same semantics as operator=() |
| SwSectionData::SwSectionData(SwSection const& rSection) |
| : m_eType(rSection.GetType()) |
| , m_sSectionName(rSection.GetSectionName()) |
| , m_sCondition(rSection.GetCondition()) |
| , m_sLinkFileName(rSection.GetLinkFileName()) |
| , m_sLinkFilePassword(rSection.GetLinkFilePassword()) |
| , m_Password(rSection.GetPassword()) |
| , m_bHiddenFlag(rSection.IsHiddenFlag()) |
| , m_bProtectFlag(rSection.IsProtect()) |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| , m_bEditInReadonlyFlag(rSection.IsEditInReadonly()) |
| // <-- |
| , m_bHidden(rSection.IsHidden()) |
| , m_bCondHiddenFlag(true) |
| , m_bConnectFlag(rSection.IsConnectFlag()) |
| { |
| } |
| |
| // this must have the same semantics as operator=() |
| SwSectionData::SwSectionData(SwSectionData const& rOther) |
| : m_eType(rOther.m_eType) |
| , m_sSectionName(rOther.m_sSectionName) |
| , m_sCondition(rOther.m_sCondition) |
| , m_sLinkFileName(rOther.m_sLinkFileName) |
| , m_sLinkFilePassword(rOther.m_sLinkFilePassword) |
| , m_Password(rOther.m_Password) |
| , m_bHiddenFlag(rOther.m_bHiddenFlag) |
| , m_bProtectFlag(rOther.m_bProtectFlag) |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| , m_bEditInReadonlyFlag(rOther.m_bEditInReadonlyFlag) |
| // <-- |
| , m_bHidden(rOther.m_bHidden) |
| , m_bCondHiddenFlag(true) |
| , m_bConnectFlag(rOther.m_bConnectFlag) |
| { |
| } |
| |
| // the semantics here are weird for reasons of backward compatibility |
| SwSectionData & SwSectionData::operator= (SwSectionData const& rOther) |
| { |
| m_eType = rOther.m_eType; |
| m_sSectionName = rOther.m_sSectionName; |
| m_sCondition = rOther.m_sCondition; |
| m_sLinkFileName = rOther.m_sLinkFileName; |
| m_sLinkFilePassword = rOther.m_sLinkFilePassword; |
| m_bConnectFlag = rOther.m_bConnectFlag; |
| m_Password = rOther.m_Password; |
| |
| m_bEditInReadonlyFlag = rOther.m_bEditInReadonlyFlag; |
| m_bProtectFlag = rOther.m_bProtectFlag; |
| |
| m_bHidden = rOther.m_bHidden; |
| // FIXME: old code did not assign m_bHiddenFlag ? |
| // FIXME: why should m_bCondHiddenFlag always default to true? |
| m_bCondHiddenFlag = true; |
| |
| return *this; |
| } |
| |
| // the semantics here are weird for reasons of backward compatibility |
| bool SwSectionData::operator==(SwSectionData const& rOther) const |
| { |
| return (m_eType == rOther.m_eType) |
| && (m_sSectionName == rOther.m_sSectionName) |
| && (m_sCondition == rOther.m_sCondition) |
| && (m_bHidden == rOther.m_bHidden) |
| && (m_bProtectFlag == rOther.m_bProtectFlag) |
| && (m_bEditInReadonlyFlag == rOther.m_bEditInReadonlyFlag) |
| && (m_sLinkFileName == rOther.m_sLinkFileName) |
| && (m_sLinkFilePassword == rOther.m_sLinkFilePassword) |
| && (m_Password == rOther.m_Password); |
| // FIXME: old code ignored m_bCondHiddenFlag m_bHiddenFlag m_bConnectFlag |
| } |
| |
| // SwSection =========================================================== |
| |
| SwSection::SwSection( |
| SectionType const eType, String const& rName, SwSectionFmt & rFormat) |
| : SwClient(& rFormat) |
| , m_Data(eType, rName) |
| { |
| SwSection *const pParentSect = GetParent(); |
| if( pParentSect ) |
| { |
| if( pParentSect->IsHiddenFlag() ) |
| { |
| SetHidden( true ); |
| } |
| |
| m_Data.SetProtectFlag( pParentSect->IsProtectFlag() ); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| m_Data.SetEditInReadonlyFlag( pParentSect->IsEditInReadonlyFlag() ); |
| // <-- |
| } |
| |
| if (!m_Data.IsProtectFlag()) |
| { |
| m_Data.SetProtectFlag( rFormat.GetProtect().IsCntntProtected() ); |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| if (!m_Data.IsEditInReadonlyFlag()) |
| { |
| m_Data.SetEditInReadonlyFlag( rFormat.GetEditInReadonly().GetValue() ); |
| } |
| // <-- |
| } |
| |
| |
| SwSection::~SwSection() |
| { |
| SwSectionFmt* pFmt = GetFmt(); |
| if( !pFmt ) |
| return; |
| |
| SwDoc* pDoc = pFmt->GetDoc(); |
| if( pDoc->IsInDtor() ) |
| { |
| // dann melden wir noch schnell unser Format um ans dflt FrameFmt, |
| // damit es keine Abhaengigkeiten gibt |
| if( pFmt->DerivedFrom() != pDoc->GetDfltFrmFmt() ) |
| pFmt->RegisterToFormat( *pDoc->GetDfltFrmFmt() ); |
| } |
| else |
| { |
| pFmt->Remove( this ); // austragen, |
| |
| if (CONTENT_SECTION != m_Data.GetType()) |
| { |
| pDoc->GetLinkManager().Remove( m_RefLink ); |
| } |
| |
| if (m_RefObj.Is()) |
| { |
| pDoc->GetLinkManager().RemoveServer( &m_RefObj ); |
| } |
| |
| // ist die Section der letzte Client im Format, kann dieses |
| // geloescht werden |
| SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt ); |
| pFmt->ModifyNotification( &aMsgHint, &aMsgHint ); |
| if( !pFmt->GetDepends() ) |
| { |
| // Bug: 28191 - nicht ins Undo aufnehmen, sollte schon vorher |
| // geschehen sein!! |
| ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); |
| pDoc->DelSectionFmt( pFmt ); // und loeschen |
| } |
| } |
| if (m_RefObj.Is()) |
| { |
| m_RefObj->Closed(); |
| } |
| } |
| |
| void SwSection::SetSectionData(SwSectionData const& rData) |
| { |
| bool const bOldHidden( m_Data.IsHidden() ); |
| m_Data = rData; |
| // now update format and reflink with new data |
| // SetLinkFileName(m_Data.GetLinkFileName()); // old code did not do this? |
| // next 2 may actually overwrite m_Data.m_b{Protect,EditInReadonly}Flag |
| // in Modify, which should result in same flag value as the old code! |
| SetProtect(m_Data.IsProtectFlag()); |
| SetEditInReadonly(m_Data.IsEditInReadonlyFlag()); |
| if (bOldHidden != m_Data.IsHidden()) // check if changed... |
| { |
| ImplSetHiddenFlag(m_Data.IsHidden(), m_Data.IsCondHidden()); |
| } |
| } |
| |
| bool SwSection::DataEquals(SwSectionData const& rCmp) const |
| { |
| // note that the old code compared the flags of the parameter with the |
| // format attributes of this; the following mess should do the same... |
| (void) GetLinkFileName(); // updates m_sLinkFileName |
| bool const bProtect(m_Data.IsProtectFlag()); |
| bool const bEditInReadonly(m_Data.IsEditInReadonlyFlag()); |
| const_cast<SwSection*>(this)->m_Data.SetProtectFlag(IsProtect()); |
| const_cast<SwSection*>(this)->m_Data |
| .SetEditInReadonlyFlag(IsEditInReadonly()); |
| bool const bResult( m_Data == rCmp ); |
| const_cast<SwSection*>(this)->m_Data.SetProtectFlag(bProtect); |
| const_cast<SwSection*>(this)->m_Data.SetEditInReadonlyFlag(bEditInReadonly); |
| return bResult; |
| } |
| |
| |
| void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, bool const bCondition) |
| { |
| SwSectionFmt* pFmt = GetFmt(); |
| ASSERT(pFmt, "ImplSetHiddenFlag: no format?"); |
| if( pFmt ) |
| { |
| const bool bHide = bTmpHidden && bCondition; |
| |
| if (bHide) // should be hidden |
| { |
| if (!m_Data.IsHiddenFlag()) // is not hidden |
| { |
| // wie sieht es mit dem Parent aus, ist der versteckt ? |
| // (eigentlich muesste das vom bHiddenFlag angezeigt werden!) |
| |
| // erstmal allen Childs sagen, das sie versteckt sind |
| SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN ); |
| pFmt->ModifyNotification( &aMsgItem, &aMsgItem ); |
| |
| // alle Frames loeschen |
| pFmt->DelFrms(); |
| } |
| } |
| else if (m_Data.IsHiddenFlag()) // show Nodes again |
| { |
| // alle Frames sichtbar machen ( Childs Sections werden vom |
| // MakeFrms beruecksichtigt). Aber nur wenn die ParentSection |
| // nichts dagegen hat ! |
| SwSection* pParentSect = pFmt->GetParentSection(); |
| if( !pParentSect || !pParentSect->IsHiddenFlag() ) |
| { |
| // erstmal allen Childs sagen, das der Parent nicht mehr |
| // versteckt ist |
| SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN ); |
| pFmt->ModifyNotification( &aMsgItem, &aMsgItem ); |
| |
| pFmt->MakeFrms(); |
| } |
| } |
| } |
| } |
| |
| sal_Bool SwSection::CalcHiddenFlag() const |
| { |
| const SwSection* pSect = this; |
| do { |
| if( pSect->IsHidden() && pSect->IsCondHidden() ) |
| return sal_True; |
| } while( 0 != ( pSect = pSect->GetParent()) ); |
| |
| return sal_False; |
| } |
| |
| bool SwSection::IsProtect() const |
| { |
| SwSectionFmt *const pFmt( GetFmt() ); |
| ASSERT(pFmt, "SwSection::IsProtect: no format?"); |
| return (pFmt) |
| ? pFmt->GetProtect().IsCntntProtected() |
| : IsProtectFlag(); |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| bool SwSection::IsEditInReadonly() const |
| { |
| SwSectionFmt *const pFmt( GetFmt() ); |
| ASSERT(pFmt, "SwSection::IsEditInReadonly: no format?"); |
| return (pFmt) |
| ? pFmt->GetEditInReadonly().GetValue() |
| : IsEditInReadonlyFlag(); |
| } |
| // <-- |
| |
| void SwSection::SetHidden(bool const bFlag) |
| { |
| if (!m_Data.IsHidden() == !bFlag) |
| return; |
| |
| m_Data.SetHidden(bFlag); |
| ImplSetHiddenFlag(bFlag, m_Data.IsCondHidden()); |
| } |
| |
| |
| void SwSection::SetProtect(bool const bFlag) |
| { |
| SwSectionFmt *const pFormat( GetFmt() ); |
| ASSERT(pFormat, "SwSection::SetProtect: no format?"); |
| if (pFormat) |
| { |
| SvxProtectItem aItem( RES_PROTECT ); |
| aItem.SetCntntProtect( (sal_Bool)bFlag ); |
| pFormat->SetFmtAttr( aItem ); |
| // note: this will call m_Data.SetProtectFlag via Modify! |
| } |
| else |
| { |
| m_Data.SetProtectFlag(bFlag); |
| } |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| void SwSection::SetEditInReadonly(bool const bFlag) |
| { |
| SwSectionFmt *const pFormat( GetFmt() ); |
| ASSERT(pFormat, "SwSection::SetEditInReadonly: no format?"); |
| if (pFormat) |
| { |
| SwFmtEditInReadonly aItem; |
| aItem.SetValue( (sal_Bool)bFlag ); |
| pFormat->SetFmtAttr( aItem ); |
| // note: this will call m_Data.SetEditInReadonlyFlag via Modify! |
| } |
| else |
| { |
| m_Data.SetEditInReadonlyFlag(bFlag); |
| } |
| } |
| // <-- |
| |
| void SwSection::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) |
| { |
| bool bRemake = false; |
| bool bUpdateFtn = false; |
| switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ) |
| { |
| case RES_ATTRSET_CHG: |
| { |
| SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet(); |
| SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet(); |
| const SfxPoolItem* pItem; |
| |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_PROTECT, sal_False, &pItem ) ) |
| { |
| m_Data.SetProtectFlag( static_cast<SvxProtectItem const*>(pItem) |
| ->IsCntntProtected() ); |
| pNewSet->ClearItem( RES_PROTECT ); |
| pOldSet->ClearItem( RES_PROTECT ); |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_EDIT_IN_READONLY, sal_False, &pItem ) ) |
| { |
| m_Data.SetEditInReadonlyFlag( |
| static_cast<SwFmtEditInReadonly const*>(pItem)->GetValue()); |
| pNewSet->ClearItem( RES_EDIT_IN_READONLY ); |
| pOldSet->ClearItem( RES_EDIT_IN_READONLY ); |
| } |
| // <-- |
| |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_FTN_AT_TXTEND, sal_False, &pItem ) || |
| SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_END_AT_TXTEND, sal_False, &pItem )) |
| { |
| bUpdateFtn = true; |
| } |
| |
| if( !pNewSet->Count() ) |
| return; |
| } |
| break; |
| |
| case RES_PROTECT: |
| if( pNew ) |
| { |
| bool bNewFlag = |
| static_cast<const SvxProtectItem*>(pNew)->IsCntntProtected(); |
| if( !bNewFlag ) |
| { |
| // Abschalten: teste ob nicht vielleich ueber die Parents |
| // doch ein Schutzt besteht! |
| const SwSection* pSect = this; |
| do { |
| if( pSect->IsProtect() ) |
| { |
| bNewFlag = true; |
| break; |
| } |
| pSect = pSect->GetParent(); |
| } while (pSect); |
| } |
| |
| m_Data.SetProtectFlag( bNewFlag ); |
| } |
| return; |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| case RES_EDIT_IN_READONLY: |
| if( pNew ) |
| { |
| const bool bNewFlag = |
| static_cast<const SwFmtEditInReadonly*>(pNew)->GetValue(); |
| m_Data.SetEditInReadonlyFlag( bNewFlag ); |
| } |
| return; |
| // <-- |
| |
| case RES_SECTION_HIDDEN: |
| m_Data.SetHiddenFlag(true); |
| return; |
| |
| case RES_SECTION_NOT_HIDDEN: |
| case RES_SECTION_RESETHIDDENFLAG: |
| m_Data.SetHiddenFlag( m_Data.IsHidden() && m_Data.IsCondHidden() ); |
| return; |
| |
| case RES_COL: |
| /* wird ggf. vom Layout erledigt */ |
| break; |
| |
| case RES_FTN_AT_TXTEND: |
| if( pNew && pOld ) |
| { |
| bUpdateFtn = true; |
| } |
| break; |
| |
| case RES_END_AT_TXTEND: |
| if( pNew && pOld ) |
| { |
| bUpdateFtn = true; |
| } |
| break; |
| |
| default: |
| CheckRegistration( pOld, pNew ); |
| break; |
| } |
| |
| if( bRemake ) |
| { |
| GetFmt()->DelFrms(); |
| GetFmt()->MakeFrms(); |
| } |
| |
| if( bUpdateFtn ) |
| { |
| SwSectionNode* pSectNd = GetFmt()->GetSectionNode( sal_False ); |
| if( pSectNd ) |
| pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd )); |
| } |
| } |
| |
| void SwSection::SetRefObject( SwServerObject* pObj ) |
| { |
| m_RefObj = pObj; |
| } |
| |
| |
| void SwSection::SetCondHidden(bool const bFlag) |
| { |
| if (!m_Data.IsCondHidden() == !bFlag) |
| return; |
| |
| m_Data.SetCondHidden(bFlag); |
| ImplSetHiddenFlag(m_Data.IsHidden(), bFlag); |
| } |
| |
| |
| // setze/erfrage den gelinkten FileNamen |
| const String& SwSection::GetLinkFileName() const |
| { |
| if (m_RefLink.Is()) |
| { |
| String sTmp; |
| switch (m_Data.GetType()) |
| { |
| case DDE_LINK_SECTION: |
| sTmp = m_RefLink->GetLinkSourceName(); |
| break; |
| |
| case FILE_LINK_SECTION: |
| { |
| String sRange, sFilter; |
| if (m_RefLink->GetLinkManager() && |
| m_RefLink->GetLinkManager()->GetDisplayNames( |
| m_RefLink, 0, &sTmp, &sRange, &sFilter )) |
| { |
| ( sTmp += sfx2::cTokenSeperator ) += sFilter; |
| ( sTmp += sfx2::cTokenSeperator ) += sRange; |
| } |
| else if( GetFmt() && !GetFmt()->GetSectionNode() ) |
| { |
| // ist die Section im UndoNodesArray, dann steht |
| // der Link nicht im LinkManager, kann also auch nicht |
| // erfragt werden. Dann returne den akt. Namen |
| return m_Data.GetLinkFileName(); |
| } |
| } |
| break; |
| default: break; |
| } |
| const_cast<SwSection*>(this)->m_Data.SetLinkFileName(sTmp); |
| } |
| return m_Data.GetLinkFileName(); |
| } |
| |
| |
| void SwSection::SetLinkFileName(const String& rNew, String const*const pPassWd) |
| { |
| if (m_RefLink.Is()) |
| { |
| m_RefLink->SetLinkSourceName( rNew ); |
| } |
| m_Data.SetLinkFileName(rNew); |
| if( pPassWd ) |
| { |
| SetLinkFilePassword( *pPassWd ); |
| } |
| } |
| |
| // falls es ein gelinkter Bereich war, dann muessen alle |
| // Child-Verknuepfungen sichtbar bemacht werden. |
| void SwSection::MakeChildLinksVisible( const SwSectionNode& rSectNd ) |
| { |
| const SwNode* pNd; |
| const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks(); |
| for( sal_uInt16 n = rLnks.Count(); n; ) |
| { |
| ::sfx2::SvBaseLink* pBLnk = &(*rLnks[ --n ]); |
| if( pBLnk && !pBLnk->IsVisible() && |
| pBLnk->ISA( SwBaseLink ) && |
| 0 != ( pNd = ((SwBaseLink*)pBLnk)->GetAnchor() ) ) |
| { |
| pNd = pNd->StartOfSectionNode(); // falls SectionNode ist! |
| const SwSectionNode* pParent; |
| while( 0 != ( pParent = pNd->FindSectionNode() ) && |
| ( CONTENT_SECTION == pParent->GetSection().GetType() |
| || pNd == &rSectNd )) |
| pNd = pParent->StartOfSectionNode(); |
| |
| // steht nur noch in einer normalen Section, also |
| // wieder anzeigen |
| if( !pParent ) |
| pBLnk->SetVisible( sal_True ); |
| } |
| } |
| } |
| |
| const SwTOXBase* SwSection::GetTOXBase() const |
| { |
| const SwTOXBase* pRet = 0; |
| if( TOX_CONTENT_SECTION == GetType() ) |
| pRet = PTR_CAST( SwTOXBaseSection, this ); |
| return pRet; |
| } |
| |
| // SwSectionFmt ======================================================== |
| |
| SwSectionFmt::SwSectionFmt( SwSectionFmt* pDrvdFrm, SwDoc *pDoc ) |
| : SwFrmFmt( pDoc->GetAttrPool(), sSectionFmtNm, pDrvdFrm ) |
| { |
| LockModify(); |
| SetFmtAttr( *GetDfltAttr( RES_COL ) ); |
| UnlockModify(); |
| } |
| |
| SwSectionFmt::~SwSectionFmt() |
| { |
| if( !GetDoc()->IsInDtor() ) |
| { |
| SwSectionNode* pSectNd; |
| const SwNodeIndex* pIdx = GetCntnt( sal_False ).GetCntntIdx(); |
| if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && |
| 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) |
| { |
| SwSection& rSect = pSectNd->GetSection(); |
| // falls es ein gelinkter Bereich war, dann muessen alle |
| // Child-Verknuepfungen sichtbar bemacht werden. |
| if( rSect.IsConnected() ) |
| rSect.MakeChildLinksVisible( *pSectNd ); |
| |
| // vorm loeschen der Nodes pruefe, ob wir uns nicht |
| // noch anzeigen muessen! |
| if( rSect.IsHiddenFlag() ) |
| { |
| SwSectionPtr pParentSect = rSect.GetParent(); |
| if( !pParentSect || !pParentSect->IsHiddenFlag() ) |
| { |
| // Nodes wieder anzeigen |
| rSect.SetHidden(false); |
| } |
| } |
| // mba: test iteration; objects are removed while iterating |
| // --> OD #i117863# |
| // use hint which allows to specify, if the content shall be saved or not |
| CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( sal_True ) ); |
| // <-- |
| |
| // hebe die Section doch mal auf |
| SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() ); |
| GetDoc()->GetNodes().SectionUp( &aRg ); |
| } |
| LockModify(); |
| ResetFmtAttr( RES_CNTNT ); |
| UnlockModify(); |
| } |
| } |
| |
| |
| SwSection * SwSectionFmt::GetSection() const |
| { |
| return SwIterator<SwSection,SwSectionFmt>::FirstElement( *this ); |
| } |
| |
| extern void lcl_DeleteFtn( SwSectionNode *pNd, sal_uLong nStt, sal_uLong nEnd ); |
| |
| //Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt). |
| void SwSectionFmt::DelFrms() |
| { |
| SwSectionNode* pSectNd; |
| const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx(); |
| if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && |
| 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) |
| { |
| // #147431# : First delete the <SwSectionFrm> of the <SwSectionFmt> instance |
| // mba: test iteration as objects are removed in iteration |
| // --> OD #i117863# |
| // use hint which allows to specify, if the content shall be saved or not |
| CallSwClientNotify( SwSectionFrmMoveAndDeleteHint( sal_False ) ); |
| // <-- |
| |
| // Then delete frames of the nested <SwSectionFmt> instances |
| SwIterator<SwSectionFmt,SwSectionFmt> aIter( *this ); |
| SwSectionFmt *pLast = aIter.First(); |
| while ( pLast ) |
| { |
| pLast->DelFrms(); |
| pLast = aIter.Next(); |
| } |
| |
| sal_uLong nEnde = pSectNd->EndOfSectionIndex(); |
| sal_uLong nStart = pSectNd->GetIndex()+1; |
| lcl_DeleteFtn( pSectNd, nStart, nEnde ); |
| } |
| if( pIdx ) |
| { |
| //JP 22.09.98: |
| //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im |
| //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum |
| //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden |
| //muesten. #56977# #55001# #56135# |
| SwNodeIndex aNextNd( *pIdx ); |
| SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, sal_True, sal_False ); |
| if( pCNd ) |
| { |
| const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC ); |
| pCNd->ModifyNotification( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem ); |
| } |
| } |
| } |
| |
| |
| //Erzeugt die Ansichten |
| void SwSectionFmt::MakeFrms() |
| { |
| SwSectionNode* pSectNd; |
| const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx(); |
| |
| if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && |
| 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) |
| { |
| SwNodeIndex aIdx( *pIdx ); |
| pSectNd->MakeFrms( &aIdx ); |
| } |
| } |
| |
| void SwSectionFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew ) |
| { |
| sal_Bool bClients = sal_False; |
| sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; |
| switch( nWhich ) |
| { |
| case RES_ATTRSET_CHG: |
| if( GetDepends() ) |
| { |
| SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet(); |
| SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet(); |
| const SfxPoolItem *pItem; |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_PROTECT, sal_False, &pItem )) |
| { |
| ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem ); |
| pNewSet->ClearItem( RES_PROTECT ); |
| pOldSet->ClearItem( RES_PROTECT ); |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_EDIT_IN_READONLY, sal_False, &pItem ) ) |
| { |
| ModifyBroadcast( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem ); |
| pNewSet->ClearItem( RES_EDIT_IN_READONLY ); |
| pOldSet->ClearItem( RES_EDIT_IN_READONLY ); |
| } |
| // <-- |
| |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_FTN_AT_TXTEND, sal_False, &pItem )) |
| { |
| ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_FTN_AT_TXTEND ), (SfxPoolItem*)pItem ); |
| pNewSet->ClearItem( RES_FTN_AT_TXTEND ); |
| pOldSet->ClearItem( RES_FTN_AT_TXTEND ); |
| } |
| if( SFX_ITEM_SET == pNewSet->GetItemState( |
| RES_END_AT_TXTEND, sal_False, &pItem )) |
| { |
| ModifyBroadcast( (SfxPoolItem*)&pOldSet->Get( RES_END_AT_TXTEND ), (SfxPoolItem*)pItem ); |
| pNewSet->ClearItem( RES_END_AT_TXTEND ); |
| pOldSet->ClearItem( RES_END_AT_TXTEND ); |
| } |
| if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() ) |
| return; |
| } |
| break; |
| |
| case RES_SECTION_RESETHIDDENFLAG: |
| case RES_FTN_AT_TXTEND: |
| case RES_END_AT_TXTEND : bClients = sal_True; |
| // no break !! |
| case RES_SECTION_HIDDEN: |
| case RES_SECTION_NOT_HIDDEN: |
| { |
| SwSection* pSect = GetSection(); |
| if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ? |
| !pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) ) |
| { |
| ModifyBroadcast( pOld, pNew ); |
| } |
| } |
| return ; |
| |
| |
| case RES_PROTECT: |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| case RES_EDIT_IN_READONLY: |
| // <-- |
| // diese Messages bis zum Ende des Baums durchreichen ! |
| if( GetDepends() ) |
| { |
| ModifyBroadcast( pOld, pNew ); |
| } |
| return; // das wars |
| |
| case RES_OBJECTDYING: |
| if( !GetDoc()->IsInDtor() && |
| ((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() ) |
| { |
| // mein Parent wird vernichtet, dann an den Parent vom Parent |
| // umhaengen und wieder aktualisieren |
| SwFrmFmt::Modify( pOld, pNew ); // erst umhaengen !!! |
| UpdateParent(); |
| return; |
| } |
| break; |
| |
| case RES_FMT_CHG: |
| if( !GetDoc()->IsInDtor() && |
| ((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() && |
| ((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) ) |
| { |
| // mein Parent wird veraendert, muss mich aktualisieren |
| SwFrmFmt::Modify( pOld, pNew ); // erst umhaengen !!! |
| UpdateParent(); |
| return; |
| } |
| break; |
| } |
| SwFrmFmt::Modify( pOld, pNew ); |
| |
| if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which())) |
| { // invalidate cached uno object |
| SetXTextSection(uno::Reference<text::XTextSection>(0)); |
| } |
| } |
| |
| // erfrage vom Format Informationen |
| sal_Bool SwSectionFmt::GetInfo( SfxPoolItem& rInfo ) const |
| { |
| switch( rInfo.Which() ) |
| { |
| case RES_FINDNEARESTNODE: |
| if( ((SwFmtPageDesc&)GetFmtAttr( RES_PAGEDESC )).GetPageDesc() ) |
| { |
| const SwSectionNode* pNd = GetSectionNode(); |
| if( pNd ) |
| ((SwFindNearestNode&)rInfo).CheckNode( *pNd ); |
| } |
| return sal_True; |
| |
| case RES_CONTENT_VISIBLE: |
| { |
| SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*this); |
| // if the current section has no own frame search for the children |
| if(!pFrm) |
| { |
| SwIterator<SwSectionFmt,SwSectionFmt> aFormatIter(*this); |
| SwSectionFmt* pChild = aFormatIter.First(); |
| while(pChild && !pFrm) |
| { |
| pFrm = SwIterator<SwFrm,SwFmt>::FirstElement(*pChild); |
| pChild = aFormatIter.Next(); |
| } |
| } |
| ((SwPtrMsgPoolItem&)rInfo).pObject = pFrm; |
| } |
| return sal_False; |
| } |
| return SwModify::GetInfo( rInfo ); |
| } |
| |
| extern "C" { |
| |
| int |
| #if defined( WNT ) |
| __cdecl |
| #endif |
| #if defined( ICC ) |
| _Optlink |
| #endif |
| lcl_SectionCmpPos( const void *pFirst, const void *pSecond) |
| { |
| const SwSectionFmt* pFSectFmt = (*(SwSectionPtr*)pFirst)->GetFmt(); |
| const SwSectionFmt* pSSectFmt = (*(SwSectionPtr*)pSecond)->GetFmt(); |
| ASSERT( pFSectFmt && pSSectFmt && |
| pFSectFmt->GetCntnt(sal_False).GetCntntIdx() && |
| pSSectFmt->GetCntnt(sal_False).GetCntntIdx(), |
| "ungueltige Sections" ); |
| return (int)((long)pFSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex()) - |
| pSSectFmt->GetCntnt(sal_False).GetCntntIdx()->GetIndex(); |
| } |
| |
| int |
| #if defined( WNT ) |
| __cdecl |
| #endif |
| #if defined( ICC ) |
| _Optlink |
| #endif |
| lcl_SectionCmpNm( const void *pFirst, const void *pSecond) |
| { |
| const SwSectionPtr pFSect = *(SwSectionPtr*)pFirst; |
| const SwSectionPtr pSSect = *(SwSectionPtr*)pSecond; |
| ASSERT( pFSect && pSSect, "ungueltige Sections" ); |
| StringCompare const eCmp = |
| pFSect->GetSectionName().CompareTo( pSSect->GetSectionName() ); |
| return eCmp == COMPARE_EQUAL ? 0 |
| : eCmp == COMPARE_LESS ? 1 : -1; |
| } |
| } |
| |
| // alle Sections, die von dieser abgeleitet sind |
| sal_uInt16 SwSectionFmt::GetChildSections( SwSections& rArr, |
| SectionSort eSort, |
| sal_Bool bAllSections ) const |
| { |
| rArr.Remove( 0, rArr.Count() ); |
| |
| if( GetDepends() ) |
| { |
| SwIterator<SwSectionFmt,SwSectionFmt> aIter(*this); |
| const SwNodeIndex* pIdx; |
| for( SwSectionFmt* pLast = aIter.First(); pLast; pLast = aIter.Next() ) |
| if( bAllSections || |
| ( 0 != ( pIdx = pLast->GetCntnt(sal_False). |
| GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() )) |
| { |
| const SwSection* Dummy = pLast->GetSection(); |
| rArr.C40_INSERT( SwSection, |
| Dummy, |
| rArr.Count() ); |
| } |
| |
| // noch eine Sortierung erwuenscht ? |
| if( 1 < rArr.Count() ) |
| switch( eSort ) |
| { |
| case SORTSECT_NAME: |
| qsort( (void*)rArr.GetData(), |
| rArr.Count(), |
| sizeof( SwSectionPtr ), |
| lcl_SectionCmpNm ); |
| break; |
| |
| case SORTSECT_POS: |
| qsort( (void*)rArr.GetData(), |
| rArr.Count(), |
| sizeof( SwSectionPtr ), |
| lcl_SectionCmpPos ); |
| break; |
| case SORTSECT_NOT: break; |
| } |
| } |
| return rArr.Count(); |
| } |
| |
| // erfrage, ob sich die Section im Nodes-Array oder UndoNodes-Array |
| // befindet. |
| sal_Bool SwSectionFmt::IsInNodesArr() const |
| { |
| const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx(); |
| return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes(); |
| } |
| |
| |
| void SwSectionFmt::UpdateParent() // Parent wurde veraendert |
| { |
| if( !GetDepends() ) |
| return; |
| |
| SwSectionPtr pSection = 0; |
| const SvxProtectItem* pProtect(0); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| const SwFmtEditInReadonly* pEditInReadonly = 0; |
| // <-- |
| bool bIsHidden = false; |
| |
| SwClientIter aIter( *this ); // TODO |
| ::SwClient * pLast = aIter.GoStart(); |
| if( pLast ) // konnte zum Anfang gesprungen werden ?? |
| do { |
| if( pLast->IsA( TYPE(SwSectionFmt) ) ) |
| { |
| if( !pSection ) |
| { |
| pSection = GetSection(); |
| if( GetRegisteredIn() ) |
| { |
| const SwSectionPtr pPS = GetParentSection(); |
| pProtect = &pPS->GetFmt()->GetProtect(); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly(); |
| // <-- |
| bIsHidden = pPS->IsHiddenFlag(); |
| } |
| else |
| { |
| pProtect = &GetProtect(); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| pEditInReadonly = &GetEditInReadonly(); |
| // <-- |
| bIsHidden = pSection->IsHidden(); |
| } |
| } |
| if (!pProtect->IsCntntProtected() != |
| !pSection->IsProtectFlag()) |
| { |
| pLast->ModifyNotification( (SfxPoolItem*)pProtect, |
| (SfxPoolItem*)pProtect ); |
| } |
| |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| if (!pEditInReadonly->GetValue() != |
| !pSection->IsEditInReadonlyFlag()) |
| { |
| pLast->ModifyNotification( (SfxPoolItem*)pEditInReadonly, |
| (SfxPoolItem*)pEditInReadonly ); |
| } |
| // <-- |
| |
| if( bIsHidden == pSection->IsHiddenFlag() ) |
| { |
| SwMsgPoolItem aMsgItem( static_cast<sal_uInt16>(bIsHidden |
| ? RES_SECTION_HIDDEN |
| : RES_SECTION_NOT_HIDDEN ) ); |
| pLast->ModifyNotification( &aMsgItem, &aMsgItem ); |
| } |
| } |
| else if( !pSection && |
| pLast->IsA( TYPE(SwSection) ) ) |
| { |
| pSection = (SwSectionPtr)pLast; |
| if( GetRegisteredIn() ) |
| { |
| const SwSectionPtr pPS = GetParentSection(); |
| pProtect = &pPS->GetFmt()->GetProtect(); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| pEditInReadonly = &pPS->GetFmt()->GetEditInReadonly(); |
| // <-- |
| bIsHidden = pPS->IsHiddenFlag(); |
| } |
| else |
| { |
| pProtect = &GetProtect(); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| pEditInReadonly = &GetEditInReadonly(); |
| // <-- |
| bIsHidden = pSection->IsHidden(); |
| } |
| } |
| } while( 0 != ( pLast = ++aIter )); |
| } |
| |
| |
| SwSectionNode* SwSectionFmt::GetSectionNode(bool const bAlways) |
| { |
| const SwNodeIndex* pIdx = GetCntnt(sal_False).GetCntntIdx(); |
| if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() )) |
| return pIdx->GetNode().GetSectionNode(); |
| return 0; |
| } |
| |
| // ist die Section eine gueltige fuers GlobalDocument? |
| const SwSection* SwSectionFmt::GetGlobalDocSection() const |
| { |
| const SwSectionNode* pNd = GetSectionNode(); |
| if( pNd && |
| ( FILE_LINK_SECTION == pNd->GetSection().GetType() || |
| TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) && |
| pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() && |
| !pNd->StartOfSectionNode()->IsSectionNode() && |
| !pNd->StartOfSectionNode()->FindSectionNode() ) |
| return &pNd->GetSection(); |
| return 0; |
| } |
| |
| // sw::Metadatable |
| ::sfx2::IXmlIdRegistry& SwSectionFmt::GetRegistry() |
| { |
| return GetDoc()->GetXmlIdRegistry(); |
| } |
| |
| bool SwSectionFmt::IsInClipboard() const |
| { |
| return GetDoc()->IsClipBoard(); |
| } |
| |
| bool SwSectionFmt::IsInUndo() const |
| { |
| return !IsInNodesArr(); |
| } |
| |
| bool SwSectionFmt::IsInContent() const |
| { |
| SwNodeIndex const*const pIdx = GetCntnt(sal_False).GetCntntIdx(); |
| OSL_ENSURE(pIdx, "SwSectionFmt::IsInContent: no index?"); |
| return (pIdx) ? !GetDoc()->IsInHeaderFooter(*pIdx) : true; |
| } |
| |
| // n.b.: if the section format represents an index, then there is both a |
| // SwXDocumentIndex and a SwXTextSection instance for this single core object. |
| // these two can both implement XMetadatable and forward to the same core |
| // section format. but here only one UNO object can be returned, |
| // so always return the text section. |
| uno::Reference< rdf::XMetadatable > |
| SwSectionFmt::MakeUnoObject() |
| { |
| uno::Reference<rdf::XMetadatable> xMeta; |
| SwSection *const pSection( GetSection() ); |
| if (pSection) |
| { |
| xMeta.set( SwXTextSection::CreateXTextSection(this, |
| TOX_HEADER_SECTION == pSection->GetType()), |
| uno::UNO_QUERY ); |
| } |
| return xMeta; |
| } |
| |
| |
| // --> OD 2007-02-14 #b6521322# |
| // Method to break section links inside a linked section |
| void lcl_BreakSectionLinksInSect( const SwSectionNode& rSectNd ) |
| { |
| if ( !rSectNd.GetDoc() ) |
| { |
| ASSERT( false, |
| "method <lcl_RemoveSectionLinksInSect(..)> - no Doc at SectionNode" ); |
| return; |
| } |
| |
| if ( !rSectNd.GetSection().IsConnected() ) |
| { |
| ASSERT( false, |
| "method <lcl_RemoveSectionLinksInSect(..)> - no Link at Section of SectionNode" ); |
| return; |
| } |
| const ::sfx2::SvBaseLink* pOwnLink( &(rSectNd.GetSection().GetBaseLink() ) ); |
| const ::sfx2::SvBaseLinks& rLnks = rSectNd.GetDoc()->GetLinkManager().GetLinks(); |
| for ( sal_uInt16 n = rLnks.Count(); n > 0; ) |
| { |
| SwIntrnlSectRefLink* pSectLnk = dynamic_cast<SwIntrnlSectRefLink*>(&(*rLnks[ --n ])); |
| if ( pSectLnk && pSectLnk != pOwnLink && |
| pSectLnk->IsInRange( rSectNd.GetIndex(), rSectNd.EndOfSectionIndex() ) ) |
| { |
| // break the link of the corresponding section. |
| // the link is also removed from the link manager |
| pSectLnk->GetSectNode()->GetSection().BreakLink(); |
| |
| // for robustness, because link is removed from the link manager |
| if ( n > rLnks.Count() ) |
| { |
| n = rLnks.Count(); |
| } |
| } |
| } |
| } |
| // <-- |
| |
| void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd ) |
| { |
| SwDoc* pDoc = rSectNd.GetDoc(); |
| SwDocShell* pDShell = pDoc->GetDocShell(); |
| if( !pDShell || !pDShell->GetMedium() ) |
| return ; |
| |
| String sName( pDShell->GetMedium()->GetName() ); |
| SwBaseLink* pBLink; |
| String sMimeType( SotExchange::GetFormatMimeType( FORMAT_FILE )); |
| uno::Any aValue; |
| aValue <<= ::rtl::OUString( sName ); // beliebiger Name |
| |
| const ::sfx2::SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks(); |
| for( sal_uInt16 n = rLnks.Count(); n; ) |
| { |
| ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]); |
| if( pLnk && pLnk != &rUpdLnk && |
| OBJECT_CLIENT_FILE == pLnk->GetObjType() && |
| pLnk->ISA( SwBaseLink ) && |
| ( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(), |
| rSectNd.EndOfSectionIndex() ) ) |
| { |
| // liegt in dem Bereich: also updaten. Aber nur wenns nicht |
| // im gleichen File liegt |
| String sFName; |
| pDoc->GetLinkManager().GetDisplayNames( pBLink, 0, &sFName, 0, 0 ); |
| if( sFName != sName ) |
| { |
| pBLink->DataChanged( sMimeType, aValue ); |
| |
| // ggfs. neu den Link-Pointer wieder suchen, damit nicht einer |
| // ausgelassen oder doppelt gerufen wird. |
| if( n >= rLnks.Count() && 0 != ( n = rLnks.Count() )) |
| --n; |
| |
| if( n && pLnk != &(*rLnks[ n ]) ) |
| { |
| // suchen - kann nur davor liegen!! |
| while( n ) |
| if( pLnk == &(*rLnks[ --n ] ) ) |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| // sucht sich die richtige DocShell raus oder erzeugt eine neue: |
| // Der Return-Wert gibt an, was mit der Shell zu geschehen hat: |
| // 0 - Fehler, konnte DocShell nicht finden |
| // 1 - DocShell ist ein existieren Document |
| // 2 - DocShell wurde neu angelegt, muss also wieder geschlossen werden ( will be assigned to xLockRef additionaly ) |
| |
| int lcl_FindDocShell( SfxObjectShellRef& xDocSh, |
| SfxObjectShellLock& xLockRef, |
| const String& rFileName, |
| const String& rPasswd, |
| String& rFilter, |
| sal_Int16 nVersion, |
| SwDocShell* pDestSh ) |
| { |
| if( !rFileName.Len() ) |
| return 0; |
| |
| // 1. existiert die Datei schon in der Liste aller Dokumente? |
| INetURLObject aTmpObj( rFileName ); |
| aTmpObj.SetMark( aEmptyStr ); |
| |
| // erstmal nur ueber die DocumentShells laufen und die mit dem |
| // Namen heraussuchen: |
| TypeId aType( TYPE(SwDocShell) ); |
| |
| SfxObjectShell* pShell = pDestSh; |
| sal_Bool bFirst = 0 != pShell; |
| |
| if( !bFirst ) |
| // keine DocShell uebergeben, also beginne mit der ersten aus der |
| // DocShell Liste |
| pShell = SfxObjectShell::GetFirst( &aType ); |
| |
| while( pShell ) |
| { |
| // die wollen wir haben |
| SfxMedium* pMed = pShell->GetMedium(); |
| if( pMed && pMed->GetURLObject() == aTmpObj ) |
| { |
| const SfxPoolItem* pItem; |
| if( ( SFX_ITEM_SET == pMed->GetItemSet()->GetItemState( |
| SID_VERSION, sal_False, &pItem ) ) |
| ? (nVersion == ((SfxInt16Item*)pItem)->GetValue()) |
| : !nVersion ) |
| { |
| // gefunden also returnen |
| xDocSh = pShell; |
| return 1; |
| } |
| } |
| |
| if( bFirst ) |
| { |
| bFirst = sal_False; |
| pShell = SfxObjectShell::GetFirst( &aType ); |
| } |
| else |
| pShell = SfxObjectShell::GetNext( *pShell, &aType ); |
| } |
| |
| // 2. selbst die Date oeffnen |
| SfxMedium* pMed = new SfxMedium( aTmpObj.GetMainURL( |
| INetURLObject::NO_DECODE ), STREAM_READ, sal_True ); |
| if( INET_PROT_FILE == aTmpObj.GetProtocol() ) |
| pMed->DownLoad(); // nur mal das Medium anfassen (DownLoaden) |
| |
| const SfxFilter* pSfxFlt = 0; |
| if( !pMed->GetError() ) |
| { |
| String sFactory(String::CreateFromAscii(SwDocShell::Factory().GetShortName())); |
| SfxFilterMatcher aMatcher( sFactory ); |
| |
| // kein Filter, dann suche ihn. Ansonsten teste, ob der angegebene |
| // ein gueltiger ist |
| if( rFilter.Len() ) |
| { |
| pSfxFlt = aMatcher.GetFilter4FilterName( rFilter ); |
| } |
| |
| if( nVersion ) |
| pMed->GetItemSet()->Put( SfxInt16Item( SID_VERSION, nVersion )); |
| |
| if( rPasswd.Len() ) |
| pMed->GetItemSet()->Put( SfxStringItem( SID_PASSWORD, rPasswd )); |
| |
| if( !pSfxFlt ) |
| aMatcher.DetectFilter( *pMed, &pSfxFlt, sal_False, sal_False ); |
| |
| if( pSfxFlt ) |
| { |
| // ohne Filter geht gar nichts |
| pMed->SetFilter( pSfxFlt ); |
| |
| // if the new shell is created, SfxObjectShellLock should be used to let it be closed later for sure |
| xLockRef = new SwDocShell( SFX_CREATE_MODE_INTERNAL ); |
| xDocSh = (SfxObjectShell*)xLockRef; |
| if( xDocSh->DoLoad( pMed ) ) |
| return 2; |
| } |
| } |
| |
| if( !xDocSh.Is() ) // Medium muss noch geloescht werden |
| delete pMed; |
| |
| return 0; // das war wohl nichts |
| } |
| |
| |
| void SwIntrnlSectRefLink::DataChanged( const String& rMimeType, |
| const uno::Any & rValue ) |
| { |
| SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False ); |
| SwDoc* pDoc = rSectFmt.GetDoc(); |
| |
| sal_uLong nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType ); |
| |
| if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() || |
| sfx2::LinkManager::RegisterStatusInfoId() == nDataFormat ) |
| { |
| // sollten wir schon wieder im Undo stehen? |
| return ; |
| } |
| |
| // --> OD 2005-02-11 #i38810# - Due to possible existing signatures, the |
| // document has to be modified after updating a link. |
| pDoc->SetModified(); |
| // set additional flag that links have been updated, in order to check this |
| // during load. |
| pDoc->SetLinksUpdated( sal_True ); |
| // <-- |
| |
| // Undo immer abschalten |
| bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo(); |
| pDoc->GetIDocumentUndoRedo().DoUndo(false); |
| sal_Bool bWasVisibleLinks = pDoc->IsVisibleLinks(); |
| pDoc->SetVisibleLinks( sal_False ); |
| |
| SwPaM* pPam; |
| ViewShell* pVSh = 0; |
| SwEditShell* pESh = pDoc->GetEditShell( &pVSh ); |
| pDoc->LockExpFlds(); |
| { |
| // am Anfang des Bereichs einen leeren TextNode einfuegen |
| SwNodeIndex aIdx( *pSectNd, +1 ); |
| SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); |
| SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx, |
| pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); |
| |
| if( pESh ) |
| pESh->StartAllAction(); |
| else if( pVSh ) |
| pVSh->StartAction(); |
| |
| SwPosition aPos( aIdx, SwIndex( pNewNd, 0 )); |
| aPos.nNode--; |
| pDoc->CorrAbs( aIdx, aEndIdx, aPos, sal_True ); |
| |
| pPam = new SwPaM( aPos ); |
| |
| //und alles dahinter liegende loeschen |
| aIdx--; |
| DelFlyInRange( aIdx, aEndIdx ); |
| _DelBookmarks(aIdx, aEndIdx); |
| aIdx++; |
| |
| pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() ); |
| } |
| |
| SwSection& rSection = pSectNd->GetSection(); |
| rSection.SetConnectFlag(false); |
| |
| ::rtl::OUString sNewFileName; |
| Reader* pRead = 0; |
| switch( nDataFormat ) |
| { |
| case FORMAT_STRING: |
| pRead = ReadAscii; |
| break; |
| |
| case FORMAT_RTF: |
| pRead = SwReaderWriter::GetReader( READER_WRITER_RTF ); |
| break; |
| |
| case FORMAT_FILE: |
| if( rValue.hasValue() && ( rValue >>= sNewFileName ) ) |
| { |
| String sFilter, sRange, sFileName( sNewFileName ); |
| pDoc->GetLinkManager().GetDisplayNames( this, 0, &sFileName, |
| &sRange, &sFilter ); |
| |
| RedlineMode_t eOldRedlineMode = nsRedlineMode_t::REDLINE_NONE; |
| SfxObjectShellRef xDocSh; |
| SfxObjectShellLock xLockRef; |
| int nRet; |
| if( !sFileName.Len() ) |
| { |
| xDocSh = pDoc->GetDocShell(); |
| nRet = 1; |
| } |
| else |
| { |
| nRet = lcl_FindDocShell( xDocSh, xLockRef, sFileName, |
| rSection.GetLinkFilePassword(), |
| sFilter, 0, pDoc->GetDocShell() ); |
| if( nRet ) |
| { |
| SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc(); |
| eOldRedlineMode = pSrcDoc->GetRedlineMode(); |
| pSrcDoc->SetRedlineMode( nsRedlineMode_t::REDLINE_SHOW_INSERT ); |
| } |
| } |
| |
| if( nRet ) |
| { |
| rSection.SetConnectFlag(true); |
| |
| SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 ); |
| SwNodeRange* pCpyRg = 0; |
| |
| if( xDocSh->GetMedium() && |
| !rSection.GetLinkFilePassword().Len() ) |
| { |
| const SfxPoolItem* pItem; |
| if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()-> |
| GetItemState( SID_PASSWORD, sal_False, &pItem ) ) |
| rSection.SetLinkFilePassword( |
| ((SfxStringItem*)pItem)->GetValue() ); |
| } |
| |
| SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc(); |
| |
| if( sRange.Len() ) |
| { |
| // Rekursionen abfangen |
| sal_Bool bRecursion = sal_False; |
| if( pSrcDoc == pDoc ) |
| { |
| SwServerObjectRef refObj( (SwServerObject*) |
| pDoc->CreateLinkSource( sRange )); |
| if( refObj.Is() ) |
| { |
| bRecursion = refObj->IsLinkInServer( this ) || |
| ChkNoDataFlag(); |
| } |
| } |
| |
| SwNodeIndex& rInsPos = pPam->GetPoint()->nNode; |
| |
| SwPaM* pCpyPam = 0; |
| if( !bRecursion && |
| pSrcDoc->SelectServerObj( sRange, pCpyPam, pCpyRg ) |
| && pCpyPam ) |
| { |
| if( pSrcDoc != pDoc || |
| pCpyPam->Start()->nNode > rInsPos || |
| rInsPos >= pCpyPam->End()->nNode ) |
| { |
| pSrcDoc->CopyRange( *pCpyPam, *pPam->GetPoint(), |
| false ); |
| } |
| delete pCpyPam; |
| } |
| if( pCpyRg && pSrcDoc == pDoc && |
| pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd ) |
| delete pCpyRg, pCpyRg = 0; |
| } |
| else if( pSrcDoc != pDoc ) |
| pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2, |
| pSrcDoc->GetNodes().GetEndOfContent() ); |
| |
| // --> OD 2007-11-30 #i81653# |
| // Update links of extern linked document or extern linked |
| // document section, if section is protected. |
| if ( pSrcDoc != pDoc && |
| rSection.IsProtectFlag() ) |
| { |
| pSrcDoc->GetLinkManager().UpdateAllLinks( sal_False, sal_True, sal_False, 0 ); |
| } |
| // <-- |
| if( pCpyRg ) |
| { |
| SwNodeIndex& rInsPos = pPam->GetPoint()->nNode; |
| sal_Bool bCreateFrm = rInsPos.GetIndex() <= |
| pDoc->GetNodes().GetEndOfExtras().GetIndex() || |
| rInsPos.GetNode().FindTableNode(); |
| |
| SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc ); |
| |
| pSrcDoc->CopyWithFlyInFly( *pCpyRg, 0, rInsPos, NULL, bCreateFrm ); |
| aSave++; |
| |
| if( !bCreateFrm ) |
| ::MakeFrms( pDoc, aSave, rInsPos ); |
| |
| // den letzten Node noch loeschen, aber nur wenn |
| // erfolgreich kopiert werden konnte, also der Bereich |
| // mehr als 1 Node enthaelt |
| if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() ) |
| { |
| aSave = rInsPos; |
| pPam->Move( fnMoveBackward, fnGoNode ); |
| pPam->SetMark(); // beide SwPositions ummelden! |
| |
| pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, sal_True ); |
| pDoc->GetNodes().Delete( aSave, 1 ); |
| } |
| delete pCpyRg; |
| } |
| |
| // --> OD 2007-02-14 #b6521322# |
| lcl_BreakSectionLinksInSect( *pSectNd ); |
| // <-- |
| |
| // update alle Links in diesem Bereich |
| lcl_UpdateLinksInSect( *this, *pSectNd ); |
| } |
| if( xDocSh.Is() ) |
| { |
| if( 2 == nRet ) |
| xDocSh->DoClose(); |
| else if( ((SwDocShell*)&xDocSh)->GetDoc() ) |
| ((SwDocShell*)&xDocSh)->GetDoc()->SetRedlineMode( |
| eOldRedlineMode ); |
| } |
| } |
| break; |
| } |
| |
| // !!!! DDE nur updaten wenn Shell vorhanden ist?? |
| uno::Sequence< sal_Int8 > aSeq; |
| if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) ) |
| { |
| if( pESh ) |
| { |
| pESh->Push(); |
| SwPaM* pCrsr = pESh->GetCrsr(); |
| *pCrsr->GetPoint() = *pPam->GetPoint(); |
| delete pPam; |
| pPam = pCrsr; |
| } |
| |
| SvMemoryStream aStrm( (void*)aSeq.getConstArray(), aSeq.getLength(), |
| STREAM_READ ); |
| aStrm.Seek( 0 ); |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| { |
| SvFileStream aDeb( String::CreateFromAscii( |
| "file:///d|/temp/update.txt" ), STREAM_WRITE ); |
| aDeb << aStrm; |
| } |
| aStrm.Seek( 0 ); |
| #endif |
| |
| // TODO/MBA: it's impossible to set a BaseURL here! |
| SwReader aTmpReader( aStrm, aEmptyStr, pDoc->GetDocShell()->GetMedium()->GetBaseURL(), *pPam ); |
| |
| if( !IsError( aTmpReader.Read( *pRead ) )) |
| { |
| rSection.SetConnectFlag(true); |
| } |
| |
| if( pESh ) |
| { |
| pESh->Pop( sal_False ); |
| pPam = 0; // pam is deleted before |
| } |
| } |
| |
| |
| // remove all undo actions and turn undo on again |
| pDoc->GetIDocumentUndoRedo().DelAllUndoObj(); |
| pDoc->GetIDocumentUndoRedo().DoUndo(bWasUndo); |
| pDoc->SetVisibleLinks( bWasVisibleLinks ); |
| |
| pDoc->UnlockExpFlds(); |
| if( !pDoc->IsExpFldsLocked() ) |
| pDoc->UpdateExpFlds(NULL, true); |
| |
| if( pESh ) |
| pESh->EndAllAction(); |
| else if( pVSh ) |
| pVSh->EndAction(); |
| delete pPam; // wurde am Anfang angelegt |
| } |
| |
| |
| void SwIntrnlSectRefLink::Closed() |
| { |
| SwDoc* pDoc = rSectFmt.GetDoc(); |
| if( pDoc && !pDoc->IsInDtor() ) |
| { |
| // Advise verabschiedet sich, den Bereich als nicht geschuetzt |
| // kennzeichnen und das Flag umsetzen |
| |
| const SwSectionFmts& rFmts = pDoc->GetSections(); |
| for( sal_uInt16 n = rFmts.Count(); n; ) |
| if( rFmts[ --n ] == &rSectFmt ) |
| { |
| ViewShell* pSh; |
| SwEditShell* pESh = pDoc->GetEditShell( &pSh ); |
| |
| if( pESh ) |
| pESh->StartAllAction(); |
| else |
| pSh->StartAction(); |
| |
| SwSectionData aSectionData(*rSectFmt.GetSection()); |
| aSectionData.SetType( CONTENT_SECTION ); |
| aSectionData.SetLinkFileName( aEmptyStr ); |
| aSectionData.SetHidden( false ); |
| aSectionData.SetProtectFlag( false ); |
| // --> FME 2004-06-22 #114856# edit in readonly sections |
| aSectionData.SetEditInReadonlyFlag( false ); |
| // <-- |
| |
| aSectionData.SetConnectFlag( false ); |
| |
| pDoc->UpdateSection( n, aSectionData ); |
| |
| // alle in der Section liegenden Links werden sichtbar |
| SwSectionNode* pSectNd = rSectFmt.GetSectionNode( sal_False ); |
| if( pSectNd ) |
| pSectNd->GetSection().MakeChildLinksVisible( *pSectNd ); |
| |
| if( pESh ) |
| pESh->EndAllAction(); |
| else |
| pSh->EndAction(); |
| break; |
| } |
| } |
| SvBaseLink::Closed(); |
| } |
| |
| |
| void SwSection::CreateLink( LinkCreateType eCreateType ) |
| { |
| SwSectionFmt* pFmt = GetFmt(); |
| ASSERT(pFmt, "SwSection::CreateLink: no format?"); |
| if (!pFmt || (CONTENT_SECTION == m_Data.GetType())) |
| return ; |
| |
| sal_uInt16 nUpdateType = sfx2::LINKUPDATE_ALWAYS; |
| |
| if (!m_RefLink.Is()) |
| { |
| // create BaseLink |
| m_RefLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF ); |
| } |
| else |
| { |
| pFmt->GetDoc()->GetLinkManager().Remove( m_RefLink ); |
| } |
| |
| SwIntrnlSectRefLink *const pLnk = |
| static_cast<SwIntrnlSectRefLink*>(& m_RefLink); |
| |
| String sCmd( m_Data.GetLinkFileName() ); |
| xub_StrLen nPos; |
| while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) ) |
| sCmd.Erase( nPos, 1 ); |
| |
| pLnk->SetUpdateMode( nUpdateType ); |
| pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() ); |
| |
| switch (m_Data.GetType()) |
| { |
| case DDE_LINK_SECTION: |
| pLnk->SetLinkSourceName( sCmd ); |
| pFmt->GetDoc()->GetLinkManager().InsertDDELink( pLnk ); |
| break; |
| case FILE_LINK_SECTION: |
| { |
| pLnk->SetContentType( FORMAT_FILE ); |
| String sFltr( sCmd.GetToken( 1, sfx2::cTokenSeperator ) ); |
| String sRange( sCmd.GetToken( 2, sfx2::cTokenSeperator ) ); |
| pFmt->GetDoc()->GetLinkManager().InsertFileLink( *pLnk, |
| static_cast<sal_uInt16>(m_Data.GetType()), |
| sCmd.GetToken( 0, sfx2::cTokenSeperator ), |
| ( sFltr.Len() ? &sFltr : 0 ), |
| ( sRange.Len() ? &sRange : 0 ) ); |
| } |
| break; |
| default: |
| ASSERT( !this, "Was ist das fuer ein Link?" ) |
| } |
| |
| switch( eCreateType ) |
| { |
| case CREATE_CONNECT: // Link gleich connecten |
| pLnk->Connect(); |
| break; |
| |
| case CREATE_UPDATE: // Link connecten und updaten |
| pLnk->Update(); |
| break; |
| case CREATE_NONE: break; |
| } |
| } |
| |
| // --> OD 2007-02-14 #b6521322# |
| void SwSection::BreakLink() |
| { |
| const SectionType eCurrentType( GetType() ); |
| if ( eCurrentType == CONTENT_SECTION || |
| eCurrentType == TOX_HEADER_SECTION || |
| eCurrentType == TOX_CONTENT_SECTION ) |
| { |
| // nothing to do |
| return; |
| } |
| |
| // release link, if it exists |
| if (m_RefLink.Is()) |
| { |
| SwSectionFmt *const pFormat( GetFmt() ); |
| ASSERT(pFormat, "SwSection::BreakLink: no format?"); |
| if (pFormat) |
| { |
| pFormat->GetDoc()->GetLinkManager().Remove( m_RefLink ); |
| } |
| m_RefLink.Clear(); |
| } |
| // change type |
| SetType( CONTENT_SECTION ); |
| // reset linked file data |
| SetLinkFileName( aEmptyStr ); |
| SetLinkFilePassword( aEmptyStr ); |
| } |
| // <-- |
| |
| const SwNode* SwIntrnlSectRefLink::GetAnchor() const |
| { |
| return rSectFmt.GetSectionNode( sal_False ); |
| } |
| |
| |
| sal_Bool SwIntrnlSectRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, |
| xub_StrLen , xub_StrLen ) const |
| { |
| SwStartNode* pSttNd = rSectFmt.GetSectionNode( sal_False ); |
| return pSttNd && |
| nSttNd < pSttNd->GetIndex() && |
| pSttNd->EndOfSectionIndex() < nEndNd; |
| } |
| |
| |
| |