diff options
Diffstat (limited to 'sw/source/core/docnode/section.cxx')
-rw-r--r-- | sw/source/core/docnode/section.cxx | 1703 |
1 files changed, 1703 insertions, 0 deletions
diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx new file mode 100644 index 000000000000..653ce6794e7e --- /dev/null +++ b/sw/source/core/docnode/section.cxx @@ -0,0 +1,1703 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 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 <node.hxx> +#include <pam.hxx> +#include <frmtool.hxx> +#include <editsh.hxx> +#include <hints.hxx> +#ifndef _DOCSH_HXX +#include <docsh.hxx> +#endif +#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> +// --> FME 2004-06-22 #114856# edit in readonly sections +#include <fmteiro.hxx> +// <-- +#include <swerror.h> + +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, USHORT nUpdateType, USHORT 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 BOOL IsInRange( ULONG nSttNd, 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*) + + + +SwSection::SwSection( SectionType eTyp, const String& rName, + SwSectionFmt* pFmt ) + : SwClient( pFmt ), sSectionNm( rName ), + eType( eTyp ) +{ + bHidden = FALSE; + bHiddenFlag = FALSE; + bProtectFlag = FALSE; + // --> FME 2004-06-22 #114856# edit in readonly sections + bEditInReadonlyFlag = FALSE; + // <-- + bCondHiddenFlag = TRUE; + bConnectFlag = TRUE; + + SwSectionPtr pParentSect = GetParent(); + if( pParentSect ) + { + if( pParentSect->IsHiddenFlag() ) + SetHidden( TRUE ); + + _SetProtectFlag( pParentSect->IsProtectFlag() ); + // --> FME 2004-06-22 #114856# edit in readonly sections + _SetEditInReadonlyFlag( pParentSect->IsEditInReadonlyFlag() ); + // <-- + } + + if( pFmt && !bProtectFlag ) + _SetProtectFlag( pFmt->GetProtect().IsCntntProtected() ); + + // --> FME 2004-06-22 #114856# edit in readonly sections + if ( pFmt && !bEditInReadonlyFlag ) + _SetEditInReadonlyFlag( pFmt->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() ) + pDoc->GetDfltFrmFmt()->Add( pFmt ); + } + else + { + pFmt->Remove( this ); // austragen, + + if( CONTENT_SECTION != eType ) // den Link austragen + pDoc->GetLinkManager().Remove( refLink ); + + if( refObj.Is() ) // als Server austragen + pDoc->GetLinkManager().RemoveServer( &refObj ); + + // ist die Section der letzte Client im Format, kann dieses + // geloescht werden + SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt ); + pFmt->Modify( &aMsgHint, &aMsgHint ); + if( !pFmt->GetDepends() ) + { + // Bug: 28191 - nicht ins Undo aufnehmen, sollte schon vorher + // geschehen sein!! + BOOL bUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + pDoc->DelSectionFmt( pFmt ); // und loeschen + pDoc->DoUndo( bUndo ); + } + } + if( refObj.Is() ) + refObj->Closed(); +} + + +SwSection& SwSection::operator=( const SwSection& rCpy ) +{ + sSectionNm = rCpy.sSectionNm; + sCondition = rCpy.sCondition; + sLinkFileName = rCpy.GetLinkFileName(); + SetLinkFilePassWd( rCpy.GetLinkFilePassWd() ); + SetConnectFlag( rCpy.IsConnectFlag() ); + SetPasswd( rCpy.GetPasswd() ); + + eType = rCpy.eType; + + if( !GetFmt() ) + { + SetProtect( rCpy.IsProtect() ); + // --> FME 2004-06-22 #114856# edit in readonly sections + SetEditInReadonly( rCpy.IsEditInReadonly() ); + // <-- + } + else if( rCpy.GetFmt() ) + { + _SetProtectFlag( rCpy.bProtectFlag ); + // --> FME 2004-06-22 #114856# edit in readonly sections + _SetEditInReadonlyFlag( rCpy.bEditInReadonlyFlag ); + // <-- + } + else + { + SetProtect( rCpy.bProtectFlag ); + // --> FME 2004-06-22 #114856# edit in readonly sections + SetEditInReadonly( rCpy.bEditInReadonlyFlag ); + // <-- + } + + bCondHiddenFlag = TRUE; // sollte immer defaultet werden + SetHidden( rCpy.bHidden ); + + return *this; +} + + +BOOL SwSection::operator==( const SwSection& rCmp ) const +{ + return sSectionNm == rCmp.sSectionNm && + sCondition == rCmp.sCondition && + eType == rCmp.eType && + bHidden == rCmp.bHidden && + IsProtect() == rCmp.IsProtect() && + // --> FME 2004-06-22 #114856# edit in readonly sections + IsEditInReadonly() == rCmp.IsEditInReadonly() && + // <-- + GetLinkFileName() == rCmp.GetLinkFileName() && + GetLinkFilePassWd() == rCmp.GetLinkFilePassWd() && + GetPasswd() == rCmp.GetPasswd() && + ( !GetFmt() || !rCmp.GetFmt() || GetFmt() == rCmp.GetFmt()); +} + + +void SwSection::_SetHiddenFlag( BOOL bTmpHidden, BOOL bCondition ) +{ + SwSectionFmt* pFmt = GetFmt(); + if( pFmt ) + { + BOOL bHide = bTmpHidden && bCondition; + + if( bHide ) // die Nodes also "verstecken" + { + if( !bHiddenFlag ) // ist nicht versteckt + { + // 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->Modify( &aMsgItem, &aMsgItem ); + + // alle Frames loeschen + pFmt->DelFrms(); + } + } + else if( bHiddenFlag ) // die Nodes wieder anzeigen + { + // 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->Modify( &aMsgItem, &aMsgItem ); + + pFmt->MakeFrms(); + } + } + } +} + +BOOL SwSection::CalcHiddenFlag() const +{ + const SwSection* pSect = this; + do { + if( pSect->IsHidden() && pSect->IsCondHidden() ) + return TRUE; + } while( 0 != ( pSect = pSect->GetParent()) ); + + return FALSE; +} + +BOOL SwSection::_IsProtect() const +{ + return GetFmt()->GetProtect().IsCntntProtected(); +} + +// --> FME 2004-06-22 #114856# edit in readonly sections +BOOL SwSection::_IsEditInReadonly() const +{ + return GetFmt()->GetEditInReadonly().GetValue(); +} +// <-- + +void SwSection::SetHidden( BOOL bFlag ) +{ + if( !bHidden == !bFlag ) + return; + + bHidden = bFlag; + _SetHiddenFlag( bHidden, bCondHiddenFlag ); +} + + +void SwSection::SetProtect( BOOL bFlag ) +{ + if( GetFmt() ) + { + SvxProtectItem aItem( RES_PROTECT ); + aItem.SetCntntProtect( (BOOL)bFlag ); + GetFmt()->SetFmtAttr( aItem ); + } + else + bProtectFlag = bFlag; +} + +// --> FME 2004-06-22 #114856# edit in readonly sections +void SwSection::SetEditInReadonly( BOOL bFlag ) +{ + if( GetFmt() ) + { + SwFmtEditInReadonly aItem; + aItem.SetValue( (BOOL)bFlag ); + GetFmt()->SetFmtAttr( aItem ); + } + else + bEditInReadonlyFlag = bFlag; +} +// <-- + +void SwSection::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + BOOL bRemake = FALSE, 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, FALSE, &pItem ) ) + { + _SetProtectFlag( ((SvxProtectItem*)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, FALSE, &pItem ) ) + { + _SetEditInReadonlyFlag( ((SwFmtEditInReadonly*)pItem)->GetValue() ); + pNewSet->ClearItem( RES_EDIT_IN_READONLY ); + pOldSet->ClearItem( RES_EDIT_IN_READONLY ); + } + // <-- + + if( SFX_ITEM_SET == pNewSet->GetItemState( + RES_FTN_AT_TXTEND, FALSE, &pItem ) || + SFX_ITEM_SET == pNewSet->GetItemState( + RES_END_AT_TXTEND, FALSE, &pItem )) + bUpdateFtn = TRUE; + + if( !pNewSet->Count() ) + return; + } + break; + + case RES_PROTECT: + if( pNew ) + { + BOOL bNewFlag = ((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; + } + } while( 0 != ( pSect = pSect->GetParent()) ); + } + + _SetProtectFlag( bNewFlag ); + } + return; + // --> FME 2004-06-22 #114856# edit in readonly sections + case RES_EDIT_IN_READONLY: + if( pNew ) + { + BOOL bNewFlag = ((SwFmtEditInReadonly*)pNew)->GetValue(); + _SetEditInReadonlyFlag( bNewFlag ); + } + return; + // <-- + + case RES_SECTION_HIDDEN: + bHiddenFlag = TRUE; + return; + + case RES_SECTION_NOT_HIDDEN: + case RES_SECTION_RESETHIDDENFLAG: + bHiddenFlag = bHidden && bCondHiddenFlag; + 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; + } + + if( bRemake ) + { + GetFmt()->DelFrms(); + GetFmt()->MakeFrms(); + } + + if( bUpdateFtn ) + { + SwSectionNode* pSectNd = GetFmt()->GetSectionNode( FALSE ); + if( pSectNd ) + pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd )); + } + SwClient::Modify( pOld, pNew ); +} + +void SwSection::SetRefObject( SwServerObject* pObj ) +{ + refObj = pObj; +} + + +void SwSection::SetCondHidden( BOOL bFlag ) +{ + if( !bCondHiddenFlag == !bFlag ) + return; + + bCondHiddenFlag = bFlag; + _SetHiddenFlag( bHidden, bCondHiddenFlag ); +} + + +// setze/erfrage den gelinkten FileNamen +const String& SwSection::GetLinkFileName() const +{ + if( refLink.Is() ) + { + String sTmp; + switch( eType ) + { + case DDE_LINK_SECTION: + sTmp = refLink->GetLinkSourceName(); + break; + + case FILE_LINK_SECTION: + { + String sRange, sFilter; + if( refLink->GetLinkManager() && + refLink->GetLinkManager()->GetDisplayNames( + 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 sLinkFileName; + } + } + break; + default: break; + } + ((SwSection*)this)->sLinkFileName = sTmp; + } + return sLinkFileName; +} + + +void SwSection::SetLinkFileName( const String& rNew, const String* pPassWd ) +{ + if( refLink.Is() ) + refLink->SetLinkSourceName( rNew ); + else + sLinkFileName = rNew; + if( pPassWd ) + SetLinkFilePassWd( *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( USHORT 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( 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* 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( 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 ); + } + } + SwClientIter aIter( *this ); + SwClient *pLast = aIter.GoStart(); + while ( pLast ) + { + if ( pLast->IsA( TYPE(SwFrm) ) ) + { + SwSectionFrm *pFrm = (SwSectionFrm*)pLast; + SwSectionFrm::MoveCntntAndDelete( pFrm, TRUE ); + pLast = aIter.GoStart(); + } + else + pLast = aIter++; + } + // hebe die Section doch mal auf + SwNodeRange aRg( *pSectNd, 0, *pSectNd->EndOfSectionNode() ); + GetDoc()->GetNodes().SectionUp( &aRg ); + } + LockModify(); + ResetFmtAttr( RES_CNTNT ); + UnlockModify(); + } +} + + +SwSectionPtr SwSectionFmt::_GetSection() const +{ + if( GetDepends() ) + { + SwClientIter aIter( *(SwSectionFmt*)this ); + return (SwSectionPtr)aIter.First( TYPE(SwSection) ); + } + + ASSERT( FALSE, "keine Section als Client." ) + return 0; +} + +extern void lcl_DeleteFtn( SwSectionNode *pNd, ULONG nStt, ULONG nEnd ); + +//Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt). +void SwSectionFmt::DelFrms() +{ + SwSectionNode* pSectNd; + const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); + if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && + 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) + { + SwClientIter aIter( *this ); + SwClient *pLast = aIter.GoStart(); + // --> OD 2007-08-14 #147431# + // First delete the <SwSectionFrm> of the <SwSectionFmt> instance + while ( pLast ) + { + if ( pLast->IsA( TYPE(SwFrm) ) ) + { + SwSectionFrm *pFrm = (SwSectionFrm*)pLast; + SwSectionFrm::MoveCntntAndDelete( pFrm, FALSE ); + pLast = aIter.GoStart(); + } + else + { + pLast = aIter++; + } + } + // Then delete frames of the nested <SwSectionFmt> instances + pLast = aIter.GoStart(); + while ( pLast ) + { + if ( pLast->IsA( TYPE(SwSectionFmt) ) ) + { + ((SwSectionFmt*)pLast)->DelFrms(); + } + pLast = aIter++; + } + // <-- + ULONG nEnde = pSectNd->EndOfSectionIndex(); + 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, TRUE, FALSE ); + if( pCNd ) + { + const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC ); + pCNd->Modify( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem ); + } + } +} + + +//Erzeugt die Ansichten +void SwSectionFmt::MakeFrms() +{ + SwSectionNode* pSectNd; + const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); + + if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && + 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) + { + SwNodeIndex aIdx( *pIdx ); + pSectNd->MakeFrms( &aIdx ); + } +} + +void lcl_ClientIter( SwSectionFmt* pFmt, const SfxPoolItem* pOld, + const SfxPoolItem* pNew ) +{ + SwClientIter aIter( *pFmt ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) + do { + pLast->Modify( (SfxPoolItem*)pOld, (SfxPoolItem*)pNew ); + } while( 0 != ( pLast = aIter++ )); +} + +void SwSectionFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + BOOL bClients = FALSE; + USHORT 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, FALSE, &pItem )) + { + lcl_ClientIter( this, pItem, 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, FALSE, &pItem ) ) + { + lcl_ClientIter( this, pItem, pItem ); + pNewSet->ClearItem( RES_EDIT_IN_READONLY ); + pOldSet->ClearItem( RES_EDIT_IN_READONLY ); + } + // <-- + + if( SFX_ITEM_SET == pNewSet->GetItemState( + RES_FTN_AT_TXTEND, FALSE, &pItem )) + { + lcl_ClientIter( this, &pOldSet->Get( RES_FTN_AT_TXTEND ), + pItem ); + pNewSet->ClearItem( RES_FTN_AT_TXTEND ); + pOldSet->ClearItem( RES_FTN_AT_TXTEND ); + } + if( SFX_ITEM_SET == pNewSet->GetItemState( + RES_END_AT_TXTEND, FALSE, &pItem )) + { + lcl_ClientIter( this, &pOldSet->Get( RES_END_AT_TXTEND ), + 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 = 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() ) ) ) + { + // selbst ueber die Clients iterieren, sollte schneller sein! + SwClientIter aIter( *this ); + SwClient * pLast = aIter.GoStart(); + do { + pLast->Modify( pOld, pNew ); + } while( 0 != ( pLast = aIter++ )); + } + } + 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() ) + { + SwClientIter aIter( *this ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) // konnte zum Anfang gesprungen werden ?? + do { + pLast->Modify( pOld, pNew ); + } while( 0 != ( pLast = aIter++ )); + } + 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 +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 TRUE; + + case RES_CONTENT_VISIBLE: + { + SwFrm* pFrm = (SwFrm*)SwClientIter( *(SwSectionFmt*)this ).First( TYPE(SwFrm) ); + // if the current section has no own frame search for the children + if(!pFrm) + { + SwClientIter aFormatIter( *(SwSectionFmt*)this ); + SwSectionFmt* pChild = (SwSectionFmt*)aFormatIter. + First( TYPE(SwSectionFmt) ); + while(pChild && !pFrm) + { + pFrm = (SwFrm*)SwClientIter( *pChild ).First( TYPE(SwFrm) ); + pChild = (SwSectionFmt*)aFormatIter.Next(); + } + } + ((SwPtrMsgPoolItem&)rInfo).pObject = pFrm; + } + return 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(FALSE).GetCntntIdx() && + pSSectFmt->GetCntnt(FALSE).GetCntntIdx(), + "ungueltige Sections" ); + return (int)((long)pFSectFmt->GetCntnt(FALSE).GetCntntIdx()->GetIndex()) - + pSSectFmt->GetCntnt(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 eCmp = pFSect->GetName().CompareTo( pSSect->GetName() ); + return eCmp == COMPARE_EQUAL ? 0 + : eCmp == COMPARE_LESS ? 1 : -1; + } +} + + // alle Sections, die von dieser abgeleitet sind +USHORT SwSectionFmt::GetChildSections( SwSections& rArr, + SectionSort eSort, + BOOL bAllSections ) const +{ + rArr.Remove( 0, rArr.Count() ); + + if( GetDepends() ) + { + SwClientIter aIter( *(SwSectionFmt*)this ); + SwClient * pLast; + const SwNodeIndex* pIdx; + for( pLast = aIter.First(TYPE(SwSectionFmt)); pLast; pLast = aIter.Next() ) + if( bAllSections || + ( 0 != ( pIdx = ((SwSectionFmt*)pLast)->GetCntnt(FALSE). + GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() )) + { + const SwSection* Dummy=((SwSectionFmt*)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. +BOOL SwSectionFmt::IsInNodesArr() const +{ + const SwNodeIndex* pIdx = GetCntnt(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; + // <-- + int bIsHidden = FALSE; + + SwClientIter aIter( *this ); + 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->Modify( (SfxPoolItem*)pProtect, + (SfxPoolItem*)pProtect ); + + // --> FME 2004-06-22 #114856# edit in readonly sections + if ( pEditInReadonly->GetValue() != + pSection->IsEditInReadonlyFlag() ) + pLast->Modify( (SfxPoolItem*)pEditInReadonly, + (SfxPoolItem*)pEditInReadonly ); + // <-- + + if( bIsHidden == pSection->IsHiddenFlag() ) + { + SwMsgPoolItem aMsgItem( static_cast<USHORT>(bIsHidden + ? RES_SECTION_HIDDEN + : RES_SECTION_NOT_HIDDEN ) ); + pLast->Modify( &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 bAlways ) +{ + const SwNodeIndex* pIdx = GetCntnt(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; +} + +// --> 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 ( USHORT 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( USHORT 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 + +int lcl_FindDocShell( SfxObjectShellRef& xDocSh, + const String& rFileName, + const String& rPasswd, + String& rFilter, + 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; + 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, FALSE, &pItem ) ) + ? (nVersion == ((SfxInt16Item*)pItem)->GetValue()) + : !nVersion ) + { + // gefunden also returnen + xDocSh = pShell; + return 1; + } + } + + if( bFirst ) + { + bFirst = 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, 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, FALSE, FALSE ); + + if( pSfxFlt ) + { + // ohne Filter geht gar nichts + pMed->SetFilter( pSfxFlt ); + + xDocSh = new SwDocShell( SFX_CREATE_MODE_INTERNAL ); + 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( FALSE ); + SwDoc* pDoc = rSectFmt.GetDoc(); + + 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 bWasUndo = pDoc->DoesUndo(); + pDoc->DoUndo( FALSE ); + BOOL bWasVisibleLinks = pDoc->IsVisibleLinks(); + pDoc->SetVisibleLinks( 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, 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; + int nRet; + if( !sFileName.Len() ) + { + xDocSh = pDoc->GetDocShell(); + nRet = 1; + } + else + { + nRet = lcl_FindDocShell( xDocSh, sFileName, + rSection.GetLinkFilePassWd(), + 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.GetLinkFilePassWd().Len() ) + { + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()-> + GetItemState( SID_PASSWORD, FALSE, &pItem ) ) + rSection.SetLinkFilePassWd( + ((SfxStringItem*)pItem)->GetValue() ); + } + + SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc(); + + if( sRange.Len() ) + { + // Rekursionen abfangen + BOOL bRecursion = 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( FALSE, TRUE, FALSE, 0 ); + } + // <-- + if( pCpyRg ) + { + SwNodeIndex& rInsPos = pPam->GetPoint()->nNode; + BOOL bCreateFrm = rInsPos.GetIndex() <= + pDoc->GetNodes().GetEndOfExtras().GetIndex() || + rInsPos.GetNode().FindTableNode(); + + SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc ); + + pSrcDoc->CopyWithFlyInFly( *pCpyRg, 0, rInsPos, 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, 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( FALSE ); + pPam = 0; // pam is deleted before + } + } + + + // Alle UndoActions entfernen und Undo wieder einschalten + pDoc->DelAllUndoObj(); + pDoc->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( USHORT n = rFmts.Count(); n; ) + if( rFmts[ --n ] == &rSectFmt ) + { + ViewShell* pSh; + SwEditShell* pESh = pDoc->GetEditShell( &pSh ); + + if( pESh ) + pESh->StartAllAction(); + else + pSh->StartAction(); + + SwSection aSect( CONTENT_SECTION, aEmptyStr ); + aSect = *rSectFmt.GetSection(); + aSect.SetType( CONTENT_SECTION ); + aSect.SetLinkFileName( aEmptyStr ); + aSect.SetHidden( FALSE ); + aSect.SetProtect( FALSE ); + // --> FME 2004-06-22 #114856# edit in readonly sections + aSect.SetEditInReadonly( FALSE ); + // <-- + + aSect.SetConnectFlag( FALSE ); + + pDoc->ChgSection( n, aSect ); + + // alle in der Section liegenden Links werden sichtbar + SwSectionNode* pSectNd = rSectFmt.GetSectionNode( 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(); + if( !pFmt || CONTENT_SECTION == eType ) + return ; + + USHORT nUpdateType = sfx2::LINKUPDATE_ALWAYS; + + if( !refLink.Is() ) + // dann mal den BaseLink aufbauen + refLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF ); + else + // sonst aus dem Linkmanager entfernen + pFmt->GetDoc()->GetLinkManager().Remove( refLink ); + + SwIntrnlSectRefLink* pLnk = (SwIntrnlSectRefLink*)&refLink; + + String sCmd( sLinkFileName ); + xub_StrLen nPos; + while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) ) + sCmd.Erase( nPos, 1 ); + + pLnk->SetUpdateMode( nUpdateType ); + pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() ); + + switch( eType ) + { + 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<USHORT>(eType), + 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 ( refLink.Is() ) + { + if ( GetFmt() ) + { + GetFmt()->GetDoc()->GetLinkManager().Remove( refLink ); + } + refLink.Clear(); + } + // change type + SetType( CONTENT_SECTION ); + // reset linked file data + SetLinkFileName( aEmptyStr ); + SetLinkFilePassWd( aEmptyStr ); +} +// <-- + +const SwNode* SwIntrnlSectRefLink::GetAnchor() const +{ + return rSectFmt.GetSectionNode( FALSE ); +} + + +BOOL SwIntrnlSectRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd, + xub_StrLen , xub_StrLen ) const +{ + SwStartNode* pSttNd = rSectFmt.GetSectionNode( FALSE ); + return pSttNd && + nSttNd < pSttNd->GetIndex() && + pSttNd->EndOfSectionIndex() < nEndNd; +} + + + |