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