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