xref: /AOO41X/main/sw/source/core/frmedt/feshview.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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 <com/sun/star/embed/EmbedMisc.hpp>
28 
29 #include "hintids.hxx"
30 
31 #include <svx/sdrobjectfilter.hxx>
32 #include <svx/svditer.hxx>
33 #include <svx/svdobj.hxx>
34 #include <svx/svdouno.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <svx/svdogrp.hxx>
37 #include <svx/svdocirc.hxx>
38 #include <svx/svdopath.hxx>
39 #include <svx/sxciaitm.hxx>
40 #include <svx/xfillit.hxx>
41 #include <svx/svdocapt.hxx>
42 #include <sfx2/app.hxx>
43 #include <editeng/boxitem.hxx>
44 #include <editeng/opaqitem.hxx>
45 #include <editeng/protitem.hxx>
46 #include <svx/svdpage.hxx>
47 #include <svx/svdpagv.hxx>
48 #include <IDocumentSettingAccess.hxx>
49 #include <cmdid.h>
50 #include <poolfmt.hrc>      // fuer InitFldTypes
51 #include <frmfmt.hxx>
52 #include <frmatr.hxx>
53 #include <fmtfsize.hxx>
54 #include <fmtanchr.hxx>
55 #include <fmtornt.hxx>
56 #include <fmtsrnd.hxx>
57 #include <fmtcntnt.hxx>
58 #include <fmtflcnt.hxx>
59 #include <fmtcnct.hxx>
60 #include <docary.hxx>
61 #include <tblsel.hxx>
62 #include <swtable.hxx>
63 #include <flyfrms.hxx>
64 #include "fesh.hxx"
65 #include "rootfrm.hxx"
66 #include "pagefrm.hxx"
67 #include "sectfrm.hxx"
68 #include "doc.hxx"
69 #include <IDocumentUndoRedo.hxx>
70 #include "dview.hxx"
71 #include "dflyobj.hxx"
72 #include "dcontact.hxx"
73 #include "viewimp.hxx"
74 #include "flyfrm.hxx"
75 #include "pam.hxx"
76 #include "ndole.hxx"
77 #include "ndgrf.hxx"
78 #include "ndtxt.hxx"
79 #include "viewopt.hxx"                  // fuer GetHTMLMode
80 #include "swundo.hxx"
81 #include "notxtfrm.hxx"
82 #include "txtfrm.hxx"
83 #include "txatbase.hxx"
84 #include "mdiexp.hxx"                   // fuer Update der Statuszeile bei drag
85 #include <sortedobjs.hxx>
86 #include <HandleAnchorNodeChg.hxx>
87 #include <basegfx/polygon/b2dpolygon.hxx>
88 #include <switerator.hxx>
89 
90 #define SCROLLVAL 75
91 
92 using namespace com::sun::star;
93 
94 //Tattergrenze fuer Drawing-SS
95 #define MINMOVE ((sal_uInt16)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width())
96 
97 SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh )
98 {
99     if ( !pLst )
100         pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkedObjectList():0;
101 
102     if ( pLst && pLst->GetMarkCount() == 1 )
103     {
104         SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
105         if ( pO && pO->ISA(SwVirtFlyDrawObj) )
106             return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
107     }
108     return 0;
109 }
110 
111 void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly)
112 {
113     const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr();
114     if( pFlyFmt && !pSh->ActionPend() &&
115                         (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) )
116     {
117         // dann das evt. gesetzte Macro rufen
118         pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt );
119 extern sal_Bool bNoInterrupt;       // in swapp.cxx
120         // wir in dem Makro ein Dialog gestartet, dann kommt das
121         // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist
122         // Flag bei uns immer gesetzt und schaltet nie die auf die
123         // entsp. Shell um !!!!!!!
124         bNoInterrupt = sal_False;
125     }
126     else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() )
127     {
128         // --> OD 2007-07-25 #136039#
129         // assure consistent cursor
130         pSh->KillPams();
131         pSh->ClearMark();
132         // <--
133         pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), sal_True);
134     }
135 }
136 
137 /*************************************************************************
138 |*
139 |*  SwFEShell::SelectObj()
140 *************************************************************************/
141 
142 sal_Bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj )
143 {
144     SwDrawView *pDView = Imp()->GetDrawView();
145     if(!pDView)
146         return sal_False;
147     SET_CURR_SHELL( this );
148     StartAction();          //Aktion ist Notwendig, damit nicht mehrere
149                             //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd)
150                             //durchkommen
151 
152     const SdrMarkList &rMrkList = pDView->GetMarkedObjectList();
153     const sal_Bool bHadSelection = rMrkList.GetMarkCount() ? sal_True : sal_False;
154     const sal_Bool bAddSelect = 0 != (SW_ADD_SELECT & nFlag);
155     const sal_Bool bEnterGroup = 0 != (SW_ENTER_GROUP & nFlag);
156     SwFlyFrm* pOldSelFly = 0;
157     const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() );
158 
159     if( bHadSelection )
160     {
161         //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist.
162         sal_Bool bUnmark = !bAddSelect;
163 
164         if ( rMrkList.GetMarkCount() == 1 )
165         {
166             //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden.
167             pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
168             if ( pOldSelFly )
169             {
170                 const sal_uInt16 nType = GetCntType();
171                 if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) ||
172                     ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected()
173                      && !IsReadOnlyAvailable() ))
174                 {
175                     //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae.
176                     //enthaelt, so muss der Crsr aus diesem entfernt werden.
177                     //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert
178                     //wird. Der Einfachheit halber wire der Crsr 'grad so neben die
179                     //linke obere Ecke gesetzt.
180                     Point aPt( pOldSelFly->Frm().Pos() );
181                     aPt.X() -= 1;
182                     sal_Bool bUnLockView = !IsViewLocked();
183                     LockView( sal_True );
184                     SetCrsr( aPt, sal_True );
185                     if( bUnLockView )
186                         LockView( sal_False );
187                 }
188                 if ( nType & CNT_GRF &&
189                      ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() )
190                 {
191                     GetWin()->Invalidate( pOldSelFly->Frm().SVRect() );
192                 }
193                 bUnmark = sal_True;
194             }
195         }
196         if ( bUnmark )
197             pDView->UnmarkAll();
198     }
199     else
200     {
201         KillPams();
202         ClearMark();
203     }
204 
205     if ( pObj )
206     {
207         ASSERT( !bEnterGroup, "SW_ENTER_GROUP is not supported" );
208         pDView->MarkObj( pObj, Imp()->GetPageView() );
209     }
210     else
211     {
212         pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup );
213     }
214 
215     const sal_Bool bRet = 0 != rMrkList.GetMarkCount();
216 
217     if ( rMrkList.GetMarkCount() > 1 )
218     {
219         //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und
220         //nun ein Fly hinzuselektiert wird.
221         for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
222         {
223             SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
224             sal_Bool bForget = pTmpObj->ISA(SwVirtFlyDrawObj);
225             if( bForget )
226             {
227                 pDView->UnmarkAll();
228                 pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
229                 break;
230             }
231         }
232     }
233 
234     if ( bRet )
235     {
236         ::lcl_GrabCursor(this, pOldSelFly);
237         if ( GetCntType() & CNT_GRF )
238         {
239             const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this );
240             ASSERT( pTmp, "Graphic without Fly" );
241             if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() )
242                 ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() );
243         }
244     }
245     else if ( !pOldSelFly && bHadSelection )
246         SetCrsr( aOldPos, sal_True);
247 
248     if( bRet || !bHadSelection )
249         CallChgLnk();
250 
251     // update der Statuszeile
252     ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
253 
254     EndAction();
255     return bRet;
256 }
257 
258 /*************************************************************************
259 |*
260 |*  sal_Bool SwFEShell::MoveAnchor( sal_uInt16 nDir )
261 |*
262 |*  Description: MoveAnchor( nDir ) looked for an another Anchor for
263 |*  the selected drawing object (or fly frame) in the given direction.
264 |*  An object "as character" doesn't moves anyway.
265 |*  A page bounded object could move to the previous/next page with up/down,
266 |*  an object bounded "at paragraph" moves to the previous/next paragraph, too.
267 |*  An object bounded "at character" moves to the previous/next paragraph
268 |*  with up/down and to the previous/next character with left/right.
269 |*  If the anchor for at paragraph/character bounded objects has vertical or
270 |*  right_to_left text direction, the directions for up/down/left/right will
271 |*  interpreted accordingly.
272 |*  An object bounded "at fly" takes the center of the actual anchor and looks
273 |*  for the nearest fly frame in the given direction.
274 |*
275 *************************************************************************/
276 
277 #define LESS_X( aPt1, aPt2, bOld ) ( aPt1.X() < aPt2.X() || \
278         ( aPt1.X() == aPt2.X() && ( aPt1.Y() < aPt2.Y() || \
279         ( aPt1.Y() == aPt2.Y() && bOld ) ) ) )
280 #define LESS_Y( aPt1, aPt2, bOld ) ( aPt1.Y() < aPt2.Y() || \
281         ( aPt1.Y() == aPt2.Y() && ( aPt1.X() < aPt2.X() || \
282         ( aPt1.X() == aPt2.X() && bOld ) ) ) )
283 
284 sal_Bool SwFEShell::MoveAnchor( sal_uInt16 nDir )
285 {
286     const SdrMarkList* pMrkList;
287     if( !Imp()->GetDrawView() ||
288         0 == (pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList()) ||
289         1 != pMrkList->GetMarkCount())
290         return sal_False;
291     SwFrm* pOld;
292     SwFlyFrm* pFly = NULL;
293     SdrObject *pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
294     if( pObj->ISA(SwVirtFlyDrawObj) )
295     {
296         pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
297         pOld = pFly->AnchorFrm();
298     }
299     else
300         pOld = ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
301     sal_Bool bRet = sal_False;
302     if( pOld )
303     {
304         SwFrm* pNew = pOld;
305         // --> OD 2004-07-16 #i28701#
306         SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
307         SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
308         SwFmtAnchor aAnch( rFmt.GetAnchor() );
309         RndStdIds nAnchorId = aAnch.GetAnchorId();
310         if ( FLY_AS_CHAR == nAnchorId )
311             return sal_False;
312         if( pOld->IsVertical() )
313         {
314             if( pOld->IsTxtFrm() )
315             {
316                 switch( nDir ) {
317                     case SW_MOVE_UP: nDir = SW_MOVE_LEFT; break;
318                     case SW_MOVE_DOWN: nDir = SW_MOVE_RIGHT; break;
319                     case SW_MOVE_LEFT: nDir = SW_MOVE_DOWN; break;
320                     case SW_MOVE_RIGHT: nDir = SW_MOVE_UP; break;
321                 }
322                 if( pOld->IsRightToLeft() )
323                 {
324                     if( nDir == SW_MOVE_LEFT )
325                         nDir = SW_MOVE_RIGHT;
326                     else if( nDir == SW_MOVE_RIGHT )
327                         nDir = SW_MOVE_LEFT;
328                 }
329             }
330         }
331         switch ( nAnchorId ) {
332             case FLY_AT_PAGE:
333             {
334                 ASSERT( pOld->IsPageFrm(), "Wrong anchor, page exspected." );
335                 if( SW_MOVE_UP == nDir )
336                     pNew = pOld->GetPrev();
337                 else if( SW_MOVE_DOWN == nDir )
338                     pNew = pOld->GetNext();
339                 if( pNew && pNew != pOld )
340                 {
341                     aAnch.SetPageNum( ((SwPageFrm*)pNew)->GetPhyPageNum() );
342                     bRet = sal_True;
343                 }
344                 break;
345             }
346             case FLY_AT_CHAR:
347             {
348                 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
349                 if( SW_MOVE_LEFT == nDir || SW_MOVE_RIGHT == nDir )
350                 {
351                     SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
352                     SwTxtNode* pTxtNd = ((SwTxtFrm*)pOld)->GetTxtNode();
353                     xub_StrLen nAct = pPos->nContent.GetIndex();
354                     if( SW_MOVE_LEFT == nDir )
355                     {
356                         bRet = sal_True;
357                         if( nAct )
358                         {
359                             --nAct;
360                             pPos->nContent.Assign( pTxtNd, nAct );
361                         }
362                         else
363                             nDir = SW_MOVE_UP;
364                     }
365                     else
366                     {
367                         xub_StrLen nMax =
368                             ((SwTxtFrm*)pOld)->GetTxtNode()->GetTxt().Len();
369                         if( nAct < nMax )
370                         {
371                             ++nAct;
372                             bRet = sal_True;
373                             pPos->nContent.Assign( pTxtNd, nAct );
374                         }
375                         else
376                             nDir = SW_MOVE_DOWN;
377                     }
378                 }
379             } // no break!
380             case FLY_AT_PARA:
381             {
382                 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
383                 if( SW_MOVE_UP == nDir )
384                     pNew = pOld->FindPrev();
385                 else if( SW_MOVE_DOWN == nDir )
386                     pNew = pOld->FindNext();
387                 if( pNew && pNew != pOld && pNew->IsCntntFrm() )
388                 {
389                     SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
390                     SwTxtNode* pTxtNd = ((SwTxtFrm*)pNew)->GetTxtNode();
391                     pPos->nNode = *pTxtNd;
392                     xub_StrLen nTmp = 0;
393                     if( bRet )
394                     {
395                         nTmp = ((SwTxtFrm*)pNew)->GetTxtNode()->GetTxt().Len();
396                         if( nTmp )
397                             --nTmp;
398                     }
399                     pPos->nContent.Assign( pTxtNd, nTmp );
400                     bRet = sal_True;
401                 }
402                 else if( SW_MOVE_UP == nDir || SW_MOVE_DOWN == nDir )
403                     bRet = sal_False;
404                 break;
405             }
406             case FLY_AT_FLY:
407             {
408                 ASSERT( pOld->IsFlyFrm(), "Wrong anchor, fly frame exspected.");
409                 SwPageFrm* pPage = pOld->FindPageFrm();
410                 ASSERT( pPage, "Where's my page?" );
411                 SwFlyFrm* pNewFly = NULL;
412                 if( pPage->GetSortedObjs() )
413                 {
414                     int i;
415                     sal_Bool bOld = sal_False;
416                     Point aCenter( pOld->Frm().Left() + pOld->Frm().Width()/2,
417                                    pOld->Frm().Top() + pOld->Frm().Height()/2 );
418                     Point aBest;
419                     for( i = 0; (sal_uInt16)i<pPage->GetSortedObjs()->Count(); ++i )
420                     {
421                         SwAnchoredObject* pAnchObj =
422                                                 (*pPage->GetSortedObjs())[i];
423                         if( pAnchObj->ISA(SwFlyFrm) )
424                         {
425                             SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(pAnchObj);
426                             if( pTmp == pOld )
427                                 bOld = sal_True;
428                             else
429                             {
430                                 const SwFlyFrm* pCheck = pFly ? pTmp : 0;
431                                 while( pCheck )
432                                 {
433                                     if( pCheck == pFly )
434                                         break;
435                                     const SwFrm *pNxt = pCheck->GetAnchorFrm();
436                                     pCheck = pNxt ? pNxt->FindFlyFrm() : NULL;
437                                 }
438                                 if( pCheck || pTmp->IsProtected() )
439                                     continue;
440                                 Point aNew( pTmp->Frm().Left() +
441                                             pTmp->Frm().Width()/2,
442                                             pTmp->Frm().Top() +
443                                             pTmp->Frm().Height()/2 );
444                                 sal_Bool bAccept = sal_False;
445                                 switch( nDir ) {
446                                     case SW_MOVE_RIGHT:
447                                     {
448                                         bAccept = LESS_X( aCenter, aNew, bOld )
449                                              && ( !pNewFly ||
450                                              LESS_X( aNew, aBest, sal_False ) );
451                                         break;
452                                     }
453                                     case SW_MOVE_LEFT:
454                                     {
455                                         bAccept = LESS_X( aNew, aCenter, !bOld )
456                                              && ( !pNewFly ||
457                                              LESS_X( aBest, aNew, sal_True ) );
458                                         break;
459                                     }
460                                     case SW_MOVE_UP:
461                                     {
462                                         bAccept = LESS_Y( aNew, aCenter, !bOld )
463                                              && ( !pNewFly ||
464                                              LESS_Y( aBest, aNew, sal_True ) );
465                                         break;
466                                     }
467                                     case SW_MOVE_DOWN:
468                                     {
469                                         bAccept = LESS_Y( aCenter, aNew, bOld )
470                                              && ( !pNewFly ||
471                                              LESS_Y( aNew, aBest, sal_False ) );
472                                         break;
473                                     }
474                                 }
475                                 if( bAccept )
476                                 {
477                                     pNewFly = pTmp;
478                                     aBest = aNew;
479                                 }
480                             }
481                         }
482                     }
483                 }
484 
485                 if( pNewFly )
486                 {
487                     SwPosition aPos( *pNewFly->GetFmt()->
488                                         GetCntnt().GetCntntIdx());
489                     aAnch.SetAnchor( &aPos );
490                     bRet = sal_True;
491                 }
492                 break;
493             }
494             default: break;
495         }
496         if( bRet )
497         {
498             StartAllAction();
499             // --> OD 2006-02-28 #125892#
500             // handle change of anchor node:
501             // if count of the anchor frame also change, the fly frames have to be
502             // re-created. Thus, delete all fly frames except the <this> before the
503             // anchor attribute is change and re-create them afterwards.
504             {
505                 SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
506                 SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
507                 if ( pFlyFrmFmt )
508                 {
509                     pHandleAnchorNodeChg =
510                         new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
511                 }
512                 rFmt.GetDoc()->SetAttr( aAnch, rFmt );
513                 delete pHandleAnchorNodeChg;
514             }
515             // <--
516             // --> OD 2004-06-24 #i28701# - no call of method
517             // <CheckCharRectAndTopOfLine()> for to-character anchored
518             // Writer fly frame needed. This method call can cause a
519             // format of the anchor frame, which is no longer intended.
520                     // Instead clear the anchor character rectangle and
521                     // the top of line values for all to-character anchored objects.
522             pAnchoredObj->ClearCharRectAndTopOfLine();
523             EndAllAction();
524         }
525     }
526     return bRet;
527 }
528 
529 /*************************************************************************
530 |*
531 |*  SwFEShell::GetSelFrmType()
532 |*
533 *************************************************************************/
534 
535 const SdrMarkList* SwFEShell::_GetMarkList() const
536 {
537     const SdrMarkList* pMarkList = NULL;
538     if( Imp()->GetDrawView() != NULL )
539         pMarkList = &Imp()->GetDrawView()->GetMarkedObjectList();
540     return pMarkList;
541 }
542 
543 sal_uInt16 SwFEShell::GetSelFrmType() const
544 {
545     sal_uInt16 eType;
546 
547     // get marked frame list, and check if anything is selected
548     const SdrMarkList* pMarkList = _GetMarkList();
549     if( pMarkList == NULL  ||  pMarkList->GetMarkCount() == 0 )
550         eType = FRMTYPE_NONE;
551     else
552     {
553         // obtain marked item as fly frame; if no fly frame, it must
554         // be a draw object
555         const SwFlyFrm* pFly = ::GetFlyFromMarked(pMarkList, (ViewShell*)this);
556         if ( pFly != NULL )
557         {
558             if( pFly->IsFlyLayFrm() )
559                 eType = FRMTYPE_FLY_FREE;
560             else if( pFly->IsFlyAtCntFrm() )
561                 eType = FRMTYPE_FLY_ATCNT;
562             else
563             {
564                 ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" );
565                 eType = FRMTYPE_FLY_INCNT;
566             }
567         }
568         else
569             eType = FRMTYPE_DRAWOBJ;
570     }
571 
572     return eType;
573 }
574 
575 // #108784# does the draw selection contain a control?
576 bool SwFEShell::IsSelContainsControl() const
577 {
578     bool bRet = false;
579 
580     // basically, copy the mechanism from GetSelFrmType(), but call
581     // CheckControl... if you get a drawing object
582     const SdrMarkList* pMarkList = _GetMarkList();
583     if( pMarkList != NULL  &&  pMarkList->GetMarkCount() == 1 )
584     {
585         // if we have one marked object, get the SdrObject and check
586         // whether it contains a control
587         const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
588         bRet = pSdrObject && ::CheckControlLayer( pSdrObject );
589     }
590     return bRet;
591 }
592 
593 /*************************************************************************
594 |*
595 |*  SwFEShell::Scroll()
596 |*
597 *************************************************************************/
598 
599 void SwFEShell::ScrollTo( const Point &rPt )
600 {
601     const SwRect aRect( rPt, rPt );
602     if ( IsScrollMDI( this, aRect ) &&
603          (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ||
604           Imp()->IsDragPossible( rPt )) )
605     {
606         //SwSaveHdl aSave( Imp() );
607         ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL );
608     }
609 }
610 
611 /*************************************************************************
612 |*
613 |*  SwFEShell::SetDragMode()
614 |*
615 *************************************************************************/
616 
617 void SwFEShell::SetDragMode( sal_uInt16 eDragMode )
618 {
619     if ( Imp()->HasDrawView() )
620         Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode );
621 }
622 
623 /*************************************************************************
624 |*
625 |*  SwFEShell::BeginDrag()
626 |*
627 *************************************************************************/
628 
629 long SwFEShell::BeginDrag( const Point* pPt, sal_Bool )
630 {
631     SdrView *pView = Imp()->GetDrawView();
632     if ( pView && pView->AreObjectsMarked() )
633     {
634         delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0;
635         SdrHdl* pHdl = pView->PickHandle( *pPt );
636         pView->BegDragObj( *pPt, 0 /*GetWin()*/, pHdl );
637         ::FrameNotify( this, FLY_DRAG );
638         return 1;
639     }
640     return 0;
641 }
642 /*************************************************************************
643 |*
644 |*  SwFEShell::Drag()
645 |*
646 *************************************************************************/
647 
648 long SwFEShell::Drag( const Point *pPt, sal_Bool )
649 {
650     ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" );
651     if ( Imp()->GetDrawView()->IsDragObj() )
652     {
653         ScrollTo( *pPt );
654         Imp()->GetDrawView()->MovDragObj( *pPt );
655         Imp()->GetDrawView()->ShowDragAnchor();
656         ::FrameNotify( this, FLY_DRAG );
657         return 1;
658     }
659     return 0;
660 }
661 
662 /*************************************************************************
663 |*
664 |*  SwFEShell::EndDrag()
665 |*
666 *************************************************************************/
667 
668 long SwFEShell::EndDrag( const Point *, sal_Bool )
669 {
670     ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" );
671     SdrView *pView = Imp()->GetDrawView();
672     if ( pView->IsDragObj() )
673     {
674         //Start-/EndActions nur an der ViewShell aufsetzen
675         ViewShell *pSh = this;
676         do {
677             pSh->StartAction();
678         } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
679 
680         StartUndo( UNDO_START );
681 
682         //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen.
683         //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder
684         //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das
685         //Xor also wieder zur Anzeige bringen.
686 
687         // Reanimation from the hack #50778 to fix bug #97057
688         // May be not the best solution, but the one with lowest risc at the moment.
689         //pView->ShowShownXor( GetOut() );
690 
691         pView->EndDragObj();
692         // DrawUndo-Action auf FlyFrames werden nicht gespeichert
693         //              Die Fly aendern das Flag
694         GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
695         ChgAnchor( 0, sal_True );
696 
697         EndUndo( UNDO_END );
698 
699         do {
700             pSh->EndAction();
701             if( pSh->IsA( TYPE( SwCrsrShell ) ) )
702                 ((SwCrsrShell*)pSh)->CallChgLnk();
703         } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
704 
705         GetDoc()->SetModified();
706         ::FrameNotify( this, FLY_DRAG );
707         return 1;
708     }
709     return 0;
710 }
711 
712 /*************************************************************************
713 |*
714 |*  SwFEShell::BreakDrag()
715 |*
716 *************************************************************************/
717 
718 void SwFEShell::BreakDrag()
719 {
720     ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
721     if ( Imp()->GetDrawView()->IsDragObj() )
722         Imp()->GetDrawView()->BrkDragObj();
723     SetChainMarker();
724 }
725 
726 /*************************************************************************
727 |*
728 |*  SwFEShell::SelFlyGrabCrsr()
729 |*
730 |*  Beschreibung        Wenn ein Fly selektiert ist, zieht er den Crsr in
731 |*                      den ersten CntntFrm
732 *************************************************************************/
733 
734 const SwFrmFmt* SwFEShell::SelFlyGrabCrsr()
735 {
736     if ( Imp()->HasDrawView() )
737     {
738         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
739         SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
740 
741         if( pFly )
742         {
743             SwCntntFrm *pCFrm = pFly->ContainsCntnt();
744             if ( pCFrm )
745             {
746                 SwCntntNode *pCNode = pCFrm->GetNode();
747                 // --> OD 2007-07-25 #126039#
748                 // assure, that the cursor is consistent.
749                 KillPams();
750                 ClearMark();
751                 // <--
752                 SwPaM       *pCrsr  = GetCrsr();
753 
754                 pCrsr->GetPoint()->nNode = *pCNode;
755                 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
756 
757                 SwRect& rChrRect = (SwRect&)GetCharRect();
758                 rChrRect = pFly->Prt();
759                 rChrRect.Pos() += pFly->Frm().Pos();
760                 GetCrsrDocPos() = rChrRect.Pos();
761             }
762             return pFly->GetFmt();
763         }
764     }
765     return 0;
766 }
767 
768 
769 /*************************************************************************
770 |*
771 |*  SwFEShell::SelectionToTop(), SelectionToBottom()
772 |*
773 |*  Beschreibung        Selektion nach oben/unten (Z-Order)
774 |*
775 *************************************************************************/
776 
777 void lcl_NotifyNeighbours( const SdrMarkList *pLst )
778 {
779     //Die Regeln fuer die Ausweichmanoever haben sich veraendert.
780     //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt
781     //   werden.
782     //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden.
783     //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden.
784     //4. Auch Zeichenobjekte koennen Rahmen verdraengen
785 
786     for( sal_uInt16 j = 0; j < pLst->GetMarkCount(); ++j )
787     {
788         SwPageFrm *pPage;
789         sal_Bool bCheckNeighbours = sal_False;
790         sal_Int16 aHori = text::HoriOrientation::NONE;
791         SwRect aRect;
792         SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
793         if ( pO->ISA(SwVirtFlyDrawObj) )
794         {
795             SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
796 
797             const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
798             aHori = rHori.GetHoriOrient();
799             if( text::HoriOrientation::NONE != aHori && text::HoriOrientation::CENTER != aHori &&
800                 pFly->IsFlyAtCntFrm() )
801             {
802                 bCheckNeighbours = sal_True;
803                 pFly->InvalidatePos();
804                 pFly->Frm().Pos().Y() += 1;
805             }
806 
807             pPage = pFly->FindPageFrm();
808             aRect = pFly->Frm();
809         }
810         else
811         {
812             SwFrm* pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchorFrm( pO );
813             if( !pAnch )
814                 continue;
815             pPage = pAnch->FindPageFrm();
816             // --> OD 2006-08-15 #i68520# - naming changed
817             aRect = GetBoundRectOfAnchoredObj( pO );
818             // <--
819         }
820 
821         sal_uInt32 nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0;
822         for ( sal_uInt32 i = 0; i < nCount; ++i )
823         {
824             SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i];
825             if ( !pAnchoredObj->ISA(SwFlyFrm) )
826                 continue;
827 
828             SwFlyFrm* pAct = static_cast<SwFlyFrm*>(pAnchoredObj);
829             SwRect aTmpCalcPnt( pAct->Prt() );
830             aTmpCalcPnt += pAct->Frm().Pos();
831             if ( aRect.IsOver( aTmpCalcPnt ) )
832             {
833                 SwCntntFrm *pCnt = pAct->ContainsCntnt();
834                 while ( pCnt )
835                 {
836                     aTmpCalcPnt = pCnt->Prt();
837                     aTmpCalcPnt += pCnt->Frm().Pos();
838                     if ( aRect.IsOver( aTmpCalcPnt ) )
839                         ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG );
840                     pCnt = pCnt->GetNextCntntFrm();
841                 }
842             }
843             if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() )
844             {
845                 const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient();
846                 if ( rH.GetHoriOrient() == aHori &&
847                      pAct->Frm().Top()    <= aRect.Bottom() &&
848                      pAct->Frm().Bottom() >= aRect.Top() )
849                 {
850                     pAct->InvalidatePos();
851                     pAct->Frm().Pos().Y() += 1;
852                 }
853             }
854         }
855     }
856 }
857 
858 void SwFEShell::SelectionToTop( sal_Bool bTop )
859 {
860     ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
861     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
862     ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
863 
864     SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
865     if ( pFly && pFly->IsFlyInCntFrm() )
866         return;
867 
868     StartAllAction();
869     if ( bTop )
870         Imp()->GetDrawView()->PutMarkedToTop();
871     else
872         Imp()->GetDrawView()->MovMarkedToTop();
873     ::lcl_NotifyNeighbours( &rMrkList );
874     GetDoc()->SetModified();
875     EndAllAction();
876 }
877 
878 void SwFEShell::SelectionToBottom( sal_Bool bBottom )
879 {
880     ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
881     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
882     ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
883 
884     SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
885     if ( pFly && pFly->IsFlyInCntFrm() )
886         return;
887 
888     StartAllAction();
889     if ( bBottom )
890         Imp()->GetDrawView()->PutMarkedToBtm();
891     else
892         Imp()->GetDrawView()->MovMarkedToBtm();
893     ::lcl_NotifyNeighbours( &rMrkList );
894     GetDoc()->SetModified();
895     EndAllAction();
896 }
897 
898 /*************************************************************************
899 |*
900 |*  SwFEShell::GetLayerId()
901 |*
902 |*  Beschreibung        Objekt ueber/unter dem Dokument?
903 |*                      2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig
904 *************************************************************************/
905 
906 short SwFEShell::GetLayerId() const
907 {
908     short nRet = SHRT_MAX;
909     if ( Imp()->HasDrawView() )
910     {
911         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
912         for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
913         {
914             const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
915             if( !pObj )
916                 continue;
917             if ( nRet == SHRT_MAX )
918                 nRet = pObj->GetLayer();
919             else if ( nRet != pObj->GetLayer() )
920             {
921                 nRet = -1;
922                 break;
923             }
924         }
925     }
926     if ( nRet == SHRT_MAX )
927         nRet = -1;
928     return nRet;
929 }
930 
931 /*************************************************************************
932 |*
933 |*  SwFEShell::SelectionToHeaven(), SelectionToHell()
934 |*
935 |*  Beschreibung        Objekt ueber/unter dem Dokument
936 |*
937 *************************************************************************/
938 // OD 25.06.2003 #108784#
939 // Note: only visible objects can be marked. Thus, objects with invisible
940 //       layer IDs have not to be considered.
941 //       If <SwFEShell> exists, layout exists!!
942 void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
943 {
944     if ( Imp()->HasDrawView() )
945     {
946         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
947         const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
948         // OD 25.06.2003 #108784# - correct type of <nControls>
949         for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
950         {
951             SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
952             if( !pObj )
953                 continue;
954             // OD 21.08.2003 #i18447# - no change of layer for controls
955             // or group objects containing controls.
956             // --> OD 2010-09-14 #i113730#
957             // consider that a member of a drawing group has been selected.
958             const SwContact* pContact = ::GetUserCall( pObj );
959             ASSERT( pContact && pContact->GetMaster(), "<SwFEShell::ChangeOpaque(..)> - missing contact or missing master object at contact!" );
960             const bool bControlObj = ( pContact && pContact->GetMaster() )
961                                      ? ::CheckControlLayer( pContact->GetMaster() )
962                                      : ::CheckControlLayer( pObj );
963             // <--
964             if ( !bControlObj && pObj->GetLayer() != nLayerId )
965             {
966                 pObj->SetLayer( nLayerId );
967                 InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) );
968                 if ( pObj->ISA(SwVirtFlyDrawObj) )
969                 {
970                     SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
971                     SvxOpaqueItem aOpa( pFmt->GetOpaque() );
972                     aOpa.SetValue(  nLayerId == pIDDMA->GetHellId() );
973                     pFmt->SetFmtAttr( aOpa );
974                 }
975             }
976         }
977         GetDoc()->SetModified();
978     }
979 }
980 
981 void SwFEShell::SelectionToHeaven()
982 {
983     ChangeOpaque( getIDocumentDrawModelAccess()->GetHeavenId() );
984 }
985 
986 void SwFEShell::SelectionToHell()
987 {
988     ChangeOpaque( getIDocumentDrawModelAccess()->GetHellId() );
989 }
990 
991 /*************************************************************************
992 |*
993 |*  SwFEShell::IsObjSelected(), IsFrmSelected()
994 |*
995 *************************************************************************/
996 
997 sal_uInt16 SwFEShell::IsObjSelected() const
998 {
999     if ( IsFrmSelected() || !Imp()->HasDrawView() )
1000         return 0;
1001     else
1002         return sal_uInt16( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() );
1003 }
1004 
1005 sal_Bool SwFEShell::IsFrmSelected() const
1006 {
1007     if ( !Imp()->HasDrawView() )
1008         return sal_False;
1009     else
1010         return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
1011                                         (ViewShell*)this );
1012 }
1013 
1014 sal_Bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const
1015 {
1016     if ( IsFrmSelected() || !Imp()->HasDrawView() )
1017         return sal_False;
1018     else
1019         return Imp()->GetDrawView()
1020                     ->IsObjMarked( const_cast< SdrObject * >( &rObj ) );
1021 }
1022 
1023 /*************************************************************************
1024 |*
1025 |*  SwFEShell::EndTextEdit()
1026 |*
1027 *************************************************************************/
1028 
1029 void SwFEShell::EndTextEdit()
1030 {
1031     //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt
1032     //keinen Text mehr enthaelt und keine Attribute traegt) wird das
1033     //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten.
1034 
1035     ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
1036             "EndTextEdit an no Object" );
1037 
1038     StartAllAction();
1039     SdrView *pView = Imp()->GetDrawView();
1040     SdrObject *pObj = pView->GetTextEditObject();
1041     SdrObjUserCall* pUserCall;
1042     if( 0 != ( pUserCall = GetUserCall(pObj) ) )
1043     {
1044         SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster();
1045         if( !pTmp )
1046             pTmp = pObj;
1047         pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() );
1048     }
1049     if ( !pObj->GetUpGroup() )
1050     {
1051         if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) )
1052         {
1053             if ( pView->GetMarkedObjectList().GetMarkCount() > 1 )
1054             {
1055                 {
1056                     SdrMarkList aSave( pView->GetMarkedObjectList() );
1057                     aSave.DeleteMark( aSave.FindObject( pObj ) );
1058                     if ( aSave.GetMarkCount() )
1059                     {
1060                         pView->UnmarkAll();
1061                         pView->MarkObj( pObj, Imp()->GetPageView() );
1062                     }
1063                     DelSelectedObj();
1064                     if ( aSave.GetMarkCount() )
1065                     {
1066                         for ( sal_uInt16 i = 0; i < aSave.GetMarkCount(); ++i )
1067                             pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(),
1068                                             Imp()->GetPageView() );
1069                     }
1070                 }
1071             }
1072             else
1073                 DelSelectedObj();
1074         }
1075     }
1076     else
1077         pView->SdrEndTextEdit();
1078     EndAllAction();
1079 }
1080 
1081 /*************************************************************************
1082 |*
1083 |*  SwFEShell::IsInsideSelectedObj()
1084 |*
1085 *************************************************************************/
1086 
1087 int SwFEShell::IsInsideSelectedObj( const Point &rPt )
1088 {
1089     if( Imp()->HasDrawView() )
1090     {
1091         SwDrawView *pDView = Imp()->GetDrawView();
1092 
1093         if( pDView->GetMarkedObjectList().GetMarkCount() &&
1094             pDView->IsMarkedObjHit( rPt ) )
1095         {
1096             return SDRHIT_OBJECT;
1097         }
1098     }
1099     return SDRHIT_NONE;
1100 }
1101 
1102 /*************************************************************************
1103 |*
1104 |*  SwFEShell::IsObjSelectable()
1105 |*
1106 *************************************************************************/
1107 
1108 bool SwFEShell::IsObjSelectable( const Point& rPt )
1109 {
1110     SET_CURR_SHELL(this);
1111 #ifdef OLD
1112     if( Imp()->HasDrawView() )
1113         return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE );
1114     return 0;
1115 #else
1116     SwDrawView *pDView = Imp()->GetDrawView();
1117     bool bRet = false;
1118     if( pDView )
1119     {
1120         SdrObject* pObj;
1121         SdrPageView* pPV;
1122         sal_uInt16 nOld = pDView->GetHitTolerancePixel();
1123         pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1124 
1125         bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE );
1126         pDView->SetHitTolerancePixel( nOld );
1127     }
1128     return bRet;
1129 #endif
1130 }
1131 
1132 // #107513#
1133 // Test if there is a object at that position and if it should be selected.
1134 sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
1135 {
1136     SET_CURR_SHELL(this);
1137     SwDrawView *pDrawView = Imp()->GetDrawView();
1138     sal_Bool bRet(sal_False);
1139 
1140     if(pDrawView)
1141     {
1142         SdrObject* pObj;
1143         SdrPageView* pPV;
1144         sal_uInt16 nOld(pDrawView->GetHitTolerancePixel());
1145 
1146         pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2);
1147         bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE);
1148         pDrawView->SetHitTolerancePixel(nOld);
1149 
1150         if ( bRet && pObj )
1151         {
1152             const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
1153             // --> OD 2009-12-30 #i89920#
1154             // Do not select object in background which is overlapping this text
1155             // at the given position.
1156             bool bObjInBackground( false );
1157             {
1158                 if ( pObj->GetLayer() == pIDDMA->GetHellId() )
1159                 {
1160                     const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
1161                     const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1162                     const SwFmtSurround& rSurround = rFmt.GetSurround();
1163                     if ( rSurround.GetSurround() == SURROUND_THROUGHT )
1164                     {
1165                         bObjInBackground = true;
1166                     }
1167                 }
1168             }
1169             if ( bObjInBackground )
1170             {
1171                 const SwPageFrm* pPageFrm = GetLayout()->GetPageAtPos( rPt );
1172                 if( pPageFrm )
1173                 {
1174                     const SwCntntFrm* pCntntFrm( pPageFrm->ContainsCntnt() );
1175                     while ( pCntntFrm )
1176                     {
1177                         if ( pCntntFrm->UnionFrm().IsInside( rPt ) )
1178                         {
1179                             const SwTxtFrm* pTxtFrm =
1180                                     dynamic_cast<const SwTxtFrm*>(pCntntFrm);
1181                             if ( pTxtFrm )
1182                             {
1183                                 SwPosition* pPos =
1184                                     new SwPosition( *(pTxtFrm->GetTxtNode()) );
1185                                 Point aTmpPt( rPt );
1186                                 if ( pTxtFrm->GetKeyCrsrOfst( pPos, aTmpPt ) )
1187                                 {
1188                                     SwRect aCursorCharRect;
1189                                     if ( pTxtFrm->GetCharRect( aCursorCharRect, *pPos ) )
1190                                     {
1191                                         if ( aCursorCharRect.IsOver( SwRect( pObj->GetLastBoundRect() ) ) )
1192                                         {
1193                                             bRet = sal_False;
1194                                         }
1195                                     }
1196                                 }
1197                             }
1198                             else
1199                             {
1200                                 bRet = sal_False;
1201                             }
1202                             break;
1203                         }
1204 
1205                         pCntntFrm = pCntntFrm->GetNextCntntFrm();
1206                     }
1207                 }
1208             }
1209             // <--
1210 
1211             if ( bRet )
1212             {
1213                 const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0);
1214                 for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++)
1215                 {
1216                     SdrObject *pCandidate = pPage->GetObj(a);
1217 
1218                     if (pCandidate->ISA(SwVirtFlyDrawObj) &&
1219                        ( (SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt) )
1220                     {
1221                         bRet = sal_False;
1222                     }
1223                 }
1224             }
1225         }
1226     }
1227 
1228     return bRet;
1229 }
1230 
1231 /*************************************************************************
1232 |*
1233 |*  SwFEShell::GotoObj()
1234 |*
1235 |*  Beschreibung        Wenn ein Obj selektiert ist, gehen wir von dessen
1236 |*      TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
1237 |*
1238 *************************************************************************/
1239 /* ------------------------------------
1240  * Beinhaltet das Objekt ein Control oder Gruppen,
1241  * die nur aus Controls bestehen
1242  * --------------------------------------------------*/
1243 sal_Bool lcl_IsControlGroup( const SdrObject *pObj )
1244 {
1245     sal_Bool bRet = sal_False;
1246     if(pObj->ISA(SdrUnoObj))
1247         bRet = sal_True;
1248     else if( pObj->ISA( SdrObjGroup ) )
1249     {
1250         bRet = sal_True;
1251         const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
1252         for ( sal_uInt16 i = 0; i < pLst->GetObjCount(); ++i )
1253             if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) )
1254                 return sal_False;
1255     }
1256     return bRet;
1257 }
1258 
1259 namespace
1260 {
1261     class MarkableObjectsOnly : public ::svx::ISdrObjectFilter
1262     {
1263     public:
1264         MarkableObjectsOnly( SdrPageView* i_pPV )
1265             :m_pPV( i_pPV )
1266         {
1267         }
1268 
1269         virtual bool    includeObject( const SdrObject& i_rObject ) const
1270         {
1271             return m_pPV && m_pPV->GetView().IsObjMarkable( const_cast< SdrObject* >( &i_rObject ), m_pPV );
1272         }
1273 
1274     private:
1275         SdrPageView*    m_pPV;
1276     };
1277 }
1278 
1279 const SdrObject* SwFEShell::GetBestObject( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType, sal_Bool bFlat, const ::svx::ISdrObjectFilter* pFilter )
1280 {
1281     if( !Imp()->HasDrawView() )
1282         return NULL;
1283 
1284     const SdrObject *pBest  = 0,
1285                     *pTop   = 0;
1286 
1287     const long nTmp = bNext ? LONG_MAX : 0;
1288     Point aBestPos( nTmp, nTmp );
1289     Point aTopPos(  nTmp, nTmp );
1290     Point aCurPos;
1291     Point aPos;
1292     sal_Bool bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType);
1293     sal_Bool bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType);
1294 
1295     if( !bNoFly && bNoDraw )
1296     {
1297         SwFlyFrm *pFly = GetCurrFrm( sal_False )->FindFlyFrm();
1298         if( pFly )
1299             pBest = pFly->GetVirtDrawObj();
1300     }
1301     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1302     SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView();
1303 
1304     MarkableObjectsOnly aDefaultFilter( pPV );
1305     if ( !pFilter )
1306         pFilter = &aDefaultFilter;
1307 
1308     if( !pBest || rMrkList.GetMarkCount() == 1 )
1309     {
1310         // Ausgangspunkt bestimmen.
1311         SdrObjList* pList = NULL;
1312         if ( rMrkList.GetMarkCount() )
1313         {
1314             const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
1315             if( pStartObj->ISA(SwVirtFlyDrawObj) )
1316                 aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos();
1317             else
1318                 aPos = pStartObj->GetSnapRect().TopLeft();
1319 
1320             // If an object inside a group is selected, we want to
1321             // iterate over the group members.
1322             if ( ! pStartObj->GetUserCall() )
1323                 pList = pStartObj->GetObjList();
1324         }
1325         else
1326         {
1327             // If no object is selected, we check if we just entered a group.
1328             // In this case we want to iterate over the group members.
1329             aPos = GetCharRect().Center();
1330             const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0;
1331             if ( pStartObj && pStartObj->ISA( SdrObjGroup ) )
1332                 pList = pStartObj->GetSubList();
1333         }
1334 
1335         if ( ! pList )
1336         {
1337             // Here we are if
1338             // A  No object has been selected and no group has been entered or
1339             // B  An object has been selected and it is not inside a group
1340             pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 );
1341         }
1342 
1343 
1344         ASSERT( pList, "No object list to iterate" )
1345 
1346         SdrObjListIter aObjIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS );
1347         while ( aObjIter.IsMore() )
1348         {
1349             SdrObject* pObj = aObjIter.Next();
1350             sal_Bool bFlyFrm = pObj->ISA(SwVirtFlyDrawObj);
1351             if( ( bNoFly && bFlyFrm ) ||
1352                 ( bNoDraw && !bFlyFrm ) ||
1353                 ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) ||
1354                 ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) ||
1355                 ( pFilter && !pFilter->includeObject( *pObj ) ) )
1356                 continue;
1357             if( bFlyFrm )
1358             {
1359                 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj;
1360                 SwFlyFrm *pFly = pO->GetFlyFrm();
1361                 if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) )
1362                 {
1363                     switch ( eType )
1364                     {
1365                         case GOTOOBJ_FLY_FRM:
1366                             if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1367                                 continue;
1368                         break;
1369                         case GOTOOBJ_FLY_GRF:
1370                             if ( pFly->Lower() &&
1371                                 (pFly->Lower()->IsLayoutFrm() ||
1372                                 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode()))
1373                                 continue;
1374                         break;
1375                         case GOTOOBJ_FLY_OLE:
1376                             if ( pFly->Lower() &&
1377                                 (pFly->Lower()->IsLayoutFrm() ||
1378                                 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode()))
1379                                 continue;
1380                         break;
1381                     }
1382                 }
1383                 aCurPos = pFly->Frm().Pos();
1384             }
1385             else
1386                 aCurPos = pObj->GetCurrentBoundRect().TopLeft();
1387 
1388             // Sonderfall wenn ein anderes Obj auf selber Y steht.
1389             if( aCurPos != aPos &&          // nur wenn ich es nicht selber bin
1390                 aCurPos.Y() == aPos.Y() &&  // ist die Y Position gleich
1391                 (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
1392                         (aCurPos.X() < aPos.X())) ) // " reverse
1393             {
1394                 aBestPos = Point( nTmp, nTmp );
1395                 SdrObjListIter aTmpIter( *pList, bFlat ? IM_FLAT : IM_DEEPNOGROUPS );
1396                 while ( aTmpIter.IsMore() )
1397                 {
1398                     SdrObject* pTmpObj = aTmpIter.Next();
1399                     bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj);
1400                     if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) )
1401                         continue;
1402                     if( bFlyFrm )
1403                     {
1404                         SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj;
1405                         aCurPos = pO->GetFlyFrm()->Frm().Pos();
1406                     }
1407                     else
1408                         aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft();
1409 
1410                     if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
1411                         (bNext? (aCurPos.X() > aPos.X()) :  // liegt neben mir
1412                                 (aCurPos.X() < aPos.X())) &&    // " reverse
1413                         (bNext? (aCurPos.X() < aBestPos.X()) :  // besser als Beste
1414                                 (aCurPos.X() > aBestPos.X())) ) // " reverse
1415                     {
1416                         aBestPos = aCurPos;
1417                         pBest = pTmpObj;
1418                     }
1419                 }
1420                 break;
1421             }
1422 
1423             if( (
1424                 (bNext? (aPos.Y() < aCurPos.Y()) :          // nur unter mir
1425                         (aPos.Y() > aCurPos.Y())) &&        // " reverse
1426                 (bNext? (aBestPos.Y() > aCurPos.Y()) :      // naeher drunter
1427                         (aBestPos.Y() < aCurPos.Y()))
1428                     ) ||    // " reverse
1429                         (aBestPos.Y() == aCurPos.Y() &&
1430                 (bNext? (aBestPos.X() > aCurPos.X()) :      // weiter links
1431                         (aBestPos.X() < aCurPos.X()))))     // " reverse
1432 
1433             {
1434                 aBestPos = aCurPos;
1435                 pBest = pObj;
1436             }
1437 
1438             if( (bNext? (aTopPos.Y() > aCurPos.Y()) :       // hoeher als Beste
1439                         (aTopPos.Y() < aCurPos.Y())) ||     // " reverse
1440                         (aTopPos.Y() == aCurPos.Y() &&
1441                 (bNext? (aTopPos.X() > aCurPos.X()) :       // weiter links
1442                         (aTopPos.X() < aCurPos.X()))))      // " reverse
1443             {
1444                 aTopPos = aCurPos;
1445                 pTop = pObj;
1446             }
1447         }
1448         // leider nichts gefunden
1449         if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
1450             pBest = pTop;
1451     }
1452 
1453     return pBest;
1454 }
1455 
1456 sal_Bool SwFEShell::GotoObj( sal_Bool bNext, sal_uInt16 /*GOTOOBJ_...*/ eType )
1457 {
1458     const SdrObject* pBest = GetBestObject( bNext, eType );
1459 
1460     if ( !pBest )
1461         return sal_False;
1462 
1463     sal_Bool bFlyFrm = pBest->ISA(SwVirtFlyDrawObj);
1464     if( bFlyFrm )
1465     {
1466         SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest;
1467         const SwRect& rFrm = pO->GetFlyFrm()->Frm();
1468         SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest );
1469         if( !ActionPend() )
1470             MakeVisible( rFrm );
1471     }
1472     else
1473     {
1474         SelectObj( Point(), 0, (SdrObject*)pBest );
1475         if( !ActionPend() )
1476             MakeVisible( pBest->GetCurrentBoundRect() );
1477     }
1478     CallChgLnk();
1479     return sal_True;
1480 }
1481 
1482 /*************************************************************************
1483 |*
1484 |*  SwFEShell::BeginCreate()
1485 |*
1486 *************************************************************************/
1487 
1488 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/  eSdrObjectKind, const Point &rPos )
1489 {
1490     sal_Bool bRet = sal_False;
1491 
1492     if ( !Imp()->HasDrawView() )
1493         Imp()->MakeDrawView();
1494 
1495     if ( GetPageNumber( rPos ) )
1496     {
1497         Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind );
1498         if ( eSdrObjectKind == OBJ_CAPTION )
1499             bRet = Imp()->GetDrawView()->BegCreateCaptionObj(
1500                         rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ),
1501                         GetOut() );
1502         else
1503             bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1504     }
1505     if ( bRet )
1506     {
1507         ::FrameNotify( this, FLY_DRAG_START );
1508     }
1509     return bRet;
1510 }
1511 
1512 sal_Bool SwFEShell::BeginCreate( sal_uInt16 /*SdrObjKind ?*/  eSdrObjectKind, sal_uInt32 eObjInventor,
1513                              const Point &rPos )
1514 {
1515     sal_Bool bRet = sal_False;
1516 
1517     if ( !Imp()->HasDrawView() )
1518         Imp()->MakeDrawView();
1519 
1520     if ( GetPageNumber( rPos ) )
1521     {
1522         Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor );
1523         bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1524     }
1525     if ( bRet )
1526         ::FrameNotify( this, FLY_DRAG_START );
1527     return bRet;
1528 }
1529 
1530 /*************************************************************************
1531 |*
1532 |*  SwFEShell::MoveCreate()
1533 |*
1534 *************************************************************************/
1535 
1536 void SwFEShell::MoveCreate( const Point &rPos )
1537 {
1538     ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
1539     if ( GetPageNumber( rPos ) )
1540     {
1541         ScrollTo( rPos );
1542         Imp()->GetDrawView()->MovCreateObj( rPos );
1543         ::FrameNotify( this, FLY_DRAG );
1544     }
1545 }
1546 
1547 /*************************************************************************
1548 |*
1549 |*  SwFEShell::EndCreate(), ImpEndCreate()
1550 |*
1551 *************************************************************************/
1552 
1553 sal_Bool SwFEShell::EndCreate( sal_uInt16 eSdrCreateCmd )
1554 {
1555     // Damit das Undo-Object aus der DrawEngine nicht bei uns
1556     // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz
1557     // das Undo abschalten
1558     ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" );
1559     if( !Imp()->GetDrawView()->IsGroupEntered() )
1560     {
1561         GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
1562     }
1563     sal_Bool bCreate = Imp()->GetDrawView()->EndCreateObj(
1564                                     SdrCreateCmd( eSdrCreateCmd ) );
1565     GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
1566 
1567     if ( !bCreate )
1568     {
1569         ::FrameNotify( this, FLY_DRAG_END );
1570         return sal_False;
1571     }
1572 
1573     if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT )
1574     {
1575         ::FrameNotify( this, FLY_DRAG );
1576         return sal_True;
1577     }
1578     return ImpEndCreate();
1579 }
1580 
1581 
1582 sal_Bool SwFEShell::ImpEndCreate()
1583 {
1584     ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1,
1585             "Neues Object nicht selektiert." );
1586 
1587     SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1588 
1589     if( rSdrObj.GetSnapRect().IsEmpty() )
1590     {
1591         // das Object vergessen wir lieber, fuerht nur
1592         //              zu Problemen
1593         Imp()->GetDrawView()->DeleteMarked();
1594         Imp()->GetDrawView()->UnmarkAll();
1595         ::FrameNotify( this, FLY_DRAG_END );
1596         return sal_False;
1597     }
1598 
1599     if( rSdrObj.GetUpGroup() )
1600     {
1601         Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() );
1602         Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() );
1603         // OD 2004-04-05 #i26791# - direct object positioning for group members
1604         rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor );
1605         rSdrObj.NbcSetAnchorPos( aNewAnchor );
1606         ::FrameNotify( this, FLY_DRAG );
1607         return sal_True;
1608     }
1609 
1610     LockPaint();
1611     StartAllAction();
1612 
1613     Imp()->GetDrawView()->UnmarkAll();
1614 
1615     const Rectangle &rBound = rSdrObj.GetSnapRect();
1616     Point aPt( rBound.TopRight() );
1617 
1618     //Fremde Identifier sollen in den Default laufen.
1619     //Ueberschneidungen sind moeglich!!
1620     sal_uInt16 nIdent = SdrInventor == rSdrObj.GetObjInventor()
1621                         ? rSdrObj.GetObjIdentifier()
1622                         : 0xFFFF;
1623 
1624     //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst.
1625     SwFmtAnchor aAnch;
1626     const SwFrm *pAnch = 0;
1627     sal_Bool bCharBound = sal_False;
1628     if( rSdrObj.ISA( SdrUnoObj ) )
1629     {
1630         SwPosition aPos( GetDoc()->GetNodes() );
1631         SwCrsrMoveState aState( MV_SETONLYTEXT );
1632         Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 );
1633         GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState ); //swmod 080317
1634 
1635         //Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt
1636         if( !aPos.nNode.GetNode().IsProtect() )
1637         {
1638             pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, &aPos );
1639             SwRect aTmp;
1640             pAnch->GetCharRect( aTmp, aPos );
1641 
1642             //Der Crsr darf nicht zu weit entfernt sein.
1643             bCharBound = sal_True;
1644             Rectangle aRect( aTmp.SVRect() );
1645             aRect.Left()  -= MM50*2;
1646             aRect.Top()   -= MM50*2;
1647             aRect.Right() += MM50*2;
1648             aRect.Bottom()+= MM50*2;
1649 
1650             if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
1651                 bCharBound = sal_False;
1652 
1653                 //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt.
1654             if( bCharBound )
1655                 bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode );
1656 
1657             if( bCharBound )
1658             {
1659                 aAnch.SetType( FLY_AS_CHAR );
1660                 aAnch.SetAnchor( &aPos );
1661             }
1662         }
1663     }
1664 
1665     if( !bCharBound )
1666     {
1667         // OD 16.05.2003 #108784# - allow native drawing objects in header/footer.
1668         // Thus, set <bBodyOnly> to <false> for these objects using value
1669         // of <nIdent> - value <0xFFFF> indicates control objects, which aren't
1670         // allowed in header/footer.
1671         //bool bBodyOnly = OBJ_NONE != nIdent;
1672         bool bBodyOnly = 0xFFFF == nIdent;
1673         bool bAtPage = false;
1674         const SwFrm* pPage = 0;
1675         SwCrsrMoveState aState( MV_SETONLYTEXT );
1676         Point aPoint( aPt );
1677         SwPosition aPos( GetDoc()->GetNodes() );
1678         GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
1679 
1680         //nicht in ReadnOnly-Inhalt setzen
1681         if( aPos.nNode.GetNode().IsProtect() )
1682             // dann darf er nur seitengebunden sein. Oder sollte man
1683             // die naechste nicht READONLY Position suchen?
1684             bAtPage = true;
1685 
1686         pAnch = aPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPoint, 0, sal_False );
1687 
1688         if( !bAtPage )
1689         {
1690             const SwFlyFrm *pTmp = pAnch->FindFlyFrm();
1691             if( pTmp )
1692             {
1693                 const SwFrm* pTmpFrm = pAnch;
1694                 SwRect aBound( rBound );
1695                 while( pTmp )
1696                 {
1697                     if( pTmp->Frm().IsInside( aBound ) )
1698                     {
1699                         if( !bBodyOnly || !pTmp->FindFooterOrHeader() )
1700                             pPage = pTmpFrm;
1701                         break;
1702                     }
1703                     pTmp = pTmp->GetAnchorFrm()
1704                                 ? pTmp->GetAnchorFrm()->FindFlyFrm()
1705                                 : 0;
1706                     pTmpFrm = pTmp;
1707                 }
1708             }
1709 
1710             if( !pPage )
1711                 pPage = pAnch->FindPageFrm();
1712 
1713             // immer ueber FindAnchor gehen, damit der Frame immer an den
1714             // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum
1715             // nachfolgenden kommen. DAS IST FALSCH
1716             pAnch = ::FindAnchor( pPage, aPt, bBodyOnly );
1717             aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode();
1718 
1719             //nicht in ReadnOnly-Inhalt setzen
1720             if( aPos.nNode.GetNode().IsProtect() )
1721                 // dann darf er nur seitengebunden sein. Oder sollte man
1722                 // die naechste nicht READONLY Position suchen?
1723                 bAtPage = true;
1724             else
1725             {
1726                 aAnch.SetType( FLY_AT_PARA );
1727                 aAnch.SetAnchor( &aPos );
1728             }
1729         }
1730 
1731         if( bAtPage )
1732         {
1733             pPage = pAnch->FindPageFrm();
1734 
1735             aAnch.SetType( FLY_AT_PAGE );
1736             aAnch.SetPageNum( pPage->GetPhyPageNum() );
1737             pAnch = pPage;      // die Page wird jetzt zum Anker
1738         }
1739     }
1740 
1741     SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
1742                                             RES_SURROUND, RES_ANCHOR, 0 );
1743     aSet.Put( aAnch );
1744 
1745     // OD 2004-03-30 #i26791# - determine relative object position
1746     SwTwips nXOffset;
1747     SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top();
1748     {
1749         if( pAnch->IsVertical() )
1750         {
1751             nXOffset = nYOffset;
1752             nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1753         }
1754         else if( pAnch->IsRightToLeft() )
1755             nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1756         else
1757             nXOffset = rBound.Left() - pAnch->Frm().Left();
1758         if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1759         {
1760             SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1761             do {
1762                 pTmp = pTmp->FindMaster();
1763                 ASSERT( pTmp, "Where's my Master?" );
1764                 // OD 2004-03-30 #i26791# - correction: add frame area height
1765                 // of master frames.
1766                 nYOffset += pTmp->IsVertical() ?
1767                             pTmp->Frm().Width() : pTmp->Frm().Height();
1768             } while ( pTmp->IsFollow() );
1769         }
1770     }
1771 
1772     if( OBJ_NONE == nIdent )
1773     {
1774         //Bei OBJ_NONE wird ein Fly eingefuegt.
1775         const long nWidth = rBound.Right()  - rBound.Left();
1776         const long nHeight= rBound.Bottom() - rBound.Top();
1777         aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth,  long(MINFLY) ),
1778                                               Max( nHeight, long(MINFLY) )));
1779 
1780         SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1781         SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1782         aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
1783         aSet.Put( aHori );
1784         aSet.Put( aVert );
1785 
1786         //Schnell noch das Rechteck merken
1787         const SwRect aFlyRect( rBound );
1788 
1789         //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten
1790         //ueber vorhandene SS erzeugt werden.
1791         GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); // see above
1792         // --> OD 2005-08-08 #i52858# - method name changed
1793         SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 );
1794         // <--
1795         if( !pPg )
1796         {
1797             SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel();
1798             pPg = pTmpSdrModel->AllocPage( sal_False );
1799             pTmpSdrModel->InsertPage( pPg );
1800         }
1801         pPg->RecalcObjOrdNums();
1802         SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() );
1803         SdrObject::Free( pRemovedObject );
1804         GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
1805 
1806         SwFlyFrm* pFlyFrm;
1807         if( NewFlyFrm( aSet, sal_True ) &&
1808             ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
1809             0 != ( pFlyFrm = FindFlyFrm() ))
1810         {
1811             SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT );
1812             //Horizontale Ausrichtung:
1813             const sal_Bool bLeftFrm = aFlyRect.Left() <
1814                                       pAnch->Frm().Left() + pAnch->Prt().Left(),
1815                            bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
1816                                       pAnch->Frm().Left() + pAnch->Prt().Width()/2;
1817             if( bLeftFrm || bLeftPrt )
1818             {
1819                 aHori.SetHoriOrient( text::HoriOrientation::LEFT );
1820                 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1821             }
1822             else
1823             {
1824                 const sal_Bool bRightFrm = aFlyRect.Left() >
1825                                            pAnch->Frm().Left() + pAnch->Prt().Width();
1826                 aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
1827                 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1828             }
1829             aHtmlSet.Put( aHori );
1830             aVert.SetVertOrient( text::VertOrientation::TOP );
1831             aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
1832             aHtmlSet.Put( aVert );
1833 
1834             GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() );
1835         }
1836     }
1837     else
1838     {
1839         Point aRelNullPt;
1840         if( OBJ_CAPTION == nIdent )
1841             aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos();
1842         else
1843             aRelNullPt = rBound.TopLeft();
1844 
1845         aSet.Put( aAnch );
1846         aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
1847         // OD 2004-03-30 #i26791# - set horizontal position
1848         SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1849         aSet.Put( aHori );
1850         // OD 2004-03-30 #i26791# - set vertical position
1851         if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1852         {
1853             SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1854             do {
1855                 pTmp = pTmp->FindMaster();
1856                 ASSERT( pTmp, "Where's my Master?" );
1857                 nYOffset += pTmp->IsVertical() ?
1858                             pTmp->Prt().Width() : pTmp->Prt().Height();
1859             } while ( pTmp->IsFollow() );
1860         }
1861         SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1862         aSet.Put( aVert );
1863         SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
1864         // --> OD 2004-10-25 #i36010# - set layout direction of the position
1865         pFmt->SetPositionLayoutDir(
1866             text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
1867         // <--
1868         // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set
1869         pFmt->PosAttrSet();
1870         // <--
1871 
1872         SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj );
1873         // --> OD 2004-11-22 #i35635#
1874         pContact->MoveObjToVisibleLayer( &rSdrObj );
1875         // <--
1876         if( bCharBound )
1877         {
1878             ASSERT( aAnch.GetAnchorId() == FLY_AS_CHAR, "wrong AnchorType" );
1879             SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
1880             SwFmtFlyCnt aFmt( pFmt );
1881             pNd->InsertItem(aFmt,
1882                             aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 );
1883             SwFmtVertOrient aVertical( pFmt->GetVertOrient() );
1884             aVertical.SetVertOrient( text::VertOrientation::LINE_CENTER );
1885             pFmt->SetFmtAttr( aVertical );
1886         }
1887         if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1888         {
1889             SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1890             do {
1891                 pTmp = pTmp->FindMaster();
1892                 ASSERT( pTmp, "Where's my Master?" );
1893             } while( pTmp->IsFollow() );
1894             pAnch = pTmp;
1895         }
1896 
1897         pContact->ConnectToLayout();
1898 
1899         // OD 25.06.2003 #108784# - mark object at frame the object is inserted at.
1900         {
1901             SdrObject* pMarkObj = pContact->GetDrawObjectByAnchorFrm( *pAnch );
1902             if ( pMarkObj )
1903             {
1904                 Imp()->GetDrawView()->MarkObj( pMarkObj, Imp()->GetPageView(),
1905                                                 sal_False, sal_False );
1906             }
1907             else
1908             {
1909                 Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(),
1910                                                 sal_False, sal_False );
1911             }
1912         }
1913     }
1914 
1915     GetDoc()->SetModified();
1916 
1917     KillPams();
1918     EndAllActionAndCall();
1919     UnlockPaint();
1920     return sal_True;
1921 }
1922 
1923 
1924 /*************************************************************************
1925 |*
1926 |*  SwFEShell::BreakCreate()
1927 |*
1928 *************************************************************************/
1929 
1930 void SwFEShell::BreakCreate()
1931 {
1932     ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" );
1933     Imp()->GetDrawView()->BrkCreateObj();
1934     ::FrameNotify( this, FLY_DRAG_END );
1935 }
1936 
1937 /*************************************************************************
1938 |*
1939 |*  SwFEShell::IsDrawCreate()
1940 |*
1941 *************************************************************************/
1942 
1943 sal_Bool SwFEShell::IsDrawCreate() const
1944 {
1945     return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : sal_False;
1946 }
1947 
1948 /*************************************************************************
1949 |*
1950 |*  SwFEShell::BeginMark()
1951 |*
1952 *************************************************************************/
1953 
1954 sal_Bool SwFEShell::BeginMark( const Point &rPos )
1955 {
1956     if ( !Imp()->HasDrawView() )
1957         Imp()->MakeDrawView();
1958 
1959     if ( GetPageNumber( rPos ) )
1960     {
1961         SwDrawView* pDView = Imp()->GetDrawView();
1962 
1963         if (pDView->HasMarkablePoints())
1964             return pDView->BegMarkPoints( rPos );
1965         else
1966             return pDView->BegMarkObj( rPos );
1967     }
1968     else
1969         return sal_False;
1970 }
1971 
1972 /*************************************************************************
1973 |*
1974 |*  SwFEShell::MoveMark()
1975 |*
1976 *************************************************************************/
1977 
1978 void SwFEShell::MoveMark( const Point &rPos )
1979 {
1980     ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" );
1981 
1982     if ( GetPageNumber( rPos ) )
1983     {
1984         ScrollTo( rPos );
1985         SwDrawView* pDView = Imp()->GetDrawView();
1986 //      Imp()->GetDrawView()->MovMarkObj( rPos );
1987 
1988         if (pDView->IsInsObjPoint())
1989             pDView->MovInsObjPoint( rPos );
1990         else if (pDView->IsMarkPoints())
1991             pDView->MovMarkPoints( rPos );
1992         else
1993             pDView->MovAction( rPos );
1994     }
1995 }
1996 
1997 /*************************************************************************
1998 |*
1999 |*  SwFEShell::EndMark()
2000 |*
2001 *************************************************************************/
2002 
2003 sal_Bool SwFEShell::EndMark()
2004 {
2005     sal_Bool bRet = sal_False;
2006     ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" );
2007 
2008     if (Imp()->GetDrawView()->IsMarkObj())
2009     {
2010         bRet = Imp()->GetDrawView()->EndMarkObj();
2011 
2012         if ( bRet )
2013         {
2014             sal_Bool bShowHdl = sal_False;
2015             SwDrawView* pDView = Imp()->GetDrawView();
2016             //Rahmen werden auf diese Art nicht Selektiert, es sein denn es
2017             //ist nur ein Rahmen.
2018             SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkedObjectList();
2019             SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
2020 
2021             if ( rMrkList.GetMarkCount() > 1 )
2022                 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2023                 {
2024                     SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2025                     if( pObj->ISA(SwVirtFlyDrawObj) )
2026                     {
2027                         if ( !bShowHdl )
2028                         {
2029                             //HMHpDView->HideMarkHdl();
2030                             bShowHdl = sal_True;
2031                         }
2032                         rMrkList.DeleteMark( i );
2033                         --i;    //keinen auslassen.
2034                     }
2035                 }
2036 
2037             if( bShowHdl )
2038             {
2039                 pDView->MarkListHasChanged();
2040                 pDView->AdjustMarkHdl();
2041                 //HMHpDView->ShowMarkHdl();
2042             }
2043 
2044             if ( rMrkList.GetMarkCount() )
2045                 ::lcl_GrabCursor(this, pOldSelFly);
2046             else
2047                 bRet = sal_False;
2048         }
2049         if ( bRet )
2050             ::FrameNotify( this, FLY_DRAG_START );
2051     }
2052     else
2053     {
2054         if (Imp()->GetDrawView()->IsMarkPoints())
2055             bRet = Imp()->GetDrawView()->EndMarkPoints();
2056     }
2057 
2058     SetChainMarker();
2059     return bRet;
2060 }
2061 
2062 /*************************************************************************
2063 |*
2064 |*  SwFEShell::BreakSelect()
2065 |*
2066 *************************************************************************/
2067 
2068 void SwFEShell::BreakMark()
2069 {
2070     ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" );
2071     Imp()->GetDrawView()->BrkMarkObj();
2072 }
2073 
2074 /*************************************************************************
2075 |*
2076 |*  SwFEShell::GetAnchorId()
2077 |*
2078 *************************************************************************/
2079 
2080 short SwFEShell::GetAnchorId() const
2081 {
2082     short nRet = SHRT_MAX;
2083     if ( Imp()->HasDrawView() )
2084     {
2085         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2086         for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2087         {
2088             SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2089             if ( pObj->ISA(SwVirtFlyDrawObj) )
2090             {
2091                 nRet = -1;
2092                 break;
2093             }
2094             SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2095             short nId = static_cast<short>(pContact->GetFmt()->GetAnchor().GetAnchorId());
2096             if ( nRet == SHRT_MAX )
2097                 nRet = nId;
2098             else if ( nRet != nId )
2099             {
2100                 nRet = -1;
2101                 break;
2102             }
2103         }
2104     }
2105     if ( nRet == SHRT_MAX )
2106         nRet = -1;
2107     return nRet;
2108 }
2109 
2110 /*************************************************************************
2111 |*
2112 |*  SwFEShell::ChgAnchor()
2113 |*
2114 *************************************************************************/
2115 
2116 void SwFEShell::ChgAnchor( int eAnchorId, sal_Bool bSameOnly, sal_Bool bPosCorr )
2117 {
2118     ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" );
2119     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2120     if( rMrkList.GetMarkCount() &&
2121         !rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
2122     {
2123         StartAllAction();
2124 
2125         if( GetDoc()->ChgAnchor( rMrkList, (RndStdIds)eAnchorId, bSameOnly, bPosCorr ))
2126             Imp()->GetDrawView()->UnmarkAll();
2127 
2128         EndAllAction();
2129 
2130         ::FrameNotify( this, FLY_DRAG );
2131     }
2132 }
2133 
2134 /*************************************************************************
2135 |*
2136 |*  SwFEShell::DelSelectedObj()
2137 |*
2138 *************************************************************************/
2139 
2140 void SwFEShell::DelSelectedObj()
2141 {
2142     ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" );
2143     if ( Imp()->HasDrawView() )
2144     {
2145         StartAllAction();
2146         Imp()->GetDrawView()->DeleteMarked();
2147         EndAllAction();
2148         ::FrameNotify( this, FLY_DRAG_END );
2149     }
2150 }
2151 
2152 /*************************************************************************
2153 |*
2154 |*  SwFEShell::GetObjSize(), GetAnchorObjDiff()
2155 |*
2156 |*  Beschreibung        Fuer die Statuszeile zum Erfragen der aktuellen
2157 |*                      Verhaeltnisse
2158 |*
2159 *************************************************************************/
2160 
2161 Size SwFEShell::GetObjSize() const
2162 {
2163     Rectangle aRect;
2164     if ( Imp()->HasDrawView() )
2165     {
2166         if ( Imp()->GetDrawView()->IsAction() )
2167             Imp()->GetDrawView()->TakeActionRect( aRect );
2168         else
2169             aRect = Imp()->GetDrawView()->GetAllMarkedRect();
2170     }
2171     return aRect.GetSize();
2172 }
2173 
2174 Point SwFEShell::GetAnchorObjDiff() const
2175 {
2176     const SdrView *pView = Imp()->GetDrawView();
2177     ASSERT( pView, "GetAnchorObjDiff without DrawView?" );
2178 
2179     Rectangle aRect;
2180     if ( Imp()->GetDrawView()->IsAction() )
2181         Imp()->GetDrawView()->TakeActionRect( aRect );
2182     else
2183         aRect = Imp()->GetDrawView()->GetAllMarkedRect();
2184 
2185     Point aRet( aRect.TopLeft() );
2186 
2187     if ( IsFrmSelected() )
2188     {
2189         SwFlyFrm *pFly = FindFlyFrm();
2190         aRet -= pFly->GetAnchorFrm()->Frm().Pos();
2191     }
2192     else
2193     {
2194         const SdrObject *pObj = pView->GetMarkedObjectList().GetMarkCount() == 1 ?
2195                                 pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : 0;
2196         if ( pObj )
2197             aRet -= pObj->GetAnchorPos();
2198     }
2199 
2200     return aRet;
2201 }
2202 
2203 Point SwFEShell::GetObjAbsPos() const
2204 {
2205     ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" );
2206     return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
2207 }
2208 
2209 
2210 
2211 /*************************************************************************
2212 |*
2213 |*  SwFEShell::IsGroupSelected()
2214 |*
2215 *************************************************************************/
2216 
2217 sal_Bool SwFEShell::IsGroupSelected()
2218 {
2219     if ( IsObjSelected() )
2220     {
2221         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2222         for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2223         {
2224             SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2225             // OD 30.06.2003 #108784# - consider 'virtual' drawing objects.
2226             // Thus, use corresponding method instead of checking type.
2227             if ( pObj->IsGroupObject() &&
2228                  // --> FME 2004-12-08 #i38505# No ungroup allowed for 3d objects
2229                  !pObj->Is3DObj() &&
2230                  // <--
2231                  FLY_AS_CHAR != ((SwDrawContact*)GetUserCall(pObj))->
2232                                       GetFmt()->GetAnchor().GetAnchorId() )
2233             {
2234                 return sal_True;
2235             }
2236         }
2237     }
2238     return sal_False;
2239 }
2240 
2241 // OD 27.06.2003 #108784# - change return type.
2242 // OD 27.06.2003 #108784# - adjustments for drawing objects in header/footer:
2243 //      allow group, only if all selected objects are in the same header/footer
2244 //      or not in header/footer.
2245 bool SwFEShell::IsGroupAllowed() const
2246 {
2247     bool bIsGroupAllowed = false;
2248     if ( IsObjSelected() > 1 )
2249     {
2250         bIsGroupAllowed = true;
2251         const SdrObject* pUpGroup = 0L;
2252         const SwFrm* pHeaderFooterFrm = 0L;
2253         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2254         for ( sal_uInt16 i = 0; bIsGroupAllowed && i < rMrkList.GetMarkCount(); ++i )
2255         {
2256             const SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2257             if ( i )
2258                 bIsGroupAllowed = pObj->GetUpGroup() == pUpGroup;
2259             else
2260                 pUpGroup = pObj->GetUpGroup();
2261 
2262             if ( bIsGroupAllowed )
2263             {
2264                 SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) );
2265                 if ( !pFrmFmt )
2266                 {
2267                     ASSERT( false,
2268                             "<SwFEShell::IsGroupAllowed()> - missing frame format" );
2269                     bIsGroupAllowed = false;
2270                 }
2271                 else if ( FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
2272                 {
2273                     bIsGroupAllowed = false;
2274                 }
2275             }
2276 
2277             // OD 27.06.2003 #108784# - check, if all selected objects are in the
2278             // same header/footer or not in header/footer.
2279             if ( bIsGroupAllowed )
2280             {
2281                 const SwFrm* pAnchorFrm = 0L;
2282                 if ( pObj->ISA(SwVirtFlyDrawObj) )
2283                 {
2284                     const SwFlyFrm* pFlyFrm =
2285                             static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
2286                     if ( pFlyFrm )
2287                     {
2288                         pAnchorFrm = pFlyFrm->GetAnchorFrm();
2289                     }
2290                 }
2291                 else
2292                 {
2293                     SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
2294                     if ( pDrawContact )
2295                     {
2296                         pAnchorFrm = pDrawContact->GetAnchorFrm( pObj );
2297                     }
2298                 }
2299                 if ( pAnchorFrm )
2300                 {
2301                     if ( i )
2302                     {
2303                         bIsGroupAllowed =
2304                             ( pAnchorFrm->FindFooterOrHeader() == pHeaderFooterFrm );
2305                     }
2306                     else
2307                     {
2308                         pHeaderFooterFrm = pAnchorFrm->FindFooterOrHeader();
2309                     }
2310                 }
2311             }
2312 
2313         }
2314     }
2315 
2316     return bIsGroupAllowed;
2317 }
2318 
2319 /*************************************************************************
2320 |*
2321 |*  SwFEShell::GroupSelection()
2322 |*
2323 |*  Beschreibung        Die Gruppe bekommt den Anker und das Contactobjekt
2324 |*                      des ersten in der Selektion
2325 |*
2326 *************************************************************************/
2327 
2328 void SwFEShell::GroupSelection()
2329 {
2330     if ( IsGroupAllowed() )
2331     {
2332         StartAllAction();
2333         StartUndo( UNDO_START );
2334 
2335         GetDoc()->GroupSelection( *Imp()->GetDrawView() );
2336 
2337         EndUndo( UNDO_END );
2338         EndAllAction();
2339     }
2340 }
2341 
2342 /*************************************************************************
2343 |*
2344 |*  SwFEShell::UnGroupSelection()
2345 |*
2346 |*  Beschreibung        Die Einzelobjekte bekommen eine Kopie vom Anker und
2347 |*                      Contactobjekt der Gruppe.
2348 |*
2349 *************************************************************************/
2350 
2351 void SwFEShell::UnGroupSelection()
2352 {
2353     if ( IsGroupSelected() )
2354     {
2355         StartAllAction();
2356         StartUndo( UNDO_START );
2357 
2358         GetDoc()->UnGroupSelection( *Imp()->GetDrawView() );
2359 
2360         EndUndo( UNDO_END );
2361         EndAllAction();
2362     }
2363 }
2364 
2365 /*************************************************************************
2366 |*
2367 |*  SwFEShell::MirrorSelection()
2368 |*
2369 *************************************************************************/
2370 
2371 void SwFEShell::MirrorSelection( sal_Bool bHorizontal )
2372 {
2373     SdrView *pView = Imp()->GetDrawView();
2374     if ( IsObjSelected() && pView->IsMirrorAllowed() )
2375     {
2376         if ( bHorizontal )
2377             pView->MirrorAllMarkedHorizontal();
2378         else
2379             pView->MirrorAllMarkedVertical();
2380     }
2381 }
2382 
2383 // springe zum benannten Rahmen (Grafik/OLE)
2384 
2385 sal_Bool SwFEShell::GotoFly( const String& rName, FlyCntType eType, sal_Bool bSelFrm )
2386 {
2387     sal_Bool bRet = sal_False;
2388 static sal_uInt8 __READONLY_DATA aChkArr[ 4 ] = {
2389              /* FLYCNTTYPE_ALL */   0,
2390              /* FLYCNTTYPE_FRM */   ND_TEXTNODE,
2391              /* FLYCNTTYPE_GRF */   ND_GRFNODE,
2392              /* FLYCNTTYPE_OLE */   ND_OLENODE
2393             };
2394 
2395     const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]);
2396     if( pFlyFmt )
2397     {
2398         SET_CURR_SHELL( this );
2399 
2400         SwFlyFrm* pFrm = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFlyFmt );
2401         if( pFrm )
2402         {
2403             if( bSelFrm )
2404             {
2405                 SelectObj( pFrm->Frm().Pos(), 0, pFrm->GetVirtDrawObj() );
2406                 if( !ActionPend() )
2407                     MakeVisible( pFrm->Frm() );
2408             }
2409             else
2410             {
2411                 // --> OD 2004-06-11 #i28701# - no format here
2412 //                pFrm->GetAnchorFrm()->Calc();
2413                 SwCntntFrm *pCFrm = pFrm->ContainsCntnt();
2414                 if ( pCFrm )
2415                 {
2416                     SwCntntNode *pCNode = pCFrm->GetNode();
2417                     ClearMark();
2418                     SwPaM* pCrsr = GetCrsr();
2419 
2420                     pCrsr->GetPoint()->nNode = *pCNode;
2421                     pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
2422 
2423                     SwRect& rChrRect = (SwRect&)GetCharRect();
2424                     rChrRect = pFrm->Prt();
2425                     rChrRect.Pos() += pFrm->Frm().Pos();
2426                     GetCrsrDocPos() = rChrRect.Pos();
2427                 }
2428             }
2429             bRet = sal_True;
2430         }
2431     }
2432     return bRet;
2433 }
2434 
2435 sal_uInt16 SwFEShell::GetFlyCount( FlyCntType eType ) const
2436 {
2437     return GetDoc()->GetFlyCount(eType);
2438 }
2439 
2440 
2441 const SwFrmFmt*  SwFEShell::GetFlyNum(sal_uInt16 nIdx, FlyCntType eType ) const
2442 {
2443     return GetDoc()->GetFlyNum(nIdx, eType );
2444 }
2445 
2446 // zeige das akt. selektierte "Object" an
2447 void SwFEShell::MakeSelVisible()
2448 {
2449     if( Imp()->HasDrawView() &&
2450         Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2451     {
2452         MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() );
2453     }
2454     else
2455         SwCrsrShell::MakeSelVisible();
2456 }
2457 
2458 
2459 //Welcher Schutz ist am selektierten Objekt gesetzt?
2460 sal_uInt8 SwFEShell::IsSelObjProtected( sal_uInt16 eType ) const
2461 {
2462     int nChk = 0;
2463     const bool bParent = (eType & FLYPROTECT_PARENT);
2464     if( Imp()->HasDrawView() )
2465     {
2466         const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2467         for( sal_uLong i = rMrkList.GetMarkCount(); i; )
2468         {
2469             SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj();
2470             if( !bParent )
2471             {
2472                 nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) |
2473                         ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 );
2474 
2475                 if( pObj->ISA(SwVirtFlyDrawObj) )
2476                 {
2477                     SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2478                     if ( (FLYPROTECT_CONTENT & eType) && pFly->GetFmt()->GetProtect().IsCntntProtected() )
2479                         nChk |= FLYPROTECT_CONTENT;
2480 
2481                     if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
2482                     {
2483                         SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
2484                         uno::Reference < embed::XEmbeddedObject > xObj( pNd ? pNd->GetOLEObj().GetOleRef() : 0 );
2485                         if ( xObj.is() )
2486                         {
2487                             // TODO/LATER: use correct aspect
2488                             const bool bNeverResize = (embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT ));
2489                             if ( (FLYPROTECT_CONTENT & eType) && bNeverResize )
2490                             {
2491                                 nChk |= FLYPROTECT_SIZE;
2492                                 nChk |= FLYPROTECT_FIXED;
2493                             }
2494 
2495                             // set FLYPROTECT_POS if it is a Math object anchored 'as char' and baseline alignment is activated
2496                             const bool bProtectMathPos = SotExchange::IsMath( xObj->getClassID() )
2497                                     && FLY_AS_CHAR == pFly->GetFmt()->GetAnchor().GetAnchorId()
2498                                     && pDoc->get( IDocumentSettingAccess::MATH_BASELINE_ALIGNMENT );
2499                             if ((FLYPROTECT_POS & eType) && bProtectMathPos)
2500                                 nChk |= FLYPROTECT_POS;
2501                         }
2502                     }
2503                 }
2504                 nChk &= eType;
2505                 if( nChk == eType )
2506                     return static_cast<sal_uInt8>(eType);
2507             }
2508             const SwFrm* pAnch;
2509             if( pObj->ISA(SwVirtFlyDrawObj) )
2510                 pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchorFrm();
2511             else
2512             {
2513                 SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj);
2514                 pAnch = pTmp ? pTmp->GetAnchorFrm( pObj ) : NULL;
2515             }
2516             if( pAnch && pAnch->IsProtected() )
2517                 return static_cast<sal_uInt8>(eType);
2518         }
2519     }
2520     return static_cast<sal_uInt8>(nChk);
2521 }
2522 
2523 sal_Bool SwFEShell::GetObjAttr( SfxItemSet &rSet ) const
2524 {
2525     if ( !IsObjSelected() )
2526         return sal_False;
2527 
2528     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2529     for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2530     {
2531         SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2532         SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2533         // --> OD 2007-07-24 #143008# - make code robust
2534         ASSERT( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact> - please inform OD." );
2535         if ( pContact )
2536         {
2537             if ( i )
2538                 rSet.MergeValues( pContact->GetFmt()->GetAttrSet() );
2539             else
2540                 rSet.Put( pContact->GetFmt()->GetAttrSet() );
2541         }
2542         // <--
2543     }
2544     return sal_True;
2545 }
2546 
2547 sal_Bool SwFEShell::SetObjAttr( const SfxItemSet& rSet )
2548 {
2549     SET_CURR_SHELL( this );
2550 
2551     if ( !rSet.Count() )
2552     {   ASSERT( !this, "SetObjAttr, empty set." );
2553         return sal_False;
2554     }
2555 
2556     StartAllAction();
2557     StartUndo( UNDO_INSATTR );
2558 
2559     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2560     for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2561     {
2562         SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2563         SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2564         GetDoc()->SetAttr( rSet, *pContact->GetFmt() );
2565     }
2566 
2567     EndUndo( UNDO_INSATTR );
2568     EndAllActionAndCall();
2569     GetDoc()->SetModified();
2570     return sal_True;
2571 }
2572 
2573 sal_Bool SwFEShell::IsAlignPossible() const
2574 {
2575     sal_uInt16 nCnt;
2576     if ( 0 < (nCnt = IsObjSelected()) )
2577     {
2578         sal_Bool bRet = sal_True;
2579         if ( nCnt == 1 )
2580         {
2581             SdrObject *pO = Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
2582             SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO);
2583             //only as character bound drawings can be aligned
2584             bRet = (pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_AS_CHAR);
2585         }
2586         if ( bRet )
2587             return Imp()->GetDrawView()->IsAlignPossible();
2588     }
2589     return sal_False;
2590 }
2591 
2592 
2593 //Temporaerer Fix bis SS von JOE da ist
2594 void SwFEShell::CheckUnboundObjects()
2595 {
2596     SET_CURR_SHELL( this );
2597 
2598     const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2599     for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
2600     {
2601         SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2602         if ( !GetUserCall(pObj) )
2603         {
2604             const Rectangle &rBound = pObj->GetSnapRect();
2605             const Point aPt( rBound.TopLeft() );
2606             const SwFrm *pPage = GetLayout()->Lower();
2607             const SwFrm *pLast = pPage;
2608             while ( pPage && !pPage->Frm().IsInside( aPt ) )
2609             {
2610                 if ( aPt.Y() > pPage->Frm().Bottom() )
2611                     pLast = pPage;
2612                 pPage = pPage->GetNext();
2613             }
2614             if ( !pPage )
2615                 pPage = pLast;
2616             ASSERT( pPage, "Page not found." );
2617 
2618             //Fremde Identifier sollen in den Default laufen.
2619             //Ueberschneidungen sind moeglich!!
2620             sal_uInt16 nIdent =
2621                     Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ?
2622                             Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF;
2623 
2624             SwFmtAnchor aAnch;
2625             const SwFrm *pAnch = 0;
2626             {
2627             pAnch = ::FindAnchor( pPage, aPt, sal_True );
2628             SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
2629             aAnch.SetType( FLY_AT_PARA );
2630             aAnch.SetAnchor( &aPos );
2631             ((SwRect&)GetCharRect()).Pos() = aPt;
2632             }
2633 
2634             //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert.
2635             StartAllAction();
2636 
2637             SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
2638                                             RES_SURROUND, RES_ANCHOR, 0 );
2639             aSet.Put( aAnch );
2640 
2641             Point aRelNullPt;
2642 
2643             if( OBJ_CAPTION == nIdent )
2644                 aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos();
2645             else
2646                 aRelNullPt = rBound.TopLeft();
2647 
2648             aSet.Put( aAnch );
2649             aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
2650             SwFrmFmt* pFmt = getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
2651 
2652             SwDrawContact *pContact = new SwDrawContact(
2653                                             (SwDrawFrmFmt*)pFmt, pObj );
2654 
2655             // --> OD 2004-11-22 #i35635#
2656             pContact->MoveObjToVisibleLayer( pObj );
2657             // <--
2658             pContact->ConnectToLayout();
2659 
2660             EndAllAction();
2661         }
2662     }
2663 }
2664 
2665 void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner)
2666 {
2667     GetDoc()->SetCalcFieldValueHdl(pOutliner);
2668 }
2669 
2670 
2671 
2672 int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource,
2673                             const Point &rPt ) const
2674 {
2675     rRect.Clear();
2676 
2677     //Die Source darf noch keinen Follow haben.
2678     const SwFmtChain &rChain = rSource.GetChain();
2679     if ( rChain.GetNext() )
2680         return SW_CHAIN_SOURCE_CHAINED;
2681 
2682     if( Imp()->HasDrawView() )
2683     {
2684         SdrObject* pObj;
2685         SdrPageView* pPView;
2686         SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
2687         const sal_uInt16 nOld = pDView->GetHitTolerancePixel();
2688         pDView->SetHitTolerancePixel( 0 );
2689         if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) &&
2690             pObj->ISA(SwVirtFlyDrawObj) )
2691         {
2692             SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2693             rRect = pFly->Frm();
2694 
2695             //Ziel darf natuerlich nicht gleich Source sein und es
2696             //darf keine geschlossene Kette entstehen.
2697             SwFrmFmt *pFmt = pFly->GetFmt();
2698             return GetDoc()->Chainable(rSource, *pFmt);
2699         }
2700         pDView->SetHitTolerancePixel( nOld );
2701     }
2702     return SW_CHAIN_NOT_FOUND;
2703 }
2704 
2705 int SwFEShell::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
2706 {
2707     return GetDoc()->Chain(rSource, rDest);
2708 }
2709 
2710 int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt )
2711 {
2712     SwRect aDummy;
2713     int nErr = Chainable( aDummy, rSource, rPt );
2714     if ( !nErr )
2715     {
2716         StartAllAction();
2717         SdrObject* pObj;
2718         SdrPageView* pPView;
2719         SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
2720         const sal_uInt16 nOld = pDView->GetHitTolerancePixel();
2721         pDView->SetHitTolerancePixel( 0 );
2722         pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE );
2723         pDView->SetHitTolerancePixel( nOld );
2724         SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2725 
2726         SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
2727         GetDoc()->Chain(rSource, *pFmt);
2728         EndAllAction();
2729         SetChainMarker();
2730     }
2731     return nErr;
2732 }
2733 
2734 void SwFEShell::Unchain( SwFrmFmt &rFmt )
2735 {
2736     StartAllAction();
2737     GetDoc()->Unchain(rFmt);
2738     EndAllAction();
2739 }
2740 
2741 
2742 void SwFEShell::HideChainMarker()
2743 {
2744     if ( pChainFrom )
2745     {
2746         delete pChainFrom;
2747         pChainFrom = 0L;
2748     }
2749     if ( pChainTo )
2750     {
2751         delete pChainTo;
2752         pChainTo = 0L;
2753     }
2754 }
2755 
2756 void SwFEShell::SetChainMarker()
2757 {
2758     sal_Bool bDelFrom = sal_True,
2759              bDelTo   = sal_True;
2760     if ( IsFrmSelected() )
2761     {
2762         SwFlyFrm *pFly = FindFlyFrm();
2763 
2764         if ( pFly->GetPrevLink() )
2765         {
2766             bDelFrom = sal_False;
2767             const SwFrm *pPre = pFly->GetPrevLink();
2768 
2769             Point aStart( pPre->Frm().Right(), pPre->Frm().Bottom());
2770             Point aEnd(pFly->Frm().Pos());
2771 
2772             if ( !pChainFrom )
2773             {
2774                 pChainFrom = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
2775             }
2776         }
2777         if ( pFly->GetNextLink() )
2778         {
2779             bDelTo = sal_False;
2780             const SwFlyFrm *pNxt = pFly->GetNextLink();
2781 
2782             Point aStart( pFly->Frm().Right(), pFly->Frm().Bottom());
2783             Point aEnd(pNxt->Frm().Pos());
2784 
2785             if ( !pChainTo )
2786             {
2787                 pChainTo = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
2788             }
2789         }
2790     }
2791 
2792     if ( bDelFrom )
2793     {
2794         delete pChainFrom, pChainFrom = 0;
2795     }
2796 
2797     if ( bDelTo )
2798     {
2799         delete pChainTo,   pChainTo = 0;
2800     }
2801 }
2802 
2803 long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const
2804 {
2805     SwFrm *pFrm = GetCurrFrm();
2806     // Steht der Cursor z.Z. in einem SectionFrm?
2807     if( pFrm && pFrm->IsInSct() )
2808     {
2809         SwSectionFrm* pSect = pFrm->FindSctFrm();
2810         do
2811         {
2812             // Ist es der Gewuenschte?
2813             if( pSect->KnowsFormat( rFmt ) )
2814                 return pSect->Frm().Width();
2815             // fuer geschachtelte Bereiche
2816             pSect = pSect->GetUpper()->FindSctFrm();
2817         }
2818         while( pSect );
2819     }
2820     SwIterator<SwSectionFrm,SwFmt> aIter( rFmt );
2821     for ( SwSectionFrm* pSct = aIter.First(); pSct; pSct = aIter.Next() )
2822     {
2823         if( !pSct->IsFollow() )
2824         {
2825             return pSct->Frm().Width();
2826         }
2827     }
2828     return 0;
2829 }
2830 
2831 void SwFEShell::CreateDefaultShape( sal_uInt16 /*SdrObjKind ?*/ eSdrObjectKind, const Rectangle& rRect,
2832                 sal_uInt16 nSlotId)
2833 {
2834     SdrView* pDrawView = GetDrawView();
2835     SdrModel* pDrawModel = pDrawView->GetModel();
2836     SdrObject* pObj = SdrObjFactory::MakeNewObject(
2837         SdrInventor, eSdrObjectKind,
2838         0L, pDrawModel);
2839 
2840     if(pObj)
2841     {
2842         Rectangle aRect(rRect);
2843         if(OBJ_CARC == eSdrObjectKind || OBJ_CCUT == eSdrObjectKind)
2844         {
2845             // force quadratic
2846             if(aRect.GetWidth() > aRect.GetHeight())
2847             {
2848                 aRect = Rectangle(
2849                     Point(aRect.Left() + ((aRect.GetWidth() - aRect.GetHeight()) / 2), aRect.Top()),
2850                     Size(aRect.GetHeight(), aRect.GetHeight()));
2851             }
2852             else
2853             {
2854                 aRect = Rectangle(
2855                     Point(aRect.Left(), aRect.Top() + ((aRect.GetHeight() - aRect.GetWidth()) / 2)),
2856                     Size(aRect.GetWidth(), aRect.GetWidth()));
2857             }
2858         }
2859         pObj->SetLogicRect(aRect);
2860 
2861         if(pObj->ISA(SdrCircObj))
2862         {
2863             SfxItemSet aAttr(pDrawModel->GetItemPool());
2864             aAttr.Put(SdrCircStartAngleItem(9000));
2865             aAttr.Put(SdrCircEndAngleItem(0));
2866             pObj->SetMergedItemSet(aAttr);
2867         }
2868         else if(pObj->ISA(SdrPathObj))
2869         {
2870             basegfx::B2DPolyPolygon aPoly;
2871 
2872             switch(eSdrObjectKind)
2873             {
2874                 case OBJ_PATHLINE:
2875                 {
2876                     basegfx::B2DPolygon aInnerPoly;
2877 
2878                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2879 
2880                     const basegfx::B2DPoint aCenterBottom(aRect.Center().X(), aRect.Bottom());
2881                     aInnerPoly.appendBezierSegment(
2882                         aCenterBottom,
2883                         aCenterBottom,
2884                         basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
2885 
2886                     const basegfx::B2DPoint aCenterTop(aRect.Center().X(), aRect.Top());
2887                     aInnerPoly.appendBezierSegment(
2888                         aCenterTop,
2889                         aCenterTop,
2890                         basegfx::B2DPoint(aRect.Right(), aRect.Top()));
2891 
2892                     aInnerPoly.setClosed(true);
2893                     aPoly.append(aInnerPoly);
2894                 }
2895                 break;
2896                 case OBJ_FREELINE:
2897                 {
2898                     basegfx::B2DPolygon aInnerPoly;
2899 
2900                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2901 
2902                     aInnerPoly.appendBezierSegment(
2903                         basegfx::B2DPoint(aRect.Left(), aRect.Top()),
2904                         basegfx::B2DPoint(aRect.Center().X(), aRect.Top()),
2905                         basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
2906 
2907                     aInnerPoly.appendBezierSegment(
2908                         basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()),
2909                         basegfx::B2DPoint(aRect.Right(), aRect.Bottom()),
2910                         basegfx::B2DPoint(aRect.Right(), aRect.Top()));
2911 
2912                     aInnerPoly.append(basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));
2913                     aInnerPoly.setClosed(true);
2914                     aPoly.append(aInnerPoly);
2915                 }
2916                 break;
2917                 case OBJ_POLY:
2918                 case OBJ_PLIN:
2919                 {
2920                     basegfx::B2DPolygon aInnerPoly;
2921                     sal_Int32 nWdt(aRect.GetWidth());
2922                     sal_Int32 nHgt(aRect.GetHeight());
2923 
2924                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2925                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 30) / 100, aRect.Top() + (nHgt * 70) / 100));
2926                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Top() + (nHgt * 15) / 100));
2927                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 65) / 100, aRect.Top()));
2928                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + nWdt, aRect.Top() + (nHgt * 30) / 100));
2929                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 50) / 100));
2930                     aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 75) / 100));
2931                     aInnerPoly.append(basegfx::B2DPoint(aRect.Bottom(), aRect.Right()));
2932 
2933                     if(OBJ_PLIN == eSdrObjectKind)
2934                     {
2935                         aInnerPoly.append(basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()));
2936                     }
2937                     else
2938                     {
2939                         aInnerPoly.setClosed(true);
2940                     }
2941 
2942                     aPoly.append(aInnerPoly);
2943                 }
2944                 break;
2945                 case OBJ_LINE :
2946                 {
2947                     sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
2948                     basegfx::B2DPolygon aTempPoly;
2949                     aTempPoly.append(basegfx::B2DPoint(aRect.TopLeft().X(), nYMiddle));
2950                     aTempPoly.append(basegfx::B2DPoint(aRect.BottomRight().X(), nYMiddle));
2951                     aPoly.append(aTempPoly);
2952                 }
2953                 break;
2954             }
2955 
2956             ((SdrPathObj*)pObj)->SetPathPoly(aPoly);
2957         }
2958         else if(pObj->ISA(SdrCaptionObj))
2959         {
2960             sal_Bool bVerticalText = ( SID_DRAW_TEXT_VERTICAL == nSlotId ||
2961                                             SID_DRAW_CAPTION_VERTICAL == nSlotId );
2962             ((SdrTextObj*)pObj)->SetVerticalWriting(bVerticalText);
2963             if(bVerticalText)
2964             {
2965                 SfxItemSet aSet(pObj->GetMergedItemSet());
2966                 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
2967                 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
2968                 pObj->SetMergedItemSet(aSet);
2969             }
2970 
2971             ((SdrCaptionObj*)pObj)->SetLogicRect(aRect);
2972             ((SdrCaptionObj*)pObj)->SetTailPos(
2973                 aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
2974         }
2975         else if(pObj->ISA(SdrTextObj))
2976         {
2977             SdrTextObj* pText = (SdrTextObj*)pObj;
2978             pText->SetLogicRect(aRect);
2979 
2980             sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotId);
2981             sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nSlotId);
2982 
2983             pText->SetVerticalWriting(bVertical);
2984 
2985             if(bVertical)
2986             {
2987                 SfxItemSet aSet(pDrawModel->GetItemPool());
2988                 aSet.Put(SdrTextAutoGrowWidthItem(sal_True));
2989                 aSet.Put(SdrTextAutoGrowHeightItem(sal_False));
2990                 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
2991                 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
2992                 pText->SetMergedItemSet(aSet);
2993             }
2994 
2995             if(bMarquee)
2996             {
2997                 SfxItemSet aSet(pDrawModel->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST);
2998                 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
2999                 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
3000                 aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) );
3001                 aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) );
3002                 aSet.Put( SdrTextAniCountItem( 1 ) );
3003                 aSet.Put( SdrTextAniAmountItem( (sal_Int16)GetWin()->PixelToLogic(Size(2,1)).Width()) );
3004                 pObj->SetMergedItemSetAndBroadcast(aSet);
3005             }
3006         }
3007         SdrPageView* pPageView = pDrawView->GetSdrPageView();
3008         pDrawView->InsertObjectAtView(pObj, *pPageView);
3009     }
3010     ImpEndCreate();
3011 }
3012 
3013 /** SwFEShell::GetShapeBackgrd
3014 
3015     OD 02.09.2002 for #102450#:
3016     method determines background color of the page the selected drawing
3017     object is on and returns this color.
3018     If no color is found, because no drawing object is selected or ...,
3019     color COL_BLACK (default color on constructing object of class Color)
3020     is returned.
3021 
3022     @author OD
3023 
3024     @returns an object of class Color
3025 */
3026 const Color SwFEShell::GetShapeBackgrd() const
3027 {
3028     Color aRetColor;
3029 
3030     // check, if a draw view exists
3031     ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
3032     if( Imp()->GetDrawView() )
3033     {
3034         // determine list of selected objects
3035         const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
3036         // check, if exactly one object is selected.
3037         ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
3038         if ( pMrkList->GetMarkCount() == 1)
3039         {
3040             // get selected object
3041             const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
3042             // check, if selected object is a shape (drawing object)
3043             ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
3044             if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
3045             {
3046                 // determine page frame of the frame the shape is anchored.
3047                 const SwFrm* pAnchorFrm =
3048                         static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
3049                 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
3050                 if ( pAnchorFrm )
3051                 {
3052                     const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
3053                     ASSERT( pPageFrm, "inconsistent modell - no page!");
3054                     if ( pPageFrm )
3055                     {
3056                         aRetColor = pPageFrm->GetDrawBackgrdColor();
3057                     }
3058                 }
3059             }
3060         }
3061     }
3062 
3063     return aRetColor;
3064 }
3065 
3066 /** Is default horizontal text direction for selected drawing object right-to-left
3067 
3068     OD 09.12.2002 #103045#
3069     Because drawing objects only painted for each page only, the default
3070     horizontal text direction of a drawing object is given by the corresponding
3071     page property.
3072 
3073     @author OD
3074 
3075     @returns boolean, indicating, if the horizontal text direction of the
3076     page, the selected drawing object is on, is right-to-left.
3077 */
3078 bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const
3079 {
3080     bool bRet = false;
3081 
3082     // check, if a draw view exists
3083     ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
3084     if( Imp()->GetDrawView() )
3085     {
3086         // determine list of selected objects
3087         const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
3088         // check, if exactly one object is selected.
3089         ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
3090         if ( pMrkList->GetMarkCount() == 1)
3091         {
3092             // get selected object
3093             const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
3094             // check, if selected object is a shape (drawing object)
3095             ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
3096             if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
3097             {
3098                 // determine page frame of the frame the shape is anchored.
3099                 const SwFrm* pAnchorFrm =
3100                         static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
3101                 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
3102                 if ( pAnchorFrm )
3103                 {
3104                     const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
3105                     ASSERT( pPageFrm, "inconsistent modell - no page!");
3106                     if ( pPageFrm )
3107                     {
3108                         bRet = pPageFrm->IsRightToLeft() ? true : false;
3109                     }
3110                 }
3111             }
3112         }
3113     }
3114 
3115     return bRet;
3116 }
3117 
3118 Point SwFEShell::GetRelativePagePosition(const Point& rDocPos)
3119 {
3120     Point aRet(-1, -1);
3121     const SwFrm *pPage = GetLayout()->Lower();
3122     while ( pPage && !pPage->Frm().IsInside( rDocPos ) )
3123     {
3124         pPage = pPage->GetNext();
3125     }
3126     if(pPage)
3127     {
3128         aRet = rDocPos - pPage->Frm().TopLeft();
3129     }
3130     return aRet;
3131 }
3132 
3133