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