update dev300-m58
[ooovba.git] / sw / source / core / txtnode / atrflyin.cxx
blobe9f1debf1656a92eb4f2c405da0a9e220ce1a9b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: atrflyin.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
36 #include "hintids.hxx"
37 #include "cntfrm.hxx" // _GetFly
38 #include "doc.hxx"
39 #include "pam.hxx" // fuer SwTxtFlyCnt
40 #include "flyfrm.hxx" // fuer SwTxtFlyCnt
41 #include "ndtxt.hxx" // SwFlyFrmFmt
42 #include "frmfmt.hxx" // SwFlyFrmFmt
43 #include <fmtflcnt.hxx>
44 #include <txtflcnt.hxx>
45 #include <fmtanchr.hxx>
46 #include "swfont.hxx"
47 #include "txtfrm.hxx"
48 #include "flyfrms.hxx"
49 // --> OD 2004-11-09 #i26945#
50 #include <objectformatter.hxx>
51 // <--
53 SwFmtFlyCnt::SwFmtFlyCnt( SwFrmFmt *pFrmFmt )
54 : SfxPoolItem( RES_TXTATR_FLYCNT ),
55 pTxtAttr( 0 ),
56 pFmt( pFrmFmt )
60 int __EXPORT SwFmtFlyCnt::operator==( const SfxPoolItem& rAttr ) const
62 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
63 return( pTxtAttr && ((SwFmtFlyCnt&)rAttr).pTxtAttr &&
64 *pTxtAttr->GetStart() == *((SwFmtFlyCnt&)rAttr).pTxtAttr->GetStart() &&
65 pFmt == ((SwFmtFlyCnt&)rAttr).GetFrmFmt() );
68 SfxPoolItem* __EXPORT SwFmtFlyCnt::Clone( SfxItemPool* ) const
70 return new SwFmtFlyCnt( pFmt );
73 SwTxtFlyCnt::SwTxtFlyCnt( SwFmtFlyCnt& rAttr, xub_StrLen nStartPos )
74 : SwTxtAttr( rAttr, nStartPos )
76 rAttr.pTxtAttr = this;
81 /*************************************************************************
82 * SwTxtFlyCnt::MakeTxtHint()
84 * An dieser Stelle soll einmal der Gesamtzusammenhang bei der Erzeugung
85 * eines neuen SwTxtFlyCnt erlaeutert werden.
86 * Das MakeTxtHint() wird z.B. im SwTxtNode::Copy() gerufen.
87 * Fuer die komplette Verdopplung sind folgende Schritte notwendig:
88 * 1) Duplizieren des pFmt incl. Inhalt, Attributen etc.
89 * 2) Setzen des Ankers
90 * 3) Benachrichtigung
91 * Da fuer die Bewaeltigung der Aufgaben nicht immer alle Informationen
92 * bereitstehen und darueber hinaus bestimmte Methoden erst zu einem
93 * spaeteren Zeitpunkt gerufen werden duerfen (weil nocht nicht alle
94 * Nodeinformationen vorliegen), verteilt sich der Ablauf.
95 * ad 1) MakeTxtHint() wird durch den Aufruf von SwDoc::CopyLayout()
96 * der das neue FlyFrmFmt erzeugt und mit dem duplizierten Inhalt des
97 * FlyFrm verbunden.
98 * ad 2) SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das
99 * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt
100 * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt
101 * werden, da der Zielnode unbestimmt ist.
102 * ad 3) _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen
103 * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner
104 * gefunden, so wird ein neuer FlyFrm angelegt.
105 * Kritisch an diesem Vorgehen ist, dass das pCntnt->AppendFly() eine
106 * sofortige Neuformatierung von pCntnt anstoesst. Die Rekursion kommt
107 * allerdings durch den Lockmechanismus in SwTxtFrm::Format() nicht
108 * zu stande.
109 * Attraktiv ist der Umstand, dass niemand ueber die vom Node abhaengigen
110 * CntntFrms iterieren braucht, um die FlyInCntFrm anzulegen. Dies geschieht
111 * bei der Arbeit.
112 *************************************************************************/
114 void SwTxtFlyCnt::CopyFlyFmt( SwDoc* pDoc )
116 SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt();
117 ASSERT( pFmt, "von welchem Format soll ich eine Kopie erzeugen?" )
118 // Das FlyFrmFmt muss dupliziert werden.
119 // In CopyLayoutFmt (siehe doclay.cxx) wird das FlyFrmFmt erzeugt
120 // und der Inhalt dupliziert.
122 // fuers kopieren vom Attribut das Undo immer abschalten
123 BOOL bUndo = pDoc->DoesUndo();
124 pDoc->DoUndo( FALSE );
125 SwFmtAnchor aAnchor( pFmt->GetAnchor() );
126 if( FLY_PAGE != aAnchor.GetAnchorId() &&
127 pDoc != pFmt->GetDoc() ) // Unterschiedliche Docs?
129 // JP 03.06.96: dann sorge dafuer, das der koperierte Anker auf
130 // gueltigen Content zeigt! Die Umsetzung auf die
131 // richtige Position erfolgt spaeter.
132 SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), +2 );
133 SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
134 if( !pCNd )
135 pCNd = pDoc->GetNodes().GoNext( &aIdx );
137 SwPosition* pPos = (SwPosition*)aAnchor.GetCntntAnchor();
138 pPos->nNode = aIdx;
139 if( FLY_IN_CNTNT == aAnchor.GetAnchorId() )
140 pPos->nContent.Assign( pCNd, 0 );
141 else
143 pPos->nContent.Assign( 0, 0 );
144 ASSERT( !this, "CopyFlyFmt: Was fuer ein Anker?" );
148 SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, false, false );
149 pDoc->DoUndo( bUndo );
150 ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew );
153 /*************************************************************************
154 * SwTxtFlyCnt::SetAnchor()
156 * SetAnchor() wird von SwTxtNode::Insert() gerufen und sorgt fuer das
157 * setzen des Ankers (die SwPosition des Dummy-Zeichens wird dem FlyFrmFmt
158 * per SetAttr bekannt gegeben). Dies kann nicht im MakeTxtHint erledigt
159 * werden, da der Zielnode unbestimmt ist.
160 * (siehe Kommentar in SwTxtFlyCnt::MakeTxtHint)
161 *************************************************************************/
163 void SwTxtFlyCnt::SetAnchor( const SwTxtNode *pNode )
165 // fuers Undo muss der neue Anker schon bekannt sein !
167 // Wir ermitteln den Index im Nodesarray zum Node
169 SwDoc* pDoc = (SwDoc*)pNode->GetDoc();
171 SwIndex aIdx( (SwTxtNode*)pNode, *GetStart() );
172 SwPosition aPos( *pNode->StartOfSectionNode(), aIdx );
173 SwFrmFmt* pFmt = GetFlyCnt().GetFrmFmt();
174 SwFmtAnchor aAnchor( pFmt->GetAnchor() );
176 if( !aAnchor.GetCntntAnchor() ||
177 !aAnchor.GetCntntAnchor()->nNode.GetNode().GetNodes().IsDocNodes() ||
178 &aAnchor.GetCntntAnchor()->nNode.GetNode() != (SwNode*)pNode )
179 aPos.nNode = *pNode;
180 else
181 aPos.nNode = aAnchor.GetCntntAnchor()->nNode;
183 aAnchor.SetType( FLY_IN_CNTNT ); // defaulten !!
184 aAnchor.SetAnchor( &aPos );
186 // beim Ankerwechsel werden immer alle FlyFrms vom Attribut geloescht
187 // JP 25.04.95: wird innerhalb des SplitNodes die Frames verschoben
188 // koennen die Frames erhalten bleiben.
189 if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() )
190 && RES_DRAWFRMFMT != pFmt->Which() )
191 pFmt->DelFrms();
193 // stehen wir noch im falschen Dokument ?
194 if( pDoc != pFmt->GetDoc() )
196 // fuers kopieren vom Attribut das Undo immer abschalten
197 BOOL bUndo = pDoc->DoesUndo();
198 pDoc->DoUndo( FALSE );
199 SwFrmFmt* pNew = pDoc->CopyLayoutFmt( *pFmt, aAnchor, false, false );
200 pDoc->DoUndo( bUndo );
202 bUndo = pFmt->GetDoc()->DoesUndo();
203 pFmt->GetDoc()->DoUndo( FALSE );
204 pFmt->GetDoc()->DelLayoutFmt( pFmt );
205 pFmt->GetDoc()->DoUndo( bUndo );
206 ((SwFmtFlyCnt&)GetFlyCnt()).SetFlyFmt( pNew );
208 else if( pNode->GetpSwpHints() &&
209 pNode->GetpSwpHints()->IsInSplitNode() &&
210 RES_DRAWFRMFMT != pFmt->Which() )
212 pFmt->LockModify();
213 pFmt->SetFmtAttr( aAnchor ); // nur den Anker neu setzen
214 pFmt->UnlockModify();
216 else
217 pFmt->SetFmtAttr( aAnchor ); // nur den Anker neu setzen
219 // Am Node haengen u.a. abhaengige CntFrms.
220 // Fuer jeden CntFrm wird ein SwFlyInCntFrm angelegt.
223 /*************************************************************************
224 * SwTxtFlyCnt::_GetFlyFrm()
226 * _GetFlyFrm() wird im Formatierungsprozess vom LineIter gerufen
227 * und sucht den FlyFrm zum Dummyzeichen des aktuellen CntntFrm. Wird keiner
228 * gefunden, so wird ein neuer FlyFrm angelegt.
229 * (siehe Kommentar ind SwTxtFlyCnt::MakeTxtHint)
230 *************************************************************************/
232 SwFlyInCntFrm *SwTxtFlyCnt::_GetFlyFrm( const SwFrm *pCurrFrm )
234 SwFrmFmt* pFrmFmt = GetFlyCnt().GetFrmFmt();
235 if( RES_DRAWFRMFMT == pFrmFmt->Which() )
237 ASSERT( !this, "SwTxtFlyCnt::_GetFlyFrm: DrawInCnt-Baustelle!" );
238 return NULL;
241 SwClientIter aIter( *GetFlyCnt().pFmt );
242 ASSERT( pCurrFrm->IsTxtFrm(), "SwTxtFlyCnt::_GetFlyFrm for TxtFrms only." );
244 if( aIter.GoStart() )
246 SwTxtFrm *pFirst = (SwTxtFrm*)pCurrFrm;
247 while ( pFirst->IsFollow() )
248 pFirst = pFirst->FindMaster();
250 { SwFrm * pFrm = PTR_CAST( SwFrm, aIter() );
251 if ( pFrm )
253 SwTxtFrm *pTmp = pFirst;
255 { if( ( (SwFlyFrm*)pFrm )->GetAnchorFrm() == (SwFrm*) pTmp )
257 if ( pTmp != pCurrFrm )
259 pTmp->RemoveFly( (SwFlyFrm*)pFrm );
260 ((SwTxtFrm*)pCurrFrm)->AppendFly( (SwFlyFrm*)pFrm );
262 return (SwFlyInCntFrm*)pFrm;
264 pTmp = pTmp->GetFollow();
265 } while ( pTmp );
267 } while( aIter++ );
270 // Wir haben keinen passenden FlyFrm gefunden, deswegen wird ein
271 // neuer angelegt.
272 // Dabei wird eine sofortige Neuformatierung von pCurrFrm angestossen.
273 // Die Rekursion wird durch den Lockmechanismus in SwTxtFrm::Format()
274 // abgewuergt.
275 SwFlyInCntFrm *pFly = new SwFlyInCntFrm( (SwFlyFrmFmt*)pFrmFmt, (SwFrm*)pCurrFrm );
276 ((SwFrm*)pCurrFrm)->AppendFly( pFly );
277 pFly->RegistFlys();
279 // 7922: Wir muessen dafuer sorgen, dass der Inhalt des FlyInCnt
280 // nach seiner Konstruktion stramm durchformatiert wird.
281 // --> OD 2004-11-09 #i26945# - Use new object formatter to format Writer
282 // fly frame and its content.
283 SwObjectFormatter::FormatObj( *pFly, const_cast<SwFrm*>(pCurrFrm),
284 pCurrFrm->FindPageFrm() );
285 // <--
287 return pFly;