xref: /trunk/main/sw/source/core/frmedt/fefly1.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <hintids.hxx>
28 #include <svl/itemiter.hxx>
29 #include <svtools/imapobj.hxx>
30 #include <svtools/soerr.hxx>
31 #include <editeng/protitem.hxx>
32 #include <svx/svdogrp.hxx>
33 #include <svx/svdouno.hxx>
34 #include <svx/fmglob.hxx>
35 #include <com/sun/star/form/FormButtonType.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <fmtanchr.hxx>
38 #include <txtflcnt.hxx>
39 #include <fmtcntnt.hxx>
40 #include <fmtornt.hxx>
41 #include <fmtflcnt.hxx>
42 #include <fmturl.hxx>
43 #include <fmtclds.hxx>
44 #include <fmtfsize.hxx>
45 #include <docary.hxx>
46 #include <fesh.hxx>
47 #include <rootfrm.hxx>
48 #include <pagefrm.hxx>
49 #include <cntfrm.hxx>
50 #include <txtfrm.hxx>
51 #include <viewimp.hxx>
52 #include <viscrs.hxx>
53 #include <doc.hxx>
54 #include <IDocumentUndoRedo.hxx>
55 #include <dview.hxx>
56 #include <dflyobj.hxx>
57 #include <dcontact.hxx>
58 #include <frmfmt.hxx>
59 #include <flyfrm.hxx>
60 #include <ndtxt.hxx>
61 #include <edimp.hxx>
62 #include <swtable.hxx>
63 #include <mvsave.hxx>       // Strukturen zum Sichern beim Move/Delete
64 #include <ndgrf.hxx>
65 #include <flyfrms.hxx>
66 #include <flypos.hxx>
67 #include <fldbas.hxx>
68 #include <fmtfld.hxx>
69 #include <swundo.hxx>
70 #include <frame.hxx>
71 #include <notxtfrm.hxx>
72 // --> OD 2006-03-06 #125892#
73 #include <HandleAnchorNodeChg.hxx>
74 // <--
75 #include <frmatr.hxx>
76 // --> 3.7.2010 #i972#
77 #include <ndole.hxx>
78 // <--
79 // --> OD 2009-12-29 #i89920#
80 #include <fmtsrnd.hxx>
81 #include <editeng/opaqitem.hxx>
82 // <--
83 
84 using ::rtl::OUString;
85 using namespace ::com::sun::star;
86 
87 //Zum anmelden von Flys in Flys in ...
88 //definiert in layout/frmtool.cxx
89 void RegistFlys( SwPageFrm*, const SwLayoutFrm* );
90 
91 /***********************************************************************
92 #*  Class       :  SwDoc
93 #*  Methode     :  UseSpzLayoutFmt
94 #*  Beschreibung:  Anhand des Request werden zu dem Format entsprechende
95 #*      Aenderungen an den Spezifischen Layouts vorgenommen.
96 #*  Datum       :  MA 23. Sep. 92
97 #*  Update      :  JP 09.03.98
98 #***********************************************************************/
99 
100 sal_Bool lcl_SetNewFlyPos( const SwNode& rNode, SwFmtAnchor& rAnchor,
101                         const Point& rPt )
102 {
103     sal_Bool bRet = sal_False;
104     const SwStartNode* pStNode = rNode.FindFlyStartNode();
105     if( pStNode )
106     {
107         SwPosition aPos( *pStNode );
108         rAnchor.SetAnchor( &aPos );
109         bRet = sal_True;
110     }
111     else
112     {
113         const SwCntntNode *pCntNd = rNode.GetCntntNode();
114         const SwCntntFrm* pCFrm = pCntNd ? pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &rPt, 0, sal_False ) : 0;
115         const SwPageFrm *pPg = pCFrm ? pCFrm->FindPageFrm() : 0;
116 
117         rAnchor.SetPageNum( pPg ? pPg->GetPhyPageNum() : 1 );
118         rAnchor.SetType( FLY_AT_PAGE );
119     }
120     return bRet;
121 }
122 
123 sal_Bool lcl_FindAnchorPos(
124     SwEditShell& rEditShell,
125     SwDoc& rDoc,
126     const Point& rPt,
127     const SwFrm& rFrm,
128     SfxItemSet& rSet )
129 {
130     sal_Bool bRet = sal_True;
131     SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
132     RndStdIds nNew = aNewAnch.GetAnchorId();
133     const SwFrm *pNewAnch;
134 
135     //Neuen Anker ermitteln
136     Point aTmpPnt( rPt );
137     switch( nNew )
138     {
139     case FLY_AS_CHAR:  // sollte der nicht auch mit hinein?
140     case FLY_AT_PARA:
141     case FLY_AT_CHAR: // LAYER_IMPL
142         {
143             //Ausgehend von der linken oberen Ecke des Fly den
144             //dichtesten CntntFrm suchen.
145             const SwFrm* pFrm = rFrm.IsFlyFrm() ? ((SwFlyFrm&)rFrm).GetAnchorFrm()
146                                                 : &rFrm;
147             pNewAnch = ::FindAnchor( pFrm, aTmpPnt );
148             if( pNewAnch->IsProtected() )
149             {
150                 bRet = sal_False;
151                 break;
152             }
153 
154             SwPosition aPos( *((SwCntntFrm*)pNewAnch)->GetNode() );
155             if ((FLY_AT_CHAR == nNew) || (FLY_AS_CHAR == nNew))
156             {
157                 // es muss ein TextNode gefunden werden, denn nur in diesen
158                 // ist ein Inhaltsgebundene Frames zu verankern
159                 SwCrsrMoveState aState( MV_SETONLYTEXT );
160                 aTmpPnt.X() -= 1;                   //nicht im Fly landen!!
161                 if( !pNewAnch->GetCrsrOfst( &aPos, aTmpPnt, &aState ) )
162                 {
163                     SwCntntNode* pCNd = ((SwCntntFrm*)pNewAnch)->GetNode();
164                     if( pNewAnch->Frm().Bottom() < aTmpPnt.Y() )
165                         pCNd->MakeStartIndex( &aPos.nContent );
166                     else
167                         pCNd->MakeEndIndex( &aPos.nContent );
168                 }
169                 else
170                 {
171                     if ( rEditShell.PosInsideInputFld( aPos ) )
172                     {
173                         aPos.nContent = rEditShell.StartOfInputFldAtPos( aPos );
174                     }
175                 }
176             }
177             aNewAnch.SetAnchor( &aPos );
178         }
179         break;
180 
181     case FLY_AT_FLY: // LAYER_IMPL
182         {
183             //Ausgehend von der linken oberen Ecke des Fly den
184             //dichtesten SwFlyFrm suchen.
185             SwCrsrMoveState aState( MV_SETONLYTEXT );
186             SwPosition aPos( rDoc.GetNodes() );
187             aTmpPnt.X() -= 1;                   //nicht im Fly landen!!
188             rDoc.GetCurrentLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );    //swmod 071108//swmod 071225
189             pNewAnch = ::FindAnchor(
190                 aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( rFrm.getRootFrm(), 0, 0, sal_False ),
191                 aTmpPnt )->FindFlyFrm();
192 
193             if( pNewAnch && &rFrm != pNewAnch && !pNewAnch->IsProtected() )
194             {
195                 aPos.nNode = *((SwFlyFrm*)pNewAnch)->GetFmt()->GetCntnt().
196                                 GetCntntIdx();
197                 aNewAnch.SetAnchor( &aPos );
198                 break;
199             }
200         }
201 
202         aNewAnch.SetType( nNew = FLY_AT_PAGE );
203         // no break
204 
205     case FLY_AT_PAGE:
206         pNewAnch = rFrm.FindPageFrm();
207         aNewAnch.SetPageNum( pNewAnch->GetPhyPageNum() );
208         break;
209 
210     default:
211         ASSERT( !&rDoc, "Falsche ID fuer neuen Anker." );
212     }
213 
214     rSet.Put( aNewAnch );
215     return bRet;
216 }
217 
218 //
219 //! also used in unoframe.cxx
220 //
221 sal_Bool lcl_ChkAndSetNewAnchor(
222     SwEditShell& rEditShell,
223     const SwFlyFrm& rFly,
224     SfxItemSet& rSet )
225 {
226     const SwFrmFmt& rFmt = *rFly.GetFmt();
227     const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
228     const RndStdIds nOld = rOldAnch.GetAnchorId();
229 
230     RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
231 
232     if( nOld == nNew )
233         return sal_False;
234 
235     SwDoc* pDoc = (SwDoc*)rFmt.GetDoc();
236 
237 #ifdef DBG_UTIL
238     ASSERT( !(nNew == FLY_AT_PAGE &&
239         (FLY_AT_PARA==nOld || FLY_AT_CHAR==nOld || FLY_AS_CHAR==nOld ) &&
240         pDoc->IsInHeaderFooter( rOldAnch.GetCntntAnchor()->nNode )),
241             "Unerlaubter Ankerwechsel in Head/Foot." );
242 #endif
243 
244     return ::lcl_FindAnchorPos( rEditShell, *pDoc, rFly.Frm().Pos(), rFly, rSet );
245 }
246 
247 void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, sal_Bool bNew )
248 {
249     SET_CURR_SHELL( this );
250 
251     //  Wenn es ein neuer Rahmen ist, so soll er selektiert sein.
252     //  !!Rahmen immer selektieren, wenn sie nicht selektiert sind.
253     //  - Es kann ein neuer 'alter' sein weil der Anker gewechselt wurde.
254     //  - 'alte' Rahmen sind vorher immer selektiert denn sonst wird nix
255     //    an ihnen veraendert.
256     //  Der Rahmen darf nicht per Dokumentposition selektiert werden, weil er
257     //  auf jedenfall selektiert sein muss!
258     SwViewImp *pImpl = Imp();
259     if( GetWin() && (bNew || !pImpl->GetDrawView()->AreObjectsMarked()) )
260     {
261         ASSERT( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" );
262 
263         //Wenn der Fly bereits selektiert ist gibt es hier ja wohl nichts
264         //zu tun.
265         if ( FindFlyFrm() == &rFrm )
266             return;
267 
268         //Damit der Anker ueberhaupt noch gepaintet wird.
269         if( rFrm.IsFlyInCntFrm() && rFrm.GetAnchorFrm() )
270              rFrm.GetAnchorFrm()->SetCompletePaint();
271 
272         // --> OD 2004-06-11 #i28701# - no format at all.
273 //        //Hier wurde immer kalkuliert. Leider ist der Sonderfall Fly in Fly mit
274 //        //Spalten u.U. sehr kritisch wenn der innenliegende zuerst formatiert
275 //        //wird. Um kein Risiko einzugehen entschaerfen wir nur diesen Sonderfall.
276 //        if( !rFrm.GetAnchorFrm()->IsInFly() )
277 //            rFrm.Calc();
278 
279         if( pImpl->GetDrawView()->AreObjectsMarked() )
280             pImpl->GetDrawView()->UnmarkAll();
281 
282         pImpl->GetDrawView()->MarkObj( rFrm.GetVirtDrawObj(),
283                                       pImpl->GetPageView(), sal_False, sal_False );
284         KillPams();
285         ClearMark();
286         SelFlyGrabCrsr();
287     }
288 }
289 
290 /*************************************************************************
291 |*
292 |*  SwFEShell::FindFlyFrm()
293 |*
294 |*  Beschreibung        Liefert den Fly wenn einer Selektiert ist.
295 |*  Ersterstellung      MA 03. Nov. 92
296 |*  Letzte Aenderung    MA 05. Mar. 96
297 |*
298 *************************************************************************/
299 
300 SwFlyFrm *SwFEShell::FindFlyFrm() const
301 {
302     if ( Imp()->HasDrawView() )
303     {
304         // Ein Fly ist genau dann erreichbar, wenn er selektiert ist.
305         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
306         if( rMrkList.GetMarkCount() != 1 )
307             return 0;
308 
309         SdrObject *pO = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
310         return ( pO && pO->ISA(SwVirtFlyDrawObj) ) ? ((SwVirtFlyDrawObj*)pO)->GetFlyFrm() : 0;
311     }
312     return 0;
313 }
314 
315 /*************************************************************************
316 |*
317 |*  SwFEShell::IsFlyInFly()
318 |*
319 |*  Beschreibung        Liefert sal_True, wenn der aktuelle Fly an einem anderen
320 |*                      verankert werden koennte (also innerhalb ist)
321 |*  Ersterstellung      AMA 11. Sep. 97
322 |*  Letzte Aenderung    AMA 14. Jan. 98
323 |*
324 *************************************************************************/
325 
326 const SwFrmFmt* SwFEShell::IsFlyInFly()
327 {
328     SET_CURR_SHELL( this );
329 
330     if ( !Imp()->HasDrawView() )
331         return NULL;
332 
333     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
334     if ( !rMrkList.GetMarkCount() )
335     {
336         SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
337         if( !pCntnt )
338             return NULL;
339         SwFlyFrm *pFly = pCntnt->FindFlyFrm();
340         if ( !pFly )
341             return NULL;
342         return pFly->GetFmt();
343     }
344     else if ( rMrkList.GetMarkCount() != 1 ||
345          !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
346         return NULL;
347 
348     SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
349 
350     SwFrmFmt *pFmt = FindFrmFmt( pObj );
351     if( pFmt && FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId() )
352     {
353         const SwFrm* pFly = pObj->ISA(SwVirtFlyDrawObj) ?
354             ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetAnchorFrm() :
355             ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
356         ASSERT( pFly, "IsFlyInFly: Where's my anchor?" );
357         ASSERT( pFly->IsFlyFrm(), "IsFlyInFly: Funny anchor!" );
358         return ((SwFlyFrm*)pFly)->GetFmt();
359     }
360 
361     Point aTmpPos = pObj->GetCurrentBoundRect().TopLeft();
362 
363     SwFrm *pTxtFrm;
364     {
365         SwCrsrMoveState aState( MV_SETONLYTEXT );
366         SwNodeIndex aSwNodeIndex( GetDoc()->GetNodes() );
367         SwPosition aPos( aSwNodeIndex );
368         Point aPoint( aTmpPos );
369         aPoint.X() -= 1;                    //nicht im Fly landen!!
370         GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
371         // OD 01.07.2003 #108784# - determine text frame by left-top-corner
372         // of object
373         //pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->GetFrm( 0, 0, sal_False );
374         pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aTmpPos, 0, sal_False );
375     }
376     const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aTmpPos );
377     const SwFlyFrm *pFly = pTmp->FindFlyFrm();
378     if( pFly )
379         return pFly->GetFmt();
380     return NULL;
381 }
382 
383 /*************************************************************************
384 |*
385 |*  SwFEShell::SetFlyPos
386 |*
387 |*  Ersterstellung      MA 14. Jan. 93
388 |*  Letzte Aenderung    MA 14. Feb. 95
389 |*
390 *************************************************************************/
391 
392 void SwFEShell::SetFlyPos( const Point& rAbsPos )
393 {
394     SET_CURR_SHELL( this );
395 
396     //Bezugspunkt in Dokumentkoordinaten bestimmen
397     SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
398     if( !pCntnt )
399         return;
400     SwFlyFrm *pFly = pCntnt->FindFlyFrm();
401     if ( !pFly )
402         return;
403 
404     //SwSaveHdl aSaveX( Imp() );
405 
406     //Bei Absatzgebundenen Flys muss ausgehend von der absoluten
407     //Position ein neuer Anker gesetzt werden. Anker und neue RelPos werden
408     //vom Fly selbst berechnet und gesetzt.
409     if ( pFly->IsFlyAtCntFrm() )
410         ((SwFlyAtCntFrm*)pFly)->SetAbsPos( rAbsPos );
411     else
412     {
413             const SwFrm *pAnch = pFly->GetAnchorFrm();
414             // --> OD 2004-06-11 #i28701# - no format here
415 //          pAnch->Calc();
416             Point aOrient( pAnch->Frm().Pos() );
417 
418         if ( pFly->IsFlyInCntFrm() )
419             aOrient.X() = rAbsPos.X();
420 
421         //RelPos errechnen.
422         aOrient.X() = rAbsPos.X() - aOrient.X();
423         aOrient.Y() = rAbsPos.Y() - aOrient.Y();
424         pFly->ChgRelPos( aOrient );
425     }
426     // --> OD 2004-06-11 #i28701# - no format here
427 //    pFly->Calc();
428     CallChgLnk();       // rufe das AttrChangeNotify auf der UI-Seite.
429 }
430 
431 /*************************************************************************
432 |*
433 |*  SwFEShell::FindAnchorPos
434 |*
435 |*  Ersterstellung      AMA 24. Sep. 97
436 |*  Letzte Aenderung    AMA 24. Sep. 97
437 |*
438 *************************************************************************/
439 
440 Point SwFEShell::FindAnchorPos( const Point& rAbsPos, sal_Bool bMoveIt )
441 {
442     Point aRet;
443 
444     SET_CURR_SHELL( this );
445 
446     if ( !Imp()->HasDrawView() )
447         return aRet;
448 
449     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
450     if ( rMrkList.GetMarkCount() != 1 ||
451          !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
452         return aRet;
453 
454     SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
455     // --> OD 2004-07-16 #i28701#
456     SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
457     SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
458     const RndStdIds nAnchorId = rFmt.GetAnchor().GetAnchorId();
459 
460     if ( FLY_AS_CHAR == nAnchorId )
461         return aRet;
462 
463     sal_Bool bFlyFrame = pObj->ISA(SwVirtFlyDrawObj);
464 
465     SwFlyFrm* pFly = 0L;
466     const SwFrm* pOldAnch;
467     const SwFrm* pFooterOrHeader = NULL;
468 
469     if( bFlyFrame )
470     {
471         //Bezugspunkt in Dokumentkoordinaten bestimmen
472         SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
473         if( !pCntnt )
474             return aRet;
475         pFly = pCntnt->FindFlyFrm();
476         if ( !pFly )
477             return aRet;
478         pOldAnch = pFly->GetAnchorFrm();
479         if( !pOldAnch )
480             return aRet;
481         if ( FLY_AT_PAGE != nAnchorId )
482         {
483             pFooterOrHeader = pCntnt->FindFooterOrHeader();
484         }
485     }
486     // OD 26.06.2003 #108784# - set <pFooterOrHeader> also for drawing
487     // objects, but not for control objects.
488     // Necessary for moving 'anchor symbol' at the user interface inside header/footer.
489     else if ( !::CheckControlLayer( pObj ) )
490     {
491         SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
492         if( !pCntnt )
493             return aRet;
494         pFooterOrHeader = pCntnt->FindFooterOrHeader();
495     }
496 
497     SwCntntFrm *pTxtFrm = NULL;
498     {
499         SwCrsrMoveState aState( MV_SETONLYTEXT );
500         SwPosition aPos( GetDoc()->GetNodes().GetEndOfExtras() );
501         Point aTmpPnt( rAbsPos );
502         GetLayout()->GetCrsrOfst( &aPos, aTmpPnt, &aState );
503         if ( nAnchorId != FLY_AT_CHAR
504              || !PosInsideInputFld( aPos ) )
505         {
506             pTxtFrm = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(),0,&aPos,sal_False );
507         }
508     }
509     const SwFrm *pNewAnch = NULL;
510     if( pTxtFrm != NULL )
511     {
512         if ( FLY_AT_PAGE == nAnchorId )
513         {
514             pNewAnch = pTxtFrm->FindPageFrm();
515         }
516         else
517         {
518             pNewAnch = ::FindAnchor( pTxtFrm, rAbsPos );
519 
520             if( FLY_AT_FLY == nAnchorId ) // LAYER_IMPL
521             {
522                 pNewAnch = pNewAnch->FindFlyFrm();
523             }
524         }
525     }
526 
527     if( pNewAnch && !pNewAnch->IsProtected() )
528     {
529         const SwFlyFrm* pCheck = bFlyFrame ? pNewAnch->FindFlyFrm() : 0;
530         // Falls wir innerhalb eines Rahmens landen, muss sichergestellt werden,
531         // dass der Rahmen nicht in seinem eigenen Inhalt landet!
532         while( pCheck )
533         {
534             if( pCheck == pFly )
535                 break;
536             const SwFrm *pTmp = pCheck->GetAnchorFrm();
537             pCheck = pTmp ? pTmp->FindFlyFrm() : NULL;
538         }
539         // Es darf nicht aus einer Kopf-/Fusszeile in einen anderen Bereich
540         // gewechselt werden, es darf nicht in eine Kopf-/Fusszeile hinein-
541         // gewechselt werden.
542         if( !pCheck &&
543             pFooterOrHeader == pNewAnch->FindFooterOrHeader() )
544         {
545             aRet = pNewAnch->GetFrmAnchorPos( ::HasWrap( pObj ) );
546 
547             if ( bMoveIt || (nAnchorId == FLY_AT_CHAR) )
548             {
549                 SwFmtAnchor aAnch( rFmt.GetAnchor() );
550                 switch ( nAnchorId )
551                 {
552                     case FLY_AT_PARA:
553                     {
554                         SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
555                         pPos->nNode = *pTxtFrm->GetNode();
556                         pPos->nContent.Assign(0,0);
557                         break;
558                     }
559                     case FLY_AT_PAGE:
560                     {
561                         aAnch.SetPageNum( ((const SwPageFrm*)pNewAnch)->
562                                           GetPhyPageNum() );
563                         break;
564                     }
565 
566                     case FLY_AT_FLY:
567                     {
568                         SwPosition aPos( *((SwFlyFrm*)pNewAnch)->GetFmt()->
569                                                   GetCntnt().GetCntntIdx() );
570                         aAnch.SetAnchor( &aPos );
571                         break;
572                     }
573 
574                     case FLY_AT_CHAR:
575                         {
576                             SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
577                             Point aTmpPnt( rAbsPos );
578                             if( pTxtFrm->GetCrsrOfst( pPos, aTmpPnt, NULL ) )
579                             {
580                                 SwRect aTmpRect;
581                                 pTxtFrm->GetCharRect( aTmpRect, *pPos );
582                                 aRet = aTmpRect.Pos();
583                             }
584                             else
585                             {
586                                 pPos->nNode = *pTxtFrm->GetNode();
587                                 pPos->nContent.Assign(0,0);
588                             }
589                             break;
590                         }
591                     default:
592                         break;
593 
594                 }
595 
596                 if( bMoveIt )
597                 {
598                     StartAllAction();
599                     // --> OD 2006-02-28 #125892#
600                     // handle change of anchor node:
601                     // if count of the anchor frame also change, the fly frames have to be
602                     // re-created. Thus, delete all fly frames except the <this> before the
603                     // anchor attribute is change and re-create them afterwards.
604                     {
605                         SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
606                         SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
607                         if ( pFlyFrmFmt )
608                         {
609                             pHandleAnchorNodeChg =
610                                 new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
611                         }
612                         rFmt.GetDoc()->SetAttr( aAnch, rFmt );
613                         delete pHandleAnchorNodeChg;
614                     }
615                     // <--
616                     // --> OD 2004-06-24 #i28701# - no call of method
617                     // <CheckCharRectAndTopOfLine()> for to-character anchored
618                     // Writer fly frame needed. This method call can cause a
619                     // format of the anchor frame, which is no longer intended.
620                     // Instead clear the anchor character rectangle and
621                     // the top of line values for all to-character anchored objects.
622                     pAnchoredObj->ClearCharRectAndTopOfLine();
623                     // <--
624                     EndAllAction();
625                 }
626             }
627 
628             SwRect aTmpRect( aRet, rAbsPos );
629             if( aTmpRect.HasArea() )
630                 MakeVisible( aTmpRect );
631 #ifdef DBG_UTIL
632             //TODO: That doesn't seem to be intended
633             if( Color(COL_TRANSPARENT) != GetOut()->GetLineColor() )
634             {
635                 ASSERT( sal_False, "Hey, Joe: Where's my Null Pen?" );
636                 GetOut()->SetLineColor( Color(COL_TRANSPARENT) );
637             }
638 #endif
639         }
640     }
641 
642     return aRet;
643 }
644 
645 /***********************************************************************
646 #*  Class       :  SwFEShell
647 #*  Methode     :  NewFlyFrm
648 #*  Beschreibung:
649 #*  Datum       :  MA 03. Nov. 92
650 #*  Update      :  JP 11. Aug. 93
651 #***********************************************************************/
652 
653 const SwFrmFmt *SwFEShell::NewFlyFrm( const SfxItemSet& rSet, sal_Bool bAnchValid,
654                            SwFrmFmt *pParent )
655 {
656     SET_CURR_SHELL( this );
657     StartAllAction();
658 
659     SwPaM* pCrsr = GetCrsr();
660     const Point aPt( GetCrsrDocPos() );
661 
662     SwSelBoxes aBoxes;
663     sal_Bool bMoveCntnt = sal_True;
664     if( IsTableMode() )
665     {
666         GetTblSel( *this, aBoxes );
667         if( aBoxes.Count() )
668         {
669             // die Crsr muessen noch aus dem Loeschbereich entfernt
670             // werden. Setze sie immer hinter/auf die Tabelle; ueber die
671             // Dokument-Position werden sie dann immer an die alte
672             // Position gesetzt.
673             ParkCrsr( SwNodeIndex( *aBoxes[0]->GetSttNd() ));
674 
675             // --> FME 2005-12-01 #i127787# pCurCrsr will be deleted in ParkCrsr,
676             // we better get the current pCurCrsr instead of working with the
677             // deleted one:
678             pCrsr = GetCrsr();
679             // <--
680 
681 //          KillPams();
682         }
683         else
684             bMoveCntnt = sal_False;
685     }
686     else if( !pCrsr->HasMark() && pCrsr->GetNext() == pCrsr )
687         bMoveCntnt = sal_False;
688 
689     const SwPosition& rPos = *pCrsr->Start();
690 
691     SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
692     RndStdIds eRndId = rAnch.GetAnchorId();
693     switch( eRndId )
694     {
695     case FLY_AT_PAGE:
696         if( !rAnch.GetPageNum() )       //HotFix: Bug in UpdateByExample
697             rAnch.SetPageNum( 1 );
698         break;
699 
700     case FLY_AT_FLY:
701     case FLY_AT_PARA:
702     case FLY_AT_CHAR:
703     case FLY_AS_CHAR:
704         if( !bAnchValid )
705         {
706             if( FLY_AT_FLY != eRndId )
707             {
708                 rAnch.SetAnchor( &rPos );
709             }
710             else if( lcl_SetNewFlyPos( rPos.nNode.GetNode(), rAnch, aPt ) )
711             {
712                 eRndId = FLY_AT_PAGE;
713             }
714         }
715         break;
716 
717     default:
718         ASSERT( !this, "Was sollte das fuer ein Fly werden?" )
719         break;
720     }
721 
722     SwFlyFrmFmt *pRet;
723     if( bMoveCntnt )
724     {
725         GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
726         SwFmtAnchor* pOldAnchor = 0;
727         sal_Bool bHOriChgd = sal_False, bVOriChgd = sal_False;
728         SwFmtVertOrient aOldV;
729         SwFmtHoriOrient aOldH;
730 
731         if ( FLY_AT_PAGE != eRndId )
732         {
733             // erstmal als mit Seitenbindung, Absatz/Zeichenbindung erst wenn
734             // alles verschoben ist. Dann ist die Position gueltig!
735             // JP 13.05.98: ggfs. auch noch die Hori/Vert-Orientierung
736             //              umsetzen, damit diese beim Umanker NICHT
737             //              korrigiert wird
738             pOldAnchor = new SwFmtAnchor( rAnch );
739             const_cast<SfxItemSet&>(rSet).Put( SwFmtAnchor( FLY_AT_PAGE, 1 ) );
740 
741             const SfxPoolItem* pItem;
742             if( SFX_ITEM_SET == rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem )
743                 && text::HoriOrientation::NONE == ((SwFmtHoriOrient*)pItem)->GetHoriOrient() )
744             {
745                 bHOriChgd = sal_True;
746                 aOldH = *((SwFmtHoriOrient*)pItem);
747                 ((SfxItemSet&)rSet).Put( SwFmtHoriOrient( 0, text::HoriOrientation::LEFT ) );
748             }
749             if( SFX_ITEM_SET == rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem )
750                 && text::VertOrientation::NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
751             {
752                 bVOriChgd = sal_True;
753                 aOldV = *((SwFmtVertOrient*)pItem);
754                 ((SfxItemSet&)rSet).Put( SwFmtVertOrient( 0, text::VertOrientation::TOP ) );
755             }
756         }
757 
758         pRet = GetDoc()->MakeFlyAndMove( *pCrsr, rSet, &aBoxes, pParent );
759 
760         KillPams();
761 
762         if( pOldAnchor )
763         {
764             if( pRet )
765             {
766                 // neue Position bestimmen
767                 //JP 24.03.97: immer ueber die Seitenbindung gehen - der
768                 //           chaos::Anchor darf nie im verschobenen Bereich
769                 //              liegen
770                 pRet->DelFrms();
771 
772                 const SwFrm* pAnch = ::FindAnchor( GetLayout(), aPt, sal_False );
773                 SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
774                 if ( FLY_AS_CHAR == eRndId )
775                 {
776                     aPos.nContent.Assign( ((SwCntntFrm*)pAnch)->GetNode(), 0 );
777                 }
778                 pOldAnchor->SetAnchor( &aPos );
779 
780                 // das verschieben von TabelleSelektion ist noch nicht
781                 // Undofaehig - also darf das UmAnkern auch nicht
782                 // aufgezeichnet werden.
783                 bool const bDoesUndo =
784                     GetDoc()->GetIDocumentUndoRedo().DoesUndo();
785                 SwUndoId nLastUndoId(UNDO_EMPTY);
786                 if (bDoesUndo &&
787                     GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0,
788                         & nLastUndoId))
789                 {
790                     if (UNDO_INSLAYFMT == nLastUndoId)
791                     {
792                         GetDoc()->GetIDocumentUndoRedo().DoUndo(false);
793                     }
794                 }
795 
796                 ((SfxItemSet&)rSet).Put( *pOldAnchor );
797 
798                 if( bHOriChgd )
799                     ((SfxItemSet&)rSet).Put( aOldH );
800                 if( bVOriChgd )
801                     ((SfxItemSet&)rSet).Put( aOldV );
802 
803                 GetDoc()->SetFlyFrmAttr( *pRet, (SfxItemSet&)rSet );
804                 GetDoc()->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
805             }
806             delete pOldAnchor;
807         }
808         GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
809     }
810     else
811         /* #109161# If called from a shell try to propagate an
812             existing adjust item from rPos to the content node of the
813             new frame. */
814         pRet = GetDoc()->MakeFlySection( eRndId, &rPos, &rSet, pParent, sal_True );
815 
816     if( pRet )
817     {
818         SwFlyFrm* pFrm = pRet->GetFrm( &aPt );
819         if( pFrm )
820             SelectFlyFrm( *pFrm, sal_True );
821         else
822         {
823             GetLayout()->SetAssertFlyPages();
824             pRet = 0;
825         }
826     }
827     EndAllActionAndCall();
828 
829     return pRet;
830 }
831 
832 /***********************************************************************
833 #*  Class       :  SwFEShell
834 #*  Methode     :  Insert
835 #*  Datum       :  ??
836 #*  Update      :  MA 12. Sep. 94
837 #***********************************************************************/
838 
839 void SwFEShell::Insert( const String& rGrfName, const String& rFltName,
840                         const Graphic* pGraphic,
841                         const SfxItemSet* pFlyAttrSet,
842                         const SfxItemSet* pGrfAttrSet,
843                         SwFrmFmt* pFrmFmt )
844 {
845     SwFlyFrmFmt* pFmt = 0;
846     SET_CURR_SHELL( this );
847     StartAllAction();
848     SwShellCrsr *pStartCursor = dynamic_cast<SwShellCrsr*>(this->GetSwCrsr());
849     SwShellCrsr *pCursor = pStartCursor;
850     do {
851 
852         // Anker noch nicht oder unvollstaendig gesetzt ?
853         if( pFlyAttrSet )
854         {
855             const SfxPoolItem* pItem;
856             if( SFX_ITEM_SET == pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False,
857                     &pItem ) )
858             {
859                 SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
860                 switch( pAnchor->GetAnchorId())
861                 {
862                 case FLY_AT_PARA:
863                 case FLY_AT_CHAR: // LAYER_IMPL
864                 case FLY_AS_CHAR:
865                     if( !pAnchor->GetCntntAnchor() )
866                     {
867                         pAnchor->SetAnchor( pCursor->GetPoint() );
868                     }
869                     break;
870                 case FLY_AT_FLY:
871                     if( !pAnchor->GetCntntAnchor() )
872                     {
873                         lcl_SetNewFlyPos( *pCursor->GetNode(),
874                                 *pAnchor, GetCrsrDocPos() );
875                     }
876                     break;
877                 case FLY_AT_PAGE:
878                     if( !pAnchor->GetPageNum() )
879                     {
880                         pAnchor->SetPageNum( pCursor->GetPageNum(
881                                 sal_True, &pCursor->GetPtPos() ) );
882                     }
883                     break;
884                 default :
885                     break;
886                 }
887             }
888         }
889         pFmt = GetDoc()->Insert(*pCursor, rGrfName,
890                                 rFltName, pGraphic,
891                                 pFlyAttrSet,
892                                 pGrfAttrSet, pFrmFmt );
893         ASSERT( pFmt, "Doc->Insert(notxt) failed." );
894 
895     } while( (pCursor = dynamic_cast<SwShellCrsr*>(pCursor->GetNext()))
896              != pStartCursor );
897 
898     EndAllAction();
899 
900     if( pFmt )
901     {
902         const Point aPt( GetCrsrDocPos() );
903         SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
904 
905         if( pFrm )
906             SelectFlyFrm( *pFrm, sal_True );
907         else
908             GetLayout()->SetAssertFlyPages();
909     }
910 }
911 
912 SwFlyFrmFmt* SwFEShell::InsertObject( const svt::EmbeddedObjectRef&  xObj,
913                         const SfxItemSet* pFlyAttrSet,
914                         const SfxItemSet* pGrfAttrSet,
915                         SwFrmFmt* pFrmFmt )
916 {
917     SwFlyFrmFmt* pFmt = 0;
918     SET_CURR_SHELL( this );
919     StartAllAction();
920         FOREACHPAM_START( this )
921             pFmt = GetDoc()->Insert(*PCURCRSR, xObj,
922                                     pFlyAttrSet, pGrfAttrSet, pFrmFmt );
923             ASSERT( pFmt, "Doc->Insert(notxt) failed." );
924 
925         FOREACHPAM_END()
926     EndAllAction();
927 
928     if( pFmt )
929     {
930         const Point aPt( GetCrsrDocPos() );
931         SwFlyFrm* pFrm = pFmt->GetFrm( &aPt );
932 
933         if( pFrm )
934             SelectFlyFrm( *pFrm, sal_True );
935         else
936             GetLayout()->SetAssertFlyPages();
937     }
938 
939     return pFmt;
940 }
941 
942 
943 void SwFEShell::InsertDrawObj( SdrObject& rDrawObj,
944                                const Point& rInsertPosition )
945 {
946     SET_CURR_SHELL( this );
947 
948     SfxItemSet rFlyAttrSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
949     rFlyAttrSet.Put( SwFmtAnchor( FLY_AT_PARA ));
950     // --> OD 2009-12-29 #i89920#
951     rFlyAttrSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
952     rDrawObj.SetLayer( getIDocumentDrawModelAccess()->GetHeavenId() );
953     // <--
954 
955     // find anchor position
956     SwPaM aPam( pDoc->GetNodes() );
957     {
958         SwCrsrMoveState aState( MV_SETONLYTEXT );
959         Point aTmpPt( rInsertPosition );
960         GetLayout()->GetCrsrOfst( aPam.GetPoint(), aTmpPt, &aState );
961         const SwFrm* pFrm = aPam.GetCntntNode()->getLayoutFrm( GetLayout(), 0, 0, sal_False );
962         const Point aRelPos( rInsertPosition.X() - pFrm->Frm().Left(),
963                              rInsertPosition.Y() - pFrm->Frm().Top() );
964         rDrawObj.SetRelativePos( aRelPos );
965         ::lcl_FindAnchorPos( *this, *GetDoc(), rInsertPosition, *pFrm, rFlyAttrSet );
966     }
967     // insert drawing object into the document creating a new <SwDrawFrmFmt> instance
968     SwDrawFrmFmt* pFmt = GetDoc()->Insert( aPam, rDrawObj, &rFlyAttrSet, 0 );
969 
970     // move object to visible layer
971     SwContact* pContact = static_cast<SwContact*>(rDrawObj.GetUserCall());
972     if ( pContact )
973     {
974         pContact->MoveObjToVisibleLayer( &rDrawObj );
975     }
976 
977     if ( pFmt )
978     {
979         // select drawing object
980         Imp()->GetDrawView()->MarkObj( &rDrawObj, Imp()->GetPageView(),
981                                        sal_False, sal_False );
982     }
983     else
984     {
985         GetLayout()->SetAssertFlyPages();
986     }
987 }
988 
989 /***********************************************************************
990 #*  Class       :  SwFEShell
991 #*  Methode     :  GetPageObjs
992 #*  Datum       :  ??
993 #*  Update      :  MA 11. Jan. 95
994 #***********************************************************************/
995 
996 void SwFEShell::GetPageObjs( SvPtrarr& rFillArr )
997 {
998     if( rFillArr.Count() )
999         rFillArr.Remove( 0, rFillArr.Count() );
1000 
1001     const SwFrmFmt* pFmt;
1002     for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
1003     {
1004         pFmt = (const SwFrmFmt*)(*pDoc->GetSpzFrmFmts())[n];
1005         if (FLY_AT_PAGE == pFmt->GetAnchor().GetAnchorId())
1006         {
1007             rFillArr.Insert( (VoidPtr)pFmt, rFillArr.Count() );
1008         }
1009     }
1010 }
1011 
1012 /***********************************************************************
1013 #*  Class       :  SwFEShell
1014 #*  Methode     :  SetPageFlysNewPage
1015 #*  Datum       :  ??
1016 #*  Update      :  MA 14. Feb. 95
1017 #***********************************************************************/
1018 
1019 void SwFEShell::SetPageObjsNewPage( SvPtrarr& rFillArr, int nOffset )
1020 {
1021     if( !rFillArr.Count() || !nOffset )
1022         return;
1023 
1024     StartAllAction();
1025     StartUndo();
1026 
1027     SwFrmFmt* pFmt;
1028     long nNewPage;
1029     SwRootFrm* pTmpRootFrm = GetLayout();//swmod 080317
1030     sal_uInt16 nMaxPage = pTmpRootFrm->GetPageNum();
1031     sal_Bool bTmpAssert = sal_False;
1032     for( sal_uInt16 n = 0; n < rFillArr.Count(); ++n )
1033     {
1034         pFmt = (SwFrmFmt*)rFillArr[n];
1035         if( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( pFmt ))
1036         {
1037             // FlyFmt ist noch gueltig, also behandeln
1038             SwFmtAnchor aNewAnchor( pFmt->GetAnchor() );
1039             if ((FLY_AT_PAGE != aNewAnchor.GetAnchorId()) ||
1040                 0 >= ( nNewPage = aNewAnchor.GetPageNum() + nOffset ) )
1041                 // chaos::Anchor wurde veraendert oder ungueltige SeitenNummer,
1042                 // also nicht veraendern !!
1043                 continue;
1044 
1045             if( sal_uInt16(nNewPage) > nMaxPage )
1046             {
1047                 if ( RES_DRAWFRMFMT == pFmt->Which() )
1048                 {
1049                     SwContact *pCon = pFmt->FindContactObj();
1050                     if( pCon )
1051                         ((SwDrawContact*)pCon)->DisconnectFromLayout();
1052                 }
1053                 else
1054                     pFmt->DelFrms();
1055                 bTmpAssert = sal_True;
1056             }
1057             aNewAnchor.SetPageNum( sal_uInt16(nNewPage) );
1058             pDoc->SetAttr( aNewAnchor, *pFmt );
1059         }
1060     }
1061 
1062     if( bTmpAssert )
1063         pTmpRootFrm->SetAssertFlyPages();
1064 
1065     EndUndo();
1066     EndAllAction();
1067 }
1068 
1069 /***********************************************************************
1070 #*  Class       :  SwFEShell
1071 #*  Methode     :  GetFlyFrmAttr
1072 #*  Beschreibung:  Alle Attribute in dem 'Koerbchen' werden mit den
1073 #*                 Attributen des aktuellen FlyFrms gefuellt.
1074 #*                 Sind Attribute nicht zu fuellen weil fehl am Platz oder
1075 #*                 uneindeutig (Mehrfachtselektionen) so werden sie entfernt.
1076 #*  Datum       :  MA 03. Nov. 92
1077 #*  Update      :  MA 03. Feb. 94
1078 #***********************************************************************/
1079 
1080 sal_Bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const
1081 {
1082     SwFlyFrm *pFly = FindFlyFrm();
1083     if ( !pFly )
1084     {
1085         // --> OD 2006-11-08 #139670# - make code robust
1086         SwFrm* pCurrFrm( GetCurrFrm() );
1087         if ( !pCurrFrm )
1088         {
1089             ASSERT( false,
1090                     "<SwFEShell::GetFlyFrmAttr(..)> - missing current frame. This is a serious defect, please inform OD." );
1091             return sal_False;
1092         }
1093         // <--
1094         pFly = GetCurrFrm()->FindFlyFrm();
1095         if ( !pFly )
1096         {
1097             ASSERT( !this, "GetFlyFrmAttr, no Fly selected." );
1098             return sal_False;
1099         }
1100     }
1101 
1102     SET_CURR_SHELL( (ViewShell*)this );
1103 
1104     if( !rSet.Set( pFly->GetFmt()->GetAttrSet(), sal_True ) )
1105         return sal_False;
1106 
1107     //Und die Attribute durchschaufeln. Unerlaubte Attribute entfernen, dann
1108     //alle restlichen Attribute besorgen und eintragen.
1109     const SfxPoolItem* pItem;
1110     if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False, &pItem ) )
1111     {
1112         SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
1113         RndStdIds eType = pAnchor->GetAnchorId();
1114 
1115         if ( FLY_AT_PAGE != eType )
1116         {
1117             // OD 12.11.2003 #i22341# - content anchor of anchor item is needed.
1118             // Thus, don't overwrite anchor item by default contructed anchor item.
1119             //rSet.Put( SwFmtAnchor( eType ) );
1120             if ( FLY_AS_CHAR == eType )
1121             {
1122                 rSet.ClearItem( RES_OPAQUE );
1123                 rSet.ClearItem( RES_SURROUND );
1124             }
1125         }
1126     }
1127     rSet.SetParent( pFly->GetFmt()->GetAttrSet().GetParent() );
1128     //JP 11.02.97: Bug #35894#: die Attribute MUESSEN entfern werden!
1129     rSet.ClearItem( RES_FILL_ORDER );
1130     rSet.ClearItem( RES_CNTNT );
1131     //MA: Ersteinmal entfernen (Template by example usw.)
1132     rSet.ClearItem( RES_CHAIN );
1133     return sal_True;
1134 }
1135 /***********************************************************************
1136 #*  Class       :  SwFEShell
1137 #*  Methode     :  SetFlyFrmAttr
1138 #*  Beschreibung:  Die Attribute des aktuellen Flys aendern sich.
1139 #*  Datum       :  MA 03. Nov. 92
1140 #*  Update      :  MA 01. Aug. 95
1141 #***********************************************************************/
1142 
1143 sal_Bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet )
1144 {
1145     SET_CURR_SHELL( this );
1146     sal_Bool bRet = sal_False;
1147 
1148     if( rSet.Count() )
1149     {
1150         SwFlyFrm *pFly = FindFlyFrm();
1151         if( !pFly )
1152         {
1153             ASSERT( GetCurrFrm(), "Crsr in parking zone" );
1154             pFly = GetCurrFrm()->FindFlyFrm();
1155             ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
1156         }
1157         if( pFly )
1158         {
1159             StartAllAction();
1160             const Point aPt( pFly->Frm().Pos() );
1161 
1162             if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
1163                 ::lcl_ChkAndSetNewAnchor( *this, *pFly, rSet );
1164             SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
1165 
1166             if( GetDoc()->SetFlyFrmAttr( *pFlyFmt, rSet ))
1167             {
1168                 bRet = sal_True;
1169                 SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
1170                 if( pFrm )
1171                     SelectFlyFrm( *pFrm, sal_True );
1172                 else
1173                     GetLayout()->SetAssertFlyPages();
1174             }
1175 
1176             EndAllActionAndCall();
1177         }
1178     }
1179     return bRet;
1180 }
1181 /*-- 30.03.2004 15:05:07---------------------------------------------------
1182 
1183   -----------------------------------------------------------------------*/
1184 sal_Bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet )
1185 {
1186     sal_Bool bRet = sal_False;
1187     SET_CURR_SHELL( this );
1188     if ( !rSet.Count() ||
1189             !Imp()->HasDrawView() )
1190         return bRet;
1191 
1192     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1193     if ( rMrkList.GetMarkCount() != 1 )
1194         return bRet;
1195 
1196     StartUndo();
1197     SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1198     SwFrmFmt *pFmt = FindFrmFmt( pObj );
1199     StartAllAction();
1200     if( SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
1201     {
1202         RndStdIds nNew = ((SwFmtAnchor&)rSet.Get( RES_ANCHOR )).GetAnchorId();
1203         if ( nNew != pFmt->GetAnchor().GetAnchorId() )
1204         {
1205             ChgAnchor( nNew );
1206             // --> OD 2004-06-17 #i26791# - clear anchor attribute in item set,
1207             // because method <ChgAnchor(..)> takes care of it.
1208             rSet.ClearItem( RES_ANCHOR );
1209         }
1210     }
1211 
1212     if( GetDoc()->SetFlyFrmAttr( *pFmt, rSet ))
1213     {
1214         bRet = sal_True;
1215         Point aTmp;
1216         SelectObj( aTmp, 0, pObj );
1217     }
1218     EndAllActionAndCall();
1219     EndUndo();
1220     return bRet;
1221 }
1222 
1223 
1224 /***********************************************************************
1225 #*  Class       :  SwFEShell
1226 #*  Methode     :  ResetFlyFrmAttr
1227 #*  Beschreibung:  Das gewuenschte Attribut oder die im Set befindlichen
1228 #*                  werden zurueckgesetzt.
1229 #*  Datum       :  MA 14. Mar. 97
1230 #*  Update      :  MA 14. Mar. 97
1231 #***********************************************************************/
1232 
1233 sal_Bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet )
1234 {
1235     sal_Bool bRet = sal_False;
1236 
1237     if( RES_ANCHOR != nWhich && RES_CHAIN != nWhich && RES_CNTNT != nWhich )
1238     {
1239         SET_CURR_SHELL( this );
1240 
1241         SwFlyFrm *pFly = FindFlyFrm();
1242         if( !pFly )
1243         {
1244             ASSERT( GetCurrFrm(), "Crsr in parking zone" );
1245             pFly = GetCurrFrm()->FindFlyFrm();
1246             ASSERT( pFly, "SetFlyFrmAttr, no Fly selected." );
1247         }
1248 
1249         if( pFly )
1250         {
1251             StartAllAction();
1252 
1253             if( pSet )
1254             {
1255                 SfxItemIter aIter( *pSet );
1256                 const SfxPoolItem* pItem = aIter.FirstItem();
1257                 while( pItem )
1258                 {
1259                     if( !IsInvalidItem( pItem ) &&
1260                         RES_ANCHOR != ( nWhich = pItem->Which() ) &&
1261                         RES_CHAIN != nWhich && RES_CNTNT != nWhich )
1262                         pFly->GetFmt()->ResetFmtAttr( nWhich );
1263                     pItem = aIter.NextItem();
1264                 }
1265             }
1266             else
1267                 pFly->GetFmt()->ResetFmtAttr( nWhich );
1268 
1269             bRet = sal_True;
1270             EndAllActionAndCall();
1271             GetDoc()->SetModified();
1272         }
1273     }
1274     return bRet;
1275 }
1276 
1277 /***********************************************************************
1278 #*  Class       :  SwFEShell
1279 #*  Methode     :  GetCurFrmFmt
1280 #*  Beschreibung:  liefert wenn Rahmen, dann Rahmenvorlage, sonst 0
1281 #*  Datum       :  ST 04. Jun. 93
1282 #*  Update      :
1283 #***********************************************************************/
1284 
1285 SwFrmFmt* SwFEShell::GetCurFrmFmt() const
1286 {
1287     SwFrmFmt* pRet = 0;
1288     SwLayoutFrm *pFly = FindFlyFrm();
1289     if( pFly && ( pRet = (SwFrmFmt*)pFly->GetFmt()->DerivedFrom() ) ==
1290                                             GetDoc()->GetDfltFrmFmt() )
1291         pRet = 0;
1292     return pRet;
1293 }
1294 
1295 /******************************************************************************
1296  *  Methode     :   void SwFEShell::SetFrmFmt(SwFrmFmt *pNewFmt)
1297  *  Beschreibung:
1298  *  Erstellt    :   OK 14.04.94 15:40
1299  *  Aenderung   :   MA 23. Apr. 97
1300  ******************************************************************************/
1301 
1302 void SwFEShell::SetFrmFmt( SwFrmFmt *pNewFmt, sal_Bool bKeepOrient, Point* pDocPos )
1303 {
1304     SwFlyFrm *pFly = 0;
1305     if(pDocPos)
1306     {
1307         const SwFrmFmt* pFmt = GetFmtFromObj( *pDocPos );
1308 
1309         if(PTR_CAST(SwFlyFrmFmt, pFmt))
1310             pFly = ((SwFlyFrmFmt*)pFmt)->GetFrm();
1311     }
1312     else
1313         pFly = FindFlyFrm();
1314     ASSERT( pFly, "SetFrmFmt: kein Frame" );
1315     if( pFly )
1316     {
1317         StartAllAction();
1318         SET_CURR_SHELL( this );
1319 
1320         SwFlyFrmFmt* pFlyFmt = (SwFlyFrmFmt*)pFly->GetFmt();
1321         const Point aPt( pFly->Frm().Pos() );
1322 
1323         SfxItemSet* pSet = 0;
1324         const SfxPoolItem* pItem;
1325         if( SFX_ITEM_SET == pNewFmt->GetItemState( RES_ANCHOR, sal_False, &pItem ))
1326         {
1327             pSet = new SfxItemSet( GetDoc()->GetAttrPool(), aFrmFmtSetRange );
1328             pSet->Put( *pItem );
1329             if( !::lcl_ChkAndSetNewAnchor( *this, *pFly, *pSet ))
1330                 delete pSet, pSet = 0;
1331         }
1332 
1333         if( GetDoc()->SetFrmFmtToFly( *pFlyFmt, *pNewFmt, pSet, bKeepOrient ))
1334         {
1335             SwFlyFrm* pFrm = pFlyFmt->GetFrm( &aPt );
1336             if( pFrm )
1337                 SelectFlyFrm( *pFrm, sal_True );
1338             else
1339                 GetLayout()->SetAssertFlyPages();
1340         }
1341         if( pSet )
1342             delete pSet;
1343 
1344         EndAllActionAndCall();
1345     }
1346 }
1347 
1348 /*************************************************************************
1349 |*
1350 |*  SwFEShell::GetFlyFrmFmt()
1351 |*
1352 |*  Ersterstellung      OK 23.06.93 13:15
1353 |*  Letzte Aenderung    OK 23.06.93 13:15
1354 |*
1355 *************************************************************************/
1356 
1357 const SwFrmFmt* SwFEShell::GetFlyFrmFmt() const
1358 {
1359     const SwFlyFrm* pFly = FindFlyFrm();
1360     if ( !pFly )
1361     {
1362         SwFrm* pCurrFrm = GetCurrFrm();
1363         pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
1364     }
1365     if( pFly )
1366         return pFly->GetFmt();
1367     return 0;
1368 }
1369 
1370 SwFrmFmt* SwFEShell::GetFlyFrmFmt()
1371 {
1372     SwFlyFrm* pFly = FindFlyFrm();
1373     if ( !pFly )
1374     {
1375         SwFrm* pCurrFrm = GetCurrFrm();
1376         pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0;
1377     }
1378     if( pFly )
1379         return pFly->GetFmt();
1380     return 0;
1381 }
1382 
1383 /*************************************************************************
1384 |*
1385 |*  SwFEShell::GetFlyRect()
1386 |*
1387 |*  Ersterstellung      AMA 6. Mae. 97
1388 |*  Letzte Aenderung    AMA 6. Mae. 97
1389 |*
1390 *************************************************************************/
1391 
1392 SwRect SwFEShell::GetFlyRect() const
1393 {
1394     SwCntntFrm *pCntnt = GetCurrFrm( sal_False );
1395     SwFlyFrm *pFly = pCntnt ? pCntnt->FindFlyFrm() : 0;
1396     if ( !pFly )
1397     {
1398         SwRect aRect;
1399         return aRect;
1400     }
1401     else
1402         return pFly->Frm();
1403 }
1404 
1405 /*************************************************************************
1406 |*
1407 |*  SwFEShell::GetObjRect()
1408 |*
1409 |*  Ersterstellung      MA 22. Aug. 93
1410 |*  Letzte Aenderung    MA 11. Jan. 95
1411 |*
1412 *************************************************************************/
1413 
1414 SwRect SwFEShell::GetObjRect() const
1415 {
1416     if( Imp()->HasDrawView() )
1417         return Imp()->GetDrawView()->GetAllMarkedRect();
1418     else
1419     {
1420         SwRect aRect;
1421         return aRect;
1422     }
1423 }
1424 
1425 void SwFEShell::SetObjRect( const SwRect& rRect )
1426 {
1427     if ( Imp()->HasDrawView() )
1428     {
1429         Imp()->GetDrawView()->SetAllMarkedRect( rRect.SVRect() );
1430         CallChgLnk();   // rufe das AttrChangeNotify auf der UI-Seite.
1431     }
1432 }
1433 
1434 /***********************************************************************
1435 #*  Class       :  SwFEShell
1436 #*  Methode     :  RequestObjectResize()
1437 #*  Datum       :  MA 10. Feb. 95
1438 #*  Update      :  MA 13. Jul. 95
1439 #***********************************************************************/
1440 
1441 Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference < embed::XEmbeddedObject >& xObj )
1442 {
1443     Size aResult;
1444 
1445     SwFlyFrm *pFly = FindFlyFrm( xObj );
1446     if ( !pFly )
1447     {
1448         aResult = rRect.SSize();
1449         return aResult;
1450     }
1451 
1452     aResult = pFly->Prt().SSize();
1453 
1454     sal_Bool bPosProt = pFly->GetFmt()->GetProtect().IsPosProtected();
1455     sal_Bool bSizeProt = pFly->GetFmt()->GetProtect().IsSizeProtected();
1456 
1457     StartAllAction();
1458 
1459     //MA wir lassen den Fly nicht Clippen, damit die Ole-Server mit
1460     //beliebigen Wuenschen kommen koennen. Die Formatierung uebernimmt das
1461     //Clippen. Die richtige Darstellung wird per Scalierung erledigt.
1462     //Die Scalierung wird von SwNoTxtFrm::Format durch einen Aufruf von
1463     //SwWrtShell::CalcAndSetScale() erledigt.
1464     if ( rRect.SSize() != pFly->Prt().SSize() && !bSizeProt )
1465     {
1466         Size aSz( rRect.SSize() );
1467 
1468         //JP 28.02.2001: Task 74707 - ask for fly in fly with automatic size
1469         //
1470         const SwFrm* pAnchor;
1471         const SwTxtNode* pTNd;
1472         const SwpHints* pHts;
1473         const SwFmtFrmSize& rFrmSz = pFly->GetFmt()->GetFrmSize();
1474         if( bCheckForOLEInCaption &&
1475             0 != rFrmSz.GetWidthPercent() &&
1476             0 != (pAnchor = pFly->GetAnchorFrm()) &&
1477             pAnchor->IsTxtFrm() &&
1478             !pAnchor->GetNext() && !pAnchor->GetPrev() &&
1479             pAnchor->GetUpper()->IsFlyFrm() &&
1480             0 != ( pTNd = ((SwTxtFrm*)pAnchor)->GetNode()->GetTxtNode()) &&
1481             0 != ( pHts = pTNd->GetpSwpHints() ))
1482         {
1483             // search for a sequence field:
1484             const SfxPoolItem* pItem;
1485             for( sal_uInt16 n = 0, nEnd = pHts->Count(); n < nEnd; ++n )
1486                 if( RES_TXTATR_FIELD == ( pItem =
1487                             &(*pHts)[ n ]->GetAttr())->Which() &&
1488                     TYP_SEQFLD == ((SwFmtFld*)pItem)->GetField()->GetTypeId() )
1489                 {
1490                     // sequence field found
1491                     SwFlyFrm* pChgFly = (SwFlyFrm*)pAnchor->GetUpper();
1492                     // calculate the changed size:
1493                     // width must change, height can change
1494                     Size aNewSz( aSz.Width() + pChgFly->Frm().Width() -
1495                                    pFly->Prt().Width(), aSz.Height() );
1496 
1497                     SwFrmFmt *pFmt = pChgFly->GetFmt();
1498                     SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() );
1499                     aFrmSz.SetWidth( aNewSz.Width() );
1500                     if( ATT_MIN_SIZE != aFrmSz.GetHeightSizeType() )
1501                     {
1502                         aNewSz.Height() += pChgFly->Frm().Height() -
1503                                             pFly->Prt().Height();
1504                         if( Abs( aNewSz.Height() - pChgFly->Frm().Height()) > 1 )
1505                             aFrmSz.SetHeight( aNewSz.Height() );
1506                     }
1507                     // uebers Doc fuers Undo!
1508                     pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
1509                     break;
1510                 }
1511         }
1512 
1513         // set the new Size at the fly themself
1514         if ( pFly->Prt().Height() > 0 && pFly->Prt().Width() > 0 )
1515         {
1516             aSz.Width() += pFly->Frm().Width() - pFly->Prt().Width();
1517             aSz.Height()+= pFly->Frm().Height()- pFly->Prt().Height();
1518         }
1519         aResult = pFly->ChgSize( aSz );
1520 
1521         //Wenn sich das Objekt aendert ist die Kontur hoechstwahrscheinlich daneben.
1522         ASSERT( pFly->Lower()->IsNoTxtFrm(), "Request ohne NoTxt" );
1523         SwNoTxtNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetNoTxtNode();
1524         ASSERT( pNd, "Request ohne Node" );
1525         pNd->SetContour( 0 );
1526         ClrContourCache();
1527     }
1528 
1529     //Wenn nur die Size angepasst werden soll, so wird eine Pos mit
1530     //ausgezeichneten Werten transportiert.
1531     Point aPt( pFly->Prt().Pos() );
1532     aPt += pFly->Frm().Pos();
1533     if ( rRect.Top() != LONG_MIN && rRect.Pos() != aPt && !bPosProt )
1534     {
1535         aPt = rRect.Pos();
1536         aPt.X() -= pFly->Prt().Left();
1537         aPt.Y() -= pFly->Prt().Top();
1538         //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein
1539         //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly
1540         //selbst berechnet und gesetzt.
1541         if( pFly->IsFlyAtCntFrm() )
1542             ((SwFlyAtCntFrm*)pFly)->SetAbsPos( aPt );
1543         else
1544         {
1545             const SwFrmFmt *pFmt = pFly->GetFmt();
1546             const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
1547             const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
1548             const long lXDiff = aPt.X() - pFly->Frm().Left();
1549             const long lYDiff = aPt.Y() - pFly->Frm().Top();
1550             const Point aTmp( rHori.GetPos() + lXDiff,
1551                               rVert.GetPos() + lYDiff );
1552             pFly->ChgRelPos( aTmp );
1553         }
1554     }
1555 
1556     SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt();
1557     ASSERT( pFlyFrmFmt, "fly frame format missing!" );
1558     if ( pFlyFrmFmt )
1559         pFlyFrmFmt->SetLastFlyFrmPrtRectPos( pFly->Prt().Pos() ); //stores the value of last Prt rect
1560 
1561     EndAllAction();
1562 
1563     return aResult;
1564 }
1565 
1566 
1567 /***********************************************************************
1568 #*  Class       :  SwFEShell
1569 #*  Methode     :  WizzardFindCurFrmFmt
1570 #*  Datum       :  JP 31.07.95
1571 #*  Update      :  JP 31.07.95
1572 #***********************************************************************/
1573 
1574 SwFrmFmt* SwFEShell::WizzardGetFly()
1575 {
1576     // mal nicht uebers Layout den Fly suchen. Dann kann auch ohne gueltiges
1577     // Layout ein Rahmen geloescht werden. ( z.B.: fuer die Wizard's )
1578     SwSpzFrmFmts& rSpzArr = *pDoc->GetSpzFrmFmts();
1579     sal_uInt16 nCnt = rSpzArr.Count();
1580     if( nCnt )
1581     {
1582         SwNodeIndex& rCrsrNd = GetCrsr()->GetPoint()->nNode;
1583         if( rCrsrNd.GetIndex() > pDoc->GetNodes().GetEndOfExtras().GetIndex() )
1584             // Cusor steht im Body-Bereich!
1585             return 0;
1586 
1587         for( sal_uInt16 n = 0; n < nCnt; ++n )
1588         {
1589             SwFrmFmt* pFmt = rSpzArr[ n ];
1590             const SwNodeIndex* pIdx = pFmt->GetCntnt( sal_False ).GetCntntIdx();
1591             SwStartNode* pSttNd;
1592             if( pIdx &&
1593                 0 != ( pSttNd = pIdx->GetNode().GetStartNode() ) &&
1594                 pSttNd->GetIndex() < rCrsrNd.GetIndex() &&
1595                 rCrsrNd.GetIndex() < pSttNd->EndOfSectionIndex() )
1596             {
1597                 // gefunden: also raus damit
1598                 return pFmt;
1599             }
1600         }
1601     }
1602     return 0;
1603 }
1604 
1605 void SwFEShell::SetFlyName( const String& rName )
1606 {
1607     SwLayoutFrm *pFly = FindFlyFrm();
1608     if( pFly )
1609         GetDoc()->SetFlyName( *(SwFlyFrmFmt*)pFly->GetFmt(), rName );
1610     else {
1611         ASSERT( !this, "kein FlyFrame selektiert" )
1612     }
1613 }
1614 
1615 const String& SwFEShell::GetFlyName() const
1616 {
1617     SwLayoutFrm *pFly = FindFlyFrm();
1618     if( pFly )
1619         return pFly->GetFmt()->GetName();
1620 
1621     ASSERT( !this, "kein FlyFrame selektiert" )
1622     return aEmptyStr;
1623 }
1624 
1625 
1626 const uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const
1627 {
1628     uno::Reference < embed::XEmbeddedObject > xObj;
1629     SwFlyFrm * pFly = FindFlyFrm();
1630     if (pFly && pFly->Lower() && pFly->Lower()->IsNoTxtFrm())
1631     {
1632         SwOLENode *pNd = ((SwNoTxtFrm*)pFly->Lower())->GetNode()->GetOLENode();
1633         if (pNd)
1634             xObj = pNd->GetOLEObj().GetOleRef();
1635     }
1636     return xObj;
1637 }
1638 
1639 
1640 String SwFEShell::GetUniqueGrfName() const
1641 {
1642     return GetDoc()->GetUniqueGrfName();
1643 }
1644 
1645 const SwFrmFmt* SwFEShell::IsURLGrfAtPos( const Point& rPt, String* pURL,
1646                                         String *pTargetFrameName,
1647                                         String *pDescription ) const
1648 {
1649     if( !Imp()->HasDrawView() )
1650         return 0;
1651 
1652     SdrObject* pObj;
1653     SdrPageView* pPV;
1654     const SwFrmFmt* pRet = 0;
1655     SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1656 
1657     sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1658     pDView->SetHitTolerancePixel( 2 );
1659 
1660     if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV,SDRSEARCH_PICKMACRO ) &&
1661         pObj->ISA(SwVirtFlyDrawObj) )
1662     {
1663         SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
1664         const SwFmtURL &rURL = pFly->GetFmt()->GetURL();
1665         if( rURL.GetURL().Len() || rURL.GetMap() )
1666         {
1667             sal_Bool bSetTargetFrameName = pTargetFrameName != 0;
1668             sal_Bool bSetDescription = pDescription != 0;
1669             if ( rURL.GetMap() )
1670             {
1671                 IMapObject *pObject = pFly->GetFmt()->GetIMapObject( rPt, pFly );
1672                 if ( pObject && pObject->GetURL().Len() )
1673                 {
1674                     if( pURL )
1675                         *pURL = pObject->GetURL();
1676                     if ( bSetTargetFrameName && pObject->GetTarget().Len() )
1677                     {
1678                         bSetTargetFrameName = sal_False;
1679                         *pTargetFrameName = pObject->GetTarget();
1680                     }
1681                     if ( bSetDescription )
1682                     {
1683                         bSetDescription = sal_False;
1684                         *pDescription = pObject->GetAltText();
1685                     }
1686                     pRet = pFly->GetFmt();
1687                 }
1688             }
1689             else
1690             {
1691                 if( pURL )
1692                 {
1693                     *pURL = rURL.GetURL();
1694                     if( rURL.IsServerMap() )
1695                     {
1696                         // dann die rel. Pixel Position anhaengen !!
1697                         Point aPt( rPt );
1698                         aPt -= pFly->Frm().Pos();
1699                         // ohne MapMode-Offset, ohne Offset, o ... !!!!!
1700                         aPt = GetOut()->LogicToPixel(
1701                                 aPt, MapMode( MAP_TWIP ) );
1702                         ((( *pURL += '?' ) += String::CreateFromInt32( aPt.X() ))
1703                                   += ',' ) += String::CreateFromInt32(aPt.Y() );
1704                     }
1705                 }
1706                 pRet = pFly->GetFmt();
1707             }
1708             if ( bSetTargetFrameName )
1709                 *pTargetFrameName = rURL.GetTargetFrameName();
1710             if ( bSetDescription )
1711                 *pDescription = pFly->GetFmt()->GetName();
1712         }
1713     }
1714     pDView->SetHitTolerancePixel( nOld );
1715     return pRet;
1716 }
1717 
1718 const Graphic *SwFEShell::GetGrfAtPos( const Point &rPt,
1719                                        String &rName, sal_Bool &rbLink ) const
1720 {
1721     if( !Imp()->HasDrawView() )
1722         return 0;
1723 
1724     SdrObject* pObj;
1725     SdrPageView* pPV;
1726     SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1727 
1728     if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV ) && pObj->ISA(SwVirtFlyDrawObj) )
1729     {
1730         SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
1731         if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1732         {
1733             SwGrfNode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode();
1734             if ( pNd )
1735             {
1736                 if ( pNd->IsGrfLink() )
1737                 {
1738                     //Halbfertige Grafik?
1739                     ::sfx2::SvLinkSource* pLnkObj = pNd->GetLink()->GetObj();
1740                     if( pLnkObj && pLnkObj->IsPending() )
1741                         return 0;
1742                     rbLink = sal_True;
1743                 }
1744 
1745                 pNd->GetFileFilterNms( &rName, 0 );
1746                 if ( !rName.Len() )
1747                     rName = pFly->GetFmt()->GetName();
1748                 pNd->SwapIn( sal_True );
1749                 return &pNd->GetGrf();
1750             }
1751         }
1752     }
1753     return 0;
1754 }
1755 
1756 
1757 const SwFrmFmt* SwFEShell::GetFmtFromObj( const Point& rPt, SwRect** pRectToFill ) const
1758 {
1759     SwFrmFmt* pRet = 0;
1760 
1761     if( Imp()->HasDrawView() )
1762     {
1763         SdrObject* pObj;
1764         SdrPageView* pPView;
1765 
1766         SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1767 
1768         sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1769         // Tattergrenze fuer Drawing-SS
1770         pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1771 
1772         if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
1773         {
1774             // dann teste mal was es ist:
1775             if ( pObj->ISA(SwVirtFlyDrawObj) )
1776                 pRet = ((SwVirtFlyDrawObj*)pObj)->GetFmt();
1777             else if ( pObj->GetUserCall() ) //nicht fuer Gruppenobjekte
1778                 pRet = ((SwDrawContact*)pObj->GetUserCall())->GetFmt();
1779             if(pRet && pRectToFill)
1780                 **pRectToFill = pObj->GetCurrentBoundRect();
1781         }
1782         pDView->SetHitTolerancePixel( nOld );
1783     }
1784     return pRet;
1785 }
1786 
1787 // returns a format too, if the point is over the text of any fly
1788 const SwFrmFmt* SwFEShell::GetFmtFromAnyObj( const Point& rPt ) const
1789 {
1790     const SwFrmFmt* pRet = GetFmtFromObj( rPt );
1791     if( !pRet || RES_FLYFRMFMT == pRet->Which() )
1792     {
1793         SwPosition aPos( *GetCrsr()->GetPoint() );
1794         Point aPt( rPt );
1795         GetLayout()->GetCrsrOfst( &aPos, aPt );
1796         SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
1797         SwFrm* pFrm = pNd->getLayoutFrm( GetLayout(), &rPt, 0, sal_False )->FindFlyFrm();
1798         pRet = pFrm ? ((SwLayoutFrm*)pFrm)->GetFmt() : 0;
1799     }
1800     return pRet;
1801 }
1802 
1803 ObjCntType SwFEShell::GetObjCntType( const SdrObject& rObj ) const
1804 {
1805     ObjCntType eType = OBJCNT_NONE;
1806 
1807     // OD 23.06.2003 #108784# - investigate 'master' drawing object, if method
1808     // is called for a 'virtual' drawing object.
1809     const SdrObject* pInvestigatedObj;
1810     if ( rObj.ISA(SwDrawVirtObj) )
1811     {
1812         const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(&rObj);
1813         pInvestigatedObj = &(pDrawVirtObj->GetReferencedObj());
1814     }
1815     else
1816     {
1817         pInvestigatedObj = &rObj;
1818     }
1819 
1820     if( FmFormInventor == pInvestigatedObj->GetObjInventor() )
1821     {
1822         eType = OBJCNT_CONTROL;
1823         uno::Reference< awt::XControlModel >  xModel =
1824                 ((SdrUnoObj&)(*pInvestigatedObj)).GetUnoControlModel();
1825         if( xModel.is() )
1826         {
1827             uno::Any aVal;
1828             OUString sName = OUString::createFromAscii("ButtonType");
1829             uno::Reference< beans::XPropertySet >  xSet(xModel, uno::UNO_QUERY);
1830 
1831             uno::Reference< beans::XPropertySetInfo >  xInfo = xSet->getPropertySetInfo();
1832             if(xInfo->hasPropertyByName( sName ))
1833             {
1834                 beans::Property xProperty = xInfo->getPropertyByName( sName );
1835                 aVal = xSet->getPropertyValue( sName );
1836                 if( aVal.getValue() && form::FormButtonType_URL == *((form::FormButtonType*)aVal.getValue()) )
1837                     eType = OBJCNT_URLBUTTON;
1838             }
1839         }
1840     }
1841     else if( pInvestigatedObj->ISA(SwVirtFlyDrawObj) )
1842     {
1843         SwFlyFrm *pFly = ((SwVirtFlyDrawObj&)(*pInvestigatedObj)).GetFlyFrm();
1844         if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1845         {
1846             if ( ((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode() )
1847                 eType = OBJCNT_GRF;
1848             else
1849                 eType = OBJCNT_OLE;
1850         }
1851         else
1852             eType = OBJCNT_FLY;
1853     }
1854     else if ( pInvestigatedObj->ISA( SdrObjGroup ) )
1855     {
1856         SwDrawContact* pDrawContact( dynamic_cast<SwDrawContact*>(GetUserCall( pInvestigatedObj ) ) );
1857         if ( !pDrawContact )
1858         {
1859             ASSERT( false,
1860                     "<SwFEShell::GetObjCntType(..)> - missing draw contact object" );
1861             eType = OBJCNT_NONE;
1862         }
1863         else
1864         {
1865             SwFrmFmt* pFrmFmt( pDrawContact->GetFmt() );
1866             if ( !pFrmFmt )
1867             {
1868                 ASSERT( false,
1869                         "<SwFEShell::GetObjCntType(..)> - missing frame format" );
1870                 eType = OBJCNT_NONE;
1871             }
1872             else if ( FLY_AS_CHAR != pFrmFmt->GetAnchor().GetAnchorId() )
1873             {
1874                 eType = OBJCNT_GROUPOBJ;
1875             }
1876         }
1877     }
1878     else
1879         eType = OBJCNT_SIMPLE;
1880     return eType;
1881 }
1882 
1883 ObjCntType SwFEShell::GetObjCntType( const Point &rPt, SdrObject *&rpObj ) const
1884 {
1885     ObjCntType eType = OBJCNT_NONE;
1886 
1887     if( Imp()->HasDrawView() )
1888     {
1889         SdrObject* pObj;
1890         SdrPageView* pPView;
1891 
1892         SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
1893 
1894         sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1895         // Tattergrenze fuer Drawing-SS
1896         pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1897 
1898         if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) )
1899             eType = GetObjCntType( *(rpObj = pObj) );
1900 
1901         pDView->SetHitTolerancePixel( nOld );
1902     }
1903     return eType;
1904 }
1905 
1906 ObjCntType SwFEShell::GetObjCntTypeOfSelection( SdrObject** ppObj ) const
1907 {
1908     ObjCntType eType = OBJCNT_NONE;
1909 
1910     if( Imp()->HasDrawView() )
1911     {
1912         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1913         for( sal_uInt32 i = 0, nE = rMrkList.GetMarkCount(); i < nE; ++i )
1914         {
1915             SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1916             if( !pObj )
1917                 continue;
1918             ObjCntType eTmp = GetObjCntType( *pObj );
1919             if( !i )
1920             {
1921                 eType = eTmp;
1922                 if( ppObj ) *ppObj = pObj;
1923             }
1924             else if( eTmp != eType )
1925             {
1926                 eType = OBJCNT_DONTCARE;
1927                 // einmal DontCare, immer DontCare!
1928                 break;
1929             }
1930         }
1931     }
1932     return eType;
1933 }
1934 
1935 
1936 sal_Bool SwFEShell::ReplaceSdrObj( const String& rGrfName, const String& rFltName,
1937                                 const Graphic* pGrf )
1938 {
1939     SET_CURR_SHELL( this );
1940 
1941     sal_Bool bRet = sal_False;
1942     const SdrMarkList *pMrkList;
1943     if( Imp()->HasDrawView() &&  1 ==
1944         ( pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList())->GetMarkCount() )
1945     {
1946         SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
1947         SwFrmFmt *pFmt = FindFrmFmt( pObj );
1948 
1949         // Attribute sichern und dann an der Grafik setzen
1950         SfxItemSet aFrmSet( pDoc->GetAttrPool(),
1951                             pFmt->GetAttrSet().GetRanges() );
1952         aFrmSet.Set( pFmt->GetAttrSet() );
1953 
1954         // Groesse und Position setzen ??
1955         if( !pObj->ISA(SwVirtFlyDrawObj) )
1956         {
1957             // dann mal los:
1958             const Rectangle &rBound = pObj->GetSnapRect();
1959             Point aRelPos( pObj->GetRelativePos() );
1960 
1961             const long nWidth = rBound.Right()  - rBound.Left();
1962             const long nHeight= rBound.Bottom() - rBound.Top();
1963             aFrmSet.Put( SwFmtFrmSize( ATT_MIN_SIZE,
1964                                 Max( nWidth,  long(MINFLY) ),
1965                                 Max( nHeight, long(MINFLY) )));
1966 
1967             if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_HORI_ORIENT ))
1968                 aFrmSet.Put( SwFmtHoriOrient( aRelPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1969 
1970             if( SFX_ITEM_SET != aFrmSet.GetItemState( RES_VERT_ORIENT ))
1971                 aFrmSet.Put( SwFmtVertOrient( aRelPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ));
1972 
1973         }
1974 
1975         pObj->GetOrdNum();
1976 
1977         StartAllAction();
1978         StartUndo();
1979 
1980         // das "Sdr-Object" loeschen und dafuer die Grafik einfuegen
1981         DelSelectedObj();
1982 
1983         pFmt = GetDoc()->Insert( *GetCrsr(), rGrfName, rFltName, pGrf, &aFrmSet, NULL, NULL );
1984 
1985         // die Ordnungsnummer (Z-Order) noch uebertragen
1986         // JP 04.07.98: klappt aber nicht richtig!
1987         //SdrObject* pNewObj = ::FindSdrObject( pFmt );
1988         //pNewObj->SetOrdNum( nOrdNum );
1989 
1990         EndUndo();
1991         EndAllAction();
1992         bRet = sal_True;
1993     }
1994     return bRet;
1995 }
1996 
1997 static sal_uInt16 SwFmtGetPageNum(const SwFlyFrmFmt * pFmt)
1998 {
1999     ASSERT(pFmt != NULL, "invalid argument");
2000 
2001     SwFlyFrm * pFrm = pFmt->GetFrm();
2002 
2003     sal_uInt16 aResult;
2004 
2005     if (pFrm != NULL)
2006         aResult = pFrm->GetPhyPageNum();
2007     else
2008         aResult = pFmt->GetAnchor().GetPageNum();
2009 
2010     return aResult;
2011 }
2012 
2013 #include <fmtcnct.hxx>
2014 
2015 void SwFEShell::GetConnectableFrmFmts(SwFrmFmt & rFmt,
2016                                       const String & rReference,
2017                                       sal_Bool bSuccessors,
2018                                       ::std::vector< String > & aPrevPageVec,
2019                                       ::std::vector< String > & aThisPageVec,
2020                                       ::std::vector< String > & aNextPageVec,
2021                                       ::std::vector< String > & aRestVec)
2022 {
2023     StartAction();
2024 
2025     SwFmtChain rChain = rFmt.GetChain();
2026     SwFrmFmt * pOldChainNext = (SwFrmFmt *) rChain.GetNext();
2027     SwFrmFmt * pOldChainPrev = (SwFrmFmt *) rChain.GetPrev();
2028 
2029     if (pOldChainNext)
2030         pDoc->Unchain(rFmt);
2031 
2032     if (pOldChainPrev)
2033         pDoc->Unchain(*pOldChainPrev);
2034 
2035     sal_uInt16 nCnt = pDoc->GetFlyCount(FLYCNTTYPE_FRM);
2036 
2037     /* potential successors resp. predecessors */
2038     ::std::vector< const SwFrmFmt * > aTmpSpzArray;
2039 
2040     (SwFrmFmt *) pDoc->FindFlyByName(rReference);
2041 
2042     for (sal_uInt16 n = 0; n < nCnt; n++)
2043     {
2044         const SwFrmFmt & rFmt1 = *(pDoc->GetFlyNum(n, FLYCNTTYPE_FRM));
2045 
2046         /*
2047            pFmt is a potential successor of rFmt if it is chainable after
2048            rFmt.
2049 
2050            pFmt is a potential predecessor of rFmt if rFmt is chainable
2051            after pFmt.
2052         */
2053 
2054         int nChainState;
2055 
2056         if (bSuccessors)
2057             nChainState = pDoc->Chainable(rFmt, rFmt1);
2058         else
2059             nChainState = pDoc->Chainable(rFmt1, rFmt);
2060 
2061         if (nChainState == SW_CHAIN_OK)
2062         {
2063             aTmpSpzArray.push_back(&rFmt1);
2064 
2065         }
2066 
2067     }
2068 
2069     if  (aTmpSpzArray.size() > 0)
2070     {
2071         aPrevPageVec.clear();
2072         aThisPageVec.clear();
2073         aNextPageVec.clear();
2074         aRestVec.clear();
2075 
2076         /* number of page rFmt resides on */
2077         sal_uInt16 nPageNum = SwFmtGetPageNum((SwFlyFrmFmt *) &rFmt);
2078 
2079         ::std::vector< const SwFrmFmt * >::const_iterator aIt;
2080 
2081         for (aIt = aTmpSpzArray.begin(); aIt != aTmpSpzArray.end(); aIt++)
2082         {
2083             String  aString = (*aIt)->GetName();
2084 
2085             /* rFmt is not a vaild successor or predecessor of
2086                itself */
2087             if (aString != rReference && aString != rFmt.GetName())
2088             {
2089                 sal_uInt16 nNum1 =
2090                     SwFmtGetPageNum((SwFlyFrmFmt *) *aIt);
2091 
2092                 if (nNum1 == nPageNum -1)
2093                     aPrevPageVec.push_back(aString);
2094                 else if (nNum1 == nPageNum)
2095                     aThisPageVec.push_back(aString);
2096                 else if (nNum1 == nPageNum + 1)
2097                     aNextPageVec.push_back(aString);
2098                 else
2099                     aRestVec.push_back(aString);
2100             }
2101         }
2102 
2103     }
2104 
2105     if (pOldChainNext)
2106         pDoc->Chain(rFmt, *pOldChainNext);
2107 
2108     if (pOldChainPrev)
2109         pDoc->Chain(*pOldChainPrev, rFmt);
2110 
2111     EndAction();
2112 }
2113 
2114 // --> OD 2009-07-13 #i73249#
2115 const String SwFEShell::GetObjTitle() const
2116 {
2117     String aTitle;
2118 
2119     if ( Imp()->HasDrawView() )
2120     {
2121         const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
2122         if ( pMrkList->GetMarkCount() == 1 )
2123         {
2124             const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
2125             const SwFrmFmt* pFmt = FindFrmFmt( pObj );
2126             if ( pFmt->Which() == RES_FLYFRMFMT )
2127             {
2128                 aTitle = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjTitle();
2129             }
2130             else
2131             {
2132                 aTitle = pObj->GetTitle();
2133             }
2134         }
2135     }
2136 
2137     return aTitle;
2138 }
2139 
2140 void SwFEShell::SetObjTitle( const String& rTitle )
2141 {
2142     if ( Imp()->HasDrawView() )
2143     {
2144         const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
2145         if ( pMrkList->GetMarkCount() == 1 )
2146         {
2147             SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
2148             SwFrmFmt* pFmt = FindFrmFmt( pObj );
2149             if ( pFmt->Which() == RES_FLYFRMFMT )
2150             {
2151                 GetDoc()->SetFlyFrmTitle( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)),
2152                                           rTitle );
2153             }
2154             else
2155             {
2156                 pObj->SetTitle( rTitle );
2157             }
2158         }
2159     }
2160 }
2161 
2162 const String SwFEShell::GetObjDescription() const
2163 {
2164     String aDescription;
2165 
2166     if ( Imp()->HasDrawView() )
2167     {
2168         const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
2169         if ( pMrkList->GetMarkCount() == 1 )
2170         {
2171             const SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
2172             const SwFrmFmt* pFmt = FindFrmFmt( pObj );
2173             if ( pFmt->Which() == RES_FLYFRMFMT )
2174             {
2175                 aDescription = dynamic_cast<const SwFlyFrmFmt*>(pFmt)->GetObjDescription();
2176             }
2177             else
2178             {
2179                 aDescription = pObj->GetDescription();
2180             }
2181         }
2182     }
2183 
2184     return aDescription;
2185 }
2186 
2187 void SwFEShell::SetObjDescription( const String& rDescription )
2188 {
2189     if ( Imp()->HasDrawView() )
2190     {
2191         const SdrMarkList *pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
2192         if ( pMrkList->GetMarkCount() == 1 )
2193         {
2194             SdrObject* pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
2195             SwFrmFmt* pFmt = FindFrmFmt( pObj );
2196             if ( pFmt->Which() == RES_FLYFRMFMT )
2197             {
2198                 GetDoc()->SetFlyFrmDescription( *(dynamic_cast<SwFlyFrmFmt*>(pFmt)),
2199                                                 rDescription );
2200             }
2201             else
2202             {
2203                 pObj->SetDescription( rDescription );
2204             }
2205         }
2206     }
2207 }
2208 
2209 
2210 void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj, SwFlyFrm * pFly )
2211 {
2212 #if OSL_DEBUG_LEVEL > 1
2213     SvGlobalName aCLSID( xObj->getClassID() );
2214     const bool bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
2215     ASSERT( bStarMath, "AlignFormulaToBaseline should only be called for Math objects" );
2216 
2217     if ( !bStarMath )
2218         return;
2219 #endif
2220 
2221     if (!pFly)
2222         pFly = FindFlyFrm( xObj );
2223     ASSERT( pFly , "No fly frame!" );
2224     SwFrmFmt * pFrmFmt = pFly ? pFly->GetFmt() : 0;
2225 
2226     // baseline to baseline alignment should only be applied to formulas anchored as char
2227     if ( pFly && pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
2228     {
2229         // get baseline from Math object
2230         uno::Any aBaseline;
2231         if( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
2232         {
2233             uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
2234             if ( xSet.is() )
2235             {
2236                 try
2237                 {
2238                     aBaseline = xSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BaseLine") ) );
2239                 }
2240                 catch ( uno::Exception& )
2241                 {
2242                     ASSERT( sal_False , "Baseline could not be retrieved from Starmath!" );
2243                 }
2244             }
2245         }
2246 
2247         sal_Int32 nBaseline = ::comphelper::getINT32(aBaseline);
2248         const MapMode aSourceMapMode( MAP_100TH_MM );
2249         const MapMode aTargetMapMode( MAP_TWIP );
2250         nBaseline = OutputDevice::LogicToLogic( nBaseline, aSourceMapMode.GetMapUnit(), aTargetMapMode.GetMapUnit() );
2251 
2252         ASSERT( nBaseline > 0, "Wrong value of Baseline while retrieving from Starmath!" );
2253         //nBaseline must be moved by aPrt position
2254         const SwFlyFrmFmt *pFlyFrmFmt = pFly->GetFmt();
2255         ASSERT( pFlyFrmFmt, "fly frame format missing!" );
2256         if ( pFlyFrmFmt )
2257             nBaseline += pFlyFrmFmt->GetLastFlyFrmPrtRectPos().Y();
2258 
2259         const SwFmtVertOrient &rVert = pFrmFmt->GetVertOrient();
2260         SwFmtVertOrient aVert( rVert );
2261         aVert.SetPos( -nBaseline );
2262         aVert.SetVertOrient( com::sun::star::text::VertOrientation::NONE );
2263 
2264         pFrmFmt->LockModify();
2265         pFrmFmt->SetFmtAttr( aVert );
2266         pFrmFmt->UnlockModify();
2267         pFly->InvalidatePos();
2268     }
2269 }
2270 
2271 
2272 void SwFEShell::AlignAllFormulasToBaseline()
2273 {
2274     StartAllAction();
2275 
2276     SwStartNode *pStNd;
2277     SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2278     while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
2279     {
2280         ++aIdx;
2281         SwOLENode *pOleNode = dynamic_cast< SwOLENode * >( &aIdx.GetNode() );
2282         if ( pOleNode )
2283         {
2284             const uno::Reference < embed::XEmbeddedObject > & xObj( pOleNode->GetOLEObj().GetOleRef() );
2285             if (xObj.is())
2286             {
2287                 SvGlobalName aCLSID( xObj->getClassID() );
2288                 if ( SotExchange::IsMath( aCLSID ) )
2289                     AlignFormulaToBaseline( xObj );
2290             }
2291         }
2292 
2293         aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
2294     }
2295 
2296     EndAllAction();
2297 }
2298