summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/docfly.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/docfly.cxx')
-rw-r--r--sw/source/core/doc/docfly.cxx1068
1 files changed, 1068 insertions, 0 deletions
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
new file mode 100644
index 000000000000..68c525ad74e1
--- /dev/null
+++ b/sw/source/core/doc/docfly.cxx
@@ -0,0 +1,1068 @@
+/*************************************************************************
+ *
+ * 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 <hintids.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdmark.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <fmtsrnd.hxx>
+#include <dcontact.hxx>
+
+#include <ndgrf.hxx>
+#include <doc.hxx>
+#include <ndindex.hxx>
+#include <docary.hxx>
+#include <fmtcntnt.hxx>
+#include <fmtanchr.hxx>
+#include <txtflcnt.hxx>
+#include <fmtflcnt.hxx>
+#include <txtfrm.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+#include <flyfrms.hxx>
+#include <frmtool.hxx>
+#include <frmfmt.hxx>
+#include <ndtxt.hxx>
+#include <pam.hxx>
+#include <tblsel.hxx>
+#include <swundo.hxx>
+#include <swtable.hxx>
+#include <crstate.hxx>
+#include <undobj.hxx>
+#include <fmtcnct.hxx>
+#include <dflyobj.hxx>
+
+// --> OD 2009-07-20 #i73249#
+#include <undoflystrattr.hxx>
+// <--
+
+extern USHORT GetHtmlMode( const SwDocShell* );
+
+
+using namespace ::com::sun::star;
+
+/*-----------------17.02.98 08:35-------------------
+
+--------------------------------------------------*/
+USHORT SwDoc::GetFlyCount( FlyCntType eType ) const
+{
+ const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
+ USHORT nSize = rFmts.Count();
+ USHORT nCount = 0;
+ const SwNodeIndex* pIdx;
+ for ( USHORT i = 0; i < nSize; i++)
+ {
+ const SwFrmFmt* pFlyFmt = rFmts[ i ];
+ if( RES_FLYFRMFMT == pFlyFmt->Which()
+ && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
+ && pIdx->GetNodes().IsDocNodes()
+ )
+ {
+ const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
+
+ switch( eType )
+ {
+ case FLYCNTTYPE_FRM:
+ if(!pNd->IsNoTxtNode())
+ nCount++;
+ break;
+
+ case FLYCNTTYPE_GRF:
+ if( pNd->IsGrfNode() )
+ nCount++;
+ break;
+
+ case FLYCNTTYPE_OLE:
+ if(pNd->IsOLENode())
+ nCount++;
+ break;
+
+ default:
+ nCount++;
+ }
+ }
+ }
+ return nCount;
+}
+
+/*-----------------17.02.98 08:35-------------------
+
+--------------------------------------------------*/
+// If you change this, also update SwXFrameEnumeration in unocoll.
+SwFrmFmt* SwDoc::GetFlyNum( USHORT nIdx, FlyCntType eType )
+{
+ SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
+ SwFrmFmt* pRetFmt = 0;
+ USHORT nSize = rFmts.Count();
+ const SwNodeIndex* pIdx;
+ USHORT nCount = 0;
+ for( USHORT i = 0; !pRetFmt && i < nSize; ++i )
+ {
+ SwFrmFmt* pFlyFmt = rFmts[ i ];
+ if( RES_FLYFRMFMT == pFlyFmt->Which()
+ && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
+ && pIdx->GetNodes().IsDocNodes()
+ )
+ {
+ const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
+ switch( eType )
+ {
+ case FLYCNTTYPE_FRM:
+ if( !pNd->IsNoTxtNode() && nIdx == nCount++)
+ pRetFmt = pFlyFmt;
+ break;
+ case FLYCNTTYPE_GRF:
+ if(pNd->IsGrfNode() && nIdx == nCount++ )
+ pRetFmt = pFlyFmt;
+ break;
+ case FLYCNTTYPE_OLE:
+ if(pNd->IsOLENode() && nIdx == nCount++)
+ pRetFmt = pFlyFmt;
+ break;
+ default:
+ if(nIdx == nCount++)
+ pRetFmt = pFlyFmt;
+ }
+ }
+ }
+ return pRetFmt;
+}
+
+/* */
+
+/***********************************************************************
+#* Class : SwDoc
+#* Methode : SetFlyFrmAnchor
+#* Beschreibung: Das Ankerattribut des FlyFrms aendert sich.
+#* Datum : MA 01. Feb. 94
+#* Update : JP 09.03.98
+#***********************************************************************/
+
+Point lcl_FindAnchorLayPos( SwDoc& rDoc, const SwFmtAnchor& rAnch,
+ const SwFrmFmt* pFlyFmt )
+{
+ Point aRet;
+ if( rDoc.GetRootFrm() )
+ switch( rAnch.GetAnchorId() )
+ {
+ case FLY_AS_CHAR:
+ if( pFlyFmt && rAnch.GetCntntAnchor() )
+ {
+ const SwFrm* pOld = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aRet, FALSE );
+ if( pOld )
+ aRet = pOld->Frm().Pos();
+ }
+ break;
+
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR: // LAYER_IMPL
+ if( rAnch.GetCntntAnchor() )
+ {
+ const SwPosition *pPos = rAnch.GetCntntAnchor();
+ const SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode();
+ const SwFrm* pOld = pNd ? pNd->GetFrm( &aRet, 0, FALSE ) : 0;
+ if( pOld )
+ aRet = pOld->Frm().Pos();
+ }
+ break;
+
+ case FLY_AT_FLY: // LAYER_IMPL
+ if( rAnch.GetCntntAnchor() )
+ {
+ const SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)rAnch.GetCntntAnchor()->
+ nNode.GetNode().GetFlyFmt();
+ const SwFrm* pOld = pFmt ? pFmt->GetFrm( &aRet, FALSE ) : 0;
+ if( pOld )
+ aRet = pOld->Frm().Pos();
+ }
+ break;
+
+ case FLY_AT_PAGE:
+ {
+ USHORT nPgNum = rAnch.GetPageNum();
+ const SwPageFrm *pPage = (SwPageFrm*)rDoc.GetRootFrm()->Lower();
+ for( USHORT i = 1; (i <= nPgNum) && pPage; ++i,
+ pPage = (const SwPageFrm*)pPage->GetNext() )
+ if( i == nPgNum )
+ {
+ aRet = pPage->Frm().Pos();
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return aRet;
+}
+
+#define MAKEFRMS 0
+#define IGNOREANCHOR 1
+#define DONTMAKEFRMS 2
+
+sal_Int8 SwDoc::SetFlyFrmAnchor( SwFrmFmt& rFmt, SfxItemSet& rSet, BOOL bNewFrms )
+{
+ //Ankerwechsel sind fast immer in alle 'Richtungen' erlaubt.
+ //Ausnahme: Absatz- bzw. Zeichengebundene Rahmen duerfen wenn sie in
+ //Kopf-/Fusszeilen stehen nicht Seitengebunden werden.
+ const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
+ const RndStdIds nOld = rOldAnch.GetAnchorId();
+
+ SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
+ RndStdIds nNew = aNewAnch.GetAnchorId();
+
+ // ist der neue ein gueltiger Anker?
+ if( !aNewAnch.GetCntntAnchor() && (FLY_AT_FLY == nNew ||
+ (FLY_AT_PARA == nNew) || (FLY_AS_CHAR == nNew) ||
+ (FLY_AT_CHAR == nNew) ))
+ {
+ return IGNOREANCHOR;
+ }
+
+ if( nOld == nNew )
+ return DONTMAKEFRMS;
+
+
+ Point aOldAnchorPos( ::lcl_FindAnchorLayPos( *this, rOldAnch, &rFmt ));
+ Point aNewAnchorPos( ::lcl_FindAnchorLayPos( *this, aNewAnch, 0 ));
+
+ //Die alten Frms vernichten. Dabei werden die Views implizit gehidet und
+ //doppeltes hiden waere so eine art Show!
+ rFmt.DelFrms();
+
+ if ( FLY_AS_CHAR == nOld )
+ {
+ //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
+ //werden. Leider reisst dies neben den Frms auch noch das Format mit
+ //in sein Grab. Um dass zu unterbinden loesen wir vorher die
+ //Verbindung zwischen Attribut und Format.
+ const SwPosition *pPos = rOldAnch.GetCntntAnchor();
+ SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
+ ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
+ const xub_StrLen nIdx = pPos->nContent.GetIndex();
+ SwTxtAttr * const pHnt =
+ pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
+ ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
+ "Missing FlyInCnt-Hint." );
+ ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == &rFmt,
+ "Wrong TxtFlyCnt-Hint." );
+ const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
+
+ //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
+ //werden.
+ pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
+ }
+
+ //Endlich kann das Attribut gesetzt werden. Es muss das erste Attribut
+ //sein; Undo depends on it!
+ rFmt.SetFmtAttr( aNewAnch );
+
+ //Positionskorrekturen
+ const SfxPoolItem* pItem;
+ switch( nNew )
+ {
+ case FLY_AS_CHAR:
+ //Wenn keine Positionsattribute hereinkommen, dann muss dafuer
+ //gesorgt werden, das keine unerlaubte automatische Ausrichtung
+ //bleibt.
+ {
+ const SwPosition *pPos = aNewAnch.GetCntntAnchor();
+ SwTxtNode *pNd = pPos->nNode.GetNode().GetTxtNode();
+ ASSERT( pNd, "Crsr steht nicht auf TxtNode." );
+
+ SwFmtFlyCnt aFmt( static_cast<SwFlyFrmFmt*>(&rFmt) );
+ pNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
+ }
+
+ if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, FALSE, &pItem ))
+ {
+ SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
+ BOOL bSet = TRUE;
+ switch( aOldV.GetVertOrient() )
+ {
+ case text::VertOrientation::LINE_TOP: aOldV.SetVertOrient( text::VertOrientation::TOP ); break;
+ case text::VertOrientation::LINE_CENTER: aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
+ case text::VertOrientation::LINE_BOTTOM: aOldV.SetVertOrient( text::VertOrientation::BOTTOM); break;
+ case text::VertOrientation::NONE: aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
+ default:
+ bSet = FALSE;
+ }
+ if( bSet )
+ rSet.Put( aOldV );
+ }
+ break;
+
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR: // LAYER_IMPL
+ case FLY_AT_FLY: // LAYER_IMPL
+ case FLY_AT_PAGE:
+ {
+ //Wenn keine Positionsattribute hereinschneien korrigieren wir
+ //die Position so, dass die Dokumentkoordinaten des Flys erhalten
+ //bleiben.
+ //Chg: Wenn sich in den Positionsattributen lediglich die
+ //Ausrichtung veraendert (text::RelOrientation::FRAME vs. text::RelOrientation::PRTAREA), dann wird die
+ //Position ebenfalls korrigiert.
+ if( SFX_ITEM_SET != rSet.GetItemState( RES_HORI_ORIENT, FALSE, &pItem ))
+ pItem = 0;
+
+ SwFmtHoriOrient aOldH( rFmt.GetHoriOrient() );
+
+ if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pItem ||
+ aOldH.GetPos() == ((SwFmtHoriOrient*)pItem)->GetPos() ))
+ {
+ SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldH.GetPos();
+ nPos += aOldAnchorPos.X() - aNewAnchorPos.X();
+
+ if( pItem )
+ {
+ SwFmtHoriOrient* pH = (SwFmtHoriOrient*)pItem;
+ aOldH.SetHoriOrient( pH->GetHoriOrient() );
+ aOldH.SetRelationOrient( pH->GetRelationOrient() );
+ }
+ aOldH.SetPos( nPos );
+ rSet.Put( aOldH );
+ }
+
+ if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, FALSE, &pItem ))
+ pItem = 0;
+ SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
+
+ // OD 2004-05-14 #i28922# - correction: compare <aOldV.GetVertOrient()
+ // with <text::VertOrientation::NONE>
+ if( text::VertOrientation::NONE == aOldV.GetVertOrient() && (!pItem ||
+ aOldV.GetPos() == ((SwFmtVertOrient*)pItem)->GetPos() ) )
+ {
+ SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldV.GetPos();
+ nPos += aOldAnchorPos.Y() - aNewAnchorPos.Y();
+ if( pItem )
+ {
+ SwFmtVertOrient* pV = (SwFmtVertOrient*)pItem;
+ aOldV.SetVertOrient( pV->GetVertOrient() );
+ aOldV.SetRelationOrient( pV->GetRelationOrient() );
+ }
+ aOldV.SetPos( nPos );
+ rSet.Put( aOldV );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( bNewFrms )
+ rFmt.MakeFrms();
+
+ return MAKEFRMS;
+}
+
+BOOL SwDoc::SetFlyFrmAttr( SwFrmFmt& rFlyFmt, SfxItemSet& rSet )
+{
+ if( !rSet.Count() )
+ return FALSE;
+
+ ::std::auto_ptr<SwUndoFmtAttrHelper> pSaveUndo;
+ const bool bDoesUndo = DoesUndo();
+
+ if( DoesUndo() )
+ {
+ ClearRedo();
+ pSaveUndo.reset( new SwUndoFmtAttrHelper( rFlyFmt ) );
+ // --> FME 2004-10-13 #i32968#
+ // Inserting columns in the frame causes MakeFrmFmt to put two
+ // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
+ DoUndo( FALSE );
+ // <--
+ }
+
+ //Ist das Ankerattribut dabei? Falls ja ueberlassen wir die Verarbeitung
+ //desselben einer Spezialmethode. Sie Returnt TRUE wenn der Fly neu
+ //erzeugt werden muss (z.B. weil ein Wechsel des FlyTyps vorliegt).
+ sal_Int8 nMakeFrms = SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, FALSE )?
+ SetFlyFrmAnchor( rFlyFmt, rSet, FALSE ) : DONTMAKEFRMS;
+
+ const SfxPoolItem* pItem;
+ SfxItemIter aIter( rSet );
+ SfxItemSet aTmpSet( GetAttrPool(), aFrmFmtSetRange );
+ USHORT nWhich = aIter.GetCurItem()->Which();
+ do {
+ switch( nWhich )
+ {
+ case RES_FILL_ORDER:
+ case RES_BREAK:
+ case RES_PAGEDESC:
+ case RES_CNTNT:
+ case RES_FOOTER:
+ ASSERT( !this, ":-) Unbekanntes Attribut fuer Fly." );
+ // kein break;
+ case RES_CHAIN:
+ rSet.ClearItem( nWhich );
+ break;
+ case RES_ANCHOR:
+ if( DONTMAKEFRMS != nMakeFrms )
+ break;
+
+ default:
+ if( !IsInvalidItem( aIter.GetCurItem() ) && ( SFX_ITEM_SET !=
+ rFlyFmt.GetAttrSet().GetItemState( nWhich, TRUE, &pItem ) ||
+ *pItem != *aIter.GetCurItem() ))
+ aTmpSet.Put( *aIter.GetCurItem() );
+ break;
+ }
+
+ if( aIter.IsAtEnd() )
+ break;
+
+ } while( 0 != ( nWhich = aIter.NextItem()->Which() ) );
+
+ if( aTmpSet.Count() )
+ rFlyFmt.SetFmtAttr( aTmpSet );
+
+ if( MAKEFRMS == nMakeFrms )
+ rFlyFmt.MakeFrms();
+
+ if ( pSaveUndo.get() )
+ {
+ // --> FME 2004-10-13 #i32968#
+ DoUndo( bDoesUndo );
+ // <--
+
+ if ( pSaveUndo->GetUndo() )
+ {
+ AppendUndo( pSaveUndo->ReleaseUndo() );
+ }
+ }
+
+ SetModified();
+
+ return aTmpSet.Count() || MAKEFRMS == nMakeFrms;
+}
+
+// --> OD 2009-07-20 #i73249#
+void SwDoc::SetFlyFrmTitle( SwFlyFrmFmt& rFlyFrmFmt,
+ const String& sNewTitle )
+{
+ if ( rFlyFrmFmt.GetObjTitle() == sNewTitle )
+ {
+ return;
+ }
+
+ const bool bFormerIsNoDrawUndoObj( IsNoDrawUndoObj() );
+ SetNoDrawUndoObj( true );
+
+ if ( DoesUndo() )
+ {
+ ClearRedo();
+ AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
+ UNDO_FLYFRMFMT_TITLE,
+ rFlyFrmFmt.GetObjTitle(),
+ sNewTitle ) );
+ }
+
+ rFlyFrmFmt.SetObjTitle( sNewTitle, true );
+
+ SetNoDrawUndoObj( bFormerIsNoDrawUndoObj );
+
+ SetModified();
+}
+
+void SwDoc::SetFlyFrmDescription( SwFlyFrmFmt& rFlyFrmFmt,
+ const String& sNewDescription )
+{
+ if ( rFlyFrmFmt.GetObjDescription() == sNewDescription )
+ {
+ return;
+ }
+
+ const bool bFormerIsNoDrawUndoObj( IsNoDrawUndoObj() );
+ SetNoDrawUndoObj( true );
+
+ if ( DoesUndo() )
+ {
+ ClearRedo();
+ AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
+ UNDO_FLYFRMFMT_DESCRIPTION,
+ rFlyFrmFmt.GetObjDescription(),
+ sNewDescription ) );
+ }
+
+ rFlyFrmFmt.SetObjDescription( sNewDescription, true );
+
+ SetNoDrawUndoObj( bFormerIsNoDrawUndoObj );
+
+ SetModified();
+}
+// <--
+
+/***************************************************************************
+ * Methode : BOOL SwDoc::SetFrmFmtToFly( SwFlyFrm&, SwFrmFmt& )
+ * Beschreibung:
+ * Erstellt : OK 14.04.94 15:40
+ * Aenderung : JP 23.04.98
+ ***************************************************************************/
+
+BOOL SwDoc::SetFrmFmtToFly( SwFrmFmt& rFmt, SwFrmFmt& rNewFmt,
+ SfxItemSet* pSet, BOOL bKeepOrient )
+{
+ BOOL bChgAnchor = FALSE, bFrmSz = FALSE;
+
+ const SwFmtFrmSize aFrmSz( rFmt.GetFrmSize() );
+ const SwFmtVertOrient aVert( rFmt.GetVertOrient() );
+ const SwFmtHoriOrient aHori( rFmt.GetHoriOrient() );
+
+ SwUndoSetFlyFmt* pUndo = 0;
+ if( DoesUndo() )
+ {
+ ClearRedo();
+ AppendUndo( pUndo = new SwUndoSetFlyFmt( rFmt, rNewFmt ) );
+ // --> FME 2004-10-13 #i32968#
+ // Inserting columns in the section causes MakeFrmFmt to put two
+ // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
+ DoUndo( FALSE );
+ // <--
+ }
+
+ //Erstmal die Spalten setzen, sonst gibts nix als Aerger mit dem
+ //Set/Reset/Abgleich usw.
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET != rNewFmt.GetAttrSet().GetItemState( RES_COL ))
+ rFmt.ResetFmtAttr( RES_COL );
+
+ if( rFmt.DerivedFrom() != &rNewFmt )
+ {
+ rFmt.SetDerivedFrom( &rNewFmt );
+
+ // 1. wenn nicht automatisch -> ignorieren, sonst -> wech
+ // 2. wech damit, MB!
+ if( SFX_ITEM_SET == rNewFmt.GetAttrSet().GetItemState( RES_FRM_SIZE, FALSE ))
+ {
+ rFmt.ResetFmtAttr( RES_FRM_SIZE );
+ bFrmSz = TRUE;
+ }
+
+ const SfxItemSet* pAsk = pSet;
+ if( !pAsk ) pAsk = &rNewFmt.GetAttrSet();
+ if( SFX_ITEM_SET == pAsk->GetItemState( RES_ANCHOR, FALSE, &pItem )
+ && ((SwFmtAnchor*)pItem)->GetAnchorId() !=
+ rFmt.GetAnchor().GetAnchorId() )
+ {
+ if( pSet )
+ bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, *pSet, FALSE );
+ else
+ {
+ //JP 23.04.98: muss den FlyFmt-Range haben, denn im SetFlyFrmAnchor
+ // werden Attribute in diesen gesetzt!
+ SfxItemSet aFlySet( *rNewFmt.GetAttrSet().GetPool(),
+ rNewFmt.GetAttrSet().GetRanges() );
+ aFlySet.Put( *pItem );
+ bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, aFlySet, FALSE);
+ }
+ }
+ }
+
+ //Hori und Vert nur dann resetten, wenn in der Vorlage eine
+ //automatische Ausrichtung eingestellt ist, anderfalls den alten Wert
+ //wieder hineinstopfen.
+ //JP 09.06.98: beim Update der RahmenVorlage sollte der Fly NICHT
+ // seine Orientierng verlieren (diese wird nicht geupdatet!)
+ //OS: #96584# text::HoriOrientation::NONE and text::VertOrientation::NONE are allowed now
+ if (!bKeepOrient)
+ {
+ rFmt.ResetFmtAttr(RES_VERT_ORIENT);
+ rFmt.ResetFmtAttr(RES_HORI_ORIENT);
+ }
+
+ rFmt.ResetFmtAttr( RES_PRINT, RES_SURROUND );
+ rFmt.ResetFmtAttr( RES_LR_SPACE, RES_UL_SPACE );
+ rFmt.ResetFmtAttr( RES_BACKGROUND, RES_COL );
+ rFmt.ResetFmtAttr( RES_URL, RES_EDIT_IN_READONLY );
+
+ if( !bFrmSz )
+ rFmt.SetFmtAttr( aFrmSz );
+
+ if( bChgAnchor )
+ rFmt.MakeFrms();
+
+ if( pUndo )
+ rFmt.Remove( pUndo );
+
+ SetModified();
+
+ // --> FME 2004-10-13 #i32968#
+ if ( pUndo )
+ DoUndo( TRUE );
+ // <--
+
+ return bChgAnchor;
+}
+
+void SwDoc::GetGrfNms( const SwFlyFrmFmt& rFmt, String* pGrfName,
+ String* pFltName ) const
+{
+ SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 );
+ const SwGrfNode* pGrfNd = aIdx.GetNode().GetGrfNode();
+ if( pGrfNd && pGrfNd->IsLinkedFile() )
+ pGrfNd->GetFileFilterNms( pGrfName, pFltName );
+}
+
+/*************************************************************************
+|*
+|* SwDoc::ChgAnchor()
+|*
+|* Ersterstellung MA 10. Jan. 95
+|* Letzte Aenderung JP 08.07.98
+|*
+*************************************************************************/
+
+sal_Bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
+ RndStdIds _eAnchorType,
+ const sal_Bool _bSameOnly,
+ const sal_Bool _bPosCorr )
+{
+ ASSERT( GetRootFrm(), "Ohne Layout geht gar nichts" );
+
+ if ( !_rMrkList.GetMarkCount() ||
+ _rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
+ {
+ return false;
+ }
+
+ StartUndo( UNDO_INSATTR, NULL );
+
+ BOOL bUnmark = FALSE;
+ for ( USHORT i = 0; i < _rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject* pObj = _rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( !pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+
+ // OD 27.06.2003 #108784# - consider, that drawing object has
+ // no user call. E.g.: a 'virtual' drawing object is disconnected by
+ // the anchor type change of the 'master' drawing object.
+ // Continue with next selected object and assert, if this isn't excepted.
+ if ( !pContact )
+ {
+#ifdef DBG_UTIL
+ bool bNoUserCallExcepted =
+ pObj->ISA(SwDrawVirtObj) &&
+ !static_cast<SwDrawVirtObj*>(pObj)->IsConnected();
+ ASSERT( bNoUserCallExcepted, "SwDoc::ChgAnchor(..) - no contact at selected drawing object" );
+#endif
+ continue;
+ }
+
+ // OD 2004-03-29 #i26791#
+ const SwFrm* pOldAnchorFrm = pContact->GetAnchorFrm( pObj );
+ const SwFrm* pNewAnchorFrm = pOldAnchorFrm;
+
+ // --> OD 2006-03-01 #i54336#
+ // Instead of only keeping the index position for an as-character
+ // anchored object the complete <SwPosition> is kept, because the
+ // anchor index position could be moved, if the object again is
+ // anchored as character.
+// xub_StrLen nIndx = STRING_NOTFOUND;
+ const SwPosition* pOldAsCharAnchorPos( 0L );
+ const RndStdIds eOldAnchorType = pContact->GetAnchorId();
+ if ( !_bSameOnly && eOldAnchorType == FLY_AS_CHAR )
+ {
+ pOldAsCharAnchorPos = new SwPosition( pContact->GetCntntAnchor() );
+ }
+ // <--
+
+ if ( _bSameOnly )
+ _eAnchorType = eOldAnchorType;
+
+ SwFmtAnchor aNewAnch( _eAnchorType );
+ Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() );
+ const Point aPt( aObjRect.TopLeft() );
+
+ switch ( _eAnchorType )
+ {
+ case FLY_AT_PARA:
+ case FLY_AT_CHAR:
+ {
+ const Point aNewPoint = pOldAnchorFrm &&
+ ( pOldAnchorFrm->IsVertical() ||
+ pOldAnchorFrm->IsRightToLeft() )
+ ? aObjRect.TopRight()
+ : aPt;
+
+ // OD 18.06.2003 #108784# - allow drawing objects in header/footer
+ pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aNewPoint, false );
+ if ( pNewAnchorFrm->IsTxtFrm() && ((SwTxtFrm*)pNewAnchorFrm)->IsFollow() )
+ {
+ pNewAnchorFrm = ((SwTxtFrm*)pNewAnchorFrm)->FindMaster();
+ }
+ if ( pNewAnchorFrm->IsProtected() )
+ {
+ pNewAnchorFrm = 0;
+ }
+ else
+ {
+ SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
+ aNewAnch.SetType( _eAnchorType );
+ aNewAnch.SetAnchor( &aPos );
+ }
+ }
+ break;
+
+ case FLY_AT_FLY: // LAYER_IMPL
+ {
+ //Ausgehend von der linken oberen Ecke des Fly den
+ //dichtesten SwFlyFrm suchen.
+ SwFrm *pTxtFrm;
+ {
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ SwPosition aPos( GetNodes() );
+ Point aPoint( aPt );
+ aPoint.X() -= 1;
+ GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
+ // OD 20.06.2003 #108784# - consider that drawing objects
+ // can be in header/footer. Thus, <GetFrm()> by left-top-corner
+ pTxtFrm = aPos.nNode.GetNode().
+ GetCntntNode()->GetFrm( &aPt, 0, FALSE );
+ }
+ const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aPt );
+ pNewAnchorFrm = pTmp->FindFlyFrm();
+ if( pNewAnchorFrm && !pNewAnchorFrm->IsProtected() )
+ {
+ const SwFrmFmt *pTmpFmt = ((SwFlyFrm*)pNewAnchorFrm)->GetFmt();
+ const SwFmtCntnt& rCntnt = pTmpFmt->GetCntnt();
+ SwPosition aPos( *rCntnt.GetCntntIdx() );
+ aNewAnch.SetAnchor( &aPos );
+ break;
+ }
+
+ aNewAnch.SetType( FLY_AT_PAGE );
+ // no break
+ }
+ case FLY_AT_PAGE:
+ {
+ pNewAnchorFrm = GetRootFrm()->Lower();
+ while ( pNewAnchorFrm && !pNewAnchorFrm->Frm().IsInside( aPt ) )
+ pNewAnchorFrm = pNewAnchorFrm->GetNext();
+ if ( !pNewAnchorFrm )
+ continue;
+
+ aNewAnch.SetPageNum( ((SwPageFrm*)pNewAnchorFrm)->GetPhyPageNum());
+ }
+ break;
+ case FLY_AS_CHAR:
+ if( _bSameOnly ) // Positions/Groessenaenderung
+ {
+ if( !pOldAnchorFrm )
+ {
+ pContact->ConnectToLayout();
+ pOldAnchorFrm = pContact->GetAnchorFrm();
+ }
+ ((SwTxtFrm*)pOldAnchorFrm)->Prepare();
+ }
+ else // Ankerwechsel
+ {
+ // OD 18.06.2003 #108784# - allow drawing objects in header/footer
+ pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aPt, false );
+ if( pNewAnchorFrm->IsProtected() )
+ {
+ pNewAnchorFrm = 0;
+ break;
+ }
+
+ bUnmark = ( 0 != i );
+ Point aPoint( aPt );
+ aPoint.X() -= 1; // nicht im DrawObj landen!!
+ aNewAnch.SetType( FLY_AS_CHAR );
+ SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
+ if ( pNewAnchorFrm->Frm().IsInside( aPoint ) )
+ {
+ // es muss ein TextNode gefunden werden, denn nur dort
+ // ist ein inhaltsgebundenes DrawObjekt zu verankern
+ SwCrsrMoveState aState( MV_SETONLYTEXT );
+ GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
+ }
+ else
+ {
+ SwCntntNode &rCNd = (SwCntntNode&)
+ *((SwCntntFrm*)pNewAnchorFrm)->GetNode();
+ if ( pNewAnchorFrm->Frm().Bottom() < aPt.Y() )
+ rCNd.MakeStartIndex( &aPos.nContent );
+ else
+ rCNd.MakeEndIndex( &aPos.nContent );
+ }
+ aNewAnch.SetAnchor( &aPos );
+ SetAttr( aNewAnch, *pContact->GetFmt() );
+ // OD 2004-04-13 #i26791# - adjust vertical positioning to
+ // 'center to baseline'
+ SetAttr( SwFmtVertOrient( 0, text::VertOrientation::CENTER, text::RelOrientation::FRAME ), *pContact->GetFmt() );
+ SwTxtNode *pNd = aPos.nNode.GetNode().GetTxtNode();
+ ASSERT( pNd, "Cursor not positioned at TxtNode." );
+
+ SwFmtFlyCnt aFmt( pContact->GetFmt() );
+ pNd->InsertItem( aFmt, aPos.nContent.GetIndex(), 0 );
+ }
+ break;
+ default:
+ ASSERT( !this, "unexpected AnchorId." );
+ }
+
+ if ( (FLY_AS_CHAR != _eAnchorType) &&
+ pNewAnchorFrm &&
+ ( !_bSameOnly || pNewAnchorFrm != pOldAnchorFrm ) )
+ {
+ // OD 2004-04-06 #i26791# - Direct object positioning no longer
+ // needed. Apply of attributes (method call <SetAttr(..)>) takes
+ // care of the invalidation of the object position.
+ SetAttr( aNewAnch, *pContact->GetFmt() );
+ if ( _bPosCorr )
+ {
+ // --> OD 2004-08-24 #i33313# - consider not connected
+ // 'virtual' drawing objects
+ if ( pObj->ISA(SwDrawVirtObj) &&
+ !static_cast<SwDrawVirtObj*>(pObj)->IsConnected() )
+ {
+ SwRect aNewObjRect( aObjRect );
+ static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( 0L ))
+ ->AdjustPositioningAttr( pNewAnchorFrm,
+ &aNewObjRect );
+
+ }
+ else
+ {
+ static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ))
+ ->AdjustPositioningAttr( pNewAnchorFrm );
+ }
+ }
+ }
+
+ // --> OD 2006-03-01 #i54336#
+ if ( pNewAnchorFrm && pOldAsCharAnchorPos )
+ {
+ //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
+ //werden. Leider reisst dies neben den Frms auch noch das Format mit
+ //in sein Grab. Um dass zu unterbinden loesen wir vorher die
+ //Verbindung zwischen Attribut und Format.
+ const xub_StrLen nIndx( pOldAsCharAnchorPos->nContent.GetIndex() );
+ SwTxtNode* pTxtNode( pOldAsCharAnchorPos->nNode.GetNode().GetTxtNode() );
+ ASSERT( pTxtNode, "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object" );
+ ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
+ SwTxtAttr * const pHnt =
+ pTxtNode->GetTxtAttrForCharAt( nIndx, RES_TXTATR_FLYCNT );
+ const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
+
+ //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
+ //werden.
+ pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIndx, nIndx );
+ delete pOldAsCharAnchorPos;
+ }
+ // <--
+ }
+ }
+
+ EndUndo( UNDO_END, NULL );
+ SetModified();
+
+ return bUnmark;
+}
+
+
+/* -----------------23.07.98 13:56-------------------
+ *
+ * --------------------------------------------------*/
+int SwDoc::Chainable( const SwFrmFmt &rSource, const SwFrmFmt &rDest )
+{
+ //Die Source darf noch keinen Follow haben.
+ const SwFmtChain &rOldChain = rSource.GetChain();
+ if ( rOldChain.GetNext() )
+ return SW_CHAIN_SOURCE_CHAINED;
+
+ //Ziel darf natuerlich nicht gleich Source sein und es
+ //darf keine geschlossene Kette entstehen.
+ const SwFrmFmt *pFmt = &rDest;
+ do {
+ if( pFmt == &rSource )
+ return SW_CHAIN_SELF;
+ pFmt = pFmt->GetChain().GetNext();
+ } while ( pFmt );
+
+ //Auch eine Verkettung von Innen nach aussen oder von aussen
+ //nach innen ist nicht zulaessig.
+ if( rDest.IsLowerOf( rSource ) || rSource .IsLowerOf( rDest ) )
+ return SW_CHAIN_SELF;
+
+ //Das Ziel darf noch keinen Master haben.
+ const SwFmtChain &rChain = rDest.GetChain();
+ if( rChain.GetPrev() )
+ return SW_CHAIN_IS_IN_CHAIN;
+
+ //Das Ziel muss leer sein.
+ const SwNodeIndex* pCntIdx = rDest.GetCntnt().GetCntntIdx();
+ if( !pCntIdx )
+ return SW_CHAIN_NOT_FOUND;
+
+ SwNodeIndex aNxtIdx( *pCntIdx, 1 );
+ const SwTxtNode* pTxtNd = aNxtIdx.GetNode().GetTxtNode();
+ if( !pTxtNd )
+ return SW_CHAIN_NOT_FOUND;
+
+ const ULONG nFlySttNd = pCntIdx->GetIndex();
+ if( 2 != ( pCntIdx->GetNode().EndOfSectionIndex() - nFlySttNd ) ||
+ pTxtNd->GetTxt().Len() )
+ return SW_CHAIN_NOT_EMPTY;
+
+ USHORT nArrLen = GetSpzFrmFmts()->Count();
+ for( USHORT n = 0; n < nArrLen; ++n )
+ {
+ const SwFmtAnchor& rAnchor = (*GetSpzFrmFmts())[ n ]->GetAnchor();
+ ULONG nTstSttNd;
+ // OD 11.12.2003 #i20622# - to-frame anchored objects are allowed.
+ if ( ((rAnchor.GetAnchorId() == FLY_AT_PARA) ||
+ (rAnchor.GetAnchorId() == FLY_AT_CHAR)) &&
+ 0 != rAnchor.GetCntntAnchor() &&
+ nFlySttNd <= ( nTstSttNd =
+ rAnchor.GetCntntAnchor()->nNode.GetIndex() ) &&
+ nTstSttNd < nFlySttNd + 2 )
+ {
+ return SW_CHAIN_NOT_EMPTY;
+ }
+ }
+
+ //Auf die richtige Area muessen wir auch noch einen Blick werfen.
+ //Beide Flys muessen im selben Bereich (Body, Head/Foot, Fly) sitzen
+ //Wenn die Source nicht der selektierte Rahmen ist, so reicht es
+ //Wenn ein passender gefunden wird (Der Wunsch kann z.B. von der API
+ //kommen).
+
+ // both in the same fly, header, footer or on the page?
+ const SwFmtAnchor &rSrcAnchor = rSource.GetAnchor(),
+ &rDstAnchor = rDest.GetAnchor();
+ ULONG nEndOfExtras = GetNodes().GetEndOfExtras().GetIndex();
+ BOOL bAllowed = FALSE;
+ if ( FLY_AT_PAGE == rSrcAnchor.GetAnchorId() )
+ {
+ if ( (FLY_AT_PAGE == rDstAnchor.GetAnchorId()) ||
+ ( rDstAnchor.GetCntntAnchor() &&
+ rDstAnchor.GetCntntAnchor()->nNode.GetIndex() > nEndOfExtras ))
+ bAllowed = TRUE;
+ }
+ else if( rSrcAnchor.GetCntntAnchor() && rDstAnchor.GetCntntAnchor() )
+ {
+ const SwNodeIndex &rSrcIdx = rSrcAnchor.GetCntntAnchor()->nNode,
+ &rDstIdx = rDstAnchor.GetCntntAnchor()->nNode;
+ const SwStartNode* pSttNd = 0;
+ if( rSrcIdx == rDstIdx ||
+ ( !pSttNd &&
+ 0 != ( pSttNd = rSrcIdx.GetNode().FindFlyStartNode() ) &&
+ pSttNd == rDstIdx.GetNode().FindFlyStartNode() ) ||
+ ( !pSttNd &&
+ 0 != ( pSttNd = rSrcIdx.GetNode().FindFooterStartNode() ) &&
+ pSttNd == rDstIdx.GetNode().FindFooterStartNode() ) ||
+ ( !pSttNd &&
+ 0 != ( pSttNd = rSrcIdx.GetNode().FindHeaderStartNode() ) &&
+ pSttNd == rDstIdx.GetNode().FindHeaderStartNode() ) ||
+ ( !pSttNd && rDstIdx.GetIndex() > nEndOfExtras &&
+ rSrcIdx.GetIndex() > nEndOfExtras ))
+ bAllowed = TRUE;
+ }
+
+ return bAllowed ? SW_CHAIN_OK : SW_CHAIN_WRONG_AREA;
+}
+/* -----------------23.07.98 13:56-------------------
+ *
+ * --------------------------------------------------*/
+int SwDoc::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
+{
+ int nErr = Chainable( rSource, rDest );
+ if ( !nErr )
+ {
+ StartUndo( UNDO_CHAINE, NULL );
+
+ SwFlyFrmFmt& rDestFmt = (SwFlyFrmFmt&)rDest;
+
+ //Follow an den Master haengen.
+ SwFmtChain aChain = rDestFmt.GetChain();
+ aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
+ SetAttr( aChain, rDestFmt );
+
+ SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_CHAIN, RES_CHAIN, 0 );
+
+ //Follow an den Master haengen.
+ aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
+ SetAttr( aChain, rDestFmt );
+
+ //Master an den Follow haengen und dafuer sorgen, dass der Master
+ //eine fixierte Hoehe hat.
+ aChain = rSource.GetChain();
+ aChain.SetNext( &rDestFmt );
+ aSet.Put( aChain );
+
+ SwFmtFrmSize aSize( rSource.GetFrmSize() );
+ if ( aSize.GetHeightSizeType() != ATT_FIX_SIZE )
+ {
+ SwClientIter aIter( rSource );
+ SwFlyFrm *pFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm) );
+ if ( pFly )
+ aSize.SetHeight( pFly->Frm().Height() );
+ aSize.SetHeightSizeType( ATT_FIX_SIZE );
+ aSet.Put( aSize );
+ }
+ SetAttr( aSet, rSource );
+
+ EndUndo( UNDO_CHAINE, NULL );
+ }
+ return nErr;
+}
+/* -----------------23.07.98 13:56-------------------
+ *
+ * --------------------------------------------------*/
+void SwDoc::Unchain( SwFrmFmt &rFmt )
+{
+ SwFmtChain aChain( rFmt.GetChain() );
+ if ( aChain.GetNext() )
+ {
+ StartUndo( UNDO_UNCHAIN, NULL );
+ SwFrmFmt *pFollow = aChain.GetNext();
+ aChain.SetNext( 0 );
+ SetAttr( aChain, rFmt );
+ aChain = pFollow->GetChain();
+ aChain.SetPrev( 0 );
+ SetAttr( aChain, *pFollow );
+ EndUndo( UNDO_UNCHAIN, NULL );
+ }
+}
+
+
+