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