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