update dev300-m58
[ooovba.git] / sw / source / core / frmedt / feshview.cxx
blob72f9ff07965dec6731e181c0bafca944b78bcd24
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: feshview.cxx,v $
10 * $Revision: 1.61.136.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <com/sun/star/embed/EmbedMisc.hpp>
34 #include "hintids.hxx"
36 #ifdef WIN
37 #define NEEDED_BY_FESHVIEW
38 #define _FESHVIEW_ONLY_INLINE_NEEDED
39 #endif
41 #include <svx/svdobj.hxx>
42 #include <svx/svdouno.hxx>
43 #include <svx/svdoole2.hxx>
44 #include <svx/svdogrp.hxx>
45 #include <svx/svdocirc.hxx>
46 #include <svx/svdopath.hxx>
47 #include <svx/sxciaitm.hxx>
48 #include <svx/xfillit.hxx>
49 #include <svx/svdocapt.hxx>
50 #include <sfx2/app.hxx>
51 #include <svx/boxitem.hxx>
52 #include <svx/opaqitem.hxx>
53 #include <svx/protitem.hxx>
54 #include <svx/svdpage.hxx>
55 #include <svx/svdpagv.hxx>
57 #ifndef _POOLFMT_HRC
58 #include <poolfmt.hrc> // fuer InitFldTypes
59 #endif
60 #include <frmfmt.hxx>
61 #include <frmatr.hxx>
62 #include <fmtfsize.hxx>
63 #include <fmtanchr.hxx>
64 #include <fmtornt.hxx>
65 #include <fmtsrnd.hxx>
66 #include <fmtcntnt.hxx>
67 #include <fmtflcnt.hxx>
68 #include <fmtcnct.hxx>
69 #include <docary.hxx>
70 #include <tblsel.hxx>
71 #include <swtable.hxx>
72 #include <flyfrms.hxx>
73 #include "fesh.hxx"
74 #include "rootfrm.hxx"
75 #include "pagefrm.hxx"
76 #include "sectfrm.hxx"
77 #include "doc.hxx"
78 #include "dview.hxx"
79 #include "dflyobj.hxx"
80 #include "dcontact.hxx"
81 #include "viewimp.hxx"
82 #include "flyfrm.hxx"
83 #include "pam.hxx"
84 #include "ndole.hxx"
85 #include "ndgrf.hxx"
86 #include "ndtxt.hxx"
87 #include "viewopt.hxx" // fuer GetHTMLMode
88 #include "swundo.hxx"
89 #include "notxtfrm.hxx"
90 #include "txtfrm.hxx"
91 #include "txatbase.hxx"
92 #include "mdiexp.hxx" // fuer Update der Statuszeile bei drag
93 // OD 2004-05-24 #i28701#
94 #include <sortedobjs.hxx>
95 // --> OD 2006-03-06 #125892#
96 #include <HandleAnchorNodeChg.hxx>
97 // <--
98 #include <basegfx/polygon/b2dpolygon.hxx>
100 #define SCROLLVAL 75
102 using namespace com::sun::star;
104 //Tattergrenze fuer Drawing-SS
105 #define MINMOVE ((USHORT)GetOut()->PixelToLogic(Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width())
107 SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh )
109 if ( !pLst )
110 pLst = pSh->HasDrawView() ? &pSh->Imp()->GetDrawView()->GetMarkedObjectList():0;
112 if ( pLst && pLst->GetMarkCount() == 1 )
114 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
115 if ( pO->ISA(SwVirtFlyDrawObj) )
116 return ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
118 return 0;
121 void lcl_GrabCursor( SwFEShell* pSh, SwFlyFrm* pOldSelFly)
123 const SwFrmFmt *pFlyFmt = pSh->SelFlyGrabCrsr();
124 if( pFlyFmt && !pSh->ActionPend() &&
125 (!pOldSelFly || pOldSelFly->GetFmt() != pFlyFmt) )
127 // dann das evt. gesetzte Macro rufen
128 pSh->GetFlyMacroLnk().Call( (void*)pFlyFmt );
129 extern BOOL bNoInterrupt; // in swapp.cxx
130 // wir in dem Makro ein Dialog gestartet, dann kommt das
131 // MouseButtonUp zu diesem und nicht zu uns. Dadurch ist
132 // Flag bei uns immer gesetzt und schaltet nie die auf die
133 // entsp. Shell um !!!!!!!
134 bNoInterrupt = FALSE;
136 else if( !pFlyFmt || RES_DRAWFRMFMT == pFlyFmt->Which() )
138 // --> OD 2007-07-25 #136039#
139 // assure consistent cursor
140 pSh->KillPams();
141 pSh->ClearMark();
142 // <--
143 pSh->SetCrsr( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), TRUE);
147 /*************************************************************************
149 |* SwFEShell::SelectObj()
151 |* Ersterstellung MA 16. Nov. 92
152 |* Letzte Aenderung MA 22. Oct. 96
154 *************************************************************************/
156 BOOL SwFEShell::SelectObj( const Point& rPt, BYTE nFlag, SdrObject *pObj )
158 SwDrawView *pDView = Imp()->GetDrawView();
159 if(!pDView)
160 return sal_False;
161 SET_CURR_SHELL( this );
162 StartAction(); //Aktion ist Notwendig, damit nicht mehrere
163 //AttrChgdNotify (etwa durch Unmark->MarkListHasChgd)
164 //durchkommen
166 const SdrMarkList &rMrkList = pDView->GetMarkedObjectList();
167 const BOOL bHadSelection = rMrkList.GetMarkCount() ? TRUE : FALSE;
168 const BOOL bAddSelect = 0 != (SW_ADD_SELECT & nFlag);
169 const BOOL bEnterGroup = 0 != (SW_ENTER_GROUP & nFlag);
170 SwFlyFrm* pOldSelFly = 0;
171 const Point aOldPos( pDView->GetAllMarkedRect().TopLeft() );
173 if( bHadSelection )
175 //Unmark rufen wenn !bAddSelect oder wenn ein Fly selektiert ist.
176 BOOL bUnmark = !bAddSelect;
178 if ( rMrkList.GetMarkCount() == 1 )
180 //Wenn ein Fly selektiert ist, so muss er erst deselektiert werden.
181 pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
182 if ( pOldSelFly )
184 const USHORT nType = GetCntType();
185 if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) ||
186 ( pOldSelFly->GetFmt()->GetProtect().IsCntntProtected()
187 && !IsReadOnlyAvailable() ))
189 //Wenn ein Fly deselektiert wird, der Grafik, Ole o.ae.
190 //enthaelt, so muss der Crsr aus diesem entfernt werden.
191 //Desgleichen wenn ein Fly mit geschuetztem Inhalt deselektiert
192 //wird. Der Einfachheit halber wire der Crsr 'grad so neben die
193 //linke obere Ecke gesetzt.
194 Point aPt( pOldSelFly->Frm().Pos() );
195 aPt.X() -= 1;
196 BOOL bUnLockView = !IsViewLocked();
197 LockView( TRUE );
198 SetCrsr( aPt, TRUE );
199 if( bUnLockView )
200 LockView( FALSE );
202 if ( nType & CNT_GRF &&
203 ((SwNoTxtFrm*)pOldSelFly->Lower())->HasAnimation() )
205 GetWin()->Invalidate( pOldSelFly->Frm().SVRect() );
207 bUnmark = TRUE;
210 if ( bUnmark )
211 pDView->UnmarkAll();
213 else
215 KillPams();
216 ClearMark();
219 if ( pObj )
221 ASSERT( !bEnterGroup, "SW_ENTER_GROUP is not supported" );
222 pDView->MarkObj( pObj, Imp()->GetPageView() );
224 else
226 pDView->MarkObj( rPt, MINMOVE, bAddSelect, bEnterGroup );
229 const BOOL bRet = 0 != rMrkList.GetMarkCount();
231 if ( rMrkList.GetMarkCount() > 1 )
233 //Ganz dumm ist es, wenn Zeichenobjekte Selektiert waren und
234 //nun ein Fly hinzuselektiert wird.
235 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
237 SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
238 BOOL bForget = pTmpObj->ISA(SwVirtFlyDrawObj);
239 if( bForget )
241 pDView->UnmarkAll();
242 if ( pTmpObj )
243 pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup );
244 else
245 pDView->MarkObj( rPt, MINMOVE );
246 break;
251 if ( bRet )
253 ::lcl_GrabCursor(this, pOldSelFly);
254 if ( GetCntType() & CNT_GRF )
256 const SwFlyFrm *pTmp = GetFlyFromMarked( &rMrkList, this );
257 ASSERT( pTmp, "Graphic without Fly" );
258 if ( ((SwNoTxtFrm*)pTmp->Lower())->HasAnimation() )
259 ((SwNoTxtFrm*)pTmp->Lower())->StopAnimation( GetOut() );
262 else if ( !pOldSelFly && bHadSelection )
263 SetCrsr( aOldPos, TRUE);
265 if( bRet || !bHadSelection )
266 CallChgLnk();
268 // update der Statuszeile
269 ::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
271 EndAction();
272 return bRet;
275 /*************************************************************************
277 |* sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
279 |* Created AMA 05/28/2002
280 |* Last modify AMA 05/30/2002
282 |* Description: MoveAnchor( nDir ) looked for an another Anchor for
283 |* the selected drawing object (or fly frame) in the given direction.
284 |* An object "as character" doesn't moves anyway.
285 |* A page bounded object could move to the previous/next page with up/down,
286 |* an object bounded "at paragraph" moves to the previous/next paragraph, too.
287 |* An object bounded "at character" moves to the previous/next paragraph
288 |* with up/down and to the previous/next character with left/right.
289 |* If the anchor for at paragraph/character bounded objects has vertical or
290 |* right_to_left text direction, the directions for up/down/left/right will
291 |* interpreted accordingly.
292 |* An object bounded "at fly" takes the center of the actual anchor and looks
293 |* for the nearest fly frame in the given direction.
295 *************************************************************************/
297 #define LESS_X( aPt1, aPt2, bOld ) ( aPt1.X() < aPt2.X() || \
298 ( aPt1.X() == aPt2.X() && ( aPt1.Y() < aPt2.Y() || \
299 ( aPt1.Y() == aPt2.Y() && bOld ) ) ) )
300 #define LESS_Y( aPt1, aPt2, bOld ) ( aPt1.Y() < aPt2.Y() || \
301 ( aPt1.Y() == aPt2.Y() && ( aPt1.X() < aPt2.X() || \
302 ( aPt1.X() == aPt2.X() && bOld ) ) ) )
304 sal_Bool SwFEShell::MoveAnchor( USHORT nDir )
306 const SdrMarkList* pMrkList;
307 if( !Imp()->GetDrawView() ||
308 0 == (pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList()) ||
309 1 != pMrkList->GetMarkCount())
310 return sal_False;
311 SwFrm* pOld;
312 SwFlyFrm* pFly = NULL;
313 SdrObject *pObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
314 if( pObj->ISA(SwVirtFlyDrawObj) )
316 pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
317 pOld = pFly->AnchorFrm();
319 else
320 pOld = ((SwDrawContact*)GetUserCall(pObj))->GetAnchorFrm( pObj );
321 sal_Bool bRet = sal_False;
322 if( pOld )
324 SwFrm* pNew = pOld;
325 // --> OD 2004-07-16 #i28701#
326 SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
327 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
328 SwFmtAnchor aAnch( rFmt.GetAnchor() );
329 RndStdIds nAnchorId = aAnch.GetAnchorId();
330 if ( FLY_IN_CNTNT == nAnchorId )
331 return sal_False;
332 if( pOld->IsVertical() )
334 if( pOld->IsTxtFrm() )
336 switch( nDir ) {
337 case SW_MOVE_UP: nDir = SW_MOVE_LEFT; break;
338 case SW_MOVE_DOWN: nDir = SW_MOVE_RIGHT; break;
339 case SW_MOVE_LEFT: nDir = SW_MOVE_DOWN; break;
340 case SW_MOVE_RIGHT: nDir = SW_MOVE_UP; break;
342 if( pOld->IsRightToLeft() )
344 if( nDir == SW_MOVE_LEFT )
345 nDir = SW_MOVE_RIGHT;
346 else if( nDir == SW_MOVE_RIGHT )
347 nDir = SW_MOVE_LEFT;
351 switch ( nAnchorId ) {
352 case FLY_PAGE:
354 ASSERT( pOld->IsPageFrm(), "Wrong anchor, page exspected." );
355 if( SW_MOVE_UP == nDir )
356 pNew = pOld->GetPrev();
357 else if( SW_MOVE_DOWN == nDir )
358 pNew = pOld->GetNext();
359 if( pNew && pNew != pOld )
361 aAnch.SetPageNum( ((SwPageFrm*)pNew)->GetPhyPageNum() );
362 bRet = sal_True;
364 break;
366 case FLY_AUTO_CNTNT:
368 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
369 if( SW_MOVE_LEFT == nDir || SW_MOVE_RIGHT == nDir )
371 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
372 SwTxtNode* pTxtNd = ((SwTxtFrm*)pOld)->GetTxtNode();
373 xub_StrLen nAct = pPos->nContent.GetIndex();
374 if( SW_MOVE_LEFT == nDir )
376 bRet = sal_True;
377 if( nAct )
379 --nAct;
380 pPos->nContent.Assign( pTxtNd, nAct );
382 else
383 nDir = SW_MOVE_UP;
385 else
387 xub_StrLen nMax =
388 ((SwTxtFrm*)pOld)->GetTxtNode()->GetTxt().Len();
389 if( nAct < nMax )
391 ++nAct;
392 bRet = sal_True;
393 pPos->nContent.Assign( pTxtNd, nAct );
395 else
396 nDir = SW_MOVE_DOWN;
399 } // no break!
400 case FLY_AT_CNTNT:
402 ASSERT( pOld->IsCntntFrm(), "Wrong anchor, page exspected." );
403 if( SW_MOVE_UP == nDir )
404 pNew = pOld->FindPrev();
405 else if( SW_MOVE_DOWN == nDir )
406 pNew = pOld->FindNext();
407 if( pNew && pNew != pOld && pNew->IsCntntFrm() )
409 SwPosition *pPos = (SwPosition*)aAnch.GetCntntAnchor();
410 SwTxtNode* pTxtNd = ((SwTxtFrm*)pNew)->GetTxtNode();
411 pPos->nNode = *pTxtNd;
412 xub_StrLen nTmp = 0;
413 if( bRet )
415 nTmp = ((SwTxtFrm*)pNew)->GetTxtNode()->GetTxt().Len();
416 if( nTmp )
417 --nTmp;
419 pPos->nContent.Assign( pTxtNd, nTmp );
420 bRet = sal_True;
422 else if( SW_MOVE_UP == nDir || SW_MOVE_DOWN == nDir )
423 bRet = sal_False;
424 break;
426 case FLY_AT_FLY:
428 ASSERT( pOld->IsFlyFrm(), "Wrong anchor, fly frame exspected.");
429 SwPageFrm* pPage = pOld->FindPageFrm();
430 ASSERT( pPage, "Where's my page?" );
431 SwFlyFrm* pNewFly = NULL;
432 if( pPage->GetSortedObjs() )
434 int i;
435 sal_Bool bOld = sal_False;
436 Point aCenter( pOld->Frm().Left() + pOld->Frm().Width()/2,
437 pOld->Frm().Top() + pOld->Frm().Height()/2 );
438 Point aBest;
439 for( i = 0; (USHORT)i<pPage->GetSortedObjs()->Count(); ++i )
441 SwAnchoredObject* pAnchObj =
442 (*pPage->GetSortedObjs())[i];
443 if( pAnchObj->ISA(SwFlyFrm) )
445 SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(pAnchObj);
446 if( pTmp == pOld )
447 bOld = sal_True;
448 else
450 const SwFlyFrm* pCheck = pFly ? pTmp : 0;
451 while( pCheck )
453 if( pCheck == pFly )
454 break;
455 const SwFrm *pNxt = pCheck->GetAnchorFrm();
456 pCheck = pNxt ? pNxt->FindFlyFrm() : NULL;
458 if( pCheck || pTmp->IsProtected() )
459 continue;
460 Point aNew( pTmp->Frm().Left() +
461 pTmp->Frm().Width()/2,
462 pTmp->Frm().Top() +
463 pTmp->Frm().Height()/2 );
464 sal_Bool bAccept = sal_False;
465 switch( nDir ) {
466 case SW_MOVE_RIGHT:
468 bAccept = LESS_X( aCenter, aNew, bOld )
469 && ( !pNewFly ||
470 LESS_X( aNew, aBest, sal_False ) );
471 break;
473 case SW_MOVE_LEFT:
475 bAccept = LESS_X( aNew, aCenter, !bOld )
476 && ( !pNewFly ||
477 LESS_X( aBest, aNew, sal_True ) );
478 break;
480 case SW_MOVE_UP:
482 bAccept = LESS_Y( aNew, aCenter, !bOld )
483 && ( !pNewFly ||
484 LESS_Y( aBest, aNew, sal_True ) );
485 break;
487 case SW_MOVE_DOWN:
489 bAccept = LESS_Y( aCenter, aNew, bOld )
490 && ( !pNewFly ||
491 LESS_Y( aNew, aBest, sal_False ) );
492 break;
495 if( bAccept )
497 pNewFly = pTmp;
498 aBest = aNew;
505 if( pNewFly )
507 SwPosition aPos( *pNewFly->GetFmt()->
508 GetCntnt().GetCntntIdx());
509 aAnch.SetAnchor( &aPos );
510 bRet = sal_True;
512 break;
514 default: break;
516 if( bRet )
518 StartAllAction();
519 // --> OD 2006-02-28 #125892#
520 // handle change of anchor node:
521 // if count of the anchor frame also change, the fly frames have to be
522 // re-created. Thus, delete all fly frames except the <this> before the
523 // anchor attribute is change and re-create them afterwards.
525 SwHandleAnchorNodeChg* pHandleAnchorNodeChg( 0L );
526 SwFlyFrmFmt* pFlyFrmFmt( dynamic_cast<SwFlyFrmFmt*>(&rFmt) );
527 if ( pFlyFrmFmt )
529 pHandleAnchorNodeChg =
530 new SwHandleAnchorNodeChg( *pFlyFrmFmt, aAnch );
532 rFmt.GetDoc()->SetAttr( aAnch, rFmt );
533 delete pHandleAnchorNodeChg;
535 // <--
536 // --> OD 2004-06-24 #i28701# - no call of method
537 // <CheckCharRectAndTopOfLine()> for to-character anchored
538 // Writer fly frame needed. This method call can cause a
539 // format of the anchor frame, which is no longer intended.
540 // Instead clear the anchor character rectangle and
541 // the top of line values for all to-character anchored objects.
542 pAnchoredObj->ClearCharRectAndTopOfLine();
543 EndAllAction();
546 return bRet;
549 /*************************************************************************
551 |* SwFEShell::GetSelFrmType()
553 |* Ersterstellung MA 12. Jan. 93
554 |* Letzte Aenderung JP 19.03.96
556 *************************************************************************/
558 const SdrMarkList* SwFEShell::_GetMarkList() const
560 const SdrMarkList* pMarkList = NULL;
561 if( Imp()->GetDrawView() != NULL )
562 pMarkList = &Imp()->GetDrawView()->GetMarkedObjectList();
563 return pMarkList;
566 USHORT SwFEShell::GetSelFrmType() const
568 USHORT eType;
570 // get marked frame list, and check if anything is selected
571 const SdrMarkList* pMarkList = _GetMarkList();
572 if( pMarkList == NULL || pMarkList->GetMarkCount() == 0 )
573 eType = FRMTYPE_NONE;
574 else
576 // obtain marked item as fly frame; if no fly frame, it must
577 // be a draw object
578 const SwFlyFrm* pFly = ::GetFlyFromMarked(pMarkList, (ViewShell*)this);
579 if ( pFly != NULL )
581 if( pFly->IsFlyLayFrm() )
582 eType = FRMTYPE_FLY_FREE;
583 else if( pFly->IsFlyAtCntFrm() )
584 eType = FRMTYPE_FLY_ATCNT;
585 else
587 ASSERT( pFly->IsFlyInCntFrm(), "Neuer Rahmentyp?" );
588 eType = FRMTYPE_FLY_INCNT;
591 else
592 eType = FRMTYPE_DRAWOBJ;
595 return eType;
598 // #108784# does the draw selection contain a control?
599 bool SwFEShell::IsSelContainsControl() const
601 bool bRet = false;
603 // basically, copy the mechanism from GetSelFrmType(), but call
604 // CheckControl... if you get a drawing object
605 const SdrMarkList* pMarkList = _GetMarkList();
606 if( pMarkList != NULL && pMarkList->GetMarkCount() == 1 )
608 // if we have one marked object, get the SdrObject and check
609 // whether it contains a control
610 const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
611 bRet = CheckControlLayer( pSdrObject );
613 return bRet;
616 /*************************************************************************
618 |* SwFEShell::Scroll()
620 |* Ersterstellung MA 20. Dec. 94
621 |* Letzte Aenderung MA 27. Jul. 95
623 *************************************************************************/
625 void SwFEShell::ScrollTo( const Point &rPt )
627 const SwRect aRect( rPt, rPt );
628 if ( IsScrollMDI( this, aRect ) &&
629 (!Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ||
630 Imp()->IsDragPossible( rPt )) )
632 //SwSaveHdl aSave( Imp() );
633 ScrollMDI( this, aRect, SCROLLVAL, SCROLLVAL );
637 /*************************************************************************
639 |* SwFEShell::SetDragMode()
641 |* Ersterstellung MA 30. Jan. 95
642 |* Letzte Aenderung MA 30. Jan. 95
644 *************************************************************************/
646 void SwFEShell::SetDragMode( UINT16 eDragMode )
648 if ( Imp()->HasDrawView() )
649 Imp()->GetDrawView()->SetDragMode( (SdrDragMode)eDragMode );
652 /*************************************************************************
654 |* SwFEShell::BeginDrag()
656 |* Ersterstellung MS 10.06.92
657 |* Letzte Aenderung MA 13. Mar. 96
659 *************************************************************************/
661 long SwFEShell::BeginDrag( const Point* pPt, BOOL )
663 SdrView *pView = Imp()->GetDrawView();
664 if ( pView && pView->AreObjectsMarked() )
666 delete pChainFrom; delete pChainTo; pChainFrom = pChainTo = 0;
667 SdrHdl* pHdl = pView->PickHandle( *pPt );
668 pView->BegDragObj( *pPt, 0 /*GetWin()*/, pHdl );
669 ::FrameNotify( this, FLY_DRAG );
670 return 1;
672 return 0;
674 /*************************************************************************
676 |* SwFEShell::Drag()
678 |* Ersterstellung MS 10.06.92
679 |* Letzte Aenderung MA 13. Mar. 96
681 *************************************************************************/
683 long SwFEShell::Drag( const Point *pPt, BOOL )
685 ASSERT( Imp()->HasDrawView(), "Drag without DrawView?" );
686 if ( Imp()->GetDrawView()->IsDragObj() )
688 ScrollTo( *pPt );
689 Imp()->GetDrawView()->MovDragObj( *pPt );
690 Imp()->GetDrawView()->ShowDragAnchor();
691 ::FrameNotify( this, FLY_DRAG );
692 return 1;
694 return 0;
697 /*************************************************************************
699 |* SwFEShell::EndDrag()
701 |* Ersterstellung MS 10.06.92
702 |* Letzte Aenderung MA 13. Mar. 96
704 *************************************************************************/
706 long SwFEShell::EndDrag( const Point *, BOOL )
708 ASSERT( Imp()->HasDrawView(), "EndDrag without DrawView?" );
709 SdrView *pView = Imp()->GetDrawView();
710 if ( pView->IsDragObj() )
712 //Start-/EndActions nur an der ViewShell aufsetzen
713 ViewShell *pSh = this;
714 do {
715 pSh->StartAction();
716 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
718 StartUndo( UNDO_START );
720 //#50778# Bug im Draging: Im StartAction wird ein HideShowXor gerufen.
721 //Im EndDragObj() wird dies unsinniger und faelschlicherweise wieder
722 //Rueckgaengig gemacht. Um Konsistenz herzustellen muessen wir das
723 //Xor also wieder zur Anzeige bringen.
725 // Reanimation from the hack #50778 to fix bug #97057
726 // May be not the best solution, but the one with lowest risc at the moment.
727 //pView->ShowShownXor( GetOut() );
729 pView->EndDragObj();
730 // JP 18.08.95: DrawUndo-Action auf FlyFrames werden nicht gespeichert
731 // Die Fly aendern das Flag
732 GetDoc()->SetNoDrawUndoObj( FALSE );
733 ChgAnchor( 0, TRUE );
735 EndUndo( UNDO_END );
737 do {
738 pSh->EndAction();
739 if( pSh->IsA( TYPE( SwCrsrShell ) ) )
740 ((SwCrsrShell*)pSh)->CallChgLnk();
741 } while ( this != (pSh = (ViewShell*)pSh->GetNext()) );
743 GetDoc()->SetModified();
744 ::FrameNotify( this, FLY_DRAG );
745 return 1;
747 return 0;
750 /*************************************************************************
752 |* SwFEShell::BreakDrag()
754 |* Ersterstellung OM 02. Okt. 95
755 |* Letzte Aenderung OM 02. Okt. 95
757 *************************************************************************/
759 void SwFEShell::BreakDrag()
761 ASSERT( Imp()->HasDrawView(), "BreakDrag without DrawView?" );
762 if ( Imp()->GetDrawView()->IsDragObj() )
763 Imp()->GetDrawView()->BrkDragObj();
764 SetChainMarker();
767 /*************************************************************************
769 |* SwFEShell::SelFlyGrabCrsr()
771 |* Beschreibung Wenn ein Fly selektiert ist, zieht er den Crsr in
772 |* den ersten CntntFrm
773 |* Ersterstellung MA 11. Dec. 92
774 |* Letzte Aenderung MA 07. Oct. 96
776 *************************************************************************/
778 const SwFrmFmt* SwFEShell::SelFlyGrabCrsr()
780 if ( Imp()->HasDrawView() )
782 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
783 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
785 if( pFly )
787 // --> OD 2004-06-11 #i28701# - no format here
788 // pFly->GetAnchorFrm()->Calc();
789 SwCntntFrm *pCFrm = pFly->ContainsCntnt();
790 if ( pCFrm )
792 SwCntntNode *pCNode = pCFrm->GetNode();
793 // --> OD 2007-07-25 #126039#
794 // assure, that the cursor is consistent.
795 KillPams();
796 ClearMark();
797 // <--
798 SwPaM *pCrsr = GetCrsr();
800 pCrsr->GetPoint()->nNode = *pCNode;
801 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
803 SwRect& rChrRect = (SwRect&)GetCharRect();
804 rChrRect = pFly->Prt();
805 rChrRect.Pos() += pFly->Frm().Pos();
806 GetCrsrDocPos() = rChrRect.Pos();
808 return pFly->GetFmt();
811 return 0;
815 /*************************************************************************
817 |* SwFEShell::SelectionToTop(), SelectionToBottom()
819 |* Beschreibung Selektion nach oben/unten (Z-Order)
821 |* Ersterstellung MA 05. Nov. 92
822 |* Letzte Aenderung MA 03. Jun. 96
824 *************************************************************************/
826 void lcl_NotifyNeighbours( const SdrMarkList *pLst )
828 //Die Regeln fuer die Ausweichmanoever haben sich veraendert.
829 //1. Die Umgebung des Fly und aller innenliegenden muss benachrichtigt
830 // werden.
831 //2. Der Inhalt des Rahmen selbst muss benachrichtigt werden.
832 //3. Rahmen die dem Rahmen ausweichen bzw. wichen muessen benachrichtigt werden.
833 //4. Auch Zeichenobjekte koennen Rahmen verdraengen
835 for( USHORT j = 0; j < pLst->GetMarkCount(); ++j )
837 SwPageFrm *pPage;
838 BOOL bCheckNeighbours = FALSE;
839 sal_Int16 aHori = text::HoriOrientation::NONE;
840 SwRect aRect;
841 SdrObject *pO = pLst->GetMark( 0 )->GetMarkedSdrObj();
842 if ( pO->ISA(SwVirtFlyDrawObj) )
844 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
846 const SwFmtHoriOrient &rHori = pFly->GetFmt()->GetHoriOrient();
847 aHori = rHori.GetHoriOrient();
848 if( text::HoriOrientation::NONE != aHori && text::HoriOrientation::CENTER != aHori &&
849 pFly->IsFlyAtCntFrm() )
851 bCheckNeighbours = TRUE;
852 pFly->InvalidatePos();
853 pFly->Frm().Pos().Y() += 1;
856 pPage = pFly->FindPageFrm();
857 aRect = pFly->Frm();
859 else
861 SwFrm* pAnch = ( (SwDrawContact*)GetUserCall(pO) )->GetAnchorFrm( pO );
862 if( !pAnch )
863 continue;
864 pPage = pAnch->FindPageFrm();
865 // --> OD 2006-08-15 #i68520# - naming changed
866 aRect = GetBoundRectOfAnchoredObj( pO );
867 // <--
870 sal_uInt32 nCount = pPage->GetSortedObjs() ? pPage->GetSortedObjs()->Count() : 0;
871 for ( sal_uInt32 i = 0; i < nCount; ++i )
873 SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i];
874 if ( !pAnchoredObj->ISA(SwFlyFrm) )
875 continue;
877 SwFlyFrm* pAct = static_cast<SwFlyFrm*>(pAnchoredObj);
878 SwRect aTmpCalcPnt( pAct->Prt() );
879 aTmpCalcPnt += pAct->Frm().Pos();
880 if ( aRect.IsOver( aTmpCalcPnt ) )
882 SwCntntFrm *pCnt = pAct->ContainsCntnt();
883 while ( pCnt )
885 aTmpCalcPnt = pCnt->Prt();
886 aTmpCalcPnt += pCnt->Frm().Pos();
887 if ( aRect.IsOver( aTmpCalcPnt ) )
888 ((SwFrm*)pCnt)->Prepare( PREP_FLY_ATTR_CHG );
889 pCnt = pCnt->GetNextCntntFrm();
892 if ( bCheckNeighbours && pAct->IsFlyAtCntFrm() )
894 const SwFmtHoriOrient &rH = pAct->GetFmt()->GetHoriOrient();
895 if ( rH.GetHoriOrient() == aHori &&
896 pAct->Frm().Top() <= aRect.Bottom() &&
897 pAct->Frm().Bottom() >= aRect.Top() )
899 pAct->InvalidatePos();
900 pAct->Frm().Pos().Y() += 1;
907 void SwFEShell::SelectionToTop( BOOL bTop )
909 ASSERT( Imp()->HasDrawView(), "SelectionToTop without DrawView?" );
910 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
911 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
913 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
914 if ( pFly && pFly->IsFlyInCntFrm() )
915 return;
917 StartAllAction();
918 if ( bTop )
919 Imp()->GetDrawView()->PutMarkedToTop();
920 else
921 Imp()->GetDrawView()->MovMarkedToTop();
922 ::lcl_NotifyNeighbours( &rMrkList );
923 GetDoc()->SetModified();
924 EndAllAction();
927 void SwFEShell::SelectionToBottom( BOOL bBottom )
929 ASSERT( Imp()->HasDrawView(), "SelectionToBottom without DrawView?" );
930 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
931 ASSERT( rMrkList.GetMarkCount(), "Kein Object Selektiert." );
933 SwFlyFrm *pFly = ::GetFlyFromMarked( &rMrkList, this );
934 if ( pFly && pFly->IsFlyInCntFrm() )
935 return;
937 StartAllAction();
938 if ( bBottom )
939 Imp()->GetDrawView()->PutMarkedToBtm();
940 else
941 Imp()->GetDrawView()->MovMarkedToBtm();
942 ::lcl_NotifyNeighbours( &rMrkList );
943 GetDoc()->SetModified();
944 EndAllAction();
947 /*************************************************************************
949 |* SwFEShell::GetLayerId()
951 |* Beschreibung Objekt ueber/unter dem Dokument?
952 |* 2 Controls, 1 Heaven, 0 Hell, -1 Uneindeutig
953 |* Ersterstellung MA 20. Dec. 94
954 |* Letzte Aenderung MA 20. Dec. 94
956 *************************************************************************/
958 short SwFEShell::GetLayerId() const
960 short nRet = SHRT_MAX;
961 if ( Imp()->HasDrawView() )
963 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
964 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
966 const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
967 if ( nRet == SHRT_MAX )
968 nRet = pObj->GetLayer();
969 else if ( nRet != pObj->GetLayer() )
971 nRet = -1;
972 break;
976 if ( nRet == SHRT_MAX )
977 nRet = -1;
978 return nRet;
981 /*************************************************************************
983 |* SwFEShell::SelectionToHeaven(), SelectionToHell()
985 |* Beschreibung Objekt ueber/unter dem Dokument
986 |* Ersterstellung MA 20. Dec. 94
987 |* Letzte Aenderung AMA 04. Jun. 98
989 *************************************************************************/
990 // OD 25.06.2003 #108784#
991 // Note: only visible objects can be marked. Thus, objects with invisible
992 // layer IDs have not to be considered.
993 // If <SwFEShell> exists, layout exists!!
994 void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
996 if ( Imp()->HasDrawView() )
998 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
999 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
1000 // OD 25.06.2003 #108784# - correct type of <nControls>
1001 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
1003 SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
1004 // OD 21.08.2003 #i18447# - no change of layer for controls
1005 // or group objects containing controls.
1006 const bool bControlObj = ::CheckControlLayer( pObj );
1007 //if ( pObj->GetLayer() != nLayerId && pObj->GetLayer() != nControls )
1008 if ( !bControlObj && pObj->GetLayer() != nLayerId )
1010 pObj->SetLayer( nLayerId );
1011 InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) );
1012 if ( pObj->ISA(SwVirtFlyDrawObj) )
1014 SwFmt *pFmt = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
1015 SvxOpaqueItem aOpa( pFmt->GetOpaque() );
1016 aOpa.SetValue( nLayerId == pIDDMA->GetHellId() );
1017 pFmt->SetFmtAttr( aOpa );
1021 GetDoc()->SetModified();
1025 void SwFEShell::SelectionToHeaven()
1027 ChangeOpaque( getIDocumentDrawModelAccess()->GetHeavenId() );
1030 void SwFEShell::SelectionToHell()
1032 ChangeOpaque( getIDocumentDrawModelAccess()->GetHellId() );
1035 /*************************************************************************
1037 |* SwFEShell::IsObjSelected(), IsFrmSelected()
1039 |* Ersterstellung MA 16. Nov. 92
1040 |* Letzte Aenderung MA 17. Jan. 95
1042 *************************************************************************/
1044 USHORT SwFEShell::IsObjSelected() const
1046 if ( IsFrmSelected() || !Imp()->HasDrawView() )
1047 return 0;
1048 else
1049 return USHORT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() );
1052 BOOL SwFEShell::IsFrmSelected() const
1054 if ( !Imp()->HasDrawView() )
1055 return FALSE;
1056 else
1057 return 0 != ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
1058 (ViewShell*)this );
1061 sal_Bool SwFEShell::IsObjSelected( const SdrObject& rObj ) const
1063 if ( IsFrmSelected() || !Imp()->HasDrawView() )
1064 return sal_False;
1065 else
1066 return Imp()->GetDrawView()
1067 ->IsObjMarked( const_cast< SdrObject * >( &rObj ) );
1070 /*************************************************************************
1072 |* SwFEShell::EndTextEdit()
1074 |* Ersterstellung MA 19. Feb. 96
1075 |* Letzte Aenderung MA 19. Feb. 96
1077 *************************************************************************/
1079 void SwFEShell::EndTextEdit()
1081 //Beenden des TextEditModus. Wenn gewuenscht (default wenn das Objekt
1082 //keinen Text mehr enthaelt und keine Attribute traegt) wird das
1083 //Objekt gel�scht. Alle anderen markierten Objekte bleiben erhalten.
1085 ASSERT( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(),
1086 "EndTextEdit an no Object" );
1088 StartAllAction();
1089 SdrView *pView = Imp()->GetDrawView();
1090 SdrObject *pObj = pView->GetTextEditObject();
1091 SdrObjUserCall* pUserCall;
1092 if( 0 != ( pUserCall = GetUserCall(pObj) ) )
1094 SdrObject *pTmp = ((SwContact*)pUserCall)->GetMaster();
1095 if( !pTmp )
1096 pTmp = pObj;
1097 pUserCall->Changed( *pTmp, SDRUSERCALL_RESIZE, pTmp->GetLastBoundRect() );
1099 if ( !pObj->GetUpGroup() )
1101 if ( SDRENDTEXTEDIT_SHOULDBEDELETED == pView->SdrEndTextEdit(sal_True) )
1103 if ( pView->GetMarkedObjectList().GetMarkCount() > 1 )
1106 SdrMarkList aSave( pView->GetMarkedObjectList() );
1107 aSave.DeleteMark( aSave.FindObject( pObj ) );
1108 if ( aSave.GetMarkCount() )
1110 pView->UnmarkAll();
1111 pView->MarkObj( pObj, Imp()->GetPageView() );
1113 DelSelectedObj();
1114 if ( aSave.GetMarkCount() )
1116 for ( USHORT i = 0; i < aSave.GetMarkCount(); ++i )
1117 pView->MarkObj( aSave.GetMark( i )->GetMarkedSdrObj(),
1118 Imp()->GetPageView() );
1122 else
1123 DelSelectedObj();
1126 else
1127 pView->SdrEndTextEdit();
1128 EndAllAction();
1131 /*************************************************************************
1133 |* SwFEShell::IsInsideSelectedObj()
1135 |* Ersterstellung MA 16. Nov. 92
1136 |* Letzte Aenderung MA 08. Nov. 96
1138 *************************************************************************/
1140 int SwFEShell::IsInsideSelectedObj( const Point &rPt )
1142 if( Imp()->HasDrawView() )
1144 SwDrawView *pDView = Imp()->GetDrawView();
1146 if( pDView->GetMarkedObjectList().GetMarkCount() &&
1147 pDView->IsMarkedObjHit( rPt ) )
1149 return SDRHIT_OBJECT;
1152 return SDRHIT_NONE;
1155 /*************************************************************************
1157 |* SwFEShell::IsObjSelectable()
1159 |* Ersterstellung MA 16. Nov. 92
1160 |* Letzte Aenderung MA 02. Feb. 95
1162 *************************************************************************/
1164 bool SwFEShell::IsObjSelectable( const Point& rPt )
1166 SET_CURR_SHELL(this);
1167 #ifdef OLD
1168 if( Imp()->HasDrawView() )
1169 return Imp()->GetDrawView()->PickSomething( rPt, MINMOVE );
1170 return 0;
1171 #else
1172 SwDrawView *pDView = Imp()->GetDrawView();
1173 bool bRet = false;
1174 if( pDView )
1176 SdrObject* pObj;
1177 SdrPageView* pPV;
1178 USHORT nOld = pDView->GetHitTolerancePixel();
1179 pDView->SetHitTolerancePixel( pDView->GetMarkHdlSizePixel()/2 );
1181 bRet = 0 != pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE );
1182 pDView->SetHitTolerancePixel( nOld );
1184 return bRet;
1185 #endif
1188 // #107513#
1189 // Test if there is a draw object at that position and if it should be selected.
1190 // The 'should' is aimed at Writer text fly frames which may be in front of
1191 // the draw object.
1192 sal_Bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
1194 SET_CURR_SHELL(this);
1195 SwDrawView *pDrawView = Imp()->GetDrawView();
1196 sal_Bool bRet(sal_False);
1198 if(pDrawView)
1200 SdrObject* pObj;
1201 SdrPageView* pPV;
1202 sal_uInt16 nOld(pDrawView->GetHitTolerancePixel());
1204 pDrawView->SetHitTolerancePixel(pDrawView->GetMarkHdlSizePixel()/2);
1205 bRet = pDrawView->PickObj(rPt, pDrawView->getHitTolLog(), pObj, pPV, SDRSEARCH_PICKMARKABLE);
1206 pDrawView->SetHitTolerancePixel(nOld);
1208 if(bRet && pObj)
1210 const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
1211 if( pObj->GetLayer() == pIDDMA->GetHellId() )
1213 const SwFrm *pPageFrm = GetLayout()->Lower();
1214 while( pPageFrm && !pPageFrm->Frm().IsInside( rPt ) )
1216 if ( rPt.Y() < pPageFrm->Frm().Top() )
1217 pPageFrm = 0;
1218 else
1219 pPageFrm = pPageFrm->GetNext();
1221 if( pPageFrm )
1223 SwRect aTmp( pPageFrm->Prt() );
1224 aTmp += pPageFrm->Frm().Pos();
1225 if( aTmp.IsInside( rPt ) )
1226 return sal_False;
1230 const SdrPage* pPage = pIDDMA->GetDrawModel()->GetPage(0);
1231 // --> FME 2005-04-18 #i20965# Use GetOrdNum() instead of GetOrdNumDirect()
1232 // because ordnums might be wrong
1233 for(sal_uInt32 a(pObj->GetOrdNum() + 1); bRet && a < pPage->GetObjCount(); a++)
1235 // <--
1236 SdrObject *pCandidate = pPage->GetObj(a);
1238 if(pCandidate->ISA(SwVirtFlyDrawObj) && ((SwVirtFlyDrawObj*)pCandidate)->GetCurrentBoundRect().IsInside(rPt))
1240 bRet = sal_False;
1246 return bRet;
1249 /*************************************************************************
1251 |* SwFEShell::GotoObj()
1253 |* Beschreibung Wenn ein Obj selektiert ist, gehen wir von dessen
1254 |* TopLeft aus, andernfalls von der Mitte des aktuellen CharRects.
1255 |* Ersterstellung MA 01. Jun. 95
1256 |* Letzte Aenderung MA 30. Apr. 96
1258 *************************************************************************/
1259 /* -----------------23.09.98 10:29-------------------
1260 * Beinhaltet das Objekt ein Control oder Gruppen,
1261 * die nur aus Controls bestehen
1262 * --------------------------------------------------*/
1263 BOOL lcl_IsControlGroup( const SdrObject *pObj )
1265 BOOL bRet = FALSE;
1266 if(pObj->ISA(SdrUnoObj))
1267 bRet = TRUE;
1268 else if( pObj->ISA( SdrObjGroup ) )
1270 bRet = TRUE;
1271 const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
1272 for ( USHORT i = 0; i < pLst->GetObjCount(); ++i )
1273 if( !::lcl_IsControlGroup( pLst->GetObj( i ) ) )
1274 return FALSE;
1276 return bRet;
1279 BOOL SwFEShell::GotoObj( BOOL bNext, USHORT /*GOTOOBJ_...*/ eType )
1281 if( !Imp()->HasDrawView() )
1282 return FALSE;
1283 else
1285 const SdrObject *pBest = 0,
1286 *pTop = 0;
1288 const long nTmp = bNext ? LONG_MAX : 0;
1289 Point aBestPos( nTmp, nTmp );
1290 Point aTopPos( nTmp, nTmp );
1291 Point aCurPos;
1292 Point aPos;
1293 BOOL bRet = FALSE;
1294 BOOL bNoDraw = 0 == (GOTOOBJ_DRAW_ANY & eType);
1295 BOOL bNoFly = 0 == (GOTOOBJ_FLY_ANY & eType);
1297 if( !bNoFly && bNoDraw )
1299 SwFlyFrm *pFly = GetCurrFrm( FALSE )->FindFlyFrm();
1300 if( pFly )
1301 pBest = pFly->GetVirtDrawObj();
1303 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1304 SdrPageView* pPV = Imp()->GetDrawView()->GetSdrPageView();
1306 if( !pBest || rMrkList.GetMarkCount() == 1 )
1308 // Ausgangspunkt bestimmen.
1309 SdrObjList* pList = NULL;
1310 if ( rMrkList.GetMarkCount() )
1312 const SdrObject* pStartObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
1313 if( pStartObj->ISA(SwVirtFlyDrawObj) )
1314 aPos = ((SwVirtFlyDrawObj*)pStartObj)->GetFlyFrm()->Frm().Pos();
1315 else
1316 aPos = pStartObj->GetSnapRect().TopLeft();
1318 // If an object inside a group is selected, we want to
1319 // iterate over the group members.
1320 if ( ! pStartObj->GetUserCall() )
1321 pList = pStartObj->GetObjList();
1323 else
1325 // If no object is selected, we check if we just entered a group.
1326 // In this case we want to iterate over the group members.
1327 aPos = GetCharRect().Center();
1328 const SdrObject* pStartObj = pPV ? pPV->GetAktGroup() : 0;
1329 if ( pStartObj && pStartObj->ISA( SdrObjGroup ) )
1330 pList = pStartObj->GetSubList();
1333 if ( ! pList )
1335 // Here we are if
1336 // A No object has been selected and no group has been entered or
1337 // B An object has been selected and it is not inside a group
1338 pList = getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 );
1342 ASSERT( pList, "No object list to iterate" )
1344 const ULONG nObjs = pList->GetObjCount();
1345 for( ULONG nObj = 0; nObj < nObjs; ++nObj )
1347 SdrObject* pObj = pList->GetObj( nObj );
1348 BOOL bFlyFrm = pObj->ISA(SwVirtFlyDrawObj);
1349 if( ( bNoFly && bFlyFrm ) ||
1350 ( bNoDraw && !bFlyFrm ) ||
1351 ( eType == GOTOOBJ_DRAW_SIMPLE && lcl_IsControlGroup( pObj ) ) ||
1352 ( eType == GOTOOBJ_DRAW_CONTROL && !lcl_IsControlGroup( pObj ) ) ||
1353 ( pPV && ! pPV->GetView().IsObjMarkable( pObj, pPV ) ) )
1354 continue;
1355 if( bFlyFrm )
1357 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pObj;
1358 SwFlyFrm *pFly = pO->GetFlyFrm();
1359 if( GOTOOBJ_FLY_ANY != ( GOTOOBJ_FLY_ANY & eType ) )
1361 switch ( eType )
1363 case GOTOOBJ_FLY_FRM:
1364 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
1365 continue;
1366 break;
1367 case GOTOOBJ_FLY_GRF:
1368 if ( pFly->Lower() &&
1369 (pFly->Lower()->IsLayoutFrm() ||
1370 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetGrfNode()))
1371 continue;
1372 break;
1373 case GOTOOBJ_FLY_OLE:
1374 if ( pFly->Lower() &&
1375 (pFly->Lower()->IsLayoutFrm() ||
1376 !((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode()))
1377 continue;
1378 break;
1381 aCurPos = pFly->Frm().Pos();
1383 else
1384 aCurPos = pObj->GetCurrentBoundRect().TopLeft();
1386 // Sonderfall wenn ein anderes Obj auf selber Y steht.
1387 if( aCurPos != aPos && // nur wenn ich es nicht selber bin
1388 aCurPos.Y() == aPos.Y() && // ist die Y Position gleich
1389 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
1390 (aCurPos.X() < aPos.X())) ) // " reverse
1392 aBestPos = Point( nTmp, nTmp );
1393 for( ULONG i = 0; i < nObjs; ++i )
1395 SdrObject *pTmpObj = pList->GetObj( i );
1396 bFlyFrm = pTmpObj->ISA(SwVirtFlyDrawObj);
1397 if( ( bNoFly && bFlyFrm ) || ( bNoDraw && !bFlyFrm ) )
1398 continue;
1399 if( bFlyFrm )
1401 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pTmpObj;
1402 aCurPos = pO->GetFlyFrm()->Frm().Pos();
1404 else
1405 aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft();
1407 if( aCurPos != aPos && aCurPos.Y() == aPos.Y() &&
1408 (bNext? (aCurPos.X() > aPos.X()) : // liegt neben mir
1409 (aCurPos.X() < aPos.X())) && // " reverse
1410 (bNext? (aCurPos.X() < aBestPos.X()) : // besser als Beste
1411 (aCurPos.X() > aBestPos.X())) ) // " reverse
1413 aBestPos = aCurPos;
1414 pBest = pTmpObj;
1417 break;
1420 if( (bNext? (aPos.Y() < aCurPos.Y()) : // nur unter mir
1421 (aPos.Y() > aCurPos.Y())) && // " reverse
1422 (bNext? (aBestPos.Y() > aCurPos.Y()) : // naeher drunter
1423 (aBestPos.Y() < aCurPos.Y())) || // " reverse
1424 (aBestPos.Y() == aCurPos.Y() &&
1425 (bNext? (aBestPos.X() > aCurPos.X()) : // weiter links
1426 (aBestPos.X() < aCurPos.X())))) // " reverse
1429 aBestPos = aCurPos;
1430 pBest = pObj;
1433 if( (bNext? (aTopPos.Y() > aCurPos.Y()) : // hoeher als Beste
1434 (aTopPos.Y() < aCurPos.Y())) || // " reverse
1435 (aTopPos.Y() == aCurPos.Y() &&
1436 (bNext? (aTopPos.X() > aCurPos.X()) : // weiter links
1437 (aTopPos.X() < aCurPos.X())))) // " reverse
1439 aTopPos = aCurPos;
1440 pTop = pObj;
1443 // leider nichts gefunden
1444 if( (bNext? (aBestPos.X() == LONG_MAX) : (aBestPos.X() == 0)) )
1445 pBest = pTop;
1448 if( pBest )
1450 BOOL bFlyFrm = pBest->ISA(SwVirtFlyDrawObj);
1451 if( bFlyFrm )
1453 SwVirtFlyDrawObj *pO = (SwVirtFlyDrawObj*)pBest;
1454 const SwRect& rFrm = pO->GetFlyFrm()->Frm();
1455 SelectObj( rFrm.Pos(), 0, (SdrObject*)pBest );
1456 if( !ActionPend() )
1457 MakeVisible( rFrm );
1459 else
1461 SelectObj( Point(), 0, (SdrObject*)pBest );
1462 if( !ActionPend() )
1463 MakeVisible( pBest->GetCurrentBoundRect() );
1465 CallChgLnk();
1466 bRet = TRUE;
1468 return bRet;
1472 /*************************************************************************
1474 |* SwFEShell::BeginCreate()
1476 |* Ersterstellung MA 20. Dec. 94
1477 |* Letzte Aenderung MA 21. Mar. 95
1479 *************************************************************************/
1481 BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, const Point &rPos )
1483 BOOL bRet = FALSE;
1485 if ( !Imp()->HasDrawView() )
1486 Imp()->MakeDrawView();
1488 if ( GetPageNumber( rPos ) )
1490 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind );
1491 if ( eSdrObjectKind == OBJ_CAPTION )
1492 bRet = Imp()->GetDrawView()->BegCreateCaptionObj(
1493 rPos, Size( lMinBorder - MINFLY, lMinBorder - MINFLY ),
1494 GetOut() );
1495 else
1496 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1498 if ( bRet )
1500 ::FrameNotify( this, FLY_DRAG_START );
1502 return bRet;
1505 BOOL SwFEShell::BeginCreate( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, UINT32 eObjInventor,
1506 const Point &rPos )
1508 BOOL bRet = FALSE;
1510 if ( !Imp()->HasDrawView() )
1511 Imp()->MakeDrawView();
1513 if ( GetPageNumber( rPos ) )
1515 Imp()->GetDrawView()->SetCurrentObj( eSdrObjectKind, eObjInventor );
1516 bRet = Imp()->GetDrawView()->BegCreateObj( rPos, GetOut() );
1518 if ( bRet )
1519 ::FrameNotify( this, FLY_DRAG_START );
1520 return bRet;
1523 /*************************************************************************
1525 |* SwFEShell::MoveCreate()
1527 |* Ersterstellung MA 20. Dec. 94
1528 |* Letzte Aenderung MA 24. Jan. 95
1530 *************************************************************************/
1532 void SwFEShell::MoveCreate( const Point &rPos )
1534 ASSERT( Imp()->HasDrawView(), "MoveCreate without DrawView?" );
1535 if ( GetPageNumber( rPos ) )
1537 ScrollTo( rPos );
1538 Imp()->GetDrawView()->MovCreateObj( rPos );
1539 ::FrameNotify( this, FLY_DRAG );
1543 /*************************************************************************
1545 |* SwFEShell::EndCreate(), ImpEndCreate()
1547 |* Ersterstellung MA 20. Dec. 94
1548 |* Letzte Aenderung MA 14. Oct. 96
1550 *************************************************************************/
1552 BOOL SwFEShell::EndCreate( UINT16 eSdrCreateCmd )
1554 // JP 18.08.95: Damit das Undo-Object aus der DrawEngine nicht bei uns
1555 // gespeichert wird, (wir erzeugen ein eigenes Undo-Object!) hier kurz
1556 // das Undo abschalten
1557 ASSERT( Imp()->HasDrawView(), "EndCreate without DrawView?" );
1558 if( !Imp()->GetDrawView()->IsGroupEntered() )
1559 GetDoc()->SetNoDrawUndoObj( TRUE );
1560 BOOL bCreate = Imp()->GetDrawView()->EndCreateObj(
1561 SdrCreateCmd( eSdrCreateCmd ) );
1562 GetDoc()->SetNoDrawUndoObj( FALSE );
1564 if ( !bCreate )
1566 ::FrameNotify( this, FLY_DRAG_END );
1567 return FALSE;
1570 if ( (SdrCreateCmd)eSdrCreateCmd == SDRCREATE_NEXTPOINT )
1572 ::FrameNotify( this, FLY_DRAG );
1573 return TRUE;
1575 return ImpEndCreate();
1579 BOOL SwFEShell::ImpEndCreate()
1581 ASSERT( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1,
1582 "Neues Object nicht selektiert." );
1584 SdrObject& rSdrObj = *Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
1586 if( rSdrObj.GetSnapRect().IsEmpty() )
1588 //JP 10.04.95: das Object vergessen wir lieber, fuerht nur
1589 // zu Problemen
1590 Imp()->GetDrawView()->DeleteMarked();
1591 Imp()->GetDrawView()->UnmarkAll();
1592 ::FrameNotify( this, FLY_DRAG_END );
1593 return FALSE;
1596 if( rSdrObj.GetUpGroup() )
1598 Point aTmpPos( rSdrObj.GetSnapRect().TopLeft() );
1599 Point aNewAnchor( rSdrObj.GetUpGroup()->GetAnchorPos() );
1600 // OD 2004-04-05 #i26791# - direct object positioning for group members
1601 rSdrObj.NbcSetRelativePos( aTmpPos - aNewAnchor );
1602 rSdrObj.NbcSetAnchorPos( aNewAnchor );
1603 ::FrameNotify( this, FLY_DRAG );
1604 return TRUE;
1607 LockPaint();
1608 StartAllAction();
1610 Imp()->GetDrawView()->UnmarkAll();
1612 const Rectangle &rBound = rSdrObj.GetSnapRect();
1613 Point aPt( rBound.TopRight() );
1615 //Fremde Identifier sollen in den Default laufen.
1616 //Ueberschneidungen sind moeglich!!
1617 UINT16 nIdent = SdrInventor == rSdrObj.GetObjInventor()
1618 ? rSdrObj.GetObjIdentifier()
1619 : 0xFFFF;
1621 //Default fuer Controls ist Zeichengebunden, Absatzgebunden sonst.
1622 SwFmtAnchor aAnch;
1623 const SwFrm *pAnch = 0;
1624 BOOL bCharBound = FALSE;
1625 if( rSdrObj.ISA( SdrUnoObj ) )
1627 SwPosition aPos( GetDoc()->GetNodes() );
1628 SwCrsrMoveState aState( MV_SETONLYTEXT );
1629 Point aPoint( aPt.X(), aPt.Y() + rBound.GetHeight()/2 );
1630 getIDocumentLayoutAccess()->GetRootFrm()->GetCrsrOfst( &aPos, aPoint, &aState );
1632 //JP 22.01.99: Zeichenbindung ist im ReadnOnly-Inhalt nicht erlaubt
1633 if( !aPos.nNode.GetNode().IsProtect() )
1635 pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, &aPos );
1636 SwRect aTmp;
1637 pAnch->GetCharRect( aTmp, aPos );
1639 //Der Crsr darf nicht zu weit entfernt sein.
1640 bCharBound = TRUE;
1641 Rectangle aRect( aTmp.SVRect() );
1642 aRect.Left() -= MM50*2;
1643 aRect.Top() -= MM50*2;
1644 aRect.Right() += MM50*2;
1645 aRect.Bottom()+= MM50*2;
1647 if( !aRect.IsOver( rBound ) && !::GetHtmlMode( GetDoc()->GetDocShell() ))
1648 bCharBound = FALSE;
1650 //Bindung in Kopf-/Fusszeilen ist ebenfalls nicht erlaubt.
1651 if( bCharBound )
1652 bCharBound = !GetDoc()->IsInHeaderFooter( aPos.nNode );
1654 if( bCharBound )
1656 aAnch.SetType( FLY_IN_CNTNT );
1657 aAnch.SetAnchor( &aPos );
1662 if( !bCharBound )
1664 // OD 16.05.2003 #108784# - allow native drawing objects in header/footer.
1665 // Thus, set <bBodyOnly> to <false> for these objects using value
1666 // of <nIdent> - value <0xFFFF> indicates control objects, which aren't
1667 // allowed in header/footer.
1668 //bool bBodyOnly = OBJ_NONE != nIdent;
1669 bool bBodyOnly = 0xFFFF == nIdent;
1670 bool bAtPage = false;
1671 const SwFrm* pPage = 0;
1672 SwCrsrMoveState aState( MV_SETONLYTEXT );
1673 Point aPoint( aPt );
1674 SwPosition aPos( GetDoc()->GetNodes() );
1675 GetLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
1677 //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
1678 if( aPos.nNode.GetNode().IsProtect() )
1679 // dann darf er nur seitengebunden sein. Oder sollte man
1680 // die naechste nicht READONLY Position suchen?
1681 bAtPage = true;
1683 pAnch = aPos.nNode.GetNode().GetCntntNode()->GetFrm( &aPoint, 0, FALSE );
1685 if( !bAtPage )
1687 const SwFlyFrm *pTmp = pAnch->FindFlyFrm();
1688 if( pTmp )
1690 const SwFrm* pTmpFrm = pAnch;
1691 SwRect aBound( rBound );
1692 while( pTmp )
1694 if( pTmp->Frm().IsInside( aBound ) )
1696 if( !bBodyOnly || !pTmp->FindFooterOrHeader() )
1697 pPage = pTmpFrm;
1698 break;
1700 pTmp = pTmp->GetAnchorFrm()
1701 ? pTmp->GetAnchorFrm()->FindFlyFrm()
1702 : 0;
1703 pTmpFrm = pTmp;
1707 if( !pPage )
1708 pPage = pAnch->FindPageFrm();
1710 // immer ueber FindAnchor gehen, damit der Frame immer an den
1711 // davorgehen gebunden wird. Beim GetCrsOfst kann man auch zum
1712 // nachfolgenden kommen. DAS IST FALSCH
1713 pAnch = ::FindAnchor( pPage, aPt, bBodyOnly );
1714 aPos.nNode = *((SwCntntFrm*)pAnch)->GetNode();
1716 //JP 22.01.99: nicht in ReadnOnly-Inhalt setzen
1717 if( aPos.nNode.GetNode().IsProtect() )
1718 // dann darf er nur seitengebunden sein. Oder sollte man
1719 // die naechste nicht READONLY Position suchen?
1720 bAtPage = true;
1721 else
1723 aAnch.SetType( FLY_AT_CNTNT );
1724 aAnch.SetAnchor( &aPos );
1728 if( bAtPage )
1730 pPage = pAnch->FindPageFrm();
1732 aAnch.SetType( FLY_PAGE );
1733 aAnch.SetPageNum( pPage->GetPhyPageNum() );
1734 pAnch = pPage; // die Page wird jetzt zum Anker
1738 SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
1739 RES_SURROUND, RES_ANCHOR, 0 );
1740 aSet.Put( aAnch );
1742 // OD 2004-03-30 #i26791# - determine relative object position
1743 SwTwips nXOffset;
1744 SwTwips nYOffset = rBound.Top() - pAnch->Frm().Top();
1746 if( pAnch->IsVertical() )
1748 nXOffset = nYOffset;
1749 nYOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1751 else if( pAnch->IsRightToLeft() )
1752 nXOffset = pAnch->Frm().Left()+pAnch->Frm().Width()-rBound.Right();
1753 else
1754 nXOffset = rBound.Left() - pAnch->Frm().Left();
1755 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1757 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1758 do {
1759 pTmp = pTmp->FindMaster();
1760 ASSERT( pTmp, "Where's my Master?" );
1761 // OD 2004-03-30 #i26791# - correction: add frame area height
1762 // of master frames.
1763 nYOffset += pTmp->IsVertical() ?
1764 pTmp->Frm().Width() : pTmp->Frm().Height();
1765 } while ( pTmp->IsFollow() );
1769 if( OBJ_NONE == nIdent )
1771 //Bei OBJ_NONE wird ein Fly eingefuegt.
1772 const long nWidth = rBound.Right() - rBound.Left();
1773 const long nHeight= rBound.Bottom() - rBound.Top();
1774 aSet.Put( SwFmtFrmSize( ATT_MIN_SIZE, Max( nWidth, long(MINFLY) ),
1775 Max( nHeight, long(MINFLY) )));
1777 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1778 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1779 aSet.Put( SwFmtSurround( SURROUND_PARALLEL ) );
1780 aSet.Put( aHori );
1781 aSet.Put( aVert );
1783 //Schnell noch das Rechteck merken
1784 const SwRect aFlyRect( rBound );
1786 //Erzeugtes Object wegwerfen, so kann der Fly am elegentesten
1787 //ueber vorhandene SS erzeugt werden.
1788 GetDoc()->SetNoDrawUndoObj( TRUE ); // siehe oben
1789 // --> OD 2005-08-08 #i52858# - method name changed
1790 SdrPage *pPg = getIDocumentDrawModelAccess()->GetOrCreateDrawModel()->GetPage( 0 );
1791 // <--
1792 if( !pPg )
1794 SdrModel* pTmpSdrModel = getIDocumentDrawModelAccess()->GetDrawModel();
1795 pPg = pTmpSdrModel->AllocPage( FALSE );
1796 pTmpSdrModel->InsertPage( pPg );
1798 pPg->RecalcObjOrdNums();
1799 SdrObject* pRemovedObject = pPg->RemoveObject( rSdrObj.GetOrdNumDirect() );
1800 SdrObject::Free( pRemovedObject );
1801 GetDoc()->SetNoDrawUndoObj( FALSE );
1803 SwFlyFrm* pFlyFrm;
1804 if( NewFlyFrm( aSet, TRUE ) &&
1805 ::GetHtmlMode( GetDoc()->GetDocShell() ) &&
1806 0 != ( pFlyFrm = FindFlyFrm() ))
1808 SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT );
1809 //Horizontale Ausrichtung:
1810 const BOOL bLeftFrm = aFlyRect.Left() <
1811 pAnch->Frm().Left() + pAnch->Prt().Left(),
1812 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
1813 pAnch->Frm().Left() + pAnch->Prt().Width()/2;
1814 if( bLeftFrm || bLeftPrt )
1816 aHori.SetHoriOrient( text::HoriOrientation::LEFT );
1817 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1819 else
1821 const BOOL bRightFrm = aFlyRect.Left() >
1822 pAnch->Frm().Left() + pAnch->Prt().Width();
1823 aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
1824 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
1826 aHtmlSet.Put( aHori );
1827 aVert.SetVertOrient( text::VertOrientation::TOP );
1828 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
1829 aHtmlSet.Put( aVert );
1831 GetDoc()->SetAttr( aHtmlSet, *pFlyFrm->GetFmt() );
1834 else
1836 Point aRelNullPt;
1837 if( OBJ_CAPTION == nIdent )
1838 aRelNullPt = ((SdrCaptionObj&)rSdrObj).GetTailPos();
1839 else
1840 aRelNullPt = rBound.TopLeft();
1842 aSet.Put( aAnch );
1843 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
1844 // OD 2004-03-30 #i26791# - set horizontal position
1845 SwFmtHoriOrient aHori( nXOffset, text::HoriOrientation::NONE, text::RelOrientation::FRAME );
1846 aSet.Put( aHori );
1847 // OD 2004-03-30 #i26791# - set vertical position
1848 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1850 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1851 do {
1852 pTmp = pTmp->FindMaster();
1853 ASSERT( pTmp, "Where's my Master?" );
1854 nYOffset += pTmp->IsVertical() ?
1855 pTmp->Prt().Width() : pTmp->Prt().Height();
1856 } while ( pTmp->IsFollow() );
1858 SwFmtVertOrient aVert( nYOffset, text::VertOrientation::NONE, text::RelOrientation::FRAME );
1859 aSet.Put( aVert );
1860 SwDrawFrmFmt* pFmt = (SwDrawFrmFmt*)getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
1861 // --> OD 2004-10-25 #i36010# - set layout direction of the position
1862 pFmt->SetPositionLayoutDir(
1863 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
1864 // <--
1865 // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set
1866 pFmt->PosAttrSet();
1867 // <--
1869 SwDrawContact *pContact = new SwDrawContact( pFmt, &rSdrObj );
1870 // --> OD 2004-11-22 #i35635#
1871 pContact->MoveObjToVisibleLayer( &rSdrObj );
1872 // <--
1873 if( bCharBound )
1875 ASSERT( aAnch.GetAnchorId() == FLY_IN_CNTNT, "wrong AnchorType" );
1876 SwTxtNode *pNd = aAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
1877 pNd->InsertItem( SwFmtFlyCnt( pFmt ),
1878 aAnch.GetCntntAnchor()->nContent.GetIndex(), 0 );
1879 SwFmtVertOrient aVertical( pFmt->GetVertOrient() );
1880 aVertical.SetVertOrient( text::VertOrientation::LINE_CENTER );
1881 pFmt->SetFmtAttr( aVertical );
1883 if( pAnch->IsTxtFrm() && ((SwTxtFrm*)pAnch)->IsFollow() )
1885 SwTxtFrm* pTmp = (SwTxtFrm*)pAnch;
1886 do {
1887 pTmp = pTmp->FindMaster();
1888 ASSERT( pTmp, "Where's my Master?" );
1889 } while( pTmp->IsFollow() );
1890 pAnch = pTmp;
1893 pContact->ConnectToLayout();
1895 // OD 25.06.2003 #108784# - mark object at frame the object is inserted at.
1897 SdrObject* pMarkObj = pContact->GetDrawObjectByAnchorFrm( *pAnch );
1898 if ( pMarkObj )
1900 Imp()->GetDrawView()->MarkObj( pMarkObj, Imp()->GetPageView(),
1901 FALSE, FALSE );
1903 else
1905 Imp()->GetDrawView()->MarkObj( &rSdrObj, Imp()->GetPageView(),
1906 FALSE, FALSE );
1911 GetDoc()->SetModified();
1913 KillPams();
1914 EndAllActionAndCall();
1915 UnlockPaint();
1916 return TRUE;
1920 /*************************************************************************
1922 |* SwFEShell::BreakCreate()
1924 |* Ersterstellung MA 20. Dec. 94
1925 |* Letzte Aenderung MA 09. Jan. 95
1927 *************************************************************************/
1929 void SwFEShell::BreakCreate()
1931 ASSERT( Imp()->HasDrawView(), "BreakCreate without DrawView?" );
1932 Imp()->GetDrawView()->BrkCreateObj();
1933 ::FrameNotify( this, FLY_DRAG_END );
1936 /*************************************************************************
1938 |* SwFEShell::IsDrawCreate()
1940 |* Ersterstellung OM 16. Mar. 95
1941 |* Letzte Aenderung OM 16. Mar. 95
1943 *************************************************************************/
1945 BOOL SwFEShell::IsDrawCreate() const
1947 return Imp()->HasDrawView() ? Imp()->GetDrawView()->IsCreateObj() : FALSE;
1950 /*************************************************************************
1952 |* SwFEShell::BeginMark()
1954 |* Ersterstellung OM 07. Feb. 95
1955 |* Letzte Aenderung OM 07. Feb. 95
1957 *************************************************************************/
1959 BOOL SwFEShell::BeginMark( const Point &rPos )
1961 if ( !Imp()->HasDrawView() )
1962 Imp()->MakeDrawView();
1964 if ( GetPageNumber( rPos ) )
1966 SwDrawView* pDView = Imp()->GetDrawView();
1968 if (pDView->HasMarkablePoints())
1969 return pDView->BegMarkPoints( rPos );
1970 else
1971 return pDView->BegMarkObj( rPos );
1973 else
1974 return FALSE;
1977 /*************************************************************************
1979 |* SwFEShell::MoveMark()
1981 |* Ersterstellung OM 07. Feb. 95
1982 |* Letzte Aenderung OM 07. Feb. 95
1984 *************************************************************************/
1986 void SwFEShell::MoveMark( const Point &rPos )
1988 ASSERT( Imp()->HasDrawView(), "MoveMark without DrawView?" );
1990 if ( GetPageNumber( rPos ) )
1992 ScrollTo( rPos );
1993 SwDrawView* pDView = Imp()->GetDrawView();
1994 // Imp()->GetDrawView()->MovMarkObj( rPos );
1996 if (pDView->IsInsObjPoint())
1997 pDView->MovInsObjPoint( rPos );
1998 else if (pDView->IsMarkPoints())
1999 pDView->MovMarkPoints( rPos );
2000 else
2001 pDView->MovAction( rPos );
2005 /*************************************************************************
2007 |* SwFEShell::EndMark()
2009 |* Ersterstellung OM 07. Feb. 95
2010 |* Letzte Aenderung MA 08. Feb. 95
2012 *************************************************************************/
2014 BOOL SwFEShell::EndMark()
2016 BOOL bRet = FALSE;
2017 ASSERT( Imp()->HasDrawView(), "EndMark without DrawView?" );
2019 if (Imp()->GetDrawView()->IsMarkObj())
2021 bRet = Imp()->GetDrawView()->EndMarkObj();
2023 if ( bRet )
2025 BOOL bShowHdl = FALSE;
2026 SwDrawView* pDView = Imp()->GetDrawView();
2027 //Rahmen werden auf diese Art nicht Selektiert, es sein denn es
2028 //ist nur ein Rahmen.
2029 SdrMarkList &rMrkList = (SdrMarkList&)pDView->GetMarkedObjectList();
2030 SwFlyFrm* pOldSelFly = ::GetFlyFromMarked( &rMrkList, this );
2032 if ( rMrkList.GetMarkCount() > 1 )
2033 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2035 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2036 if( pObj->ISA(SwVirtFlyDrawObj) )
2038 if ( !bShowHdl )
2040 //HMHpDView->HideMarkHdl();
2041 bShowHdl = TRUE;
2043 rMrkList.DeleteMark( i );
2044 --i; //keinen auslassen.
2048 if( bShowHdl )
2050 pDView->MarkListHasChanged();
2051 pDView->AdjustMarkHdl();
2052 //HMHpDView->ShowMarkHdl();
2055 if ( rMrkList.GetMarkCount() )
2056 ::lcl_GrabCursor(this, pOldSelFly);
2057 else
2058 bRet = FALSE;
2060 if ( bRet )
2061 ::FrameNotify( this, FLY_DRAG_START );
2063 else
2065 if (Imp()->GetDrawView()->IsMarkPoints())
2066 bRet = Imp()->GetDrawView()->EndMarkPoints();
2069 SetChainMarker();
2070 return bRet;
2073 /*************************************************************************
2075 |* SwFEShell::BreakSelect()
2077 |* Ersterstellung OM 07. Feb. 95
2078 |* Letzte Aenderung OM 07. Feb. 95
2080 *************************************************************************/
2082 void SwFEShell::BreakMark()
2084 ASSERT( Imp()->HasDrawView(), "BreakMark without DrawView?" );
2085 Imp()->GetDrawView()->BrkMarkObj();
2088 /*************************************************************************
2090 |* SwFEShell::GetAnchorId()
2092 |* Ersterstellung MA 30. Jan. 95
2093 |* Letzte Aenderung MA 30. Jan. 95
2095 *************************************************************************/
2097 short SwFEShell::GetAnchorId() const
2099 short nRet = SHRT_MAX;
2100 if ( Imp()->HasDrawView() )
2102 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2103 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2105 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2106 if ( pObj->ISA(SwVirtFlyDrawObj) )
2108 nRet = -1;
2109 break;
2111 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2112 short nId = static_cast<short>(pContact->GetFmt()->GetAnchor().GetAnchorId());
2113 if ( nRet == SHRT_MAX )
2114 nRet = nId;
2115 else if ( nRet != nId )
2117 nRet = -1;
2118 break;
2122 if ( nRet == SHRT_MAX )
2123 nRet = -1;
2124 return nRet;
2127 /*************************************************************************
2129 |* SwFEShell::ChgAnchor()
2131 |* Ersterstellung MA 10. Jan. 95
2132 |* Letzte Aenderung MA 30. May. 96
2134 *************************************************************************/
2136 void SwFEShell::ChgAnchor( int eAnchorId, BOOL bSameOnly, BOOL bPosCorr )
2138 ASSERT( Imp()->HasDrawView(), "ChgAnchor without DrawView?" );
2139 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2140 if( rMrkList.GetMarkCount() &&
2141 !rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
2143 StartAllAction();
2145 if( GetDoc()->ChgAnchor( rMrkList, (RndStdIds)eAnchorId, bSameOnly, bPosCorr ))
2146 Imp()->GetDrawView()->UnmarkAll();
2148 EndAllAction();
2150 ::FrameNotify( this, FLY_DRAG );
2154 /*************************************************************************
2156 |* SwFEShell::DelSelectedObj()
2158 |* Ersterstellung MA 03. Nov. 92
2159 |* Letzte Aenderung MA 14. Nov. 95
2161 *************************************************************************/
2163 void SwFEShell::DelSelectedObj()
2165 ASSERT( Imp()->HasDrawView(), "DelSelectedObj(), no DrawView available" );
2166 if ( Imp()->HasDrawView() )
2168 StartAllAction();
2169 Imp()->GetDrawView()->DeleteMarked();
2170 EndAllAction();
2171 ::FrameNotify( this, FLY_DRAG_END );
2175 /*************************************************************************
2177 |* SwFEShell::GetObjSize(), GetAnchorObjDiff()
2179 |* Beschreibung Fuer die Statuszeile zum Erfragen der aktuellen
2180 |* Verhaeltnisse
2181 |* Ersterstellung MA 25. Apr. 95
2182 |* Letzte Aenderung MA 25. Apr. 95
2184 *************************************************************************/
2186 Size SwFEShell::GetObjSize() const
2188 Rectangle aRect;
2189 if ( Imp()->HasDrawView() )
2191 if ( Imp()->GetDrawView()->IsAction() )
2192 Imp()->GetDrawView()->TakeActionRect( aRect );
2193 else
2194 aRect = Imp()->GetDrawView()->GetAllMarkedRect();
2196 return aRect.GetSize();
2199 Point SwFEShell::GetAnchorObjDiff() const
2201 const SdrView *pView = Imp()->GetDrawView();
2202 ASSERT( pView, "GetAnchorObjDiff without DrawView?" );
2204 Rectangle aRect;
2205 if ( Imp()->GetDrawView()->IsAction() )
2206 Imp()->GetDrawView()->TakeActionRect( aRect );
2207 else
2208 aRect = Imp()->GetDrawView()->GetAllMarkedRect();
2210 Point aRet( aRect.TopLeft() );
2212 if ( IsFrmSelected() )
2214 SwFlyFrm *pFly = FindFlyFrm();
2215 aRet -= pFly->GetAnchorFrm()->Frm().Pos();
2217 else
2219 const SdrObject *pObj = pView->GetMarkedObjectList().GetMarkCount() == 1 ?
2220 pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj() : 0;
2221 if ( pObj )
2222 aRet -= pObj->GetAnchorPos();
2225 return aRet;
2228 Point SwFEShell::GetObjAbsPos() const
2230 ASSERT( Imp()->GetDrawView(), "GetObjAbsPos() without DrawView?" );
2231 return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
2236 /*************************************************************************
2238 |* SwFEShell::IsGroupSelected()
2240 |* Ersterstellung MA 30. Jan. 95
2241 |* Letzte Aenderung MA 30. May. 96
2243 *************************************************************************/
2245 BOOL SwFEShell::IsGroupSelected()
2247 if ( IsObjSelected() )
2249 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2250 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2252 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2253 // OD 30.06.2003 #108784# - consider 'virtual' drawing objects.
2254 // Thus, use corresponding method instead of checking type.
2255 if ( pObj->IsGroupObject() &&
2256 // --> FME 2004-12-08 #i38505# No ungroup allowed for 3d objects
2257 !pObj->Is3DObj() &&
2258 // <--
2259 FLY_IN_CNTNT != ((SwDrawContact*)GetUserCall(pObj))->
2260 GetFmt()->GetAnchor().GetAnchorId() )
2262 return TRUE;
2266 return FALSE;
2269 // OD 27.06.2003 #108784# - change return type.
2270 // OD 27.06.2003 #108784# - adjustments for drawing objects in header/footer:
2271 // allow group, only if all selected objects are in the same header/footer
2272 // or not in header/footer.
2273 bool SwFEShell::IsGroupAllowed() const
2275 bool bIsGroupAllowed = false;
2276 if ( IsObjSelected() > 1 )
2278 bIsGroupAllowed = true;
2279 const SdrObject* pUpGroup = 0L;
2280 const SwFrm* pHeaderFooterFrm = 0L;
2281 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2282 for ( USHORT i = 0; bIsGroupAllowed && i < rMrkList.GetMarkCount(); ++i )
2284 const SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2285 if ( i )
2286 bIsGroupAllowed = pObj->GetUpGroup() == pUpGroup;
2287 else
2288 pUpGroup = pObj->GetUpGroup();
2290 // --> OD 2006-11-06 #130889# - make code robust
2291 // if ( bIsGroupAllowed &&
2292 // FLY_IN_CNTNT == ::FindFrmFmt( (SdrObject*)pObj )->GetAnchor().GetAnchorId() )
2293 // {
2294 // bIsGroupAllowed = false;
2295 // }
2296 if ( bIsGroupAllowed )
2298 SwFrmFmt* pFrmFmt( ::FindFrmFmt( const_cast<SdrObject*>(pObj) ) );
2299 if ( !pFrmFmt )
2301 ASSERT( false,
2302 "<SwFEShell::IsGroupAllowed()> - missing frame format" );
2303 bIsGroupAllowed = false;
2305 else if ( FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() )
2307 bIsGroupAllowed = false;
2310 // <--
2312 // OD 27.06.2003 #108784# - check, if all selected objects are in the
2313 // same header/footer or not in header/footer.
2314 if ( bIsGroupAllowed )
2316 const SwFrm* pAnchorFrm = 0L;
2317 if ( pObj->ISA(SwVirtFlyDrawObj) )
2319 const SwFlyFrm* pFlyFrm =
2320 static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
2321 if ( pFlyFrm )
2323 pAnchorFrm = pFlyFrm->GetAnchorFrm();
2326 else
2328 SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
2329 if ( pDrawContact )
2331 pAnchorFrm = pDrawContact->GetAnchorFrm( pObj );
2334 if ( pAnchorFrm )
2336 if ( i )
2338 bIsGroupAllowed =
2339 ( pAnchorFrm->FindFooterOrHeader() == pHeaderFooterFrm );
2341 else
2343 pHeaderFooterFrm = pAnchorFrm->FindFooterOrHeader();
2351 return bIsGroupAllowed;
2354 /*************************************************************************
2356 |* SwFEShell::GroupSelection()
2358 |* Beschreibung Die Gruppe bekommt den Anker und das Contactobjekt
2359 |* des ersten in der Selektion
2360 |* Ersterstellung MA 30. Jan. 95
2361 |* Letzte Aenderung MA 23. Apr. 95
2363 *************************************************************************/
2365 void SwFEShell::GroupSelection()
2367 if ( IsGroupAllowed() )
2369 StartAllAction();
2370 StartUndo( UNDO_START );
2372 GetDoc()->GroupSelection( *Imp()->GetDrawView() );
2374 EndUndo( UNDO_END );
2375 EndAllAction();
2379 /*************************************************************************
2381 |* SwFEShell::UnGroupSelection()
2383 |* Beschreibung Die Einzelobjekte bekommen eine Kopie vom Anker und
2384 |* Contactobjekt der Gruppe.
2385 |* Ersterstellung MA 30. Jan. 95
2386 |* Letzte Aenderung MA 01. Feb. 95
2388 *************************************************************************/
2390 void SwFEShell::UnGroupSelection()
2392 if ( IsGroupSelected() )
2394 StartAllAction();
2395 StartUndo( UNDO_START );
2397 GetDoc()->UnGroupSelection( *Imp()->GetDrawView() );
2399 EndUndo( UNDO_END );
2400 EndAllAction();
2404 /*************************************************************************
2406 |* SwFEShell::MirrorSelection()
2408 |* Ersterstellung MA 06. Aug. 95
2409 |* Letzte Aenderung MA 06. Aug. 95
2411 *************************************************************************/
2413 void SwFEShell::MirrorSelection( BOOL bHorizontal )
2415 SdrView *pView = Imp()->GetDrawView();
2416 if ( IsObjSelected() && pView->IsMirrorAllowed() )
2418 if ( bHorizontal )
2419 pView->MirrorAllMarkedHorizontal();
2420 else
2421 pView->MirrorAllMarkedVertical();
2425 // springe zum benannten Rahmen (Grafik/OLE)
2427 BOOL SwFEShell::GotoFly( const String& rName, FlyCntType eType, BOOL bSelFrm )
2429 BOOL bRet = FALSE;
2430 static BYTE __READONLY_DATA aChkArr[ 4 ] = {
2431 /* FLYCNTTYPE_ALL */ 0,
2432 /* FLYCNTTYPE_FRM */ ND_TEXTNODE,
2433 /* FLYCNTTYPE_GRF */ ND_GRFNODE,
2434 /* FLYCNTTYPE_OLE */ ND_OLENODE
2437 const SwFlyFrmFmt* pFlyFmt = pDoc->FindFlyByName( rName, aChkArr[ eType]);
2438 if( pFlyFmt )
2440 SET_CURR_SHELL( this );
2442 SwClientIter aIter( *(SwModify*)pFlyFmt );
2443 SwFlyFrm* pFrm = (SwFlyFrm*)aIter.First( TYPE( SwFlyFrm ));
2444 if( pFrm )
2446 ASSERT( pFrm->IsFlyFrm(), "Wrong FrmType" );
2447 if( bSelFrm )
2449 SelectObj( pFrm->Frm().Pos(), 0, ((SwFlyFrm*)pFrm)->GetVirtDrawObj() );
2450 if( !ActionPend() )
2451 MakeVisible( pFrm->Frm() );
2453 else
2455 // --> OD 2004-06-11 #i28701# - no format here
2456 // pFrm->GetAnchorFrm()->Calc();
2457 SwCntntFrm *pCFrm = pFrm->ContainsCntnt();
2458 if ( pCFrm )
2460 SwCntntNode *pCNode = pCFrm->GetNode();
2461 ClearMark();
2462 SwPaM* pCrsr = GetCrsr();
2464 pCrsr->GetPoint()->nNode = *pCNode;
2465 pCrsr->GetPoint()->nContent.Assign( pCNode, 0 );
2467 SwRect& rChrRect = (SwRect&)GetCharRect();
2468 rChrRect = pFrm->Prt();
2469 rChrRect.Pos() += pFrm->Frm().Pos();
2470 GetCrsrDocPos() = rChrRect.Pos();
2473 bRet = TRUE;
2476 return bRet;
2479 USHORT SwFEShell::GetFlyCount( FlyCntType eType ) const
2481 return GetDoc()->GetFlyCount(eType);
2485 const SwFrmFmt* SwFEShell::GetFlyNum(USHORT nIdx, FlyCntType eType ) const
2487 return GetDoc()->GetFlyNum(nIdx, eType );
2490 // zeige das akt. selektierte "Object" an
2491 void SwFEShell::MakeSelVisible()
2493 if( Imp()->HasDrawView() &&
2494 Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )
2496 MakeVisible( Imp()->GetDrawView()->GetAllMarkedRect() );
2498 else
2499 SwCrsrShell::MakeSelVisible();
2503 //Welcher Schutz ist am selektierten Objekt gesetzt?
2504 BYTE SwFEShell::IsSelObjProtected( USHORT eType ) const
2506 int nChk = 0;
2507 const bool bParent = (eType & FLYPROTECT_PARENT);
2508 if( Imp()->HasDrawView() )
2510 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2511 for( ULONG i = rMrkList.GetMarkCount(); i; )
2513 SdrObject *pObj = rMrkList.GetMark( --i )->GetMarkedSdrObj();
2514 if( !bParent )
2516 nChk |= ( pObj->IsMoveProtect() ? FLYPROTECT_POS : 0 ) |
2517 ( pObj->IsResizeProtect()? FLYPROTECT_SIZE : 0 );
2519 if( FLYPROTECT_CONTENT & eType && pObj->ISA(SwVirtFlyDrawObj) )
2521 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2522 if ( pFly->GetFmt()->GetProtect().IsCntntProtected() )
2523 nChk |= FLYPROTECT_CONTENT;
2525 if ( pFly->Lower() && pFly->Lower()->IsNoTxtFrm() )
2527 SwOLENode *pNd = ((SwCntntFrm*)pFly->Lower())->GetNode()->GetOLENode();
2528 if ( pNd )
2530 uno::Reference < embed::XEmbeddedObject > xObj = pNd->GetOLEObj().GetOleRef();
2532 // TODO/LATER: use correct aspect
2533 if ( xObj.is() &&
2534 embed::EmbedMisc::EMBED_NEVERRESIZE & xObj->getStatus( embed::Aspects::MSOLE_CONTENT ) )
2536 nChk |= FLYPROTECT_SIZE;
2537 nChk |= FLYPROTECT_FIXED;
2542 nChk &= eType;
2543 if( nChk == eType )
2544 return static_cast<BYTE>(eType);
2546 const SwFrm* pAnch;
2547 if( pObj->ISA(SwVirtFlyDrawObj) )
2548 pAnch = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchorFrm();
2549 else
2551 SwDrawContact* pTmp = (SwDrawContact*)GetUserCall(pObj);
2552 pAnch = pTmp ? pTmp->GetAnchorFrm( pObj ) : NULL;
2554 if( pAnch && pAnch->IsProtected() )
2555 return static_cast<BYTE>(eType);
2558 return static_cast<BYTE>(nChk);
2561 BOOL SwFEShell::GetObjAttr( SfxItemSet &rSet ) const
2563 if ( !IsObjSelected() )
2564 return FALSE;
2566 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2567 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2569 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2570 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2571 // --> OD 2007-07-24 #143008# - make code robust
2572 ASSERT( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact> - please inform OD." );
2573 if ( pContact )
2575 if ( i )
2576 rSet.MergeValues( pContact->GetFmt()->GetAttrSet() );
2577 else
2578 rSet.Put( pContact->GetFmt()->GetAttrSet() );
2580 // <--
2582 return TRUE;
2585 BOOL SwFEShell::SetObjAttr( const SfxItemSet& rSet )
2587 SET_CURR_SHELL( this );
2589 if ( !rSet.Count() )
2590 { ASSERT( !this, "SetObjAttr, empty set." );
2591 return FALSE;
2594 StartAllAction();
2595 StartUndo( UNDO_INSATTR );
2597 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2598 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2600 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2601 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
2602 GetDoc()->SetAttr( rSet, *pContact->GetFmt() );
2605 EndUndo( UNDO_INSATTR );
2606 EndAllActionAndCall();
2607 GetDoc()->SetModified();
2608 return TRUE;
2611 BOOL SwFEShell::IsAlignPossible() const
2613 USHORT nCnt;
2614 if ( 0 < (nCnt = IsObjSelected()) )
2616 BOOL bRet = TRUE;
2617 if ( nCnt == 1 )
2619 SdrObject *pO = Imp()->GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
2620 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pO);
2621 //only as character bound drawings can be aligned
2622 bRet = pC->GetFmt()->GetAnchor().GetAnchorId() == FLY_IN_CNTNT;
2624 if ( bRet )
2625 return Imp()->GetDrawView()->IsAlignPossible();
2627 return FALSE;
2631 //Temporaerer Fix bis SS von JOE da ist
2632 void SwFEShell::CheckUnboundObjects()
2634 SET_CURR_SHELL( this );
2636 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
2637 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
2639 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
2640 if ( !GetUserCall(pObj) )
2642 const Rectangle &rBound = pObj->GetSnapRect();
2643 const Point aPt( rBound.TopLeft() );
2644 const SwFrm *pPage = GetLayout()->Lower();
2645 const SwFrm *pLast = pPage;
2646 while ( pPage && !pPage->Frm().IsInside( aPt ) )
2648 if ( aPt.Y() > pPage->Frm().Bottom() )
2649 pLast = pPage;
2650 pPage = pPage->GetNext();
2652 if ( !pPage )
2653 pPage = pLast;
2654 ASSERT( pPage, "Page not found." );
2656 //Fremde Identifier sollen in den Default laufen.
2657 //Ueberschneidungen sind moeglich!!
2658 UINT16 nIdent =
2659 Imp()->GetDrawView()->GetCurrentObjInventor() == SdrInventor ?
2660 Imp()->GetDrawView()->GetCurrentObjIdentifier() : 0xFFFF;
2662 SwFmtAnchor aAnch;
2663 const SwFrm *pAnch = 0;
2665 pAnch = ::FindAnchor( pPage, aPt, TRUE );
2666 SwPosition aPos( *((SwCntntFrm*)pAnch)->GetNode() );
2667 aAnch.SetType( FLY_AT_CNTNT );
2668 aAnch.SetAnchor( &aPos );
2669 ((SwRect&)GetCharRect()).Pos() = aPt;
2672 //Erst hier die Action, damit das GetCharRect aktuelle Werte liefert.
2673 StartAllAction();
2675 SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
2676 RES_SURROUND, RES_ANCHOR, 0 );
2677 aSet.Put( aAnch );
2679 Point aRelNullPt;
2681 if( OBJ_CAPTION == nIdent )
2682 aRelNullPt = ((SdrCaptionObj*)pObj)->GetTailPos();
2683 else
2684 aRelNullPt = rBound.TopLeft();
2686 aSet.Put( aAnch );
2687 aSet.Put( SwFmtSurround( SURROUND_THROUGHT ) );
2688 SwFrmFmt* pFmt = getIDocumentLayoutAccess()->MakeLayoutFmt( RND_DRAW_OBJECT, &aSet );
2690 SwDrawContact *pContact = new SwDrawContact(
2691 (SwDrawFrmFmt*)pFmt, pObj );
2693 // --> OD 2004-11-22 #i35635#
2694 pContact->MoveObjToVisibleLayer( pObj );
2695 // <--
2696 pContact->ConnectToLayout();
2698 EndAllAction();
2703 void SwFEShell::SetCalcFieldValueHdl(Outliner* pOutliner)
2705 GetDoc()->SetCalcFieldValueHdl(pOutliner);
2710 int SwFEShell::Chainable( SwRect &rRect, const SwFrmFmt &rSource,
2711 const Point &rPt ) const
2713 rRect.Clear();
2715 //Die Source darf noch keinen Follow haben.
2716 const SwFmtChain &rChain = rSource.GetChain();
2717 if ( rChain.GetNext() )
2718 return SW_CHAIN_SOURCE_CHAINED;
2720 if( Imp()->HasDrawView() )
2722 SdrObject* pObj;
2723 SdrPageView* pPView;
2724 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
2725 const USHORT nOld = pDView->GetHitTolerancePixel();
2726 pDView->SetHitTolerancePixel( 0 );
2727 if( pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE ) &&
2728 pObj->ISA(SwVirtFlyDrawObj) )
2730 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2731 rRect = pFly->Frm();
2733 //Ziel darf natuerlich nicht gleich Source sein und es
2734 //darf keine geschlossene Kette entstehen.
2735 SwFrmFmt *pFmt = pFly->GetFmt();
2736 return GetDoc()->Chainable(rSource, *pFmt);
2738 pDView->SetHitTolerancePixel( nOld );
2740 return SW_CHAIN_NOT_FOUND;
2742 /* -----------------------------09.08.2002 07:40------------------------------
2744 ---------------------------------------------------------------------------*/
2745 int SwFEShell::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
2747 return GetDoc()->Chain(rSource, rDest);
2750 int SwFEShell::Chain( SwFrmFmt &rSource, const Point &rPt )
2752 SwRect aDummy;
2753 int nErr = Chainable( aDummy, rSource, rPt );
2754 if ( !nErr )
2756 StartAllAction();
2757 SdrObject* pObj;
2758 SdrPageView* pPView;
2759 SwDrawView *pDView = (SwDrawView*)Imp()->GetDrawView();
2760 const USHORT nOld = pDView->GetHitTolerancePixel();
2761 pDView->SetHitTolerancePixel( 0 );
2762 pDView->PickObj( rPt, pDView->getHitTolLog(), pObj, pPView, SDRSEARCH_PICKMARKABLE );
2763 pDView->SetHitTolerancePixel( nOld );
2764 SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
2766 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
2767 GetDoc()->Chain(rSource, *pFmt);
2768 EndAllAction();
2769 SetChainMarker();
2771 return nErr;
2774 void SwFEShell::Unchain( SwFrmFmt &rFmt )
2776 StartAllAction();
2777 GetDoc()->Unchain(rFmt);
2778 EndAllAction();
2782 void SwFEShell::HideChainMarker()
2784 if ( pChainFrom )
2786 delete pChainFrom;
2787 pChainFrom = 0L;
2789 if ( pChainTo )
2791 delete pChainTo;
2792 pChainTo = 0L;
2796 void SwFEShell::SetChainMarker()
2798 BOOL bDelFrom = TRUE,
2799 bDelTo = TRUE;
2800 if ( IsFrmSelected() )
2802 SwFlyFrm *pFly = FindFlyFrm();
2804 if ( pFly->GetPrevLink() )
2806 bDelFrom = FALSE;
2807 const SwFrm *pPre = pFly->GetPrevLink();
2809 Point aStart( pPre->Frm().Right(), pPre->Frm().Bottom());
2810 Point aEnd(pFly->Frm().Pos());
2812 if ( !pChainFrom )
2814 pChainFrom = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
2817 if ( pFly->GetNextLink() )
2819 bDelTo = FALSE;
2820 const SwFlyFrm *pNxt = pFly->GetNextLink();
2822 Point aStart( pFly->Frm().Right(), pFly->Frm().Bottom());
2823 Point aEnd(pNxt->Frm().Pos());
2825 if ( !pChainTo )
2827 pChainTo = new SdrDropMarkerOverlay( *GetDrawView(), aStart, aEnd );
2832 if ( bDelFrom )
2834 delete pChainFrom, pChainFrom = 0;
2837 if ( bDelTo )
2839 delete pChainTo, pChainTo = 0;
2843 long SwFEShell::GetSectionWidth( SwFmt& rFmt ) const
2845 SwFrm *pFrm = GetCurrFrm();
2846 // Steht der Cursor z.Z. in einem SectionFrm?
2847 if( pFrm && pFrm->IsInSct() )
2849 SwSectionFrm* pSect = pFrm->FindSctFrm();
2852 // Ist es der Gewuenschte?
2853 if( pSect->GetRegisteredIn() == &rFmt )
2854 return pSect->Frm().Width();
2855 // fuer geschachtelte Bereiche
2856 pSect = pSect->GetUpper()->FindSctFrm();
2858 while( pSect );
2860 SwClientIter aIter( rFmt );
2861 SwClient *pLast = aIter.GoStart();
2862 while ( pLast )
2864 if ( pLast->IsA( TYPE(SwFrm) ) )
2866 SwSectionFrm* pSct = (SwSectionFrm*)pLast;
2867 if( !pSct->IsFollow() )
2868 return pSct->Frm().Width();
2870 pLast = aIter++;
2872 return 0;
2874 /* -----------------------------2002/06/24 15:07------------------------------
2876 ---------------------------------------------------------------------------*/
2877 void SwFEShell::CreateDefaultShape( UINT16 /*SdrObjKind ?*/ eSdrObjectKind, const Rectangle& rRect,
2878 USHORT nSlotId)
2880 SdrView* pDrawView = GetDrawView();
2881 SdrModel* pDrawModel = pDrawView->GetModel();
2882 SdrObject* pObj = SdrObjFactory::MakeNewObject(
2883 SdrInventor, eSdrObjectKind,
2884 0L, pDrawModel);
2886 if(pObj)
2888 Rectangle aRect(rRect);
2889 if(OBJ_CARC == eSdrObjectKind || OBJ_CCUT == eSdrObjectKind)
2891 // force quadratic
2892 if(aRect.GetWidth() > aRect.GetHeight())
2894 aRect = Rectangle(
2895 Point(aRect.Left() + ((aRect.GetWidth() - aRect.GetHeight()) / 2), aRect.Top()),
2896 Size(aRect.GetHeight(), aRect.GetHeight()));
2898 else
2900 aRect = Rectangle(
2901 Point(aRect.Left(), aRect.Top() + ((aRect.GetHeight() - aRect.GetWidth()) / 2)),
2902 Size(aRect.GetWidth(), aRect.GetWidth()));
2905 pObj->SetLogicRect(aRect);
2907 if(pObj->ISA(SdrCircObj))
2909 SfxItemSet aAttr(pDrawModel->GetItemPool());
2910 aAttr.Put(SdrCircStartAngleItem(9000));
2911 aAttr.Put(SdrCircEndAngleItem(0));
2912 pObj->SetMergedItemSet(aAttr);
2914 else if(pObj->ISA(SdrPathObj))
2916 basegfx::B2DPolyPolygon aPoly;
2918 switch(eSdrObjectKind)
2920 case OBJ_PATHLINE:
2922 basegfx::B2DPolygon aInnerPoly;
2924 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2926 const basegfx::B2DPoint aCenterBottom(aRect.Center().X(), aRect.Bottom());
2927 aInnerPoly.appendBezierSegment(
2928 aCenterBottom,
2929 aCenterBottom,
2930 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
2932 const basegfx::B2DPoint aCenterTop(aRect.Center().X(), aRect.Top());
2933 aInnerPoly.appendBezierSegment(
2934 aCenterTop,
2935 aCenterTop,
2936 basegfx::B2DPoint(aRect.Right(), aRect.Top()));
2938 aInnerPoly.setClosed(true);
2939 aPoly.append(aInnerPoly);
2941 break;
2942 case OBJ_FREELINE:
2944 basegfx::B2DPolygon aInnerPoly;
2946 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2948 aInnerPoly.appendBezierSegment(
2949 basegfx::B2DPoint(aRect.Left(), aRect.Top()),
2950 basegfx::B2DPoint(aRect.Center().X(), aRect.Top()),
2951 basegfx::B2DPoint(aRect.Center().X(), aRect.Center().Y()));
2953 aInnerPoly.appendBezierSegment(
2954 basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()),
2955 basegfx::B2DPoint(aRect.Right(), aRect.Bottom()),
2956 basegfx::B2DPoint(aRect.Right(), aRect.Top()));
2958 aInnerPoly.append(basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));
2959 aInnerPoly.setClosed(true);
2960 aPoly.append(aInnerPoly);
2962 break;
2963 case OBJ_POLY:
2964 case OBJ_PLIN:
2966 basegfx::B2DPolygon aInnerPoly;
2967 sal_Int32 nWdt(aRect.GetWidth());
2968 sal_Int32 nHgt(aRect.GetHeight());
2970 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Bottom()));
2971 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 30) / 100, aRect.Top() + (nHgt * 70) / 100));
2972 aInnerPoly.append(basegfx::B2DPoint(aRect.Left(), aRect.Top() + (nHgt * 15) / 100));
2973 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 65) / 100, aRect.Top()));
2974 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + nWdt, aRect.Top() + (nHgt * 30) / 100));
2975 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 50) / 100));
2976 aInnerPoly.append(basegfx::B2DPoint(aRect.Left() + (nWdt * 80) / 100, aRect.Top() + (nHgt * 75) / 100));
2977 aInnerPoly.append(basegfx::B2DPoint(aRect.Bottom(), aRect.Right()));
2979 if(OBJ_PLIN == eSdrObjectKind)
2981 aInnerPoly.append(basegfx::B2DPoint(aRect.Center().X(), aRect.Bottom()));
2983 else
2985 aInnerPoly.setClosed(true);
2988 aPoly.append(aInnerPoly);
2990 break;
2991 case OBJ_LINE :
2993 sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
2994 basegfx::B2DPolygon aTempPoly;
2995 aTempPoly.append(basegfx::B2DPoint(aRect.TopLeft().X(), nYMiddle));
2996 aTempPoly.append(basegfx::B2DPoint(aRect.BottomRight().X(), nYMiddle));
2997 aPoly.append(aTempPoly);
2999 break;
3002 ((SdrPathObj*)pObj)->SetPathPoly(aPoly);
3004 else if(pObj->ISA(SdrCaptionObj))
3006 BOOL bVerticalText = ( SID_DRAW_TEXT_VERTICAL == nSlotId ||
3007 SID_DRAW_CAPTION_VERTICAL == nSlotId );
3008 ((SdrTextObj*)pObj)->SetVerticalWriting(bVerticalText);
3009 if(bVerticalText)
3011 SfxItemSet aSet(pObj->GetMergedItemSet());
3012 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
3013 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
3014 pObj->SetMergedItemSet(aSet);
3017 ((SdrCaptionObj*)pObj)->SetLogicRect(aRect);
3018 ((SdrCaptionObj*)pObj)->SetTailPos(
3019 aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
3021 else if(pObj->ISA(SdrTextObj))
3023 SdrTextObj* pText = (SdrTextObj*)pObj;
3024 pText->SetLogicRect(aRect);
3026 sal_Bool bVertical = (SID_DRAW_TEXT_VERTICAL == nSlotId);
3027 sal_Bool bMarquee = (SID_DRAW_TEXT_MARQUEE == nSlotId);
3029 pText->SetVerticalWriting(bVertical);
3031 if(bVertical)
3033 SfxItemSet aSet(pDrawModel->GetItemPool());
3034 aSet.Put(SdrTextAutoGrowWidthItem(TRUE));
3035 aSet.Put(SdrTextAutoGrowHeightItem(FALSE));
3036 aSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP));
3037 aSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT));
3038 pText->SetMergedItemSet(aSet);
3041 if(bMarquee)
3043 SfxItemSet aSet(pDrawModel->GetItemPool(), SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST);
3044 aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
3045 aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
3046 aSet.Put( SdrTextAniKindItem( SDRTEXTANI_SLIDE ) );
3047 aSet.Put( SdrTextAniDirectionItem( SDRTEXTANI_LEFT ) );
3048 aSet.Put( SdrTextAniCountItem( 1 ) );
3049 aSet.Put( SdrTextAniAmountItem( (INT16)GetWin()->PixelToLogic(Size(2,1)).Width()) );
3050 pObj->SetMergedItemSetAndBroadcast(aSet);
3053 SdrPageView* pPageView = pDrawView->GetSdrPageView();
3054 pDrawView->InsertObjectAtView(pObj, *pPageView);
3056 ImpEndCreate();
3059 /** SwFEShell::GetShapeBackgrd
3061 OD 02.09.2002 for #102450#:
3062 method determines background color of the page the selected drawing
3063 object is on and returns this color.
3064 If no color is found, because no drawing object is selected or ...,
3065 color COL_BLACK (default color on constructing object of class Color)
3066 is returned.
3068 @author OD
3070 @returns an object of class Color
3072 const Color SwFEShell::GetShapeBackgrd() const
3074 Color aRetColor;
3076 // check, if a draw view exists
3077 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
3078 if( Imp()->GetDrawView() )
3080 // determine list of selected objects
3081 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
3082 // check, if exactly one object is selected.
3083 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
3084 if ( pMrkList->GetMarkCount() == 1)
3086 // get selected object
3087 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
3088 // check, if selected object is a shape (drawing object)
3089 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
3090 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
3092 // determine page frame of the frame the shape is anchored.
3093 const SwFrm* pAnchorFrm =
3094 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
3095 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
3096 if ( pAnchorFrm )
3098 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
3099 ASSERT( pPageFrm, "inconsistent modell - no page!");
3100 if ( pPageFrm )
3102 aRetColor = pPageFrm->GetDrawBackgrdColor();
3109 return aRetColor;
3112 /** Is default horizontal text direction for selected drawing object right-to-left
3114 OD 09.12.2002 #103045#
3115 Because drawing objects only painted for each page only, the default
3116 horizontal text direction of a drawing object is given by the corresponding
3117 page property.
3119 @author OD
3121 @returns boolean, indicating, if the horizontal text direction of the
3122 page, the selected drawing object is on, is right-to-left.
3124 bool SwFEShell::IsShapeDefaultHoriTextDirR2L() const
3126 bool bRet = false;
3128 // check, if a draw view exists
3129 ASSERT( Imp()->GetDrawView(), "wrong usage of SwFEShell::GetShapeBackgrd - no draw view!");
3130 if( Imp()->GetDrawView() )
3132 // determine list of selected objects
3133 const SdrMarkList* pMrkList = &Imp()->GetDrawView()->GetMarkedObjectList();
3134 // check, if exactly one object is selected.
3135 ASSERT( pMrkList->GetMarkCount() == 1, "wrong usage of SwFEShell::GetShapeBackgrd - no selected object!");
3136 if ( pMrkList->GetMarkCount() == 1)
3138 // get selected object
3139 const SdrObject *pSdrObj = pMrkList->GetMark( 0 )->GetMarkedSdrObj();
3140 // check, if selected object is a shape (drawing object)
3141 ASSERT( !pSdrObj->ISA(SwVirtFlyDrawObj), "wrong usage of SwFEShell::GetShapeBackgrd - selected object is not a drawing object!");
3142 if ( !pSdrObj->ISA(SwVirtFlyDrawObj) )
3144 // determine page frame of the frame the shape is anchored.
3145 const SwFrm* pAnchorFrm =
3146 static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrm( pSdrObj );
3147 ASSERT( pAnchorFrm, "inconsistent modell - no anchor at shape!");
3148 if ( pAnchorFrm )
3150 const SwPageFrm* pPageFrm = pAnchorFrm->FindPageFrm();
3151 ASSERT( pPageFrm, "inconsistent modell - no page!");
3152 if ( pPageFrm )
3154 bRet = pPageFrm->IsRightToLeft() ? true : false;
3161 return bRet;
3163 /* -----------------20.03.2003 14:35-----------------
3165 --------------------------------------------------*/
3166 Point SwFEShell::GetRelativePagePosition(const Point& rDocPos)
3168 Point aRet(-1, -1);
3169 const SwFrm *pPage = GetLayout()->Lower();
3170 while ( pPage && !pPage->Frm().IsInside( rDocPos ) )
3172 pPage = pPage->GetNext();
3174 if(pPage)
3176 aRet = rDocPos - pPage->Frm().TopLeft();
3178 return aRet;