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